Re: [Regression, post-rc2] Commit a5ee4eb7541 breaks OpenGL on RS780(was: Re: Linux 2.6.34-rc3)

From: Clemens Ladisch
Date: Sat Apr 03 2010 - 14:08:25 EST

Rafael J. Wysocki wrote:
> From: Clemens Ladisch <clemens@xxxxxxxxxx>
> Subject: PCI quirk: RS780/RS880: disable MSI completely
> The missing initialization of the nb_cntl.strap_msi_enable does not
> seem to be the only problem that prevents MSI, so that quirk is not
> sufficient to enable MSI on all machines. To be safe, disable MSI
> unconditionally for the internal graphics and HDMI audio on these
> chipsets.
> [rjw: Added the PCI_VENDOR_ID_AI quirk.]
> ...
> +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x9602, quirk_disable_msi);
> +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASUSTEK, 0x9602, quirk_disable_msi);
> +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AI, 0x9602, quirk_disable_msi);

I fear I have to NACK this. The fact that two OEMs have changed the vendor
ID makes it likely that this is a bug in AMD's template BIOS code, and that
we will see the same problem on other systems using other vendor IDs.

So we should not use the vendor ID of device 0x9602 to declare the quirk, but
use some other device with an ID that is known to be correct. We already
access the configuration space of the host bridge, so we should use that.

Furthermore, the quirk in my first patch was never run at all on the ALi
system, so it is probable that the nb_cntl.strap_msi_enable detection
would actually work. Rafael, please test this patch; if it doesn't work
on your system, we can still remove the check for the strap_msi_enable bit.


Subject: PCI quirk: RS780/RS880: work around wrong vendor IDs of RS780 bridge

On many RS780 systems, the vendor ID of the PCI/PCI bridge for the
internal graphics is set to that of the mainboard vendor, so the quirk
would not match and failed to notice the disabled MSI.

Since we do not know in advance all possible vendor IDs, we have to
declare the quirk on another device with an ID that is known to be
correct, and use that as a stepping stone to find the PCI/PCI bridge,
if present.

Signed-off-by: Clemens Ladisch <clemens@xxxxxxxxxx>
Cc: <stable@xxxxxxxxxx>

--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
* MSI does not work with the AMD RS780/RS880 internal graphics and HDMI audio
* devices unless the BIOS has initialized the nb_cntl.strap_msi_enable bit.
-static void __init rs780_int_gfx_disable_msi(struct pci_dev *int_gfx_bridge)
+static void __init rs780_int_gfx_disable_msi(struct pci_dev *host_bridge)
+ struct pci_dev *int_gfx_bridge;
u32 nb_cntl;

- if (!int_gfx_bridge->subordinate)
+ /*
+ * Many OEMs change the vendor ID of the internal graphics PCI/PCI
+ * bridge, so we use the possible vendor/device IDs of the host bridge
+ * for the declared quirk, and search for the PCI/PCI bridge by slot
+ * number.
+ */
+ int_gfx_bridge = pci_get_slot(host_bridge->bus, PCI_DEVFN(1, 0));
+ if (!int_gfx_bridge)
+ if (int_gfx_bridge->device != 0x9602 || !int_gfx_bridge->subordinate)
+ goto out;

- pci_bus_write_config_dword(int_gfx_bridge->bus, PCI_DEVFN(0, 0),
- 0x60, 0);
- pci_bus_read_config_dword(int_gfx_bridge->bus, PCI_DEVFN(0, 0),
- 0x64, &nb_cntl);
+ pci_write_config_dword(host_bridge, 0x60, 0);
+ pci_read_config_dword(host_bridge, 0x64, &nb_cntl);

if (!(nb_cntl & BIT(10))) {
FW_WARN "RS780: MSI for internal graphics disabled\n");
int_gfx_bridge->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;

-#define PCI_DEVICE_ID_AMD_RS780_P2P_INT_GFX 0x9602
+ pci_dev_put(int_gfx_bridge);

- rs780_int_gfx_disable_msi);
-/* wrong vendor ID on M4A785TD motherboard: */
- rs780_int_gfx_disable_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x9600, rs780_int_gfx_disable_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x9601, rs780_int_gfx_disable_msi);

#endif /* CONFIG_PCI_MSI */

To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at
Please read the FAQ at