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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59#include <common.h>
60#include <config.h>
61#include <commproc.h>
62#include <usbdevice.h>
63#include <usb/mpc8xx_udc.h>
64
65#include "ep0.h"
66
67DECLARE_GLOBAL_DATA_PTR;
68
69#define ERR(fmt, args...)\
70 serial_printf("ERROR : [%s] %s:%d: "fmt,\
71 __FILE__,__FUNCTION__,__LINE__, ##args)
72#ifdef __DEBUG_UDC__
73#define DBG(fmt,args...)\
74 serial_printf("[%s] %s:%d: "fmt,\
75 __FILE__,__FUNCTION__,__LINE__, ##args)
76#else
77#define DBG(fmt,args...)
78#endif
79
80
81#ifdef __SIMULATE_ERROR__
82static char err_poison_test = 0;
83#endif
84static struct mpc8xx_ep ep_ref[MAX_ENDPOINTS];
85static u32 address_base = STATE_NOT_READY;
86static mpc8xx_udc_state_t udc_state = 0;
87static struct usb_device_instance *udc_device = 0;
88static volatile usb_epb_t *endpoints[MAX_ENDPOINTS];
89static volatile cbd_t *tx_cbd[TX_RING_SIZE];
90static volatile cbd_t *rx_cbd[RX_RING_SIZE];
91static volatile immap_t *immr = 0;
92static volatile cpm8xx_t *cp = 0;
93static volatile usb_pram_t *usb_paramp = 0;
94static volatile usb_t *usbp = 0;
95static int rx_ct = 0;
96static int tx_ct = 0;
97
98
99static void mpc8xx_udc_state_transition_up (usb_device_state_t initial,
100 usb_device_state_t final);
101static void mpc8xx_udc_state_transition_down (usb_device_state_t initial,
102 usb_device_state_t final);
103static void mpc8xx_udc_stall (unsigned int ep);
104static void mpc8xx_udc_flush_tx_fifo (int epid);
105static void mpc8xx_udc_flush_rx_fifo (void);
106static void mpc8xx_udc_clear_rxbd (volatile cbd_t * rx_cbdp);
107static void mpc8xx_udc_init_tx (struct usb_endpoint_instance *epi,
108 struct urb *tx_urb);
109static void mpc8xx_udc_dump_request (struct usb_device_request *request);
110static void mpc8xx_udc_clock_init (volatile immap_t * immr,
111 volatile cpm8xx_t * cp);
112static int mpc8xx_udc_ep_tx (struct usb_endpoint_instance *epi);
113static int mpc8xx_udc_epn_rx (unsigned int epid, volatile cbd_t * rx_cbdp);
114static void mpc8xx_udc_ep0_rx (volatile cbd_t * rx_cbdp);
115static void mpc8xx_udc_cbd_init (void);
116static void mpc8xx_udc_endpoint_init (void);
117static void mpc8xx_udc_cbd_attach (int ep, uchar tx_size, uchar rx_size);
118static u32 mpc8xx_udc_alloc (u32 data_size, u32 alignment);
119static int mpc8xx_udc_ep0_rx_setup (volatile cbd_t * rx_cbdp);
120static void mpc8xx_udc_set_nak (unsigned int ep);
121static short mpc8xx_udc_handle_txerr (void);
122static void mpc8xx_udc_advance_rx (volatile cbd_t ** rx_cbdp, int epid);
123
124
125
126
127
128
129
130
131
132int udc_init (void)
133{
134
135 immr = (immap_t *) CONFIG_SYS_IMMR;
136 cp = (cpm8xx_t *) & (immr->im_cpm);
137 usb_paramp = (usb_pram_t *) & (cp->cp_dparam[PROFF_USB]);
138 usbp = (usb_t *) & (cp->cp_scc[0]);
139
140 memset (ep_ref, 0x00, (sizeof (struct mpc8xx_ep) * MAX_ENDPOINTS));
141
142 udc_device = 0;
143 udc_state = STATE_NOT_READY;
144
145 usbp->usmod = 0x00;
146 usbp->uscom = 0;
147
148
149 usbp->usaddr = 0x00;
150 mpc8xx_udc_clock_init (immr, cp);
151
152
153 immr->im_ioport.iop_padir &= ~0x0003;
154 immr->im_ioport.iop_papar |= 0x0003;
155
156
157 immr->im_ioport.iop_pcso |= 0x0030;
158
159
160 immr->im_ioport.iop_pcdir |= 0x0300;
161 immr->im_ioport.iop_pcpar |= 0x0300;
162
163
164 address_base = (u32) (cp->cp_dpmem + CPM_USB_BASE);
165
166
167 mpc8xx_udc_endpoint_init ();
168 mpc8xx_udc_cbd_init ();
169
170
171 usb_paramp->ep0ptr = (u32) endpoints[0];
172 usb_paramp->ep1ptr = (u32) endpoints[1];
173 usb_paramp->ep2ptr = (u32) endpoints[2];
174 usb_paramp->ep3ptr = (u32) endpoints[3];
175 usb_paramp->frame_n = 0;
176
177 DBG ("ep0ptr=0x%08x ep1ptr=0x%08x ep2ptr=0x%08x ep3ptr=0x%08x\n",
178 usb_paramp->ep0ptr, usb_paramp->ep1ptr, usb_paramp->ep2ptr,
179 usb_paramp->ep3ptr);
180
181 return 0;
182}
183
184
185
186
187
188void udc_irq (void)
189{
190 int epid = 0;
191 volatile cbd_t *rx_cbdp = 0;
192 volatile cbd_t *rx_cbdp_base = 0;
193
194 if (udc_state != STATE_READY) {
195 return;
196 }
197
198 if (usbp->usber & USB_E_BSY) {
199
200 usbp->usber |= USB_E_BSY;
201 mpc8xx_udc_flush_rx_fifo ();
202 }
203
204
205 for (epid = 0; epid < MAX_ENDPOINTS; epid++) {
206 if (!ep_ref[epid].prx) {
207 continue;
208 }
209 rx_cbdp = rx_cbdp_base = ep_ref[epid].prx;
210
211 do {
212 if (!(rx_cbdp->cbd_sc & RX_BD_E)) {
213
214 if (rx_cbdp->cbd_sc & 0x1F) {
215
216
217
218 mpc8xx_udc_clear_rxbd (rx_cbdp);
219
220 } else {
221 if (!epid) {
222 mpc8xx_udc_ep0_rx (rx_cbdp);
223
224 } else {
225
226 mpc8xx_udc_set_nak (epid);
227 mpc8xx_udc_epn_rx (epid, rx_cbdp);
228 mpc8xx_udc_clear_rxbd (rx_cbdp);
229 }
230 }
231
232
233 mpc8xx_udc_advance_rx (&rx_cbdp, epid);
234 ep_ref[epid].prx = rx_cbdp;
235 } else {
236
237 mpc8xx_udc_advance_rx (&rx_cbdp, epid);
238 }
239
240 } while (rx_cbdp != rx_cbdp_base);
241 }
242
243
244
245
246
247 if (usbp->usber & USB_E_TXB) {
248 usbp->usber |= USB_E_TXB;
249 }
250
251 if (usbp->usber & (USB_TX_ERRMASK)) {
252 mpc8xx_udc_handle_txerr ();
253 }
254
255
256 if (usbp->usber & USB_E_RESET) {
257 usbp->usber |= USB_E_RESET;
258 usbp->usaddr = 0x00;
259 udc_device->device_state = STATE_DEFAULT;
260 }
261
262
263
264
265
266
267
268
269
270
271
272
273 return;
274}
275
276
277
278
279
280int udc_endpoint_write (struct usb_endpoint_instance *epi)
281{
282 int ep = 0;
283 short epid = 1, unnak = 0, ret = 0;
284
285 if (udc_state != STATE_READY) {
286 ERR ("invalid udc_state != STATE_READY!\n");
287 return -1;
288 }
289
290 if (!udc_device || !epi) {
291 return -1;
292 }
293
294 if (udc_device->device_state != STATE_CONFIGURED) {
295 return -1;
296 }
297
298 ep = epi->endpoint_address & 0x03;
299 if (ep >= MAX_ENDPOINTS) {
300 return -1;
301 }
302
303
304 for (epid = 1; epid < MAX_ENDPOINTS; epid++) {
305
306
307 if (ep_ref[epid].sc & USB_DIR_IN) {
308 continue;
309 }
310
311 if (!(usbp->usep[epid] & (USEP_THS_NAK | USEP_RHS_NAK))) {
312 unnak |= 1 << epid;
313 }
314
315 mpc8xx_udc_set_nak (epid);
316 }
317
318 mpc8xx_udc_init_tx (&udc_device->bus->endpoint_array[ep],
319 epi->tx_urb);
320 ret = mpc8xx_udc_ep_tx (&udc_device->bus->endpoint_array[ep]);
321
322
323 for (epid = 1; epid < MAX_ENDPOINTS; epid++) {
324 if (unnak & (1 << epid)) {
325 udc_unset_nak (epid);
326 }
327 }
328
329 return ret;
330}
331
332
333
334
335
336static int mpc8xx_udc_assign_urb (int ep, char direction)
337{
338 struct usb_endpoint_instance *epi = 0;
339
340 if (ep >= MAX_ENDPOINTS) {
341 goto err;
342 }
343 epi = &udc_device->bus->endpoint_array[ep];
344 if (!epi) {
345 goto err;
346 }
347
348 if (!ep_ref[ep].urb) {
349 ep_ref[ep].urb = usbd_alloc_urb (udc_device, udc_device->bus->endpoint_array);
350 if (!ep_ref[ep].urb) {
351 goto err;
352 }
353 } else {
354 ep_ref[ep].urb->actual_length = 0;
355 }
356
357 switch (direction) {
358 case USB_DIR_IN:
359 epi->tx_urb = ep_ref[ep].urb;
360 break;
361 case USB_DIR_OUT:
362 epi->rcv_urb = ep_ref[ep].urb;
363 break;
364 default:
365 goto err;
366 }
367 return 0;
368
369 err:
370 udc_state = STATE_ERROR;
371 return -1;
372}
373
374
375
376
377
378
379void udc_setup_ep (struct usb_device_instance *device, unsigned int ep,
380 struct usb_endpoint_instance *epi)
381{
382 uchar direction = 0;
383 int ep_attrib = 0;
384
385 if (epi && (ep < MAX_ENDPOINTS)) {
386
387 if (ep == 0) {
388 if (epi->rcv_attributes != USB_ENDPOINT_XFER_CONTROL
389 || epi->tx_attributes !=
390 USB_ENDPOINT_XFER_CONTROL) {
391
392
393 udc_state = STATE_ERROR;
394 return;
395
396 }
397 if (!(ep_ref[ep].sc & EP_ATTACHED)) {
398 mpc8xx_udc_cbd_attach (ep, epi->tx_packetSize,
399 epi->rcv_packetSize);
400 }
401 usbp->usep[ep] = 0x0000;
402 return;
403 }
404
405 if ((epi->endpoint_address & USB_ENDPOINT_DIR_MASK)
406 == USB_DIR_IN) {
407
408 direction = 1;
409 ep_attrib = epi->tx_attributes;
410 epi->rcv_packetSize = 0;
411 ep_ref[ep].sc |= USB_DIR_IN;
412 } else {
413
414 direction = 0;
415 ep_attrib = epi->rcv_attributes;
416 epi->tx_packetSize = 0;
417 ep_ref[ep].sc &= ~USB_DIR_IN;
418 }
419
420 if (mpc8xx_udc_assign_urb (ep, epi->endpoint_address
421 & USB_ENDPOINT_DIR_MASK)) {
422 return;
423 }
424
425 switch (ep_attrib) {
426 case USB_ENDPOINT_XFER_CONTROL:
427 if (!(ep_ref[ep].sc & EP_ATTACHED)) {
428 mpc8xx_udc_cbd_attach (ep,
429 epi->tx_packetSize,
430 epi->rcv_packetSize);
431 }
432 usbp->usep[ep] = ep << 12;
433 epi->rcv_urb = epi->tx_urb = ep_ref[ep].urb;
434
435 break;
436 case USB_ENDPOINT_XFER_BULK:
437 case USB_ENDPOINT_XFER_INT:
438 if (!(ep_ref[ep].sc & EP_ATTACHED)) {
439 if (direction) {
440 mpc8xx_udc_cbd_attach (ep,
441 epi->tx_packetSize,
442 0);
443 } else {
444 mpc8xx_udc_cbd_attach (ep,
445 0,
446 epi->rcv_packetSize);
447 }
448 }
449 usbp->usep[ep] = (ep << 12) | ((ep_attrib) << 8);
450
451 break;
452 case USB_ENDPOINT_XFER_ISOC:
453 default:
454 serial_printf ("Error endpoint attrib %d>3\n", ep_attrib);
455 udc_state = STATE_ERROR;
456 break;
457 }
458 }
459
460}
461
462
463
464
465
466void udc_connect (void)
467{
468
469
470
471
472 if (udc_state != STATE_ERROR) {
473 udc_state = STATE_READY;
474 usbp->usmod |= USMOD_EN;
475 }
476}
477
478
479
480
481
482void udc_disconnect (void)
483{
484
485
486
487
488 if (udc_state != STATE_ERROR) {
489 udc_state = STATE_NOT_READY;
490 }
491 usbp->usmod &= ~USMOD_EN;
492}
493
494
495
496
497
498void udc_enable (struct usb_device_instance *device)
499{
500 if (udc_state == STATE_ERROR) {
501 return;
502 }
503
504 udc_device = device;
505
506 if (!ep_ref[0].urb) {
507 ep_ref[0].urb = usbd_alloc_urb (device, device->bus->endpoint_array);
508 }
509
510
511 usbp->usber = 0x03FF;
512 usbp->usbmr = 0x02F7;
513
514 return;
515}
516
517
518
519
520
521void udc_disable (void)
522{
523 int i = 0;
524
525 if (udc_state == STATE_ERROR) {
526 DBG ("Won't disable UDC. udc_state==STATE_ERROR !\n");
527 return;
528 }
529
530 udc_device = 0;
531
532 for (; i < MAX_ENDPOINTS; i++) {
533 if (ep_ref[i].urb) {
534 usbd_dealloc_urb (ep_ref[i].urb);
535 ep_ref[i].urb = 0;
536 }
537 }
538
539 usbp->usbmr = 0x00;
540 usbp->usmod = ~USMOD_EN;
541 udc_state = STATE_NOT_READY;
542}
543
544
545
546
547
548void udc_startup_events (struct usb_device_instance *device)
549{
550 udc_enable (device);
551 if (udc_state == STATE_READY) {
552 usbd_device_event_irq (device, DEVICE_CREATE, 0);
553 }
554}
555
556
557
558
559
560
561void udc_set_nak (int epid)
562{
563 if (epid) {
564 mpc8xx_udc_set_nak (epid);
565 }
566}
567
568
569
570
571
572
573
574void udc_unset_nak (int epid)
575{
576 if (epid > MAX_ENDPOINTS) {
577 return;
578 }
579
580 if (usbp->usep[epid] & (USEP_THS_NAK | USEP_RHS_NAK)) {
581 usbp->usep[epid] &= ~(USEP_THS_NAK | USEP_RHS_NAK);
582 __asm__ ("eieio");
583 }
584}
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636static void mpc8xx_udc_state_transition_up (usb_device_state_t initial,
637 usb_device_state_t final)
638{
639 if (initial < final) {
640 switch (initial) {
641 case STATE_ATTACHED:
642 usbd_device_event_irq (udc_device,
643 DEVICE_HUB_CONFIGURED, 0);
644 if (final == STATE_POWERED)
645 break;
646 case STATE_POWERED:
647 usbd_device_event_irq (udc_device, DEVICE_RESET, 0);
648 if (final == STATE_DEFAULT)
649 break;
650 case STATE_DEFAULT:
651 usbd_device_event_irq (udc_device,
652 DEVICE_ADDRESS_ASSIGNED, 0);
653 if (final == STATE_ADDRESSED)
654 break;
655 case STATE_ADDRESSED:
656 usbd_device_event_irq (udc_device, DEVICE_CONFIGURED,
657 0);
658 case STATE_CONFIGURED:
659 break;
660 default:
661 break;
662 }
663 }
664}
665
666static void mpc8xx_udc_state_transition_down (usb_device_state_t initial,
667 usb_device_state_t final)
668{
669 if (initial > final) {
670 switch (initial) {
671 case STATE_CONFIGURED:
672 usbd_device_event_irq (udc_device,
673 DEVICE_DE_CONFIGURED, 0);
674 if (final == STATE_ADDRESSED)
675 break;
676 case STATE_ADDRESSED:
677 usbd_device_event_irq (udc_device, DEVICE_RESET, 0);
678 if (final == STATE_DEFAULT)
679 break;
680 case STATE_DEFAULT:
681 usbd_device_event_irq (udc_device,
682 DEVICE_POWER_INTERRUPTION, 0);
683 if (final == STATE_POWERED)
684 break;
685 case STATE_POWERED:
686 usbd_device_event_irq (udc_device, DEVICE_HUB_RESET,
687 0);
688 case STATE_ATTACHED:
689 break;
690 default:
691 break;
692 }
693 }
694}
695
696
697
698
699
700
701static void mpc8xx_udc_stall (unsigned int ep)
702{
703 usbp->usep[ep] |= STALL_BITMASK;
704}
705
706
707
708
709
710
711static void mpc8xx_udc_set_nak (unsigned int ep)
712{
713 usbp->usep[ep] |= NAK_BITMASK;
714 __asm__ ("eieio");
715}
716
717
718
719
720
721
722static short mpc8xx_udc_handle_txerr ()
723{
724 short ep = 0, ret = 0;
725
726 for (; ep < TX_RING_SIZE; ep++) {
727 if (usbp->usber & (0x10 << ep)) {
728
729
730 if (tx_cbd[ep]->cbd_sc & 0x06) {
731 ret = 1;
732 mpc8xx_udc_flush_tx_fifo (ep);
733
734 } else {
735 if (usbp->usep[ep] & STALL_BITMASK) {
736 if (!ep) {
737 usbp->usep[ep] &= ~STALL_BITMASK;
738 }
739 }
740 }
741 usbp->usber |= (0x10 << ep);
742 }
743 }
744 return ret;
745}
746
747
748
749
750
751static void mpc8xx_udc_advance_rx (volatile cbd_t ** rx_cbdp, int epid)
752{
753 if ((*rx_cbdp)->cbd_sc & RX_BD_W) {
754 *rx_cbdp = (volatile cbd_t *) (endpoints[epid]->rbase + CONFIG_SYS_IMMR);
755
756 } else {
757 (*rx_cbdp)++;
758 }
759}
760
761
762
763
764
765
766static void mpc8xx_udc_flush_tx_fifo (int epid)
767{
768 volatile cbd_t *tx_cbdp = 0;
769
770 if (epid > MAX_ENDPOINTS) {
771 return;
772 }
773
774
775 immr->im_cpm.cp_cpcr = ((epid << 2) | 0x1D01);
776 __asm__ ("eieio");
777 while (immr->im_cpm.cp_cpcr & 0x01);
778
779 usbp->uscom = 0x40 | 0;
780
781
782 tx_cbdp = (cbd_t *) (endpoints[epid]->tbptr + CONFIG_SYS_IMMR);
783 tx_cbdp->cbd_sc = (TX_BD_I | TX_BD_W);
784
785
786 endpoints[epid]->tptr = endpoints[epid]->tbase;
787 endpoints[epid]->tstate = 0x00;
788 endpoints[epid]->tbcnt = 0x00;
789
790
791 immr->im_cpm.cp_cpcr = ((epid << 2) | 0x2D01);
792 __asm__ ("eieio");
793 while (immr->im_cpm.cp_cpcr & 0x01);
794
795 return;
796}
797
798
799
800
801
802
803
804
805
806
807static void mpc8xx_udc_flush_rx_fifo ()
808{
809 int i = 0;
810
811 for (i = 0; i < RX_RING_SIZE; i++) {
812 if (!(rx_cbd[i]->cbd_sc & RX_BD_E)) {
813 ERR ("buf %p used rx data len = 0x%x sc=0x%x!\n",
814 rx_cbd[i], rx_cbd[i]->cbd_datlen,
815 rx_cbd[i]->cbd_sc);
816
817 }
818 }
819 ERR ("BUG : Input over-run\n");
820}
821
822
823
824
825
826static void mpc8xx_udc_clear_rxbd (volatile cbd_t * rx_cbdp)
827{
828 rx_cbdp->cbd_datlen = 0x0000;
829 rx_cbdp->cbd_sc = ((rx_cbdp->cbd_sc & RX_BD_W) | (RX_BD_E | RX_BD_I));
830 __asm__ ("eieio");
831}
832
833
834
835
836
837
838static int mpc8xx_udc_tx_irq (int ep)
839{
840 int i = 0;
841
842 if (usbp->usber & (USB_TX_ERRMASK)) {
843 if (mpc8xx_udc_handle_txerr ()) {
844
845 return -1;
846 }
847 }
848
849 if (usbp->usber & (USB_E_RESET | USB_E_BSY)) {
850
851 return -2;
852 }
853
854 if (usbp->usber & USB_E_RXB) {
855 for (i = 0; i < RX_RING_SIZE; i++) {
856 if (!(rx_cbd[i]->cbd_sc & RX_BD_E)) {
857 if ((rx_cbd[i] == ep_ref[0].prx) || ep) {
858 return -2;
859 }
860 }
861 }
862 }
863
864 return 0;
865}
866
867
868
869
870
871
872
873
874
875
876static int mpc8xx_udc_ep_tx (struct usb_endpoint_instance *epi)
877{
878 struct urb *urb = epi->tx_urb;
879 volatile cbd_t *tx_cbdp = 0;
880 unsigned int ep = 0, pkt_len = 0, x = 0, tx_retry = 0;
881 int ret = 0;
882
883 if (!epi || (epi->endpoint_address & 0x03) >= MAX_ENDPOINTS || !urb) {
884 return -1;
885 }
886
887 ep = epi->endpoint_address & 0x03;
888 tx_cbdp = (cbd_t *) (endpoints[ep]->tbptr + CONFIG_SYS_IMMR);
889
890 if (tx_cbdp->cbd_sc & TX_BD_R || usbp->usber & USB_E_TXB) {
891 mpc8xx_udc_flush_tx_fifo (ep);
892 usbp->usber |= USB_E_TXB;
893 };
894
895 while (tx_retry++ < 100) {
896 ret = mpc8xx_udc_tx_irq (ep);
897 if (ret == -1) {
898
899 } else if (ret == -2) {
900
901 mpc8xx_udc_flush_tx_fifo (ep);
902 return -1;
903 }
904
905 tx_cbdp = (cbd_t *) (endpoints[ep]->tbptr + CONFIG_SYS_IMMR);
906 while (tx_cbdp->cbd_sc & TX_BD_R) {
907 };
908 tx_cbdp->cbd_sc = (tx_cbdp->cbd_sc & TX_BD_W);
909
910 pkt_len = urb->actual_length - epi->sent;
911
912 if (pkt_len > epi->tx_packetSize || pkt_len > EP_MAX_PKT) {
913 pkt_len = MIN (epi->tx_packetSize, EP_MAX_PKT);
914 }
915
916 for (x = 0; x < pkt_len; x++) {
917 *((unsigned char *) (tx_cbdp->cbd_bufaddr + x)) =
918 urb->buffer[epi->sent + x];
919 }
920 tx_cbdp->cbd_datlen = pkt_len;
921 tx_cbdp->cbd_sc |= (CBD_TX_BITMASK | ep_ref[ep].pid);
922 __asm__ ("eieio");
923
924#ifdef __SIMULATE_ERROR__
925 if (++err_poison_test == 2) {
926 err_poison_test = 0;
927 tx_cbdp->cbd_sc &= ~TX_BD_TC;
928 }
929#endif
930
931 usbp->uscom = (USCOM_STR | ep);
932
933 while (!(usbp->usber & USB_E_TXB)) {
934 ret = mpc8xx_udc_tx_irq (ep);
935 if (ret == -1) {
936
937 break;
938 } else if (ret == -2) {
939 if (usbp->usber & USB_E_TXB) {
940 usbp->usber |= USB_E_TXB;
941 }
942 mpc8xx_udc_flush_tx_fifo (ep);
943 return -1;
944 }
945 };
946
947 if (usbp->usber & USB_E_TXB) {
948 usbp->usber |= USB_E_TXB;
949 }
950
951
952 if (ret == -1) {
953 continue;
954 }
955
956
957 epi->sent += pkt_len;
958 epi->last = MIN (urb->actual_length - epi->sent, epi->tx_packetSize);
959 TOGGLE_TX_PID (ep_ref[ep].pid);
960
961 if (epi->sent >= epi->tx_urb->actual_length) {
962
963 epi->tx_urb->actual_length = 0;
964 epi->sent = 0;
965
966 if (ep_ref[ep].sc & EP_SEND_ZLP) {
967 ep_ref[ep].sc &= ~EP_SEND_ZLP;
968 } else {
969 return 0;
970 }
971 }
972 }
973
974 ERR ("TX fail, endpoint 0x%x tx bytes 0x%x/0x%x\n", ep, epi->sent,
975 epi->tx_urb->actual_length);
976
977 return -1;
978}
979
980
981
982
983
984static void mpc8xx_udc_dump_request (struct usb_device_request *request)
985{
986 DBG ("bmRequestType:%02x bRequest:%02x wValue:%04x "
987 "wIndex:%04x wLength:%04x ?\n",
988 request->bmRequestType,
989 request->bRequest,
990 request->wValue, request->wIndex, request->wLength);
991
992 return;
993}
994
995
996
997
998
999static int mpc8xx_udc_ep0_rx_setup (volatile cbd_t * rx_cbdp)
1000{
1001 unsigned int x = 0;
1002 struct urb *purb = ep_ref[0].urb;
1003 struct usb_endpoint_instance *epi =
1004 &udc_device->bus->endpoint_array[0];
1005
1006 for (; x < rx_cbdp->cbd_datlen; x++) {
1007 *(((unsigned char *) &ep_ref[0].urb->device_request) + x) =
1008 *((unsigned char *) (rx_cbdp->cbd_bufaddr + x));
1009 }
1010
1011 mpc8xx_udc_clear_rxbd (rx_cbdp);
1012
1013 if (ep0_recv_setup (purb)) {
1014 mpc8xx_udc_dump_request (&purb->device_request);
1015 return -1;
1016 }
1017
1018 if ((purb->device_request.bmRequestType & USB_REQ_DIRECTION_MASK)
1019 == USB_REQ_HOST2DEVICE) {
1020
1021 switch (purb->device_request.bRequest) {
1022 case USB_REQ_SET_ADDRESS:
1023
1024 ep_ref[0].pid = TX_BD_PID_DATA1;
1025 purb->actual_length = 0;
1026 mpc8xx_udc_init_tx (epi, purb);
1027 mpc8xx_udc_ep_tx (epi);
1028
1029
1030 usbp->usaddr = udc_device->address;
1031 mpc8xx_udc_state_transition_up (udc_device->device_state,
1032 STATE_ADDRESSED);
1033 return 0;
1034
1035 case USB_REQ_SET_CONFIGURATION:
1036 if (!purb->device_request.wValue) {
1037
1038 usbp->usaddr = 0x00;
1039 mpc8xx_udc_state_transition_down (udc_device->device_state,
1040 STATE_ADDRESSED);
1041 } else {
1042
1043 mpc8xx_udc_state_transition_up (udc_device->device_state,
1044 STATE_CONFIGURED);
1045 for (x = 1; x < MAX_ENDPOINTS; x++) {
1046 if ((udc_device->bus->endpoint_array[x].endpoint_address & USB_ENDPOINT_DIR_MASK)
1047 == USB_DIR_IN) {
1048 ep_ref[x].pid = TX_BD_PID_DATA0;
1049 } else {
1050 ep_ref[x].pid = RX_BD_PID_DATA0;
1051 }
1052
1053 usbp->usep[x] &= ~STALL_BITMASK;
1054 }
1055 }
1056 break;
1057 default:
1058
1059 break;
1060 }
1061
1062
1063 ep_ref[0].pid = TX_BD_PID_DATA1;
1064 purb->actual_length = 0;
1065 mpc8xx_udc_init_tx (epi, purb);
1066 mpc8xx_udc_ep_tx (epi);
1067
1068 } else {
1069
1070 if (purb->actual_length) {
1071 ep_ref[0].pid = TX_BD_PID_DATA1;
1072 mpc8xx_udc_init_tx (epi, purb);
1073
1074 if (!(purb->actual_length % EP0_MAX_PACKET_SIZE)) {
1075 ep_ref[0].sc |= EP_SEND_ZLP;
1076 }
1077
1078 if (purb->device_request.wValue ==
1079 USB_DESCRIPTOR_TYPE_DEVICE) {
1080 if (le16_to_cpu (purb->device_request.wLength)
1081 > purb->actual_length) {
1082
1083
1084
1085 if (purb->actual_length > epi->tx_packetSize) {
1086 purb->actual_length = epi->tx_packetSize;
1087 }
1088 }
1089 }
1090 mpc8xx_udc_ep_tx (epi);
1091
1092 } else {
1093
1094 ERR ("Zero length data or SETUP with DATA-IN phase ?\n");
1095 return 1;
1096 }
1097 }
1098 return 0;
1099}
1100
1101
1102
1103
1104
1105static void mpc8xx_udc_init_tx (struct usb_endpoint_instance *epi,
1106 struct urb *tx_urb)
1107{
1108 epi->sent = 0;
1109 epi->last = 0;
1110 epi->tx_urb = tx_urb;
1111}
1112
1113
1114
1115
1116
1117static void mpc8xx_udc_ep0_rx (volatile cbd_t * rx_cbdp)
1118{
1119 if (rx_cbdp->cbd_sc & RX_BD_PID_SETUP) {
1120
1121
1122 if (mpc8xx_udc_ep0_rx_setup (rx_cbdp)) {
1123 mpc8xx_udc_stall (0);
1124 }
1125
1126 } else {
1127
1128 mpc8xx_udc_clear_rxbd (rx_cbdp);
1129
1130 if ((rx_cbdp->cbd_datlen - 2)) {
1131
1132
1133
1134
1135 mpc8xx_udc_stall (0);
1136 }
1137 }
1138}
1139
1140
1141
1142
1143
1144
1145static int mpc8xx_udc_epn_rx (unsigned int epid, volatile cbd_t * rx_cbdp)
1146{
1147 struct usb_endpoint_instance *epi = 0;
1148 struct urb *urb = 0;
1149 unsigned int x = 0;
1150
1151 if (epid >= MAX_ENDPOINTS || !rx_cbdp->cbd_datlen) {
1152 return 0;
1153 }
1154
1155
1156
1157
1158 if (ep_ref[epid].pid != (rx_cbdp->cbd_sc & 0xC0)) {
1159 return 1;
1160 }
1161 TOGGLE_RX_PID (ep_ref[epid].pid);
1162
1163 epi = &udc_device->bus->endpoint_array[epid];
1164 urb = epi->rcv_urb;
1165
1166 for (; x < (rx_cbdp->cbd_datlen - 2); x++) {
1167 *((unsigned char *) (urb->buffer + urb->actual_length + x)) =
1168 *((unsigned char *) (rx_cbdp->cbd_bufaddr + x));
1169 }
1170
1171 if (x) {
1172 usbd_rcv_complete (epi, x, 0);
1173 if (ep_ref[epid].urb->status == RECV_ERROR) {
1174 DBG ("RX error unset NAK\n");
1175 udc_unset_nak (epid);
1176 }
1177 }
1178 return x;
1179}
1180
1181
1182
1183
1184
1185static void mpc8xx_udc_clock_init (volatile immap_t * immr,
1186 volatile cpm8xx_t * cp)
1187{
1188
1189#if defined(CONFIG_SYS_USB_EXTC_CLK)
1190
1191
1192 switch (CONFIG_SYS_USB_EXTC_CLK) {
1193 case 1:
1194 immr->im_ioport.iop_papar |= 0x0100;
1195 immr->im_ioport.iop_padir &= ~0x0100;
1196 cp->cp_sicr |= 0x24;
1197 break;
1198 case 2:
1199 immr->im_ioport.iop_papar |= 0x0200;
1200 immr->im_ioport.iop_padir &= ~0x0200;
1201 cp->cp_sicr |= 0x2D;
1202 break;
1203 case 3:
1204 immr->im_ioport.iop_papar |= 0x0400;
1205 immr->im_ioport.iop_padir &= ~0x0400;
1206 cp->cp_sicr |= 0x36;
1207 break;
1208 case 4:
1209 immr->im_ioport.iop_papar |= 0x0800;
1210 immr->im_ioport.iop_padir &= ~0x0800;
1211 cp->cp_sicr |= 0x3F;
1212 break;
1213 default:
1214 udc_state = STATE_ERROR;
1215 break;
1216 }
1217
1218#elif defined(CONFIG_SYS_USB_BRGCLK)
1219
1220
1221 int divisor = 0;
1222
1223 if (gd->cpu_clk < 48000000L) {
1224 ERR ("brgclk is too slow for full-speed USB!\n");
1225 udc_state = STATE_ERROR;
1226 return;
1227 }
1228
1229
1230
1231
1232 divisor = (gd->cpu_clk / 48000000L) - 1;
1233 cp->cp_sicr &= ~0x0000003F;
1234
1235 switch (CONFIG_SYS_USB_BRGCLK) {
1236 case 1:
1237 cp->cp_brgc1 |= (divisor | CPM_BRG_EN);
1238 cp->cp_sicr &= ~0x2F;
1239 break;
1240 case 2:
1241 cp->cp_brgc2 |= (divisor | CPM_BRG_EN);
1242 cp->cp_sicr |= 0x00000009;
1243 break;
1244 case 3:
1245 cp->cp_brgc3 |= (divisor | CPM_BRG_EN);
1246 cp->cp_sicr |= 0x00000012;
1247 break;
1248 case 4:
1249 cp->cp_brgc4 = (divisor | CPM_BRG_EN);
1250 cp->cp_sicr |= 0x0000001B;
1251 break;
1252 default:
1253 udc_state = STATE_ERROR;
1254 break;
1255 }
1256
1257#else
1258#error "CONFIG_SYS_USB_EXTC_CLK or CONFIG_SYS_USB_BRGCLK must be defined"
1259#endif
1260
1261}
1262
1263
1264
1265
1266
1267static void mpc8xx_udc_cbd_attach (int ep, uchar tx_size, uchar rx_size)
1268{
1269
1270 if (!tx_cbd[ep] || !rx_cbd[ep] || ep >= MAX_ENDPOINTS) {
1271 udc_state = STATE_ERROR;
1272 return;
1273 }
1274
1275 if (tx_size > USB_MAX_PKT || rx_size > USB_MAX_PKT ||
1276 (!tx_size && !rx_size)) {
1277 udc_state = STATE_ERROR;
1278 return;
1279 }
1280
1281
1282 if (rx_size) {
1283 endpoints[ep]->rbase = (u32) rx_cbd[rx_ct];
1284 endpoints[ep]->rbptr = (u32) rx_cbd[rx_ct];
1285 rx_ct++;
1286
1287 if (!ep) {
1288
1289 endpoints[ep]->rbptr = (u32) rx_cbd[rx_ct];
1290 rx_cbd[rx_ct]->cbd_sc |= RX_BD_W;
1291 rx_ct++;
1292
1293 } else {
1294 rx_ct += 2;
1295 endpoints[ep]->rbptr = (u32) rx_cbd[rx_ct];
1296 rx_cbd[rx_ct]->cbd_sc |= RX_BD_W;
1297 rx_ct++;
1298 }
1299
1300
1301 ep_ref[ep].prx = rx_cbd[rx_ct - 1];
1302 } else {
1303
1304 ep_ref[ep].prx = 0;
1305 endpoints[ep]->rbase = 0;
1306 endpoints[ep]->rbptr = 0;
1307 }
1308
1309 if (tx_size) {
1310 endpoints[ep]->tbase = (u32) tx_cbd[tx_ct];
1311 endpoints[ep]->tbptr = (u32) tx_cbd[tx_ct];
1312 tx_ct++;
1313 } else {
1314 endpoints[ep]->tbase = 0;
1315 endpoints[ep]->tbptr = 0;
1316 }
1317
1318 endpoints[ep]->tstate = 0;
1319 endpoints[ep]->tbcnt = 0;
1320 endpoints[ep]->mrblr = EP_MAX_PKT;
1321 endpoints[ep]->rfcr = 0x18;
1322 endpoints[ep]->tfcr = 0x18;
1323 ep_ref[ep].sc |= EP_ATTACHED;
1324
1325 DBG ("ep %d rbase 0x%08x rbptr 0x%08x tbase 0x%08x tbptr 0x%08x prx = %p\n",
1326 ep, endpoints[ep]->rbase, endpoints[ep]->rbptr,
1327 endpoints[ep]->tbase, endpoints[ep]->tbptr,
1328 ep_ref[ep].prx);
1329
1330 return;
1331}
1332
1333
1334
1335
1336
1337static void mpc8xx_udc_cbd_init (void)
1338{
1339 int i = 0;
1340
1341 for (; i < TX_RING_SIZE; i++) {
1342 tx_cbd[i] = (cbd_t *)
1343 mpc8xx_udc_alloc (sizeof (cbd_t), sizeof (int));
1344 }
1345
1346 for (i = 0; i < RX_RING_SIZE; i++) {
1347 rx_cbd[i] = (cbd_t *)
1348 mpc8xx_udc_alloc (sizeof (cbd_t), sizeof (int));
1349 }
1350
1351 for (i = 0; i < TX_RING_SIZE; i++) {
1352 tx_cbd[i]->cbd_bufaddr =
1353 mpc8xx_udc_alloc (EP_MAX_PKT, sizeof (int));
1354
1355 tx_cbd[i]->cbd_sc = (TX_BD_I | TX_BD_W);
1356 tx_cbd[i]->cbd_datlen = 0x0000;
1357 }
1358
1359
1360 for (i = 0; i < RX_RING_SIZE; i++) {
1361 rx_cbd[i]->cbd_bufaddr =
1362 mpc8xx_udc_alloc (EP_MAX_PKT, sizeof (int));
1363 rx_cbd[i]->cbd_sc = (RX_BD_I | RX_BD_E);
1364 rx_cbd[i]->cbd_datlen = 0x0000;
1365
1366 }
1367
1368 return;
1369}
1370
1371
1372
1373
1374
1375static void mpc8xx_udc_endpoint_init (void)
1376{
1377 int i = 0;
1378
1379 for (; i < MAX_ENDPOINTS; i++) {
1380 endpoints[i] = (usb_epb_t *)
1381 mpc8xx_udc_alloc (sizeof (usb_epb_t), 32);
1382 }
1383}
1384
1385
1386
1387
1388
1389static u32 mpc8xx_udc_alloc (u32 data_size, u32 alignment)
1390{
1391 u32 retaddr = address_base;
1392
1393 while (retaddr % alignment) {
1394 retaddr++;
1395 }
1396 address_base += data_size;
1397
1398 return retaddr;
1399}
1400