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.patch139
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)