linux/debian/patches/debian/radeon-no-modeset-without-f...

84 lines
2.7 KiB
Diff

From: Ben Hutchings <ben@decadent.org.uk>
Subject: radeon: No MODESET without firmware
Date: Sat, 17 Nov 2012 05:28:53 +0000
Bug-Debian: http://bugs.debian.org/607194
Bug-Debian: http://bugs.debian.org/607471
Bug-Debian: http://bugs.debian.org/610851
Bug-Debian: http://bugs.debian.org/627497
Bug-Debian: http://bugs.debian.org/632212
Bug-Debian: http://bugs.debian.org/637943
Bug-Debian: http://bugs.debian.org/649448
radeon requires firmware/microcode for the GPU 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.
This does not seem to happen if KMS is disabled.
Unfortunately, it is not possible to properly disable KMS once the
missing firmware is discovered. Each driver registers with the DRM
core as having certain capabilities such as DRIVER_MODESET (KMS) and
the DRM does not allow for individual devices to have different
capabilities!
Therefore, perform a basic check for the existence of
/lib/firmware/radeon when the driver is loaded, and disable KMS
if it is missing. I apologise for this gross hack, but I cannot
see any more reliable solution that doesn't involve major changes
to both DRM and radeon.
---
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -36,6 +36,8 @@
#include <drm/drm_pciids.h>
#include <linux/console.h>
#include <linux/module.h>
+#include <linux/namei.h>
+#include <linux/path.h>
/*
@@ -411,6 +413,24 @@ static struct pci_driver radeon_kms_pci_
.resume = radeon_pci_resume,
};
+/* 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
+ * assume people take the easy route and install
+ * firmware-linux-nonfree.
+ */
+static bool __init radeon_firmware_installed(void)
+{
+ struct path path;
+
+ if (kern_path("/lib/firmware/radeon", LOOKUP_DIRECTORY | LOOKUP_FOLLOW,
+ &path) == 0) {
+ path_put(&path);
+ return true;
+ }
+
+ return false;
+}
+
static int __init radeon_init(void)
{
driver = &driver_old;
@@ -435,6 +455,13 @@ static int __init radeon_init(void)
radeon_modeset = 0;
#endif
}
+ /* We have to commit to KMS before we've seen any devices, so
+ * make a basic check to reduce the risk of failure later.
+ */
+ if (radeon_modeset == 1 && !radeon_firmware_installed()) {
+ DRM_INFO("radeon kernel modesetting disabled; it requires firmware-linux-nonfree.\n");
+ radeon_modeset = 0;
+ }
if (radeon_modeset == 1) {
DRM_INFO("radeon kernel modesetting enabled.\n");
driver = &kms_driver;