1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34#include <config.h>
35
36#ifdef CONFIG_USB_OHCI
37
38
39
40#include <common.h>
41#include <malloc.h>
42#include <asm/io.h>
43#include <asm/au1x00.h>
44#include <usb.h>
45#include "au1x00_usb_ohci.h"
46
47#define OHCI_USE_NPS
48#define OHCI_VERBOSE_DEBUG
49#define OHCI_FILL_TRACE
50
51#define USBH_ENABLE_BE (1<<0)
52#define USBH_ENABLE_C (1<<1)
53#define USBH_ENABLE_E (1<<2)
54#define USBH_ENABLE_CE (1<<3)
55#define USBH_ENABLE_RD (1<<4)
56
57#ifdef __LITTLE_ENDIAN
58#define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C)
59#else
60#define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C | USBH_ENABLE_BE)
61#endif
62
63
64
65#define OHCI_CONTROL_INIT \
66 (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
67
68#undef readl
69#undef writel
70
71#define readl(a) au_readl((long)(a))
72#define writel(v,a) au_writel((v),(int)(a))
73
74#define min_t(type,x,y) ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
75
76#define DEBUG
77#ifdef DEBUG
78#define dbg(format, arg...) printf("DEBUG: " format "\n", ## arg)
79#else
80#define dbg(format, arg...) do {} while(0)
81#endif
82#define err(format, arg...) printf("ERROR: " format "\n", ## arg)
83#define SHOW_INFO
84#ifdef SHOW_INFO
85#define info(format, arg...) printf("INFO: " format "\n", ## arg)
86#else
87#define info(format, arg...) do {} while(0)
88#endif
89
90#define m16_swap(x) swap_16(x)
91#define m32_swap(x) swap_32(x)
92
93
94static ohci_t gohci;
95
96struct ohci_hcca ghcca[1];
97
98struct ohci_hcca *phcca;
99
100struct ohci_device ohci_dev;
101
102urb_priv_t urb_priv;
103
104int got_rhsc;
105
106struct usb_device *devgone;
107
108
109
110
111
112
113
114#define OHCI_QUIRK_AMD756 0xabcd
115#define read_roothub(hc, register, mask) ({ \
116 u32 temp = readl (&hc->regs->roothub.register); \
117 if (hc->flags & OHCI_QUIRK_AMD756) \
118 while (temp & mask) \
119 temp = readl (&hc->regs->roothub.register); \
120 temp; })
121
122static u32 roothub_a (struct ohci *hc)
123 { return read_roothub (hc, a, 0xfc0fe000); }
124static inline u32 roothub_b (struct ohci *hc)
125 { return readl (&hc->regs->roothub.b); }
126static inline u32 roothub_status (struct ohci *hc)
127 { return readl (&hc->regs->roothub.status); }
128static u32 roothub_portstatus (struct ohci *hc, int i)
129 { return read_roothub (hc, portstatus [i], 0xffe0fce0); }
130
131
132
133static int hc_interrupt (void);
134static void
135td_submit_job (struct usb_device * dev, unsigned long pipe, void * buffer,
136 int transfer_len, struct devrequest * setup, urb_priv_t * urb, int interval);
137
138
139
140
141
142
143
144static void urb_free_priv (urb_priv_t * urb)
145{
146 int i;
147 int last;
148 struct td * td;
149
150 last = urb->length - 1;
151 if (last >= 0) {
152 for (i = 0; i <= last; i++) {
153 td = urb->td[i];
154 if (td) {
155 td->usb_dev = NULL;
156 urb->td[i] = NULL;
157 }
158 }
159 }
160}
161
162
163
164#ifdef DEBUG
165static int sohci_get_current_frame_number (struct usb_device * dev);
166
167
168
169
170static void pkt_print (struct usb_device * dev, unsigned long pipe, void * buffer,
171 int transfer_len, struct devrequest * setup, char * str, int small)
172{
173 urb_priv_t * purb = &urb_priv;
174
175 dbg("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,len:%d/%d stat:%#lx",
176 str,
177 sohci_get_current_frame_number (dev),
178 usb_pipedevice (pipe),
179 usb_pipeendpoint (pipe),
180 usb_pipeout (pipe)? 'O': 'I',
181 usb_pipetype (pipe) < 2? (usb_pipeint (pipe)? "INTR": "ISOC"):
182 (usb_pipecontrol (pipe)? "CTRL": "BULK"),
183 purb->actual_length,
184 transfer_len, dev->status);
185#ifdef OHCI_VERBOSE_DEBUG
186 if (!small) {
187 int i, len;
188
189 if (usb_pipecontrol (pipe)) {
190 printf (__FILE__ ": cmd(8):");
191 for (i = 0; i < 8 ; i++)
192 printf (" %02x", ((__u8 *) setup) [i]);
193 printf ("\n");
194 }
195 if (transfer_len > 0 && buffer) {
196 printf (__FILE__ ": data(%d/%d):",
197 purb->actual_length,
198 transfer_len);
199 len = usb_pipeout (pipe)?
200 transfer_len: purb->actual_length;
201 for (i = 0; i < 16 && i < len; i++)
202 printf (" %02x", ((__u8 *) buffer) [i]);
203 printf ("%s\n", i < len? "...": "");
204 }
205 }
206#endif
207}
208
209
210void ep_print_int_eds (ohci_t *ohci, char * str) {
211 int i, j;
212 __u32 * ed_p;
213 for (i= 0; i < 32; i++) {
214 j = 5;
215 ed_p = &(ohci->hcca->int_table [i]);
216 if (*ed_p == 0)
217 continue;
218 printf (__FILE__ ": %s branch int %2d(%2x):", str, i, i);
219 while (*ed_p != 0 && j--) {
220 ed_t *ed = (ed_t *)m32_swap(ed_p);
221 printf (" ed: %4x;", ed->hwINFO);
222 ed_p = &ed->hwNextED;
223 }
224 printf ("\n");
225 }
226}
227
228static void ohci_dump_intr_mask (char *label, __u32 mask)
229{
230 dbg ("%s: 0x%08x%s%s%s%s%s%s%s%s%s",
231 label,
232 mask,
233 (mask & OHCI_INTR_MIE) ? " MIE" : "",
234 (mask & OHCI_INTR_OC) ? " OC" : "",
235 (mask & OHCI_INTR_RHSC) ? " RHSC" : "",
236 (mask & OHCI_INTR_FNO) ? " FNO" : "",
237 (mask & OHCI_INTR_UE) ? " UE" : "",
238 (mask & OHCI_INTR_RD) ? " RD" : "",
239 (mask & OHCI_INTR_SF) ? " SF" : "",
240 (mask & OHCI_INTR_WDH) ? " WDH" : "",
241 (mask & OHCI_INTR_SO) ? " SO" : ""
242 );
243}
244
245static void maybe_print_eds (char *label, __u32 value)
246{
247 ed_t *edp = (ed_t *)value;
248
249 if (value) {
250 dbg ("%s %08x", label, value);
251 dbg ("%08x", edp->hwINFO);
252 dbg ("%08x", edp->hwTailP);
253 dbg ("%08x", edp->hwHeadP);
254 dbg ("%08x", edp->hwNextED);
255 }
256}
257
258static char * hcfs2string (int state)
259{
260 switch (state) {
261 case OHCI_USB_RESET: return "reset";
262 case OHCI_USB_RESUME: return "resume";
263 case OHCI_USB_OPER: return "operational";
264 case OHCI_USB_SUSPEND: return "suspend";
265 }
266 return "?";
267}
268
269
270static void ohci_dump_status (ohci_t *controller)
271{
272 struct ohci_regs *regs = controller->regs;
273 __u32 temp;
274
275 temp = readl (®s->revision) & 0xff;
276 if (temp != 0x10)
277 dbg ("spec %d.%d", (temp >> 4), (temp & 0x0f));
278
279 temp = readl (®s->control);
280 dbg ("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d", temp,
281 (temp & OHCI_CTRL_RWE) ? " RWE" : "",
282 (temp & OHCI_CTRL_RWC) ? " RWC" : "",
283 (temp & OHCI_CTRL_IR) ? " IR" : "",
284 hcfs2string (temp & OHCI_CTRL_HCFS),
285 (temp & OHCI_CTRL_BLE) ? " BLE" : "",
286 (temp & OHCI_CTRL_CLE) ? " CLE" : "",
287 (temp & OHCI_CTRL_IE) ? " IE" : "",
288 (temp & OHCI_CTRL_PLE) ? " PLE" : "",
289 temp & OHCI_CTRL_CBSR
290 );
291
292 temp = readl (®s->cmdstatus);
293 dbg ("cmdstatus: 0x%08x SOC=%d%s%s%s%s", temp,
294 (temp & OHCI_SOC) >> 16,
295 (temp & OHCI_OCR) ? " OCR" : "",
296 (temp & OHCI_BLF) ? " BLF" : "",
297 (temp & OHCI_CLF) ? " CLF" : "",
298 (temp & OHCI_HCR) ? " HCR" : ""
299 );
300
301 ohci_dump_intr_mask ("intrstatus", readl (®s->intrstatus));
302 ohci_dump_intr_mask ("intrenable", readl (®s->intrenable));
303
304 maybe_print_eds ("ed_periodcurrent", readl (®s->ed_periodcurrent));
305
306 maybe_print_eds ("ed_controlhead", readl (®s->ed_controlhead));
307 maybe_print_eds ("ed_controlcurrent", readl (®s->ed_controlcurrent));
308
309 maybe_print_eds ("ed_bulkhead", readl (®s->ed_bulkhead));
310 maybe_print_eds ("ed_bulkcurrent", readl (®s->ed_bulkcurrent));
311
312 maybe_print_eds ("donehead", readl (®s->donehead));
313}
314
315static void ohci_dump_roothub (ohci_t *controller, int verbose)
316{
317 __u32 temp, ndp, i;
318
319 temp = roothub_a (controller);
320 ndp = (temp & RH_A_NDP);
321
322 if (verbose) {
323 dbg ("roothub.a: %08x POTPGT=%d%s%s%s%s%s NDP=%d", temp,
324 ((temp & RH_A_POTPGT) >> 24) & 0xff,
325 (temp & RH_A_NOCP) ? " NOCP" : "",
326 (temp & RH_A_OCPM) ? " OCPM" : "",
327 (temp & RH_A_DT) ? " DT" : "",
328 (temp & RH_A_NPS) ? " NPS" : "",
329 (temp & RH_A_PSM) ? " PSM" : "",
330 ndp
331 );
332 temp = roothub_b (controller);
333 dbg ("roothub.b: %08x PPCM=%04x DR=%04x",
334 temp,
335 (temp & RH_B_PPCM) >> 16,
336 (temp & RH_B_DR)
337 );
338 temp = roothub_status (controller);
339 dbg ("roothub.status: %08x%s%s%s%s%s%s",
340 temp,
341 (temp & RH_HS_CRWE) ? " CRWE" : "",
342 (temp & RH_HS_OCIC) ? " OCIC" : "",
343 (temp & RH_HS_LPSC) ? " LPSC" : "",
344 (temp & RH_HS_DRWE) ? " DRWE" : "",
345 (temp & RH_HS_OCI) ? " OCI" : "",
346 (temp & RH_HS_LPS) ? " LPS" : ""
347 );
348 }
349
350 for (i = 0; i < ndp; i++) {
351 temp = roothub_portstatus (controller, i);
352 dbg ("roothub.portstatus [%d] = 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s",
353 i,
354 temp,
355 (temp & RH_PS_PRSC) ? " PRSC" : "",
356 (temp & RH_PS_OCIC) ? " OCIC" : "",
357 (temp & RH_PS_PSSC) ? " PSSC" : "",
358 (temp & RH_PS_PESC) ? " PESC" : "",
359 (temp & RH_PS_CSC) ? " CSC" : "",
360
361 (temp & RH_PS_LSDA) ? " LSDA" : "",
362 (temp & RH_PS_PPS) ? " PPS" : "",
363 (temp & RH_PS_PRS) ? " PRS" : "",
364 (temp & RH_PS_POCI) ? " POCI" : "",
365 (temp & RH_PS_PSS) ? " PSS" : "",
366
367 (temp & RH_PS_PES) ? " PES" : "",
368 (temp & RH_PS_CCS) ? " CCS" : ""
369 );
370 }
371}
372
373static void ohci_dump (ohci_t *controller, int verbose)
374{
375 dbg ("OHCI controller usb-%s state", controller->slot_name);
376
377
378 ohci_dump_status (controller);
379 if (verbose)
380 ep_print_int_eds (controller, "hcca");
381 dbg ("hcca frame #%04x", controller->hcca->frame_no);
382 ohci_dump_roothub (controller, 1);
383}
384
385
386#endif
387
388
389
390
391
392
393
394int sohci_submit_job(struct usb_device *dev, unsigned long pipe, void *buffer,
395 int transfer_len, struct devrequest *setup, int interval)
396{
397 ohci_t *ohci;
398 ed_t * ed;
399 urb_priv_t *purb_priv;
400 int i, size = 0;
401
402 ohci = &gohci;
403
404
405
406 if (ohci->disabled) {
407 err("sohci_submit_job: EPIPE");
408 return -1;
409 }
410
411
412 if (!(ed = ep_add_ed (dev, pipe))) {
413 err("sohci_submit_job: ENOMEM");
414 return -1;
415 }
416
417
418 switch (usb_pipetype (pipe)) {
419 case PIPE_BULK:
420 size = (transfer_len - 1) / 4096 + 1;
421 break;
422 case PIPE_CONTROL:
423 size = (transfer_len == 0)? 2:
424 (transfer_len - 1) / 4096 + 3;
425 break;
426 }
427
428 if (size >= (N_URB_TD - 1)) {
429 err("need %d TDs, only have %d", size, N_URB_TD);
430 return -1;
431 }
432 purb_priv = &urb_priv;
433 purb_priv->pipe = pipe;
434
435
436 purb_priv->length = size;
437 purb_priv->ed = ed;
438 purb_priv->actual_length = 0;
439
440
441
442 for (i = 0; i < size; i++) {
443 purb_priv->td[i] = td_alloc (dev);
444 if (!purb_priv->td[i]) {
445 purb_priv->length = i;
446 urb_free_priv (purb_priv);
447 err("sohci_submit_job: ENOMEM");
448 return -1;
449 }
450 }
451
452 if (ed->state == ED_NEW || (ed->state & ED_DEL)) {
453 urb_free_priv (purb_priv);
454 err("sohci_submit_job: EINVAL");
455 return -1;
456 }
457
458
459 if (ed->state != ED_OPER)
460 ep_link (ohci, ed);
461
462
463 td_submit_job(dev, pipe, buffer, transfer_len, setup, purb_priv, interval);
464
465 return 0;
466}
467
468
469
470#ifdef DEBUG
471
472
473static int sohci_get_current_frame_number (struct usb_device *usb_dev)
474{
475 ohci_t *ohci = &gohci;
476
477 return m16_swap (ohci->hcca->frame_no);
478}
479#endif
480
481
482
483
484
485
486
487static int ep_link (ohci_t *ohci, ed_t *edi)
488{
489 volatile ed_t *ed = edi;
490
491 ed->state = ED_OPER;
492
493 switch (ed->type) {
494 case PIPE_CONTROL:
495 ed->hwNextED = 0;
496 if (ohci->ed_controltail == NULL) {
497 writel ((long)ed, &ohci->regs->ed_controlhead);
498 } else {
499 ohci->ed_controltail->hwNextED = m32_swap (ed);
500 }
501 ed->ed_prev = ohci->ed_controltail;
502 if (!ohci->ed_controltail && !ohci->ed_rm_list[0] &&
503 !ohci->ed_rm_list[1] && !ohci->sleeping) {
504 ohci->hc_control |= OHCI_CTRL_CLE;
505 writel (ohci->hc_control, &ohci->regs->control);
506 }
507 ohci->ed_controltail = edi;
508 break;
509
510 case PIPE_BULK:
511 ed->hwNextED = 0;
512 if (ohci->ed_bulktail == NULL) {
513 writel ((long)ed, &ohci->regs->ed_bulkhead);
514 } else {
515 ohci->ed_bulktail->hwNextED = m32_swap (ed);
516 }
517 ed->ed_prev = ohci->ed_bulktail;
518 if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] &&
519 !ohci->ed_rm_list[1] && !ohci->sleeping) {
520 ohci->hc_control |= OHCI_CTRL_BLE;
521 writel (ohci->hc_control, &ohci->regs->control);
522 }
523 ohci->ed_bulktail = edi;
524 break;
525 }
526 return 0;
527}
528
529
530
531
532
533
534
535
536static int ep_unlink (ohci_t *ohci, ed_t *ed)
537{
538 ed->hwINFO |= m32_swap (OHCI_ED_SKIP);
539
540 switch (ed->type) {
541 case PIPE_CONTROL:
542 if (ed->ed_prev == NULL) {
543 if (!ed->hwNextED) {
544 ohci->hc_control &= ~OHCI_CTRL_CLE;
545 writel (ohci->hc_control, &ohci->regs->control);
546 }
547 writel (m32_swap (*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_controlhead);
548 } else {
549 ed->ed_prev->hwNextED = ed->hwNextED;
550 }
551 if (ohci->ed_controltail == ed) {
552 ohci->ed_controltail = ed->ed_prev;
553 } else {
554 ((ed_t *)m32_swap (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev;
555 }
556 break;
557
558 case PIPE_BULK:
559 if (ed->ed_prev == NULL) {
560 if (!ed->hwNextED) {
561 ohci->hc_control &= ~OHCI_CTRL_BLE;
562 writel (ohci->hc_control, &ohci->regs->control);
563 }
564 writel (m32_swap (*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_bulkhead);
565 } else {
566 ed->ed_prev->hwNextED = ed->hwNextED;
567 }
568 if (ohci->ed_bulktail == ed) {
569 ohci->ed_bulktail = ed->ed_prev;
570 } else {
571 ((ed_t *)m32_swap (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev;
572 }
573 break;
574 }
575 ed->state = ED_UNLINK;
576 return 0;
577}
578
579
580
581
582
583
584
585
586
587
588static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe)
589{
590 td_t *td;
591 ed_t *ed_ret;
592 volatile ed_t *ed;
593
594 ed = ed_ret = &ohci_dev.ed[(usb_pipeendpoint (pipe) << 1) |
595 (usb_pipecontrol (pipe)? 0: usb_pipeout (pipe))];
596
597 if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) {
598 err("ep_add_ed: pending delete");
599
600 return NULL;
601 }
602
603 if (ed->state == ED_NEW) {
604 ed->hwINFO = m32_swap (OHCI_ED_SKIP);
605
606 td = td_alloc (usb_dev);
607 ed->hwTailP = m32_swap (td);
608 ed->hwHeadP = ed->hwTailP;
609 ed->state = ED_UNLINK;
610 ed->type = usb_pipetype (pipe);
611 ohci_dev.ed_cnt++;
612 }
613
614 ed->hwINFO = m32_swap (usb_pipedevice (pipe)
615 | usb_pipeendpoint (pipe) << 7
616 | (usb_pipeisoc (pipe)? 0x8000: 0)
617 | (usb_pipecontrol (pipe)? 0: (usb_pipeout (pipe)? 0x800: 0x1000))
618 | usb_pipeslow (pipe) << 13
619 | usb_maxpacket (usb_dev, pipe) << 16);
620
621 return ed_ret;
622}
623
624
625
626
627
628
629
630static void td_fill (ohci_t *ohci, unsigned int info,
631 void *data, int len,
632 struct usb_device *dev, int index, urb_priv_t *urb_priv)
633{
634 volatile td_t *td, *td_pt;
635#ifdef OHCI_FILL_TRACE
636 int i;
637#endif
638
639 if (index > urb_priv->length) {
640 err("index > length");
641 return;
642 }
643
644 td_pt = urb_priv->td [index];
645 td_pt->hwNextTD = 0;
646
647
648 td = urb_priv->td [index] = (td_t *)(m32_swap (urb_priv->ed->hwTailP) & ~0xf);
649
650 td->ed = urb_priv->ed;
651 td->next_dl_td = NULL;
652 td->index = index;
653 td->data = (__u32)data;
654#ifdef OHCI_FILL_TRACE
655 if (1 || (usb_pipebulk(urb_priv->pipe) &&
656 usb_pipeout(urb_priv->pipe))) {
657 for (i = 0; i < len; i++)
658 printf("td->data[%d] %#2x\n",i, ((unsigned char *)(td->data+0x80000000))[i]);
659 }
660#endif
661 if (!len)
662 data = 0;
663
664 td->hwINFO = m32_swap (info);
665 td->hwCBP = m32_swap (data);
666 if (data)
667 td->hwBE = m32_swap (data + len - 1);
668 else
669 td->hwBE = 0;
670 td->hwNextTD = m32_swap (td_pt);
671 td->hwPSW [0] = m16_swap (((__u32)data & 0x0FFF) | 0xE000);
672
673
674 td->ed->hwTailP = td->hwNextTD;
675}
676
677
678
679
680
681#define kseg_to_phys(x) ((void *)((__u32)(x) - 0x80000000))
682
683static void td_submit_job (struct usb_device *dev, unsigned long pipe, void *buffer,
684 int transfer_len, struct devrequest *setup, urb_priv_t *urb, int interval)
685{
686 ohci_t *ohci = &gohci;
687 int data_len = transfer_len;
688 void *data;
689 int cnt = 0;
690 __u32 info = 0;
691 unsigned int toggle = 0;
692
693
694 if(usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) {
695 toggle = TD_T_TOGGLE;
696 } else {
697 toggle = TD_T_DATA0;
698 usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 1);
699 }
700 urb->td_cnt = 0;
701 if (data_len)
702 data = kseg_to_phys(buffer);
703 else
704 data = 0;
705
706 switch (usb_pipetype (pipe)) {
707 case PIPE_BULK:
708 info = usb_pipeout (pipe)?
709 TD_CC | TD_DP_OUT : TD_CC | TD_DP_IN ;
710 while(data_len > 4096) {
711 td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, 4096, dev, cnt, urb);
712 data += 4096; data_len -= 4096; cnt++;
713 }
714 info = usb_pipeout (pipe)?
715 TD_CC | TD_DP_OUT : TD_CC | TD_R | TD_DP_IN ;
716 td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, data_len, dev, cnt, urb);
717 cnt++;
718
719 if (!ohci->sleeping)
720 writel (OHCI_BLF, &ohci->regs->cmdstatus);
721 break;
722
723 case PIPE_CONTROL:
724 info = TD_CC | TD_DP_SETUP | TD_T_DATA0;
725 td_fill (ohci, info, kseg_to_phys(setup), 8, dev, cnt++, urb);
726 if (data_len > 0) {
727 info = usb_pipeout (pipe)?
728 TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : TD_CC | TD_R | TD_DP_IN | TD_T_DATA1;
729
730 td_fill (ohci, info, data, data_len, dev, cnt++, urb);
731 }
732 info = usb_pipeout (pipe)?
733 TD_CC | TD_DP_IN | TD_T_DATA1: TD_CC | TD_DP_OUT | TD_T_DATA1;
734 td_fill (ohci, info, data, 0, dev, cnt++, urb);
735 if (!ohci->sleeping)
736 writel (OHCI_CLF, &ohci->regs->cmdstatus);
737 break;
738 }
739 if (urb->length != cnt)
740 dbg("TD LENGTH %d != CNT %d", urb->length, cnt);
741}
742
743
744
745
746
747
748
749
750static void dl_transfer_length(td_t * td)
751{
752 __u32 tdINFO, tdBE, tdCBP;
753 urb_priv_t *lurb_priv = &urb_priv;
754
755 tdINFO = m32_swap (td->hwINFO);
756 tdBE = m32_swap (td->hwBE);
757 tdCBP = m32_swap (td->hwCBP);
758
759
760 if (!(usb_pipecontrol(lurb_priv->pipe) &&
761 ((td->index == 0) || (td->index == lurb_priv->length - 1)))) {
762 if (tdBE != 0) {
763 if (td->hwCBP == 0)
764 lurb_priv->actual_length += tdBE - td->data + 1;
765 else
766 lurb_priv->actual_length += tdCBP - td->data;
767 }
768 }
769}
770
771
772
773
774
775
776static td_t * dl_reverse_done_list (ohci_t *ohci)
777{
778 __u32 td_list_hc;
779 td_t *td_rev = NULL;
780 td_t *td_list = NULL;
781 urb_priv_t *lurb_priv = NULL;
782
783 td_list_hc = m32_swap (ohci->hcca->done_head) & 0xfffffff0;
784 ohci->hcca->done_head = 0;
785
786 while (td_list_hc) {
787 td_list = (td_t *)td_list_hc;
788
789 if (TD_CC_GET (m32_swap (td_list->hwINFO))) {
790 lurb_priv = &urb_priv;
791 dbg(" USB-error/status: %x : %p",
792 TD_CC_GET (m32_swap (td_list->hwINFO)), td_list);
793 if (td_list->ed->hwHeadP & m32_swap (0x1)) {
794 if (lurb_priv && ((td_list->index + 1) < lurb_priv->length)) {
795 td_list->ed->hwHeadP =
796 (lurb_priv->td[lurb_priv->length - 1]->hwNextTD & m32_swap (0xfffffff0)) |
797 (td_list->ed->hwHeadP & m32_swap (0x2));
798 lurb_priv->td_cnt += lurb_priv->length - td_list->index - 1;
799 } else
800 td_list->ed->hwHeadP &= m32_swap (0xfffffff2);
801 }
802 }
803
804 td_list->next_dl_td = td_rev;
805 td_rev = td_list;
806 td_list_hc = m32_swap (td_list->hwNextTD) & 0xfffffff0;
807 }
808 return td_list;
809}
810
811
812
813
814static int dl_done_list (ohci_t *ohci, td_t *td_list)
815{
816 td_t *td_list_next = NULL;
817 ed_t *ed;
818 int cc = 0;
819 int stat = 0;
820
821 urb_priv_t *lurb_priv;
822 __u32 tdINFO, edHeadP, edTailP;
823
824 while (td_list) {
825 td_list_next = td_list->next_dl_td;
826
827 lurb_priv = &urb_priv;
828 tdINFO = m32_swap (td_list->hwINFO);
829
830 ed = td_list->ed;
831
832 dl_transfer_length(td_list);
833
834
835 cc = TD_CC_GET (tdINFO);
836 if (cc != 0) {
837 dbg("ConditionCode %#x", cc);
838 stat = cc_to_error[cc];
839 }
840
841 if (ed->state != ED_NEW) {
842 edHeadP = m32_swap (ed->hwHeadP) & 0xfffffff0;
843 edTailP = m32_swap (ed->hwTailP);
844
845
846 if ((edHeadP == edTailP) && (ed->state == ED_OPER))
847 ep_unlink (ohci, ed);
848 }
849
850 td_list = td_list_next;
851 }
852 return stat;
853}
854
855
856
857
858
859
860static __u8 root_hub_dev_des[] =
861{
862 0x12,
863 0x01,
864 0x10,
865 0x01,
866 0x09,
867 0x00,
868 0x00,
869 0x08,
870 0x00,
871 0x00,
872 0x00,
873 0x00,
874 0x00,
875 0x00,
876 0x00,
877 0x01,
878 0x00,
879 0x01
880};
881
882
883
884static __u8 root_hub_config_des[] =
885{
886 0x09,
887 0x02,
888 0x19,
889 0x00,
890 0x01,
891 0x01,
892 0x00,
893 0x40,
894
895 0x00,
896
897
898 0x09,
899 0x04,
900 0x00,
901 0x00,
902 0x01,
903 0x09,
904 0x00,
905 0x00,
906 0x00,
907
908
909 0x07,
910 0x05,
911 0x81,
912 0x03,
913 0x02,
914 0x00,
915 0xff
916};
917
918static unsigned char root_hub_str_index0[] =
919{
920 0x04,
921 0x03,
922 0x09,
923 0x04,
924};
925
926static unsigned char root_hub_str_index1[] =
927{
928 28,
929 0x03,
930 'O',
931 0,
932 'H',
933 0,
934 'C',
935 0,
936 'I',
937 0,
938 ' ',
939 0,
940 'R',
941 0,
942 'o',
943 0,
944 'o',
945 0,
946 't',
947 0,
948 ' ',
949 0,
950 'H',
951 0,
952 'u',
953 0,
954 'b',
955 0,
956};
957
958
959
960
961
962
963#define OK(x) len = (x); break
964#ifdef DEBUG
965#define WR_RH_STAT(x) {info("WR:status %#8x", (x));writel((x), &gohci.regs->roothub.status);}
966#define WR_RH_PORTSTAT(x) {info("WR:portstatus[%d] %#8x", wIndex-1, (x));writel((x), &gohci.regs->roothub.portstatus[wIndex-1]);}
967#else
968#define WR_RH_STAT(x) writel((x), &gohci.regs->roothub.status)
969#define WR_RH_PORTSTAT(x) writel((x), &gohci.regs->roothub.portstatus[wIndex-1])
970#endif
971#define RD_RH_STAT roothub_status(&gohci)
972#define RD_RH_PORTSTAT roothub_portstatus(&gohci,wIndex-1)
973
974
975
976int rh_check_port_status(ohci_t *controller)
977{
978 __u32 temp, ndp, i;
979 int res;
980
981 res = -1;
982 temp = roothub_a (controller);
983 ndp = (temp & RH_A_NDP);
984 for (i = 0; i < ndp; i++) {
985 temp = roothub_portstatus (controller, i);
986
987 if (((temp & (RH_PS_PESC | RH_PS_CSC)) ==
988 (RH_PS_PESC | RH_PS_CSC)) &&
989 ((temp & RH_PS_CCS) == 0)) {
990 res = i;
991 break;
992 }
993 }
994 return res;
995}
996
997static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
998 void *buffer, int transfer_len, struct devrequest *cmd)
999{
1000 void * data = buffer;
1001 int leni = transfer_len;
1002 int len = 0;
1003 int stat = 0;
1004 __u32 datab[4];
1005 __u8 *data_buf = (__u8 *)datab;
1006 __u16 bmRType_bReq;
1007 __u16 wValue;
1008 __u16 wIndex;
1009 __u16 wLength;
1010
1011#ifdef DEBUG
1012urb_priv.actual_length = 0;
1013pkt_print(dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe));
1014#else
1015 mdelay(1);
1016#endif
1017 if (usb_pipeint(pipe)) {
1018 info("Root-Hub submit IRQ: NOT implemented");
1019 return 0;
1020 }
1021
1022 bmRType_bReq = cmd->requesttype | (cmd->request << 8);
1023 wValue = m16_swap (cmd->value);
1024 wIndex = m16_swap (cmd->index);
1025 wLength = m16_swap (cmd->length);
1026
1027 info("Root-Hub: adr: %2x cmd(%1x): %08x %04x %04x %04x",
1028 dev->devnum, 8, bmRType_bReq, wValue, wIndex, wLength);
1029
1030 switch (bmRType_bReq) {
1031
1032
1033
1034
1035
1036
1037
1038
1039 case RH_GET_STATUS:
1040 *(__u16 *) data_buf = m16_swap (1); OK (2);
1041 case RH_GET_STATUS | RH_INTERFACE:
1042 *(__u16 *) data_buf = m16_swap (0); OK (2);
1043 case RH_GET_STATUS | RH_ENDPOINT:
1044 *(__u16 *) data_buf = m16_swap (0); OK (2);
1045 case RH_GET_STATUS | RH_CLASS:
1046 *(__u32 *) data_buf = m32_swap (
1047 RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE));
1048 OK (4);
1049 case RH_GET_STATUS | RH_OTHER | RH_CLASS:
1050 *(__u32 *) data_buf = m32_swap (RD_RH_PORTSTAT); OK (4);
1051
1052 case RH_CLEAR_FEATURE | RH_ENDPOINT:
1053 switch (wValue) {
1054 case (RH_ENDPOINT_STALL): OK (0);
1055 }
1056 break;
1057
1058 case RH_CLEAR_FEATURE | RH_CLASS:
1059 switch (wValue) {
1060 case RH_C_HUB_LOCAL_POWER:
1061 OK(0);
1062 case (RH_C_HUB_OVER_CURRENT):
1063 WR_RH_STAT(RH_HS_OCIC); OK (0);
1064 }
1065 break;
1066
1067 case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
1068 switch (wValue) {
1069 case (RH_PORT_ENABLE):
1070 WR_RH_PORTSTAT (RH_PS_CCS ); OK (0);
1071 case (RH_PORT_SUSPEND):
1072 WR_RH_PORTSTAT (RH_PS_POCI); OK (0);
1073 case (RH_PORT_POWER):
1074 WR_RH_PORTSTAT (RH_PS_LSDA); OK (0);
1075 case (RH_C_PORT_CONNECTION):
1076 WR_RH_PORTSTAT (RH_PS_CSC ); OK (0);
1077 case (RH_C_PORT_ENABLE):
1078 WR_RH_PORTSTAT (RH_PS_PESC); OK (0);
1079 case (RH_C_PORT_SUSPEND):
1080 WR_RH_PORTSTAT (RH_PS_PSSC); OK (0);
1081 case (RH_C_PORT_OVER_CURRENT):
1082 WR_RH_PORTSTAT (RH_PS_OCIC); OK (0);
1083 case (RH_C_PORT_RESET):
1084 WR_RH_PORTSTAT (RH_PS_PRSC); OK (0);
1085 }
1086 break;
1087
1088 case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
1089 switch (wValue) {
1090 case (RH_PORT_SUSPEND):
1091 WR_RH_PORTSTAT (RH_PS_PSS ); OK (0);
1092 case (RH_PORT_RESET):
1093 if (RD_RH_PORTSTAT & RH_PS_CCS)
1094 WR_RH_PORTSTAT (RH_PS_PRS);
1095 OK (0);
1096 case (RH_PORT_POWER):
1097 WR_RH_PORTSTAT (RH_PS_PPS ); OK (0);
1098 case (RH_PORT_ENABLE):
1099 if (RD_RH_PORTSTAT & RH_PS_CCS)
1100 WR_RH_PORTSTAT (RH_PS_PES );
1101 OK (0);
1102 }
1103 break;
1104
1105 case RH_SET_ADDRESS: gohci.rh.devnum = wValue; OK(0);
1106
1107 case RH_GET_DESCRIPTOR:
1108 switch ((wValue & 0xff00) >> 8) {
1109 case (0x01):
1110 len = min_t(unsigned int,
1111 leni,
1112 min_t(unsigned int,
1113 sizeof (root_hub_dev_des),
1114 wLength));
1115 data_buf = root_hub_dev_des; OK(len);
1116 case (0x02):
1117 len = min_t(unsigned int,
1118 leni,
1119 min_t(unsigned int,
1120 sizeof (root_hub_config_des),
1121 wLength));
1122 data_buf = root_hub_config_des; OK(len);
1123 case (0x03):
1124 if(wValue==0x0300) {
1125 len = min_t(unsigned int,
1126 leni,
1127 min_t(unsigned int,
1128 sizeof (root_hub_str_index0),
1129 wLength));
1130 data_buf = root_hub_str_index0;
1131 OK(len);
1132 }
1133 if(wValue==0x0301) {
1134 len = min_t(unsigned int,
1135 leni,
1136 min_t(unsigned int,
1137 sizeof (root_hub_str_index1),
1138 wLength));
1139 data_buf = root_hub_str_index1;
1140 OK(len);
1141 }
1142 default:
1143 stat = USB_ST_STALLED;
1144 }
1145 break;
1146
1147 case RH_GET_DESCRIPTOR | RH_CLASS:
1148 {
1149 __u32 temp = roothub_a (&gohci);
1150
1151 data_buf [0] = 9;
1152 data_buf [1] = 0x29;
1153 data_buf [2] = temp & RH_A_NDP;
1154 data_buf [3] = 0;
1155 if (temp & RH_A_PSM)
1156 data_buf [3] |= 0x1;
1157 if (temp & RH_A_NOCP)
1158 data_buf [3] |= 0x10;
1159 else if (temp & RH_A_OCPM)
1160 data_buf [3] |= 0x8;
1161
1162
1163 datab [1] = 0;
1164 data_buf [5] = (temp & RH_A_POTPGT) >> 24;
1165 temp = roothub_b (&gohci);
1166 data_buf [7] = temp & RH_B_DR;
1167 if (data_buf [2] < 7) {
1168 data_buf [8] = 0xff;
1169 } else {
1170 data_buf [0] += 2;
1171 data_buf [8] = (temp & RH_B_DR) >> 8;
1172 data_buf [10] = data_buf [9] = 0xff;
1173 }
1174
1175 len = min_t(unsigned int, leni,
1176 min_t(unsigned int, data_buf [0], wLength));
1177 OK (len);
1178 }
1179
1180 case RH_GET_CONFIGURATION: *(__u8 *) data_buf = 0x01; OK (1);
1181
1182 case RH_SET_CONFIGURATION: WR_RH_STAT (0x10000); OK (0);
1183
1184 default:
1185 dbg ("unsupported root hub command");
1186 stat = USB_ST_STALLED;
1187 }
1188
1189#ifdef DEBUG
1190 ohci_dump_roothub (&gohci, 1);
1191#else
1192 mdelay(1);
1193#endif
1194
1195 len = min_t(int, len, leni);
1196 if (data != data_buf)
1197 memcpy (data, data_buf, len);
1198 dev->act_len = len;
1199 dev->status = stat;
1200
1201#ifdef DEBUG
1202 if (transfer_len)
1203 urb_priv.actual_length = transfer_len;
1204 pkt_print(dev, pipe, buffer, transfer_len, cmd, "RET(rh)", 0);
1205#else
1206 mdelay(1);
1207#endif
1208
1209 return stat;
1210}
1211
1212
1213
1214
1215
1216int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
1217 int transfer_len, struct devrequest *setup, int interval)
1218{
1219 int stat = 0;
1220 int maxsize = usb_maxpacket(dev, pipe);
1221 int timeout;
1222
1223
1224 if (devgone == dev) {
1225 dev->status = USB_ST_CRC_ERR;
1226 return 0;
1227 }
1228
1229#ifdef DEBUG
1230 urb_priv.actual_length = 0;
1231 pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe));
1232#else
1233 mdelay(1);
1234#endif
1235 if (!maxsize) {
1236 err("submit_common_message: pipesize for pipe %lx is zero",
1237 pipe);
1238 return -1;
1239 }
1240
1241 if (sohci_submit_job(dev, pipe, buffer, transfer_len, setup, interval) < 0) {
1242 err("sohci_submit_job failed");
1243 return -1;
1244 }
1245
1246 mdelay(10);
1247
1248
1249
1250#define BULK_TO 5000
1251 if (usb_pipebulk(pipe))
1252 timeout = BULK_TO;
1253 else
1254 timeout = 100;
1255
1256 timeout *= 4;
1257
1258 for (;;) {
1259
1260 stat = hc_interrupt();
1261 if (stat < 0) {
1262 stat = USB_ST_CRC_ERR;
1263 break;
1264 }
1265 if (stat >= 0 && stat != 0xff) {
1266
1267 break;
1268 }
1269 if (--timeout) {
1270 udelay(250);
1271 } else {
1272 err("CTL:TIMEOUT ");
1273 stat = USB_ST_CRC_ERR;
1274 break;
1275 }
1276 }
1277
1278 if (got_rhsc) {
1279#ifdef DEBUG
1280 ohci_dump_roothub (&gohci, 1);
1281#endif
1282 got_rhsc = 0;
1283
1284 timeout = rh_check_port_status(&gohci);
1285 if (timeout >= 0) {
1286#if 0
1287
1288 usb_hub_port_connect_change(gohci.rh.dev, timeout - 1);
1289#endif
1290
1291
1292
1293
1294
1295 devgone = dev;
1296 }
1297 }
1298
1299 dev->status = stat;
1300 dev->act_len = transfer_len;
1301
1302#ifdef DEBUG
1303 pkt_print(dev, pipe, buffer, transfer_len, setup, "RET(ctlr)", usb_pipein(pipe));
1304#else
1305 mdelay(1);
1306#endif
1307
1308
1309 urb_free_priv (&urb_priv);
1310 return 0;
1311}
1312
1313
1314int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
1315 int transfer_len)
1316{
1317 info("submit_bulk_msg");
1318 return submit_common_msg(dev, pipe, buffer, transfer_len, NULL, 0);
1319}
1320
1321int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
1322 int transfer_len, struct devrequest *setup)
1323{
1324 int maxsize = usb_maxpacket(dev, pipe);
1325
1326 info("submit_control_msg");
1327#ifdef DEBUG
1328 urb_priv.actual_length = 0;
1329 pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe));
1330#else
1331 mdelay(1);
1332#endif
1333 if (!maxsize) {
1334 err("submit_control_message: pipesize for pipe %lx is zero",
1335 pipe);
1336 return -1;
1337 }
1338 if (((pipe >> 8) & 0x7f) == gohci.rh.devnum) {
1339 gohci.rh.dev = dev;
1340
1341 return ohci_submit_rh_msg(dev, pipe, buffer, transfer_len,
1342 setup);
1343 }
1344
1345 return submit_common_msg(dev, pipe, buffer, transfer_len, setup, 0);
1346}
1347
1348int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
1349 int transfer_len, int interval)
1350{
1351 info("submit_int_msg");
1352 return -1;
1353}
1354
1355
1356
1357
1358
1359
1360
1361static int hc_reset (ohci_t *ohci)
1362{
1363 int timeout = 30;
1364 int smm_timeout = 50;
1365
1366 if (readl (&ohci->regs->control) & OHCI_CTRL_IR) {
1367 writel (OHCI_OCR, &ohci->regs->cmdstatus);
1368 info("USB HC TakeOver from SMM");
1369 while (readl (&ohci->regs->control) & OHCI_CTRL_IR) {
1370 mdelay (10);
1371 if (--smm_timeout == 0) {
1372 err("USB HC TakeOver failed!");
1373 return -1;
1374 }
1375 }
1376 }
1377
1378
1379 writel (OHCI_INTR_MIE, &ohci->regs->intrdisable);
1380
1381 dbg("USB HC reset_hc usb-%s: ctrl = 0x%X ;",
1382 ohci->slot_name,
1383 readl (&ohci->regs->control));
1384
1385
1386 writel (0, &ohci->regs->control);
1387
1388
1389 writel (OHCI_HCR, &ohci->regs->cmdstatus);
1390 while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
1391 if (--timeout == 0) {
1392 err("USB HC reset timed out!");
1393 return -1;
1394 }
1395 udelay (1);
1396 }
1397 return 0;
1398}
1399
1400
1401
1402
1403
1404
1405
1406static int hc_start (ohci_t * ohci)
1407{
1408 __u32 mask;
1409 unsigned int fminterval;
1410
1411 ohci->disabled = 1;
1412
1413
1414
1415
1416 writel (0, &ohci->regs->ed_controlhead);
1417 writel (0, &ohci->regs->ed_bulkhead);
1418
1419 writel ((__u32)ohci->hcca, &ohci->regs->hcca);
1420
1421 fminterval = 0x2edf;
1422 writel ((fminterval * 9) / 10, &ohci->regs->periodicstart);
1423 fminterval |= ((((fminterval - 210) * 6) / 7) << 16);
1424 writel (fminterval, &ohci->regs->fminterval);
1425 writel (0x628, &ohci->regs->lsthresh);
1426
1427
1428 ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
1429 ohci->disabled = 0;
1430 writel (ohci->hc_control, &ohci->regs->control);
1431
1432
1433 mask = (OHCI_INTR_SO | OHCI_INTR_WDH | OHCI_INTR_SF | OHCI_INTR_RD |
1434 OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC |
1435 OHCI_INTR_OC | OHCI_INTR_MIE);
1436 writel (mask, &ohci->regs->intrdisable);
1437
1438 mask &= ~OHCI_INTR_MIE;
1439 writel (mask, &ohci->regs->intrstatus);
1440
1441 mask = OHCI_INTR_RHSC | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO;
1442 writel (mask, &ohci->regs->intrenable);
1443
1444#ifdef OHCI_USE_NPS
1445
1446 writel ((roothub_a (ohci) | RH_A_NPS) & ~RH_A_PSM,
1447 &ohci->regs->roothub.a);
1448 writel (RH_HS_LPSC, &ohci->regs->roothub.status);
1449#endif
1450
1451
1452 mdelay ((roothub_a (ohci) >> 23) & 0x1fe);
1453
1454
1455 ohci->rh.devnum = 0;
1456
1457 return 0;
1458}
1459
1460
1461
1462
1463
1464static int
1465hc_interrupt (void)
1466{
1467 ohci_t *ohci = &gohci;
1468 struct ohci_regs *regs = ohci->regs;
1469 int ints;
1470 int stat = -1;
1471
1472 if ((ohci->hcca->done_head != 0) && !(m32_swap (ohci->hcca->done_head) & 0x01)) {
1473 ints = OHCI_INTR_WDH;
1474 } else {
1475 ints = readl (®s->intrstatus);
1476 }
1477
1478
1479
1480 if (ints & OHCI_INTR_RHSC) {
1481 got_rhsc = 1;
1482 }
1483
1484 if (ints & OHCI_INTR_UE) {
1485 ohci->disabled++;
1486 err ("OHCI Unrecoverable Error, controller usb-%s disabled",
1487 ohci->slot_name);
1488
1489
1490#ifdef DEBUG
1491 ohci_dump (ohci, 1);
1492#else
1493 mdelay(1);
1494#endif
1495
1496
1497
1498
1499 hc_reset (ohci);
1500 return -1;
1501 }
1502
1503 if (ints & OHCI_INTR_WDH) {
1504 mdelay(1);
1505 writel (OHCI_INTR_WDH, ®s->intrdisable);
1506 stat = dl_done_list (&gohci, dl_reverse_done_list (&gohci));
1507 writel (OHCI_INTR_WDH, ®s->intrenable);
1508 }
1509
1510 if (ints & OHCI_INTR_SO) {
1511 dbg("USB Schedule overrun\n");
1512 writel (OHCI_INTR_SO, ®s->intrenable);
1513 stat = -1;
1514 }
1515
1516
1517 if (ints & OHCI_INTR_SF) {
1518 unsigned int frame = m16_swap (ohci->hcca->frame_no) & 1;
1519 mdelay(1);
1520 writel (OHCI_INTR_SF, ®s->intrdisable);
1521 if (ohci->ed_rm_list[frame] != NULL)
1522 writel (OHCI_INTR_SF, ®s->intrenable);
1523 stat = 0xff;
1524 }
1525
1526 writel (ints, ®s->intrstatus);
1527 return stat;
1528}
1529
1530
1531
1532
1533
1534
1535
1536static void hc_release_ohci (ohci_t *ohci)
1537{
1538 dbg ("USB HC release ohci usb-%s", ohci->slot_name);
1539
1540 if (!ohci->disabled)
1541 hc_reset (ohci);
1542}
1543
1544
1545
1546#define __read_32bit_c0_register(source, sel) \
1547({ int __res; \
1548 if (sel == 0) \
1549 __asm__ __volatile__( \
1550 "mfc0\t%0, " #source "\n\t" \
1551 : "=r" (__res)); \
1552 else \
1553 __asm__ __volatile__( \
1554 ".set\tmips32\n\t" \
1555 "mfc0\t%0, " #source ", " #sel "\n\t" \
1556 ".set\tmips0\n\t" \
1557 : "=r" (__res)); \
1558 __res; \
1559})
1560
1561#define read_c0_prid() __read_32bit_c0_register($15, 0)
1562
1563
1564
1565
1566static char ohci_inited = 0;
1567
1568int usb_lowlevel_init(void)
1569{
1570 u32 pin_func;
1571 u32 sys_freqctrl, sys_clksrc;
1572 u32 prid = read_c0_prid();
1573
1574 dbg("in usb_lowlevel_init\n");
1575
1576
1577 sys_freqctrl = au_readl(SYS_FREQCTRL0);
1578 sys_freqctrl &= ~0xFFF00000;
1579 au_writel(sys_freqctrl, SYS_FREQCTRL0);
1580
1581
1582 sys_clksrc = au_readl(SYS_CLKSRC);
1583 sys_clksrc &= ~0x00007FE0;
1584 au_writel(sys_clksrc, SYS_CLKSRC);
1585
1586 sys_freqctrl = au_readl(SYS_FREQCTRL0);
1587 sys_freqctrl &= ~0xFFF00000;
1588
1589 sys_clksrc = au_readl(SYS_CLKSRC);
1590 sys_clksrc &= ~0x00007FE0;
1591
1592 switch (prid & 0x000000FF) {
1593 case 0x00:
1594 case 0x01:
1595 case 0x02:
1596
1597 au_writel(4, SYS_CPUPLL);
1598
1599
1600
1601
1602
1603 sys_freqctrl |= ((3<<22) | (1<<21) | (0<<20));
1604 au_writel(sys_freqctrl, SYS_FREQCTRL0);
1605
1606
1607 au_writel(0x20, SYS_CPUPLL);
1608
1609 printf("Au1000: 48MHz OHCI workaround enabled\n");
1610 break;
1611
1612 default:
1613
1614 sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
1615 au_writel(sys_freqctrl, SYS_FREQCTRL0);
1616 break;
1617 }
1618
1619
1620
1621
1622 sys_clksrc |= ((4<<12) | (0<<11) | (0<<10));
1623 au_writel(sys_clksrc, SYS_CLKSRC);
1624
1625
1626 pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8080);
1627
1628 au_writel(pin_func, SYS_PINFUNC);
1629 au_writel(0x2800, SYS_TRIOUTCLR);
1630 au_writel(0x0030, SYS_OUTPUTCLR);
1631
1632 dbg("OHCI board setup complete\n");
1633
1634
1635 au_writel(USBH_ENABLE_CE, USB_HOST_CONFIG);
1636 udelay(1000);
1637 au_writel(USBH_ENABLE_INIT, USB_HOST_CONFIG);
1638 udelay(1000);
1639
1640
1641 while (au_readl(USB_HOST_CONFIG),
1642 !(au_readl(USB_HOST_CONFIG) & USBH_ENABLE_RD))
1643 udelay(1000);
1644
1645 dbg("OHCI clock running\n");
1646
1647 memset (&gohci, 0, sizeof (ohci_t));
1648 memset (&urb_priv, 0, sizeof (urb_priv_t));
1649
1650
1651 if ((__u32)&ghcca[0] & 0xff) {
1652 err("HCCA not aligned!!");
1653 return -1;
1654 }
1655 phcca = &ghcca[0];
1656 info("aligned ghcca %p", phcca);
1657 memset(&ohci_dev, 0, sizeof(struct ohci_device));
1658 if ((__u32)&ohci_dev.ed[0] & 0x7) {
1659 err("EDs not aligned!!");
1660 return -1;
1661 }
1662 memset(gtd, 0, sizeof(td_t) * (NUM_TD + 1));
1663 if ((__u32)gtd & 0x7) {
1664 err("TDs not aligned!!");
1665 return -1;
1666 }
1667 ptd = gtd;
1668 gohci.hcca = phcca;
1669 memset (phcca, 0, sizeof (struct ohci_hcca));
1670
1671 gohci.disabled = 1;
1672 gohci.sleeping = 0;
1673 gohci.irq = -1;
1674 gohci.regs = (struct ohci_regs *)(USB_OHCI_BASE | 0xA0000000);
1675
1676 gohci.flags = 0;
1677 gohci.slot_name = "au1x00";
1678
1679 dbg("OHCI revision: 0x%08x\n"
1680 " RH: a: 0x%08x b: 0x%08x\n",
1681 readl(&gohci.regs->revision),
1682 readl(&gohci.regs->roothub.a), readl(&gohci.regs->roothub.b));
1683
1684 if (hc_reset (&gohci) < 0)
1685 goto errout;
1686
1687
1688 writel (gohci.hc_control = OHCI_USB_RESET, &gohci.regs->control);
1689 mdelay (10);
1690
1691 if (hc_start (&gohci) < 0)
1692 goto errout;
1693
1694#ifdef DEBUG
1695 ohci_dump (&gohci, 1);
1696#else
1697 mdelay(1);
1698#endif
1699 ohci_inited = 1;
1700 return 0;
1701
1702 errout:
1703 err("OHCI initialization error\n");
1704 hc_release_ohci (&gohci);
1705
1706 au_writel(readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG);
1707 return -1;
1708}
1709
1710int usb_lowlevel_stop(void)
1711{
1712
1713
1714 if (!ohci_inited)
1715 return 0;
1716
1717
1718 hc_reset (&gohci);
1719
1720
1721 au_writel(readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG);
1722 return 0;
1723}
1724
1725#endif
1726