From patchwork Fri Dec 14 06:58:27 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [U-Boot,v3,2/7] usb: ehci: generic PCI support Date: Thu, 13 Dec 2012 20:58:27 -0000 From: Simon Glass X-Patchwork-Id: 206360 Message-Id: <1355468312-6090-3-git-send-email-sjg@chromium.org> To: U-Boot Mailing List Cc: Vincent Palatin From: Vincent Palatin Instead of hardcoding the PCI IDs on the USB controller, use the PCI class to detect them. Ensure the busmaster bit is properly set in the PCI configuration. Signed-off-by: Simon Glass --- Changes in v3: - Check the last PCI bus (this was unfortunately omitted in v2) Changes in v2: - Use errno where possible - Use PCI_CLASS_SERIAL_USB_EHCI instead of the number drivers/usb/host/ehci-pci.c | 41 ++++++++++++++++++++++++++++++++++++++++- 1 files changed, 40 insertions(+), 1 deletions(-) diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 29af02d..001d141 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -19,6 +19,7 @@ */ #include +#include #include #include @@ -32,6 +33,35 @@ static struct pci_device_id ehci_pci_ids[] = { {0x12D8, 0x400F}, /* Pericom */ {0, 0} }; +#else +static pci_dev_t ehci_find_class(void) +{ + int bus; + int devnum; + pci_dev_t bdf; + uint32_t class; + + for (bus = 0; bus <= pci_last_busno(); bus++) { + for (devnum = 0; devnum < PCI_MAX_PCI_DEVICES-1; devnum++) { + pci_read_config_dword(PCI_BDF(bus, devnum, 0), + PCI_CLASS_REVISION, &class); + if (class >> 16 == 0xffff) + continue; + + for (bdf = PCI_BDF(bus, devnum, 0); + bdf <= PCI_BDF(bus, devnum, + PCI_MAX_PCI_FUNCTIONS - 1); + bdf += PCI_BDF(0, 0, 1)) { + pci_read_config_dword(bdf, PCI_CLASS_REVISION, + &class); + if (class >> 8 == PCI_CLASS_SERIAL_USB_EHCI) + return bdf; + } + } + } + + return -ENODEV; +} #endif /* @@ -41,9 +71,14 @@ static struct pci_device_id ehci_pci_ids[] = { int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor) { pci_dev_t pdev; + uint32_t cmd; +#ifdef CONFIG_PCI_EHCI_DEVICE pdev = pci_find_devices(ehci_pci_ids, CONFIG_PCI_EHCI_DEVICE); - if (pdev == -1) { +#else + pdev = ehci_find_class(); +#endif + if (pdev < 0) { printf("EHCI host controller not found\n"); return -1; } @@ -57,6 +92,10 @@ int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor) (uint32_t)*hccr, (uint32_t)*hcor, (uint32_t)HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase))); + /* enable busmaster */ + pci_read_config_dword(pdev, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MASTER; + pci_write_config_dword(pdev, PCI_COMMAND, cmd); return 0; }