3 * Copyright (C) 2008-2010 coresystems GmbH
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include <libpayload-config.h>
37 #include <usb/usbdisk.h>
39 #if CONFIG(LP_USB_PCI)
41 * Initializes USB controller attached to PCI
43 * @param bus PCI bus number
44 * @param dev PCI device id at bus
45 * @param func function id of the controller
47 static int usb_controller_initialize(int bus
, int dev
, int func
)
55 pci_device
= PCI_DEV(bus
, dev
, func
);
56 class = pci_read_config32(pci_device
, 8);
57 pciid
= pci_read_config32(pci_device
, 0);
59 devclass
= class >> 16;
60 prog_if
= (class >> 8) & 0xff;
62 /* enable busmaster */
63 if (devclass
== 0xc03) {
66 pci_command
= pci_read_config16(pci_device
, PCI_COMMAND
);
67 pci_command
|= PCI_COMMAND_MASTER
;
68 pci_write_config16(pci_device
, PCI_COMMAND
, pci_command
);
70 usb_debug("%02x:%02x.%x %04x:%04x.%d ", bus
, dev
, func
,
71 pciid
>> 16, pciid
& 0xFFFF, func
);
74 #if CONFIG(LP_USB_UHCI)
75 usb_debug("UHCI controller\n");
76 uhci_pci_init(pci_device
);
78 usb_debug("UHCI controller (not supported)\n");
83 #if CONFIG(LP_USB_OHCI)
84 usb_debug("OHCI controller\n");
85 ohci_pci_init(pci_device
);
87 usb_debug("OHCI controller (not supported)\n");
92 #if CONFIG(LP_USB_EHCI)
93 usb_debug("EHCI controller\n");
94 ehci_pci_init(pci_device
);
96 usb_debug("EHCI controller (not supported)\n");
101 #if CONFIG(LP_USB_XHCI)
102 usb_debug("xHCI controller\n");
103 xhci_pci_init(pci_device
);
105 usb_debug("xHCI controller (not supported)\n");
110 usb_debug("unknown controller %x not supported\n",
119 static void usb_scan_pci_bus(int bus
)
122 for (dev
= 0; dev
< 32; dev
++) {
124 pcidev_t pci_device
= PCI_DEV(bus
, dev
, 0);
126 /* Check if there's a device here at all. */
127 if (pci_read_config32(pci_device
, REG_VENDOR_ID
) == 0xffffffff)
131 * EHCI is defined by standards to be at a higher function
132 * than the USB1 controllers. We don't want to init USB1 +
133 * devices just to "steal" those for USB2, so make sure USB2
134 * comes first by scanning multifunction devices from 7 to 0.
137 /* Check for a multifunction device. */
138 header_type
= pci_read_config8(pci_device
, REG_HEADER_TYPE
);
139 if (header_type
& HEADER_TYPE_MULTIFUNCTION
)
144 for (; func
>= 0; func
--) {
145 pci_device
= PCI_DEV(bus
, dev
, func
);
146 header_type
= pci_read_config8(pci_device
, REG_HEADER_TYPE
);
147 /* If this is a bridge, scan the other side. */
148 if ((header_type
& ~HEADER_TYPE_MULTIFUNCTION
) ==
149 HEADER_TYPE_BRIDGE
) {
150 /* Verify that the bridge is enabled */
151 if ((pci_read_config16(pci_device
, REG_COMMAND
)
153 usb_scan_pci_bus(pci_read_config8(
154 pci_device
, REG_SECONDARY_BUS
));
157 usb_controller_initialize(bus
, dev
, func
);
164 * Initialize all USB controllers attached to PCI.
166 int usb_initialize(void)
168 #if CONFIG(LP_USB_PCI)
174 hci_t
*usb_add_mmio_hc(hc_type type
, void *bar
)
177 #if CONFIG(LP_USB_OHCI)
179 return ohci_init((unsigned long)bar
);
181 #if CONFIG(LP_USB_EHCI)
183 return ehci_init((unsigned long)bar
);
185 #if CONFIG(LP_USB_DWC2)
187 return dwc2_init(bar
);
189 #if CONFIG(LP_USB_XHCI)
191 return xhci_init((unsigned long)bar
);
194 usb_debug("HC type %d (at %p) is not supported!\n", type
, bar
);