summaryrefslogtreecommitdiffstats
path: root/debian/patches/bugfix/all/radeon-amdgpu-firmware-is-required-for-drm-and-kms-on-r600-onward.patch
diff options
context:
space:
mode:
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.patch135
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)