From e0000f8ad1cf4b2f85d56033751c6eb61bc7c073 Mon Sep 17 00:00:00 2001 From: Jaka Hudoklin Date: Wed, 22 Jan 2014 10:57:43 +0100 Subject: ati-drivers: update to 13.12 (close #1569) This update is mostly effort from @MarcWeber and @vcunat, now tested on real hardware making sure it works with multiple GPUs and opencl. --- pkgs/os-specific/linux/ati-drivers/builder.sh | 5 +- pkgs/os-specific/linux/ati-drivers/default.nix | 26 +- .../linux/ati-drivers/gentoo-patches.patch | 330 +++------------------ .../linux/ati-drivers/patch-samples.patch | 26 ++ 4 files changed, 89 insertions(+), 298 deletions(-) create mode 100644 pkgs/os-specific/linux/ati-drivers/patch-samples.patch (limited to 'pkgs/os-specific/linux') diff --git a/pkgs/os-specific/linux/ati-drivers/builder.sh b/pkgs/os-specific/linux/ati-drivers/builder.sh index 2a20aa29fcc9..d1ca1b354522 100644 --- a/pkgs/os-specific/linux/ati-drivers/builder.sh +++ b/pkgs/os-specific/linux/ati-drivers/builder.sh @@ -8,7 +8,7 @@ die(){ echo $@; exit 1; } # custom unpack: unzip $src -run_file=$(echo amd-driver-installer-*) +run_file=$(echo amd-catalyst-*) sh $run_file --extract . eval "$patchPhase" @@ -181,6 +181,8 @@ GCC_MAJOR="`gcc --version | grep -o -e ") ." | head -1 | cut -d " " -f 2`" # make xorg use the ati version ln -s $out/lib/xorg/modules/extensions/{fglrx/fglrx-libglx.so,libglx.so} + # libstdc++ and gcc are needed by some libs + patchelf --set-rpath $gcc/$lib_arch $out/lib/libatiadlxx.so } { # build samples @@ -190,6 +192,7 @@ GCC_MAJOR="`gcc --version | grep -o -e ") ." | head -1 | cut -d " " -f 2`" cd samples tar xfz ../common/usr/src/ati/fglrx_sample_source.tgz + eval "$patchPhaseSamples" ( # build and install fgl_glxgears cd fgl_glxgears; diff --git a/pkgs/os-specific/linux/ati-drivers/default.nix b/pkgs/os-specific/linux/ati-drivers/default.nix index 8f5ecb712059..518ca784d4a8 100644 --- a/pkgs/os-specific/linux/ati-drivers/default.nix +++ b/pkgs/os-specific/linux/ati-drivers/default.nix @@ -13,30 +13,35 @@ # See http://thread.gmane.org/gmane.linux.distributions.nixos/4145 for a # workaround (TODO) -# The gentoo ebuild contains much more magic.. +# The gentoo ebuild contains much more magic and is usually a great resource to +# find patches :) # http://wiki.cchtml.com/index.php/Main_Page # There is one issue left: # /usr/lib/dri/fglrx_dri.so must point to /run/opengl-driver/lib/fglrx_dri.so -assert stdenv.system == "x86_64-linux"; +# You eventually have to blacklist radeon module (?) +assert stdenv.system == "x86_64-linux"; stdenv.mkDerivation { - name = "ati-drivers-13.4-${kernel.version}"; + name = "ati-drivers-13.12-${kernel.version}"; builder = ./builder.sh; inherit libXxf86vm xf86vidmodeproto; + gcc = stdenv.gcc.gcc; src = fetchurl { - url = http://www2.ati.com/drivers/linux/amd-driver-installer-catalyst-13-4-linux-x86.x86_64.zip; - sha256 = "1914ikdich0kg047bqh89ai5z4dyryj5mlw5i46n90fsfiaxa532"; + url = http://www2.ati.com/drivers/linux/amd-catalyst-13.12-linux-x86.x86_64.zip; + sha256 = "1jm0c4rqyjjhyj8a7axf4hz16bcvy8yhnkn45wc2l73xhks36h02"; curlOpts = "--referer http://support.amd.com/en-us/download/desktop?os=Linux%20x86_64"; }; - patchPhase = "patch -p0 < ${./gentoo-patches.patch}"; + # most patches are taken from gentoo + patchPhase = "patch -p1 < ${./gentoo-patches.patch}"; + patchPhaseSamples = "patch -p2 < ${./patch-samples.patch}"; buildInputs = [ xlibs.libXext xlibs.libX11 xlibs.libXinerama @@ -61,18 +66,17 @@ stdenv.mkDerivation { # without this some applications like blender don't start, but they start # with nvidia. This causes them to be symlinked to $out/lib so that they # appear in /run/opengl-driver/lib which get's added to LD_LIBRARY_PATH - extraDRIlibs = [ xorg.libXext ]; + extraDRIlibs = [ xorg.libXext ]; inherit mesa; # only required to build examples - meta = { + meta = with stdenv.lib; { description = "ATI drivers"; homepage = http://support.amd.com/us/gpudownload/Pages/index.aspx; - license = "unfree"; - maintainers = [stdenv.lib.maintainers.marcweber]; + license = licenses.unfree; + maintainers = with maintainers; [marcweber offline]; platforms = [ "x86_64-linux" ]; hydraPlatforms = []; - broken = true; }; # moved assertions here because the name is evaluated when the NixOS manual is generated diff --git a/pkgs/os-specific/linux/ati-drivers/gentoo-patches.patch b/pkgs/os-specific/linux/ati-drivers/gentoo-patches.patch index ce4871c0658b..392c2a8c29e3 100644 --- a/pkgs/os-specific/linux/ati-drivers/gentoo-patches.patch +++ b/pkgs/os-specific/linux/ati-drivers/gentoo-patches.patch @@ -1,293 +1,51 @@ -diff -Nur common/lib/modules/fglrx/build_mod/drmP.h common-r1/lib/modules/fglrx/build_mod/drmP.h ---- common/lib/modules/fglrx/build_mod/drmP.h 2013-05-15 09:26:23.555752577 +0300 -+++ common-r1/lib/modules/fglrx/build_mod/drmP.h 2013-05-16 10:39:17.496212055 +0300 -@@ -901,10 +901,6 @@ - int DRM(stub_unregister)(int minor); +diff --git a/common/lib/modules/fglrx/build_mod/firegl_public.c b/common/lib/modules/fglrx/build_mod/firegl_public.c +index d3ad3ce..9362b58 100755 +--- a/common/lib/modules/fglrx/build_mod/firegl_public.c ++++ b/common/lib/modules/fglrx/build_mod/firegl_public.c +@@ -34,6 +34,11 @@ + #include + #endif - /* Proc support (drm_proc.h) */ --extern struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, -- int minor, -- struct proc_dir_entry *root, -- struct proc_dir_entry **dev_root); - extern int DRM(proc_cleanup)(int minor, - struct proc_dir_entry *root, - struct proc_dir_entry *dev_root); -diff -Nur common/lib/modules/fglrx/build_mod/drm_proc.h common-r1/lib/modules/fglrx/build_mod/drm_proc.h ---- common/lib/modules/fglrx/build_mod/drm_proc.h 2013-05-15 09:26:23.555752577 +0300 -+++ common-r1/lib/modules/fglrx/build_mod/drm_proc.h 2013-05-19 02:16:16.584406160 +0300 -@@ -75,61 +75,6 @@ - #define DRM_PROC_ENTRIES (sizeof(DRM(proc_list))/sizeof(DRM(proc_list)[0])) - - /** -- * Initialize the DRI proc filesystem for a device. -- * -- * \param dev DRM device. -- * \param minor device minor number. -- * \param root DRI proc dir entry. -- * \param dev_root resulting DRI device proc dir entry. -- * \return root entry pointer on success, or NULL on failure. -- * -- * Create the DRI proc root entry "/proc/ati", the device proc root entry -- * "/proc/ati/%minor%/", and each entry in proc_list as -- * "/proc/ati/%minor%/%name%". -- */ --struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, int minor, -- struct proc_dir_entry *root, -- struct proc_dir_entry **dev_root) --{ -- struct proc_dir_entry *ent; -- int i, j; -- char name[64]; -- -- if (!minor) root = create_proc_entry("dri", S_IFDIR, NULL); -- if (!root) { -- DRM_ERROR("Cannot create /proc/ati\n"); -- return NULL; -- } -- -- sprintf(name, "%d", minor); -- *dev_root = create_proc_entry(name, S_IFDIR, root); -- if (!*dev_root) { -- DRM_ERROR("Cannot create /proc/ati/%s\n", name); -- return NULL; -- } -- -- for (i = 0; i < DRM_PROC_ENTRIES; i++) { -- ent = create_proc_entry(DRM(proc_list)[i].name, -- S_IFREG|S_IRUGO, *dev_root); -- if (!ent) { -- DRM_ERROR("Cannot create /proc/ati/%s/%s\n", -- name, DRM(proc_list)[i].name); -- for (j = 0; j < i; j++) -- remove_proc_entry(DRM(proc_list)[i].name, -- *dev_root); -- remove_proc_entry(name, root); -- if (!minor) remove_proc_entry("dri", NULL); -- return NULL; -- } -- ent->read_proc = DRM(proc_list)[i].f; -- ent->data = dev; -- } -- -- return root; --} -- -- --/** - * Cleanup the proc filesystem resources. - * - * \param minor device minor number. -diff -Nur common/lib/modules/fglrx/build_mod/firegl_public.c common-r1/lib/modules/fglrx/build_mod/firegl_public.c ---- common/lib/modules/fglrx/build_mod/firegl_public.c 2013-05-15 09:26:23.545752925 +0300 -+++ common-r1/lib/modules/fglrx/build_mod/firegl_public.c 2013-05-19 03:07:10.236552522 +0300 -@@ -583,6 +583,202 @@ - { "NULL", NULL, NULL} // Terminate List!!! - }; - -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) -+typedef int (read_proc_t)(char *page, char **start, off_t off, int count, int *eof, void *data); -+typedef int (write_proc_t)(struct file *file, const char __user *buffer, unsigned long count, void *data); -+#else -+#define PDE_DATA(inode) (PDE((inode))->data) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) ++#include +#endif + -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) -+typedef struct { -+ read_proc_t *read_func; -+ write_proc_t *write_func; -+ void *data; -+} gentoo_proc_wrapper_t; -+ -+#define GENTOO_PROC_WRAPPER_OVERFLOW_MAGIC 939750305 -+ -+static ssize_t gentoo_proc_wrapper_read (struct file *myfile, char __user *buffer, size_t count, loff_t *offset) { -+ int is_eof=0, retval; -+ char *start, *usebuffer=NULL; -+ gentoo_proc_wrapper_t* wrapper_data=(gentoo_proc_wrapper_t*)(myfile->private_data); -+ if (PAGE_SIZE<*offset) { -+ printk(KERN_ERR "Trying to read beyond 4k on proc\n"); -+ return -EIO; -+ } -+ //printk(KERN_NOTICE " call with: dev %p, func %p\n", wrapper_data->data, wrapper_data->read_func); -+ -+ usebuffer=kmalloc(2*PAGE_SIZE, GFP_KERNEL); -+ if (!usebuffer) -+ return -ENOMEM; -+ ((u32*)usebuffer)[1024]=GENTOO_PROC_WRAPPER_OVERFLOW_MAGIC; -+ -+ retval=wrapper_data->read_func(usebuffer, &start, *offset, count, &is_eof, wrapper_data->data); -+ -+ BUG_ON(GENTOO_PROC_WRAPPER_OVERFLOW_MAGIC != ((u32*)usebuffer)[1024]); -+ -+ if (0 > retval) -+ { -+ printk(KERN_ERR "Proc read failed with %d", retval); -+ goto out; -+ } -+ -+ if (copy_to_user(buffer, start, retval)) { -+ printk(KERN_NOTICE "copy to user failed in amd drivers proc code\n"); -+ retval=-EFAULT; -+ goto out; -+ } -+ *offset+=retval; -+ -+out: -+ if (usebuffer) -+ kfree(usebuffer); -+ return retval; -+} -+static ssize_t gentoo_proc_wrapper_write (struct file *myfile, const char __user *buffer, size_t count, loff_t *offset) { -+ gentoo_proc_wrapper_t* wrapper_data=(gentoo_proc_wrapper_t*)(myfile->private_data); -+ int retval=0; -+ void *usebuffer=NULL; -+ -+ BUG_ON(*offset); -+ if (!wrapper_data->write_func) -+ return -EPERM; -+ -+ usebuffer=kmalloc(count, GFP_KERNEL); -+ if (!usebuffer) -+ return -ENOMEM; -+ if (copy_from_user(usebuffer, buffer, count)) { -+ printk(KERN_NOTICE "copy from user failed in amd drivers proc code\n"); -+ retval=-EFAULT; -+ goto out; -+ } -+ -+ retval=wrapper_data->write_func(myfile, buffer, count, wrapper_data->data); -+ *offset+=retval; -+out: -+ if (usebuffer) -+ kfree(usebuffer); -+ return retval; -+} -+static int gentoo_proc_wrapper_open(struct inode *myinode, struct file *myfile) { -+ myfile->private_data=PDE_DATA(myinode); -+ return generic_file_open(myinode, myfile); -+} -+struct file_operations gentoo_proc_fops = { -+ .read=gentoo_proc_wrapper_read, -+ .write=gentoo_proc_wrapper_write, -+ .open=gentoo_proc_wrapper_open, -+}; -+ -+static void *gentoo_proc_wrapper_data(read_proc_t *reader, write_proc_t *writer, void *mydata) { -+ gentoo_proc_wrapper_t *retval=kmalloc(sizeof(gentoo_proc_wrapper_t), GFP_KERNEL); -+ if (!retval) -+ return retval; -+ retval->read_func=reader; -+ retval->write_func=writer; -+ retval->data=mydata; -+ return retval; -+} -+ -+static struct proc_dir_entry *firegl_proc_init( device_t *dev, -+ int minor, -+ struct proc_dir_entry *root, -+ struct proc_dir_entry **dev_root, -+ kcl_proc_list_t *proc_list ) // proc_list must be terminated! -+{ -+ struct proc_dir_entry *ent; -+ char name[64]; -+ kcl_proc_list_t *list = proc_list; -+ void *tempdata; -+ KCL_DEBUG1(FN_FIREGL_PROC, "minor %d, proc_list 0x%08lx\n", minor, (unsigned long)proc_list); -+ if (!minor) -+ { -+ root = proc_mkdir("ati", NULL); -+ } -+ -+ if (!root) -+ { -+ KCL_DEBUG_ERROR("Cannot create /proc/ati\n"); -+ return NULL; -+ } -+ -+ if (minor == 0) -+ { -+ // Global major debice number entry -+ tempdata=gentoo_proc_wrapper_data((read_proc_t*)firegl_major_proc_read, NULL, NULL); -+ if (!tempdata) -+ return NULL; -+ ent = proc_create_data("major", S_IFREG|S_IRUGO, root, &gentoo_proc_fops, tempdata); -+ if (!ent) -+ { -+ remove_proc_entry("ati", NULL); -+ KCL_DEBUG_ERROR("Cannot create /proc/ati/major\n"); -+ return NULL; -+ } -+ } -+ -+ sprintf(name, "%d", minor); -+ *dev_root = proc_mkdir(name, root); -+ if (!*dev_root) { -+ remove_proc_entry("major", root); -+ remove_proc_entry("ati", NULL); -+ KCL_DEBUG_ERROR("Cannot create /proc/ati/%s\n", name); -+ return NULL; -+ } -+ -+ while (list->f || list->fops) -+ { -+ struct file_operations *my_fops = &gentoo_proc_fops; -+ if (list->fops) -+ { -+ my_fops = (struct file_operations*)list->fops; -+ tempdata=(dev->pubdev.signature == FGL_DEVICE_SIGNATURE)? firegl_find_device(minor) : (dev); -+ } -+ else { -+ BUG_ON(!list->f); -+ tempdata=gentoo_proc_wrapper_data((read_proc_t*)list->f, NULL, (dev->pubdev.signature == FGL_DEVICE_SIGNATURE)? firegl_find_device(minor) : (dev) ); -+ if (!tempdata) -+ return NULL; -+ } -+ //printk(KERN_NOTICE "name %s, dev %p, func %p, data %p\n", list->name, (dev->pubdev.signature == FGL_DEVICE_SIGNATURE)? firegl_find_device(minor) : (dev), list->f, tempdata); -+ ent = proc_create_data(list->name, S_IFREG|S_IRUGO, *dev_root, my_fops, tempdata); -+ -+ if (!ent) -+ { -+ KCL_DEBUG_ERROR("Cannot create /proc/ati/%s/%s\n", name, list->name); -+ while (proc_list != list) -+ { -+ remove_proc_entry(proc_list->name, *dev_root); -+ proc_list++; -+ } -+ remove_proc_entry(name, root); -+ if (!minor) -+ { -+ remove_proc_entry("major", root); -+ remove_proc_entry("ati", NULL); -+ } -+ return NULL; -+ } -+ -+ list++; -+ } + -+ if (minor == 0) -+ { -+ // Global debug entry, only create it once -+ tempdata=gentoo_proc_wrapper_data((read_proc_t*)firegl_debug_proc_read_wrap, (write_proc_t*)firegl_debug_proc_write_wrap, dev); -+ if (!tempdata) -+ return NULL; -+ ent=proc_create_data("debug", S_IFREG|S_IRUGO, root, &gentoo_proc_fops, tempdata); -+ if (!ent) -+ return NULL; + #if !defined(CONFIG_X86) + #if !defined(CONFIG_X86_PC) + #if !defined(CONFIG_X86_XEN) +@@ -1543,9 +1548,17 @@ KCL_TYPE_Pid ATI_API_CALL KCL_GetTgid(void) + KCL_TYPE_Uid ATI_API_CALL KCL_GetEffectiveUid(void) + { + #ifdef current_euid ++# if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) ++ return __kuid_val(current_euid()); ++# else + return current_euid(); ++# endif + #else ++# if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) ++ return __kuid_val(current->euid); ++# else + return current->euid; ++# endif + #endif + } + + +diff -urN a/common/lib/modules/fglrx/build_mod/kcl_acpi.c common/lib/modules/fglrx/build_mod/kcl_acpi.c +--- a/common/lib/modules/fglrx/build_mod/kcl_acpi.c 2013-12-27 13:32:34.734832283 +0100 ++++ b/common/lib/modules/fglrx/build_mod/kcl_acpi.c 2013-12-27 13:33:31.849831765 +0100 +@@ -1002,7 +1002,11 @@ + #endif + { + return KCL_ACPI_ERROR; +- } + } -+ -+ return root; -+} ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,1) ++ ((acpi_tbl_table_handler)handler)(hdr); +#else - static struct proc_dir_entry *firegl_proc_init( device_t *dev, - int minor, - struct proc_dir_entry *root, -@@ -677,6 +873,7 @@ - - return root; - } + ((acpi_table_handler)handler)(hdr); +#endif - - static int firegl_proc_cleanup( int minor, - struct proc_dir_entry *root, + return KCL_ACPI_OK; + } diff --git a/pkgs/os-specific/linux/ati-drivers/patch-samples.patch b/pkgs/os-specific/linux/ati-drivers/patch-samples.patch new file mode 100644 index 000000000000..8bd24b1d022b --- /dev/null +++ b/pkgs/os-specific/linux/ati-drivers/patch-samples.patch @@ -0,0 +1,26 @@ +diff --git a/samples/fgl_glxgears/fgl_glxgears.c b/samples/fgl_glxgears/fgl_glxgears.c +index 6c8e313..2b8d035 100644 +--- a/samples/fgl_glxgears/fgl_glxgears.c ++++ b/samples/fgl_glxgears/fgl_glxgears.c +@@ -1096,8 +1096,6 @@ static void event_loop(void) + view_rotx -= 5.0; + } + else { +- r = XLookupString(&event.xkey, buffer, sizeof(buffer), +- NULL, NULL); + if (buffer[0] == 27) { + /* escape */ + return; + + +diff -Nur a/samples/fgl_glxgears/fgl_glxgears.c b/samples/fgl_glxgears/fgl_glxgears.c +--- a/samples/fgl_glxgears/fgl_glxgears.c 2012-08-29 09:59:03.000000000 +0300 ++++ b/samples/fgl_glxgears/fgl_glxgears.c 2013-09-07 09:26:11.034723135 +0300 +@@ -78,7 +78,6 @@ + #endif // _WIN32 + + #define INT_PTR ptrdiff_t +-#include + + #ifdef _WIN32 + #include -- cgit 1.4.1