Ticket #5551: ehci_sb600.2.diff

File ehci_sb600.2.diff, 2.7 KB (added by mmlr, 9 years ago)
  • src/add-ons/kernel/busses/usb/ehci.cpp

     
    134134    TRACE("constructing new EHCI host controller driver\n");
    135135    fInitOK = false;
    136136
     137    // ATI/AMD SB600/SB700 periodic list cache workaround
     138    // Logic kindly borrowed from NetBSD PR 40056
     139    if (fPCIInfo->vendor_id == AMD_SBX00_VENDOR) {
     140        bool applyWorkaround = false;
     141
     142        if (fPCIInfo->device_id == AMD_SB600_EHCI_CONTROLLER) {
     143            // always apply on SB600
     144            applyWorkaround = true;
     145        } else if (fPCIInfo->device_id == AMD_SB700_SB800_EHCI_CONTROLLER) {
     146            // only apply on certain chipsets, determined by SMBus revision
     147            pci_info smbus;
     148            int32 index = 0;
     149            while (sPCIModule->get_nth_pci_info(index++, &smbus) >= B_OK) {
     150                if (smbus.vendor_id == AMD_SBX00_VENDOR
     151                    && smbus.device_id == AMD_SBX00_SMBUS_CONTROLLER) {
     152
     153                    // Only applies to chipsets < SB710 (rev A14)
     154                    if (smbus.revision == 0x3a || smbus.revision == 0x3b)
     155                        applyWorkaround = true;
     156
     157                    break;
     158                }
     159            }
     160        }
     161
     162        if (applyWorkaround) {
     163            // According to AMD errata of SB700 and SB600 register documentation
     164            // this disables the Periodic List Cache on SB600 and the Advanced
     165            // Periodic List Cache on early SB700. Both the BSDs and Linux use
     166            // this workaround.
     167
     168            TRACE_ALWAYS("disabling SB600/SB700 periodic list cache\n");
     169            uint32 workaround = sPCIModule->read_pci_config(fPCIInfo->bus,
     170                fPCIInfo->device, fPCIInfo->function,
     171                AMD_SBX00_EHCI_MISC_REGISTER, 4);
     172
     173            sPCIModule->write_pci_config(fPCIInfo->bus, fPCIInfo->device,
     174                fPCIInfo->function, AMD_SBX00_EHCI_MISC_REGISTER, 4,
     175                workaround | AMD_SBX00_EHCI_MISC_DISABLE_PERIODIC_LIST_CACHE);
     176        }
     177    }
     178
    137179    // enable busmaster and memory mapped access
    138180    uint16 command = sPCIModule->read_pci_config(fPCIInfo->bus,
    139181        fPCIInfo->device, fPCIInfo->function, PCI_command, 2);
  • src/add-ons/kernel/busses/usb/ehci_hardware.h

     
    261261// ToDo: Periodic Frame Span Traversal Node (FSTN, EHCI Spec 3.7)
    262262
    263263
     264// Quirk registers and values
     265#define AMD_SBX00_VENDOR                0x1002
     266#define AMD_SBX00_SMBUS_CONTROLLER      0x4385
     267#define AMD_SB600_EHCI_CONTROLLER       0x4386
     268#define AMD_SB700_SB800_EHCI_CONTROLLER 0x4396
     269
     270#define AMD_SBX00_EHCI_MISC_REGISTER    0x50    // Advanced config register
     271#define AMD_SBX00_EHCI_MISC_DISABLE_PERIODIC_LIST_CACHE     (1 << 27)
     272
    264273#endif // !EHCI_HARDWARE_H