Import two PCI quirks from Linux

- Add quirk for ATI SB600 and SB700 to free SMB controller
 - Correct schedule sleep time to 10us on the VIA ehci controller

Reported by:	Dorian B<FC>ttner, Andriy Gapon
Submitted by:	Hans Petter Selasky
This commit is contained in:
thompsa 2009-09-28 07:06:47 +00:00
parent d0aa741310
commit 1e9eba768b

View File

@ -240,6 +240,50 @@ ehci_pci_probe(device_t self)
}
}
static void
ehci_pci_ati_quirk(device_t self, uint8_t is_sb700)
{
device_t smbdev;
uint32_t val;
if (is_sb700) {
/* Lookup SMBUS PCI device */
smbdev = pci_find_device(PCI_EHCI_VENDORID_ATI, 0x4385);
if (smbdev == NULL)
return;
val = pci_get_revid(smbdev);
if (val != 0x3a && val != 0x3b)
return;
}
/*
* Note: this bit is described as reserved in SB700
* Register Reference Guide.
*/
val = pci_read_config(self, 0x53, 1);
if (!(val & 0x8)) {
val |= 0x8;
pci_write_config(self, 0x53, val, 1);
device_printf(self, "AMD SB600/700 quirk applied\n");
}
}
static void
ehci_pci_via_quirk(device_t self)
{
uint32_t val;
if ((pci_get_device(self) == 0x3104) &&
((pci_get_revid(self) & 0xf0) == 0x60)) {
/* Correct schedule sleep time to 10us */
val = pci_read_config(self, 0x4b, 1);
if (val & 0x20)
return;
pci_write_config(self, 0x4b, val, 1);
device_printf(self, "VIA-quirk applied\n");
}
}
static int
ehci_pci_attach(device_t self)
{
@ -370,6 +414,32 @@ ehci_pci_attach(device_t self)
goto error;
}
ehci_pci_takecontroller(self);
/* Undocumented quirks taken from Linux */
switch (pci_get_vendor(self)) {
case PCI_EHCI_VENDORID_ATI:
/* SB600 and SB700 EHCI quirk */
switch (pci_get_device(self)) {
case 0x4386:
ehci_pci_ati_quirk(self, 0);
break;
case 0x4396:
ehci_pci_ati_quirk(self, 1);
break;
default:
break;
}
break;
case PCI_EHCI_VENDORID_VIA:
ehci_pci_via_quirk(self);
break;
default:
break;
}
err = ehci_init(sc);
if (!err) {
err = device_probe_and_attach(sc->sc_bus.bdev);