mb/google/brya/var/uldrenite: Generate RAM ID and SPD file
[coreboot2.git] / payloads / libpayload / drivers / usb / usbinit.c
bloba234b00e4b7347af9dc31e18b130f5761ca2cd46
1 /*
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
7 * are met:
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
26 * SUCH DAMAGE.
29 //#define USB_DEBUG
30 #include <libpayload-config.h>
31 #include <usb/usb.h>
32 #include "uhci.h"
33 #include "ohci.h"
34 #include "ehci.h"
35 #include "xhci.h"
36 #include "dwc2.h"
37 #include <usb/usbdisk.h>
39 #if CONFIG(LP_USB_PCI)
40 /**
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)
49 u32 class;
50 u32 devclass;
51 u32 prog_if;
52 pcidev_t pci_device;
53 u32 pciid;
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) {
64 u16 pci_command;
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);
72 switch (prog_if) {
73 case 0x00:
74 #if CONFIG(LP_USB_UHCI)
75 usb_debug("UHCI controller\n");
76 uhci_pci_init(pci_device);
77 #else
78 usb_debug("UHCI controller (not supported)\n");
79 #endif
80 break;
82 case 0x10:
83 #if CONFIG(LP_USB_OHCI)
84 usb_debug("OHCI controller\n");
85 ohci_pci_init(pci_device);
86 #else
87 usb_debug("OHCI controller (not supported)\n");
88 #endif
89 break;
91 case 0x20:
92 #if CONFIG(LP_USB_EHCI)
93 usb_debug("EHCI controller\n");
94 ehci_pci_init(pci_device);
95 #else
96 usb_debug("EHCI controller (not supported)\n");
97 #endif
98 break;
100 case 0x30:
101 #if CONFIG(LP_USB_XHCI)
102 usb_debug("xHCI controller\n");
103 xhci_pci_init(pci_device);
104 #else
105 usb_debug("xHCI controller (not supported)\n");
106 #endif
107 break;
109 default:
110 usb_debug("unknown controller %x not supported\n",
111 prog_if);
112 break;
116 return 0;
119 static void usb_scan_pci_bus(int bus)
121 int dev, func;
122 for (dev = 0; dev < 32; dev++) {
123 u8 header_type;
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)
128 continue;
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)
140 func = 7;
141 else
142 func = 0;
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)
152 & 3) != 0)
153 usb_scan_pci_bus(pci_read_config8(
154 pci_device, REG_SECONDARY_BUS));
156 else
157 usb_controller_initialize(bus, dev, func);
161 #endif
164 * Initialize all USB controllers attached to PCI.
166 int usb_initialize(void)
168 #if CONFIG(LP_USB_PCI)
169 usb_scan_pci_bus(0);
170 #endif
171 return 0;
174 hci_t *usb_add_mmio_hc(hc_type type, void *bar)
176 switch (type) {
177 #if CONFIG(LP_USB_OHCI)
178 case OHCI:
179 return ohci_init((unsigned long)bar);
180 #endif
181 #if CONFIG(LP_USB_EHCI)
182 case EHCI:
183 return ehci_init((unsigned long)bar);
184 #endif
185 #if CONFIG(LP_USB_DWC2)
186 case DWC2:
187 return dwc2_init(bar);
188 #endif
189 #if CONFIG(LP_USB_XHCI)
190 case XHCI:
191 return xhci_init((unsigned long)bar);
192 #endif
193 default:
194 usb_debug("HC type %d (at %p) is not supported!\n", type, bar);
195 return NULL;