radeon: Firmware is required for DRM and KMS on R600 onward, but not for KMS on earlier chips (Closes: #697229)

svn path=/dists/sid/linux/; revision=19720
This commit is contained in:
Ben Hutchings 2013-01-08 03:27:57 +00:00
parent 833435d74c
commit a430b5558a
4 changed files with 98 additions and 84 deletions

2
debian/changelog vendored
View File

@ -64,6 +64,8 @@ linux (3.2.36-1) UNRELEASED; urgency=low
hid-a4tech, hid-cypress, hid-ezkey (Closes: #697035), hid-kensington,
hid-keytouch, hid-kye, hid-multitouch, hid-ortek, hid-primax,
hid-quanta, hid-samsung, hid-speedlink
* radeon: Firmware is required for DRM and KMS on R600 onward, but not
for KMS on earlier chips (Closes: #697229)
[ Aurelien Jarno ]
* [armhf/vexpress] Add kernel udebs.

View File

@ -0,0 +1,95 @@
From: Ben Hutchings <ben@decadent.org.uk>
Subject: radeon: Firmware is required for DRM and KMS on R600 onward
Date: Tue, 08 Jan 2013 03:25:52 +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
Bug-Debian: http://bugs.debian.org/697229
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.
This does not seem to happen if KMS is disabled, but with both KMS
and GPU acceleration disabled radeon is not doing anything useful!
Therefore, perform a basic check for the existence of
/lib/firmware/radeon when a device is probed, and abort if it is
missing, except for the pre-R600 KMS case.
---
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -37,6 +37,8 @@
#include "drm_pciids.h"
#include <linux/console.h>
#include <linux/module.h>
+#include <linux/namei.h>
+#include <linux/path.h>
/*
@@ -257,6 +259,35 @@ static struct drm_driver driver_old = {
static 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
+ * assume people take the easy route and install
+ * firmware-linux-nonfree.
+ */
+static bool __devinit 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 __devinit
+radeon_ums_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ if (!radeon_firmware_installed()) {
+ DRM_ERROR("radeon DRM requires firmware-linux-nonfree.\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
static void radeon_kick_out_firmware_fb(struct pci_dev *pdev)
{
struct apertures_struct *ap;
@@ -276,6 +307,12 @@ static void radeon_kick_out_firmware_fb(
static int __devinit
radeon_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
+ if ((ent->driver_data & RADEON_FAMILY_MASK) >= CHIP_R600 &&
+ !radeon_firmware_installed()) {
+ DRM_ERROR("radeon kernel modesetting for R600 or later requires firmware-linux-nonfree.\n");
+ return -ENODEV;
+ }
+
/* Get rid of things like offb */
radeon_kick_out_firmware_fb(pdev);
@@ -367,6 +404,7 @@ static struct pci_driver *pdriver;
static struct pci_driver radeon_pci_driver = {
.name = DRIVER_NAME,
.id_table = pciidlist,
+ .probe = radeon_ums_pci_probe,
};
static struct pci_driver radeon_kms_pci_driver = {

View File

@ -1,83 +0,0 @@
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
@@ -37,6 +37,8 @@
#include "drm_pciids.h"
#include <linux/console.h>
#include <linux/module.h>
+#include <linux/namei.h>
+#include <linux/path.h>
/*
@@ -378,6 +380,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;
@@ -402,6 +422,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;

View File

@ -421,7 +421,7 @@ bugfix/x86/asus-laptop-Do-not-call-HWRS-on-init.patch
bugfix/x86/drm-i915-Only-kick-out-vesafb-if-we-takeover-the-fbc.patch
features/all/xen/microcode.patch
debian/radeon-no-modeset-without-firmware.patch
debian/radeon-firmware-is-required-for-drm-and-kms-on-r600-onward.patch
debian/ALSA-avoid-ABI-change-in-3.2.34.patch
debian/rtnetlink-avoid-ABI-change-in-3.2.34.patch
debian/mm-avoid-ABI-change-in-3.2.33.patch