diff options
Diffstat (limited to 'debian/patches/bugfix/all/radeon-amdgpu-firmware-is-required-for-drm-and-kms-on-r600-onward.patch')
-rw-r--r-- | debian/patches/bugfix/all/radeon-amdgpu-firmware-is-required-for-drm-and-kms-on-r600-onward.patch | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/debian/patches/bugfix/all/radeon-amdgpu-firmware-is-required-for-drm-and-kms-on-r600-onward.patch b/debian/patches/bugfix/all/radeon-amdgpu-firmware-is-required-for-drm-and-kms-on-r600-onward.patch new file mode 100644 index 000000000..a40c600ae --- /dev/null +++ b/debian/patches/bugfix/all/radeon-amdgpu-firmware-is-required-for-drm-and-kms-on-r600-onward.patch @@ -0,0 +1,139 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Subject: radeon, amdgpu: Firmware is required for DRM and KMS on R600 onward +Date: Tue, 08 Jan 2013 03:25:52 +0000 +Bug-Debian: https://bugs.debian.org/607194 +Bug-Debian: https://bugs.debian.org/607471 +Bug-Debian: https://bugs.debian.org/610851 +Bug-Debian: https://bugs.debian.org/627497 +Bug-Debian: https://bugs.debian.org/632212 +Bug-Debian: https://bugs.debian.org/637943 +Bug-Debian: https://bugs.debian.org/649448 +Bug-Debian: https://bugs.debian.org/697229 +Forwarded: no + +radeon requires firmware/microcode for the GPU in all chips, but for +newer chips (apparently R600 'Evergreen' onward) it also expects +firmware for the memory controller and other sub-blocks. + +radeon attempts to gracefully fall back and disable some features if +the firmware is not available, but becomes unstable - the framebuffer +and/or system memory may be corrupted, or the display may stay black. + +Therefore, perform a basic check for the existence of +/lib/firmware/{radeon,amdgpu} when a device is probed, and abort if it +is missing, except for the pre-R600 case. + +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 29 ++++++++++++++++++++++++ + drivers/gpu/drm/radeon/radeon_drv.c | 30 +++++++++++++++++++++++++ + 2 files changed, 59 insertions(+) + +Index: debian-kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +=================================================================== +--- debian-kernel.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c ++++ debian-kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +@@ -36,6 +36,8 @@ + #include <linux/vga_switcheroo.h> + #include <drm/drm_probe_helper.h> + #include <linux/mmu_notifier.h> ++#include <linux/namei.h> ++#include <linux/path.h> + + #include "amdgpu.h" + #include "amdgpu_irq.h" +@@ -1017,6 +1019,28 @@ MODULE_DEVICE_TABLE(pci, pciidlist); + + static struct drm_driver kms_driver; + ++/* Test that /lib/firmware/amdgpu is a directory (or symlink to a ++ * directory). We could try to match the udev search path, but let's ++ * keep it simple. ++ */ ++static bool amdgpu_firmware_installed(void) ++{ ++#if IS_BUILTIN(CONFIG_DRM_AMDGPU) ++ /* It may be too early to tell. Assume it's there. */ ++ return true; ++#else ++ struct path path; ++ ++ if (kern_path("/lib/firmware/amdgpu", LOOKUP_DIRECTORY | LOOKUP_FOLLOW, ++ &path) == 0) { ++ path_put(&path); ++ return true; ++ } ++ ++ return false; ++#endif ++} ++ + static int amdgpu_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) + { +@@ -1070,6 +1094,11 @@ static int amdgpu_pci_probe(struct pci_d + } + #endif + ++ if (!amdgpu_firmware_installed()) { ++ DRM_ERROR("amdgpu requires firmware installed\n"); ++ return -ENODEV; ++ } ++ + /* Get rid of things like offb */ + ret = drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, "amdgpudrmfb"); + if (ret) +Index: debian-kernel/drivers/gpu/drm/radeon/radeon_drv.c +=================================================================== +--- debian-kernel.orig/drivers/gpu/drm/radeon/radeon_drv.c ++++ debian-kernel/drivers/gpu/drm/radeon/radeon_drv.c +@@ -48,6 +48,8 @@ + #include <drm/drm_probe_helper.h> + #include <drm/drm_vblank.h> + #include <drm/radeon_drm.h> ++#include <linux/namei.h> ++#include <linux/path.h> + + #include "radeon_drv.h" + +@@ -321,6 +323,28 @@ static struct drm_driver kms_driver; + + bool radeon_device_is_virtual(void); + ++/* Test that /lib/firmware/radeon is a directory (or symlink to a ++ * directory). We could try to match the udev search path, but let's ++ * keep it simple. ++ */ ++static bool radeon_firmware_installed(void) ++{ ++#if IS_BUILTIN(CONFIG_DRM_RADEON) ++ /* It may be too early to tell. Assume it's there. */ ++ return true; ++#else ++ struct path path; ++ ++ if (kern_path("/lib/firmware/radeon", LOOKUP_DIRECTORY | LOOKUP_FOLLOW, ++ &path) == 0) { ++ path_put(&path); ++ return true; ++ } ++ ++ return false; ++#endif ++} ++ + static int radeon_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) + { +@@ -360,6 +384,12 @@ static int radeon_pci_probe(struct pci_d + if (vga_switcheroo_client_probe_defer(pdev)) + return -EPROBE_DEFER; + ++ if ((ent->driver_data & RADEON_FAMILY_MASK) >= CHIP_R600 && ++ !radeon_firmware_installed()) { ++ DRM_ERROR("radeon kernel modesetting for R600 or later requires firmware installed\n"); ++ return -ENODEV; ++ } ++ + /* Get rid of things like offb */ + ret = drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, "radeondrmfb"); + if (ret) |