84 lines
2.7 KiB
Diff
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;
|