LibXenon
Bare-metal Xbox 360 homebrew library
Loading...
Searching...
No Matches
usbmain.c
Go to the documentation of this file.
1/* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
3 *
4 * Main Module File: usbmain.c
5 *
6 * Main module that invokes the top of the USB stack from CFE.
7 *
8 * Author: Mitch Lichtenberg
9 *
10 *********************************************************************
11 *
12 * Copyright 2000,2001,2002,2003
13 * Broadcom Corporation. All rights reserved.
14 *
15 * This software is furnished under license and may be used and
16 * copied only in accordance with the following terms and
17 * conditions. Subject to these conditions, you may download,
18 * copy, install, use, modify and distribute modified or unmodified
19 * copies of this software in source and/or binary form. No title
20 * or ownership is transferred hereby.
21 *
22 * 1) Any source code used, modified or distributed must reproduce
23 * and retain this copyright notice and list of conditions
24 * as they appear in the source file.
25 *
26 * 2) No right is granted to use any trade name, trademark, or
27 * logo of Broadcom Corporation. The "Broadcom Corporation"
28 * name may not be used to endorse or promote products derived
29 * from this software without the prior written permission of
30 * Broadcom Corporation.
31 *
32 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
33 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
34 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
35 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
36 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
37 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
38 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
40 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
41 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
42 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
43 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
44 * THE POSSIBILITY OF SUCH DAMAGE.
45 ********************************************************************* */
46
47
48#include <nocfe/cfe.h>
49
50#if CFG_PCI
51#include "pcireg.h"
52#include "pcivar.h"
53#endif
54
55#include "usbmain.h"
56#include "usbchap9.h"
57#include "usbd.h"
58#include "pci/io.h"
60
61
62/* *********************************************************************
63 * Externs
64 ********************************************************************* */
65
66extern usb_hcdrv_t ohci_driver; /* OHCI Driver dispatch */
67
68extern int ohcidebug; /* OHCI debug control */
69extern int usb_noisy; /* USBD debug control */
70
71int ui_init_usbcmds(void); /* forward */
72void kmem_init(void);
73
74/* *********************************************************************
75 * Globals
76 ********************************************************************* */
77
78/*
79 * We keep track of the pointers to USB buses in globals.
80 * One entry in this array per USB bus (the Opti controller
81 * on the SWARM has two functions, so it's two buses)
82 */
83
84#define USB_MAX_BUS 4
85int usb_buscnt = 0;
87
88
89/* *********************************************************************
90 * usb_cfe_timer(arg)
91 *
92 * This routine is called periodically by CFE's timer routines
93 * to give the USB subsystem some time. Basically we scan
94 * for work to do to manage configuration updates, and handle
95 * interrupts from the USB controllers.
96 *
97 * Input parameters:
98 * arg - value we passed when the timer was initialized
99 * (not used)
100 *
101 * Return value:
102 * nothing
103 ********************************************************************* */
104
105static void usb_cfe_timer(void *arg)
106{
107 int idx;
108 static int in_poll = 0;
109
110 /*
111 * We sometimes call the timer routines in here, which calls
112 * the polling loop. This code is not reentrant, so
113 * prevent us from running the interrupt routine or
114 * bus daemon while we are already in there.
115 */
116
117 if (in_poll) return;
118
119 /*
120 * Do not allow nested "interrupts."
121 */
122
123 in_poll = 1;
124
125 for (idx = 0; idx < usb_buscnt; idx++) {
126 if (usb_buses[idx]) {
127 usb_poll(usb_buses[idx]);
128 usb_daemon(usb_buses[idx]);
129 }
130 }
131
132 /*
133 * Okay to call polling again.
134 */
135
136 in_poll = 0;
137}
138
139
140/* *********************************************************************
141 * usb_init_one_ohci(addr)
142 *
143 * Initialize one USB controller.
144 *
145 * Input parameters:
146 * addr - physical address of OHCI registers
147 *
148 * Return value:
149 * 0 if ok
150 * else error
151 ********************************************************************* */
152static int usb_init_one_ohci(uint32_t addr)
153{
154 usbbus_t *bus;
155 int res;
156
157 bus = UBCREATE(&ohci_driver, addr);
158
159 if (bus == NULL) {
160 printf("USB: Could not create OHCI driver structure for controller at 0x%08X\n",addr);
161 return -1;
162 }
163
165
166 res = UBSTART(bus);
167
168 if (res != 0) {
169 printf("USB: Could not init OHCI controller at 0x%08X\n",addr);
170 UBSTOP(bus);
171 return -1;
172 }
173 else {
176 }
177
178 return 0;
179}
180
181#if CFG_PCI
182/* *********************************************************************
183 * usb_init_pci_ohci()
184 *
185 * Initialize all PCI-based OHCI controllers
186 *
187 * Input parameters:
188 * nothing
189 *
190 * Return value:
191 * 0 if ok
192 * else error
193 ********************************************************************* */
194static int usb_init_pci_ohci(void)
195{
196 int res;
197 pcitag_t tag;
198 uint32_t pciclass;
199 phys_addr_t bar;
200 int idx;
201
202 idx = 0;
203
204 while (pci_find_class(PCI_CLASS_SERIALBUS,idx,&tag) == 0) {
205 pciclass = pci_conf_read(tag,PCI_CLASS_REG);
206 if ((PCI_SUBCLASS(pciclass) == PCI_SUBCLASS_SERIALBUS_USB) &&
207 (PCI_INTERFACE(pciclass) == 0x10)) {
208 /* On the BCM1250, this sets the address to "match bits" mode,
209 which eliminates the need for byte swaps of data to/from the registers. */
210 if (pci_map_mem(tag,PCI_MAPREG_START,PCI_MATCH_BITS,&bar) == 0) {
211 pci_tagprintf(tag,"OHCI USB controller found at %08X\n",(uint32_t) bar);
212 /* XXX hack: assumes physaddrs are 32 bits, bad bad! */
213 res = usb_init_one_ohci((uint32_t)bar);
214 if (res < 0) break;
215 }
216 else {
217 pci_tagprintf(tag,"Could not map OHCI base address\n");
218 }
219 }
220 idx++;
221 }
222
223 return 0;
224}
225#endif
226
227
229
230int usb_init(void)
231{
232 static int initdone = 0;
233
234 if (initdone) {
235 printf("USB has already been initialized.\n");
236 return -1;
237 }
238
239 initdone = 1;
240
241 usb_shutdown();
242
243 // preinit (start from scratch)
244 // OHCI
245 write32(0xD0120044,0xed44);
246 write32(0xD0128044,0xed44);
247 // EHCI
248 write32(0xD0121040,0x0C004020);
249 write32(0xD0129040,0x0C004020);
250 write32(0xD0121044,0x3C);
251 write32(0xD0129044,0x3C);
252
253 printf(" * Initialising USB EHCI...\n");
254 EHCI_Init();
255
256 printf(" * Initialising USB OHCI...\n");
257
258 usb_buscnt = 0;
259
260 kmem_init();
261
262#if CFG_PCI
263 usb_init_pci_ohci();
264#endif
265
266#if 0
267 usb_noisy = 1;
268 ohcidebug = 2;
269#endif
270
271 usb_init_one_ohci(0xea002000);
272 usb_init_one_ohci(0xea004000);
273
274// cfe_bg_add(usb_cfe_timer,NULL);
275 usb_initialized = 1;
276
277 return 0;
278}
279
280void usb_shutdown(void)
281{
282 // EHCI
283 // disable interrupts
284 write32(0xEA003028,0);
285 write32(0xEA005028,0);
286 // halt
287 write32(0xEA003020,0);
288 write32(0xEA005020,0);
289
290 // OHCI
291 // disable interrupts
292 write32(0xEA002014,1 << 31);
293 write32(0xEA004014,1 << 31);
294 // halt
295 write32(0xEA002004,0);
296 read32(0xEA002004);
297 write32(0xEA004004,0);
298 read32(0xEA004004);
299}
300
301void usb_do_poll(void)
302{
303 if (!usb_initialized)
304 return;
305
306 usb_cfe_timer(0);
307
309}
#define NULL
Definition: def.h:47
s32 USBStorage_Init(void)
Definition: usbstorage.c:1215
u32 uint32_t
Definition: libfdt_env.h:11
Definition: usbd.h:92
int ub_num
Definition: usbd.h:99
s32 EHCI_Init(void)
Definition: tinyehci.c:100
void usb_daemon(usbbus_t *bus)
Definition: usbd.c:410
void usb_poll(usbbus_t *bus)
Definition: usbd.c:392
void usb_initroot(usbbus_t *bus)
Definition: usbd.c:1128
#define UBSTOP(bus)
Definition: usbd.h:274
#define UBCREATE(driver, addr)
Definition: usbd.h:271
#define UBSTART(bus)
Definition: usbd.h:273
usbbus_t * bus
Definition: usbhack.c:153
usb_hcdrv_t ohci_driver
Definition: ohci.c:1717
int ohcidebug
Definition: ohci.c:199
int usb_noisy
Definition: usbd.c:68
int usb_buscnt
Definition: usbmain.c:85
usbbus_t * usb_buses[USB_MAX_BUS]
Definition: usbmain.c:86
int ui_init_usbcmds(void)
void usb_shutdown(void)
Definition: usbmain.c:280
int usb_initialized
Definition: usbmain.c:228
#define USB_MAX_BUS
Definition: usbmain.c:84
void kmem_init(void)
Definition: lib_malloc.c:607
void usb_do_poll(void)
Definition: usbmain.c:301
int usb_init(void)
Definition: usbmain.c:230