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 | 135 |
1 files changed, 135 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..fe502df7e --- /dev/null +++ b/debian/patches/bugfix/all/radeon-amdgpu-firmware-is-required-for-drm-and-kms-on-r600-onward.patch @@ -0,0 +1,135 @@ +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(+) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +@@ -39,6 +39,8 @@ + #include <linux/cc_platform.h> + #include <linux/fb.h> + #include <linux/dynamic_debug.h> ++#include <linux/namei.h> ++#include <linux/path.h> + + #include "amdgpu.h" + #include "amdgpu_irq.h" +@@ -2039,6 +2041,28 @@ static void amdgpu_get_secondary_funcs(s + } + } + ++/* 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) + { +@@ -2122,6 +2146,11 @@ static int amdgpu_pci_probe(struct pci_d + } + #endif + ++ if (!amdgpu_firmware_installed()) { ++ DRM_ERROR("amdgpu requires firmware installed\n"); ++ return -ENODEV; ++ } ++ + adev = devm_drm_dev_alloc(&pdev->dev, &amdgpu_kms_driver, typeof(*adev), ddev); + if (IS_ERR(adev)) + return PTR_ERR(adev); +--- a/drivers/gpu/drm/radeon/radeon_drv.c ++++ b/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" + #include "radeon.h" +@@ -284,6 +286,28 @@ MODULE_DEVICE_TABLE(pci, pciidlist); + + static const struct drm_driver kms_driver; + ++/* 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) + { +@@ -324,6 +348,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_aperture_remove_conflicting_pci_framebuffers(pdev, &kms_driver); + if (ret) |