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#include <linux/kernel.h>
47#include <linux/module.h>
48#include <linux/init.h>
49#include <linux/pci.h>
50#include <linux/interrupt.h>
51#include <linux/platform_device.h>
52#include <linux/usb.h>
53
54#include <linux/time.h>
55#include <linux/delay.h>
56
57#include <asm/octeon/cvmx.h>
58#include <asm/octeon/cvmx-iob-defs.h>
59
60#include <linux/usb/hcd.h>
61
62#include <linux/err.h>
63
64#include <asm/octeon/octeon.h>
65#include <asm/octeon/cvmx-helper.h>
66#include <asm/octeon/cvmx-sysinfo.h>
67#include <asm/octeon/cvmx-helper-board.h>
68
69#include "octeon-hcd.h"
70
71
72
73
74
75
76
77
78enum cvmx_usb_speed {
79 CVMX_USB_SPEED_HIGH = 0,
80 CVMX_USB_SPEED_FULL = 1,
81 CVMX_USB_SPEED_LOW = 2,
82};
83
84
85
86
87
88
89
90
91
92
93
94
95
96enum cvmx_usb_transfer {
97 CVMX_USB_TRANSFER_CONTROL = 0,
98 CVMX_USB_TRANSFER_ISOCHRONOUS = 1,
99 CVMX_USB_TRANSFER_BULK = 2,
100 CVMX_USB_TRANSFER_INTERRUPT = 3,
101};
102
103
104
105
106
107
108
109enum cvmx_usb_direction {
110 CVMX_USB_DIRECTION_OUT,
111 CVMX_USB_DIRECTION_IN,
112};
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134enum cvmx_usb_complete {
135 CVMX_USB_COMPLETE_SUCCESS,
136 CVMX_USB_COMPLETE_SHORT,
137 CVMX_USB_COMPLETE_CANCEL,
138 CVMX_USB_COMPLETE_ERROR,
139 CVMX_USB_COMPLETE_STALL,
140 CVMX_USB_COMPLETE_XACTERR,
141 CVMX_USB_COMPLETE_DATATGLERR,
142 CVMX_USB_COMPLETE_BABBLEERR,
143 CVMX_USB_COMPLETE_FRAMEERR,
144};
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161struct cvmx_usb_port_status {
162 uint32_t reserved : 25;
163 uint32_t port_enabled : 1;
164 uint32_t port_over_current : 1;
165 uint32_t port_powered : 1;
166 enum cvmx_usb_speed port_speed : 2;
167 uint32_t connected : 1;
168 uint32_t connect_change : 1;
169};
170
171
172
173
174
175
176
177
178
179
180
181union cvmx_usb_control_header {
182 uint64_t u64;
183 struct {
184 uint64_t request_type : 8;
185 uint64_t request : 8;
186 uint64_t value : 16;
187 uint64_t index : 16;
188 uint64_t length : 16;
189 } s;
190};
191
192
193
194
195
196
197
198
199
200struct cvmx_usb_iso_packet {
201 int offset;
202 int length;
203 enum cvmx_usb_complete status;
204};
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223enum cvmx_usb_initialize_flags {
224 CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI = 1 << 0,
225 CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND = 1 << 1,
226 CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK = 3 << 3,
227 CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ = 1 << 3,
228 CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ = 2 << 3,
229 CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ = 3 << 3,
230
231 CVMX_USB_INITIALIZE_FLAGS_NO_DMA = 1 << 5,
232};
233
234
235
236
237
238
239
240
241
242
243enum cvmx_usb_pipe_flags {
244 __CVMX_USB_PIPE_FLAGS_SCHEDULED = 1 << 17,
245 __CVMX_USB_PIPE_FLAGS_NEED_PING = 1 << 18,
246};
247
248
249#define CVMX_PREFETCH(address, offset) asm volatile ("pref %[type], %[off](%[rbase])" : : [rbase] "d" (address), [off] "I" (offset), [type] "n" (0))
250
251
252#define MAX_RETRIES 3
253
254
255#define MAX_CHANNELS 8
256
257
258#define MAX_USB_ADDRESS 127
259
260
261#define MAX_USB_ENDPOINT 15
262
263
264#define MAX_USB_HUB_PORT 15
265
266
267
268
269
270#define MAX_TRANSFER_BYTES ((1<<19)-1)
271
272
273
274
275
276#define MAX_TRANSFER_PACKETS ((1<<10)-1)
277
278enum {
279 USB_CLOCK_TYPE_REF_12,
280 USB_CLOCK_TYPE_REF_24,
281 USB_CLOCK_TYPE_REF_48,
282 USB_CLOCK_TYPE_CRYSTAL_12,
283};
284
285
286
287
288
289
290
291
292
293enum cvmx_usb_stage {
294 CVMX_USB_STAGE_NON_CONTROL,
295 CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE,
296 CVMX_USB_STAGE_SETUP,
297 CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE,
298 CVMX_USB_STAGE_DATA,
299 CVMX_USB_STAGE_DATA_SPLIT_COMPLETE,
300 CVMX_USB_STAGE_STATUS,
301 CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE,
302};
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324struct cvmx_usb_transaction {
325 struct list_head node;
326 enum cvmx_usb_transfer type;
327 uint64_t buffer;
328 int buffer_length;
329 uint64_t control_header;
330 int iso_start_frame;
331 int iso_number_packets;
332 struct cvmx_usb_iso_packet *iso_packets;
333 int xfersize;
334 int pktcnt;
335 int retries;
336 int actual_bytes;
337 enum cvmx_usb_stage stage;
338 struct urb *urb;
339};
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368struct cvmx_usb_pipe {
369 struct list_head node;
370 struct list_head transactions;
371 uint64_t interval;
372 uint64_t next_tx_frame;
373 enum cvmx_usb_pipe_flags flags;
374 enum cvmx_usb_speed device_speed;
375 enum cvmx_usb_transfer transfer_type;
376 enum cvmx_usb_direction transfer_dir;
377 int multi_count;
378 uint16_t max_packet;
379 uint8_t device_addr;
380 uint8_t endpoint_num;
381 uint8_t hub_device_addr;
382 uint8_t hub_port;
383 uint8_t pid_toggle;
384 uint8_t channel;
385 int8_t split_sc_frame;
386};
387
388struct cvmx_usb_tx_fifo {
389 struct {
390 int channel;
391 int size;
392 uint64_t address;
393 } entry[MAX_CHANNELS+1];
394 int head;
395 int tail;
396};
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415struct cvmx_usb_state {
416 int init_flags;
417 int index;
418 int idle_hardware_channels;
419 union cvmx_usbcx_hprt usbcx_hprt;
420 struct cvmx_usb_pipe *pipe_for_channel[MAX_CHANNELS];
421 int indent;
422 struct cvmx_usb_port_status port_status;
423 struct list_head idle_pipes;
424 struct list_head active_pipes[4];
425 uint64_t frame_number;
426 struct cvmx_usb_transaction *active_split;
427 struct cvmx_usb_tx_fifo periodic;
428 struct cvmx_usb_tx_fifo nonperiodic;
429};
430
431struct octeon_hcd {
432 spinlock_t lock;
433 struct cvmx_usb_state usb;
434 struct tasklet_struct dequeue_tasklet;
435 struct list_head dequeue_list;
436};
437
438
439#define CVMX_WAIT_FOR_FIELD32(address, type, field, op, value, timeout_usec)\
440 ({int result; \
441 do { \
442 uint64_t done = cvmx_get_cycle() + (uint64_t)timeout_usec * \
443 octeon_get_clock_rate() / 1000000; \
444 type c; \
445 while (1) { \
446 c.u32 = __cvmx_usb_read_csr32(usb, address); \
447 if (c.s.field op (value)) { \
448 result = 0; \
449 break; \
450 } else if (cvmx_get_cycle() > done) { \
451 result = -1; \
452 break; \
453 } else \
454 cvmx_wait(100); \
455 } \
456 } while (0); \
457 result; })
458
459
460
461
462
463#define USB_SET_FIELD32(address, type, field, value) \
464 do { \
465 type c; \
466 c.u32 = __cvmx_usb_read_csr32(usb, address); \
467 c.s.field = value; \
468 __cvmx_usb_write_csr32(usb, address, c.u32); \
469 } while (0)
470
471
472#define USB_FIFO_ADDRESS(channel, usb_index) (CVMX_USBCX_GOTGCTL(usb_index) + ((channel)+1)*0x1000)
473
474static int octeon_usb_get_clock_type(void)
475{
476 switch (cvmx_sysinfo_get()->board_type) {
477 case CVMX_BOARD_TYPE_BBGW_REF:
478 case CVMX_BOARD_TYPE_LANAI2_A:
479 case CVMX_BOARD_TYPE_LANAI2_U:
480 case CVMX_BOARD_TYPE_LANAI2_G:
481 case CVMX_BOARD_TYPE_UBNT_E100:
482 return USB_CLOCK_TYPE_CRYSTAL_12;
483 }
484 return USB_CLOCK_TYPE_REF_48;
485}
486
487
488
489
490
491
492
493
494
495
496
497static inline uint32_t __cvmx_usb_read_csr32(struct cvmx_usb_state *usb,
498 uint64_t address)
499{
500 uint32_t result = cvmx_read64_uint32(address ^ 4);
501 return result;
502}
503
504
505
506
507
508
509
510
511
512
513
514static inline void __cvmx_usb_write_csr32(struct cvmx_usb_state *usb,
515 uint64_t address, uint32_t value)
516{
517 cvmx_write64_uint32(address ^ 4, value);
518 cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index));
519}
520
521
522
523
524
525
526
527
528
529
530
531static inline uint64_t __cvmx_usb_read_csr64(struct cvmx_usb_state *usb,
532 uint64_t address)
533{
534 uint64_t result = cvmx_read64_uint64(address);
535 return result;
536}
537
538
539
540
541
542
543
544
545
546
547static inline void __cvmx_usb_write_csr64(struct cvmx_usb_state *usb,
548 uint64_t address, uint64_t value)
549{
550 cvmx_write64_uint64(address, value);
551}
552
553
554
555
556
557
558
559
560
561
562static inline int __cvmx_usb_pipe_needs_split(struct cvmx_usb_state *usb,
563 struct cvmx_usb_pipe *pipe)
564{
565 return pipe->device_speed != CVMX_USB_SPEED_HIGH &&
566 usb->usbcx_hprt.s.prtspd == CVMX_USB_SPEED_HIGH;
567}
568
569
570
571
572
573
574
575
576
577static inline int __cvmx_usb_get_data_pid(struct cvmx_usb_pipe *pipe)
578{
579 if (pipe->pid_toggle)
580 return 2;
581 else
582 return 0;
583}
584
585
586
587
588
589
590
591
592
593
594
595
596static int cvmx_usb_get_num_ports(void)
597{
598 int arch_ports = 0;
599
600 if (OCTEON_IS_MODEL(OCTEON_CN56XX))
601 arch_ports = 1;
602 else if (OCTEON_IS_MODEL(OCTEON_CN52XX))
603 arch_ports = 2;
604 else if (OCTEON_IS_MODEL(OCTEON_CN50XX))
605 arch_ports = 1;
606 else if (OCTEON_IS_MODEL(OCTEON_CN31XX))
607 arch_ports = 1;
608 else if (OCTEON_IS_MODEL(OCTEON_CN30XX))
609 arch_ports = 1;
610 else
611 arch_ports = 0;
612
613 return arch_ports;
614}
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630static int cvmx_usb_initialize(struct cvmx_usb_state *usb,
631 int usb_port_number)
632{
633 union cvmx_usbnx_clk_ctl usbn_clk_ctl;
634 union cvmx_usbnx_usbp_ctl_status usbn_usbp_ctl_status;
635 enum cvmx_usb_initialize_flags flags = 0;
636 int i;
637
638
639 if ((usb_port_number < 0) || (usb_port_number > 1))
640 return -EINVAL;
641
642 if (!OCTEON_IS_MODEL(OCTEON_CN52XX) && (usb_port_number > 0))
643 return -EINVAL;
644
645 if (octeon_usb_get_clock_type() == USB_CLOCK_TYPE_CRYSTAL_12) {
646
647 flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI;
648 } else {
649 flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND;
650
651 switch (octeon_usb_get_clock_type()) {
652 case USB_CLOCK_TYPE_REF_12:
653 flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ;
654 break;
655 case USB_CLOCK_TYPE_REF_24:
656 flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ;
657 break;
658 case USB_CLOCK_TYPE_REF_48:
659 flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ;
660 break;
661 default:
662 return -EINVAL;
663 break;
664 }
665 }
666
667 memset(usb, 0, sizeof(*usb));
668 usb->init_flags = flags;
669
670
671 usb->index = usb_port_number;
672 INIT_LIST_HEAD(&usb->idle_pipes);
673 for (i = 0; i < ARRAY_SIZE(usb->active_pipes); i++)
674 INIT_LIST_HEAD(&usb->active_pipes[i]);
675
676
677
678
679
680
681
682
683
684 usbn_clk_ctl.u64 = __cvmx_usb_read_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index));
685 usbn_clk_ctl.s.por = 1;
686 usbn_clk_ctl.s.hrst = 0;
687 usbn_clk_ctl.s.prst = 0;
688 usbn_clk_ctl.s.hclk_rst = 0;
689 usbn_clk_ctl.s.enable = 0;
690
691
692
693
694 if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND) {
695
696
697
698
699
700 if (OCTEON_IS_MODEL(OCTEON_CN3XXX) ||
701 OCTEON_IS_MODEL(OCTEON_CN56XX) ||
702 OCTEON_IS_MODEL(OCTEON_CN50XX))
703
704 usbn_clk_ctl.s.p_rtype = 2;
705 else
706
707 usbn_clk_ctl.s.p_rtype = 1;
708
709 switch (flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK) {
710 case CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ:
711 usbn_clk_ctl.s.p_c_sel = 0;
712 break;
713 case CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ:
714 usbn_clk_ctl.s.p_c_sel = 1;
715 break;
716 case CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ:
717 usbn_clk_ctl.s.p_c_sel = 2;
718 break;
719 }
720 } else {
721
722
723
724
725 if (OCTEON_IS_MODEL(OCTEON_CN3XXX))
726
727 usbn_clk_ctl.s.p_rtype = 3;
728 else
729
730 usbn_clk_ctl.s.p_rtype = 0;
731
732 usbn_clk_ctl.s.p_c_sel = 0;
733 }
734
735
736
737
738
739 {
740 int divisor = (octeon_get_clock_rate()+125000000-1)/125000000;
741
742 if (divisor < 4)
743 divisor = 4;
744 usbn_clk_ctl.s.divide = divisor;
745 usbn_clk_ctl.s.divide2 = 0;
746 }
747 __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
748 usbn_clk_ctl.u64);
749
750 usbn_clk_ctl.s.hclk_rst = 1;
751 __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
752 usbn_clk_ctl.u64);
753
754 cvmx_wait(64);
755
756
757
758
759
760 usbn_clk_ctl.s.por = 0;
761 __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
762 usbn_clk_ctl.u64);
763
764 mdelay(1);
765
766
767
768
769
770 usbn_usbp_ctl_status.u64 = __cvmx_usb_read_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index));
771 usbn_usbp_ctl_status.s.ate_reset = 1;
772 __cvmx_usb_write_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index),
773 usbn_usbp_ctl_status.u64);
774
775 cvmx_wait(10);
776
777
778
779
780 usbn_usbp_ctl_status.s.ate_reset = 0;
781 __cvmx_usb_write_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index),
782 usbn_usbp_ctl_status.u64);
783
784
785
786
787 usbn_clk_ctl.s.prst = 1;
788 __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
789 usbn_clk_ctl.u64);
790
791
792
793
794
795 usbn_usbp_ctl_status.s.hst_mode = 0;
796 __cvmx_usb_write_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index),
797 usbn_usbp_ctl_status.u64);
798
799 udelay(1);
800
801
802
803
804 usbn_clk_ctl.s.hrst = 1;
805 __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
806 usbn_clk_ctl.u64);
807
808 usbn_clk_ctl.s.enable = 1;
809 __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
810 usbn_clk_ctl.u64);
811 udelay(1);
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831 {
832 union cvmx_usbcx_gahbcfg usbcx_gahbcfg;
833
834 if (OCTEON_IS_MODEL(OCTEON_CN31XX))
835 usb->init_flags |= CVMX_USB_INITIALIZE_FLAGS_NO_DMA;
836 usbcx_gahbcfg.u32 = 0;
837 usbcx_gahbcfg.s.dmaen = !(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA);
838 if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
839
840 usb->idle_hardware_channels = 0x1;
841 else if (OCTEON_IS_MODEL(OCTEON_CN5XXX))
842
843 usb->idle_hardware_channels = 0xf7;
844 else
845 usb->idle_hardware_channels = 0xff;
846 usbcx_gahbcfg.s.hbstlen = 0;
847 usbcx_gahbcfg.s.nptxfemplvl = 1;
848 usbcx_gahbcfg.s.ptxfemplvl = 1;
849 usbcx_gahbcfg.s.glblintrmsk = 1;
850 __cvmx_usb_write_csr32(usb, CVMX_USBCX_GAHBCFG(usb->index),
851 usbcx_gahbcfg.u32);
852 }
853
854
855
856
857
858
859
860 {
861 union cvmx_usbcx_gusbcfg usbcx_gusbcfg;
862 usbcx_gusbcfg.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GUSBCFG(usb->index));
863 usbcx_gusbcfg.s.toutcal = 0;
864 usbcx_gusbcfg.s.ddrsel = 0;
865 usbcx_gusbcfg.s.usbtrdtim = 0x5;
866 usbcx_gusbcfg.s.phylpwrclksel = 0;
867 __cvmx_usb_write_csr32(usb, CVMX_USBCX_GUSBCFG(usb->index),
868 usbcx_gusbcfg.u32);
869 }
870
871
872
873
874
875
876 {
877 union cvmx_usbcx_gintmsk usbcx_gintmsk;
878 int channel;
879
880 usbcx_gintmsk.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GINTMSK(usb->index));
881 usbcx_gintmsk.s.otgintmsk = 1;
882 usbcx_gintmsk.s.modemismsk = 1;
883 usbcx_gintmsk.s.hchintmsk = 1;
884 usbcx_gintmsk.s.sofmsk = 0;
885
886 if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
887 usbcx_gintmsk.s.rxflvlmsk = 1;
888 __cvmx_usb_write_csr32(usb, CVMX_USBCX_GINTMSK(usb->index),
889 usbcx_gintmsk.u32);
890
891
892
893
894
895 for (channel = 0; channel < 8; channel++)
896 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), 0);
897 }
898
899 {
900
901
902
903
904
905
906 USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk,
907 prtintmsk, 1);
908 USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk,
909 disconnintmsk, 1);
910
911
912
913
914 {
915 union cvmx_usbcx_hcfg usbcx_hcfg;
916 usbcx_hcfg.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCFG(usb->index));
917 usbcx_hcfg.s.fslssupp = 0;
918 usbcx_hcfg.s.fslspclksel = 0;
919 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCFG(usb->index), usbcx_hcfg.u32);
920 }
921
922
923
924
925 USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), union cvmx_usbcx_hprt, prtpwr, 1);
926
927
928
929
930 }
931
932 return 0;
933}
934
935
936
937
938
939
940
941
942
943
944
945static int cvmx_usb_shutdown(struct cvmx_usb_state *usb)
946{
947 union cvmx_usbnx_clk_ctl usbn_clk_ctl;
948
949
950 if (!list_empty(&usb->idle_pipes) ||
951 !list_empty(&usb->active_pipes[CVMX_USB_TRANSFER_ISOCHRONOUS]) ||
952 !list_empty(&usb->active_pipes[CVMX_USB_TRANSFER_INTERRUPT]) ||
953 !list_empty(&usb->active_pipes[CVMX_USB_TRANSFER_CONTROL]) ||
954 !list_empty(&usb->active_pipes[CVMX_USB_TRANSFER_BULK]))
955 return -EBUSY;
956
957
958 usbn_clk_ctl.u64 = __cvmx_usb_read_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index));
959 usbn_clk_ctl.s.enable = 1;
960 usbn_clk_ctl.s.por = 1;
961 usbn_clk_ctl.s.hclk_rst = 1;
962 usbn_clk_ctl.s.prst = 0;
963 usbn_clk_ctl.s.hrst = 0;
964 __cvmx_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
965 usbn_clk_ctl.u64);
966 return 0;
967}
968
969
970
971
972
973
974
975
976
977
978static int cvmx_usb_enable(struct cvmx_usb_state *usb)
979{
980 union cvmx_usbcx_ghwcfg3 usbcx_ghwcfg3;
981
982 usb->usbcx_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index));
983
984
985
986
987
988 if (usb->usbcx_hprt.s.prtena)
989 return 0;
990
991
992 if (!usb->usbcx_hprt.s.prtconnsts) {
993 return -ETIMEDOUT;
994 }
995
996
997 USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), union cvmx_usbcx_hprt, prtrst, 1);
998
999
1000
1001
1002
1003 mdelay(50);
1004
1005
1006 USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), union cvmx_usbcx_hprt, prtrst, 0);
1007
1008
1009 if (CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_HPRT(usb->index), union cvmx_usbcx_hprt,
1010 prtena, ==, 1, 100000))
1011 return -ETIMEDOUT;
1012
1013
1014
1015
1016
1017 usb->usbcx_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index));
1018 usbcx_ghwcfg3.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GHWCFG3(usb->index));
1019
1020
1021
1022
1023
1024 USB_SET_FIELD32(CVMX_USBCX_GRXFSIZ(usb->index), union cvmx_usbcx_grxfsiz,
1025 rxfdep, usbcx_ghwcfg3.s.dfifodepth / 4);
1026
1027
1028
1029
1030
1031 {
1032 union cvmx_usbcx_gnptxfsiz siz;
1033 siz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GNPTXFSIZ(usb->index));
1034 siz.s.nptxfdep = usbcx_ghwcfg3.s.dfifodepth / 2;
1035 siz.s.nptxfstaddr = usbcx_ghwcfg3.s.dfifodepth / 4;
1036 __cvmx_usb_write_csr32(usb, CVMX_USBCX_GNPTXFSIZ(usb->index), siz.u32);
1037 }
1038
1039
1040
1041
1042
1043 {
1044 union cvmx_usbcx_hptxfsiz siz;
1045 siz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPTXFSIZ(usb->index));
1046 siz.s.ptxfsize = usbcx_ghwcfg3.s.dfifodepth / 4;
1047 siz.s.ptxfstaddr = 3 * usbcx_ghwcfg3.s.dfifodepth / 4;
1048 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HPTXFSIZ(usb->index), siz.u32);
1049 }
1050
1051 USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), union cvmx_usbcx_grstctl, txfnum, 0x10);
1052 USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), union cvmx_usbcx_grstctl, txfflsh, 1);
1053 CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), union cvmx_usbcx_grstctl,
1054 txfflsh, ==, 0, 100);
1055 USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), union cvmx_usbcx_grstctl, rxfflsh, 1);
1056 CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), union cvmx_usbcx_grstctl,
1057 rxfflsh, ==, 0, 100);
1058
1059 return 0;
1060}
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073static int cvmx_usb_disable(struct cvmx_usb_state *usb)
1074{
1075
1076 USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), union cvmx_usbcx_hprt, prtena, 1);
1077 return 0;
1078}
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092static struct cvmx_usb_port_status cvmx_usb_get_status(struct cvmx_usb_state *usb)
1093{
1094 union cvmx_usbcx_hprt usbc_hprt;
1095 struct cvmx_usb_port_status result;
1096
1097 memset(&result, 0, sizeof(result));
1098
1099 usbc_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index));
1100 result.port_enabled = usbc_hprt.s.prtena;
1101 result.port_over_current = usbc_hprt.s.prtovrcurract;
1102 result.port_powered = usbc_hprt.s.prtpwr;
1103 result.port_speed = usbc_hprt.s.prtspd;
1104 result.connected = usbc_hprt.s.prtconnsts;
1105 result.connect_change = (result.connected != usb->port_status.connected);
1106
1107 return result;
1108}
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162static struct cvmx_usb_pipe *cvmx_usb_open_pipe(struct cvmx_usb_state *usb,
1163 int device_addr, int
1164 endpoint_num,
1165 enum cvmx_usb_speed
1166 device_speed,
1167 int max_packet,
1168 enum cvmx_usb_transfer
1169 transfer_type,
1170 enum cvmx_usb_direction
1171 transfer_dir,
1172 int interval, int multi_count,
1173 int hub_device_addr,
1174 int hub_port)
1175{
1176 struct cvmx_usb_pipe *pipe;
1177
1178 if (unlikely((device_addr < 0) || (device_addr > MAX_USB_ADDRESS)))
1179 return NULL;
1180 if (unlikely((endpoint_num < 0) || (endpoint_num > MAX_USB_ENDPOINT)))
1181 return NULL;
1182 if (unlikely(device_speed > CVMX_USB_SPEED_LOW))
1183 return NULL;
1184 if (unlikely((max_packet <= 0) || (max_packet > 1024)))
1185 return NULL;
1186 if (unlikely(transfer_type > CVMX_USB_TRANSFER_INTERRUPT))
1187 return NULL;
1188 if (unlikely((transfer_dir != CVMX_USB_DIRECTION_OUT) &&
1189 (transfer_dir != CVMX_USB_DIRECTION_IN)))
1190 return NULL;
1191 if (unlikely(interval < 0))
1192 return NULL;
1193 if (unlikely((transfer_type == CVMX_USB_TRANSFER_CONTROL) && interval))
1194 return NULL;
1195 if (unlikely(multi_count < 0))
1196 return NULL;
1197 if (unlikely((device_speed != CVMX_USB_SPEED_HIGH) &&
1198 (multi_count != 0)))
1199 return NULL;
1200 if (unlikely((hub_device_addr < 0) || (hub_device_addr > MAX_USB_ADDRESS)))
1201 return NULL;
1202 if (unlikely((hub_port < 0) || (hub_port > MAX_USB_HUB_PORT)))
1203 return NULL;
1204
1205 pipe = kzalloc(sizeof(*pipe), GFP_ATOMIC);
1206 if (!pipe)
1207 return NULL;
1208 if ((device_speed == CVMX_USB_SPEED_HIGH) &&
1209 (transfer_dir == CVMX_USB_DIRECTION_OUT) &&
1210 (transfer_type == CVMX_USB_TRANSFER_BULK))
1211 pipe->flags |= __CVMX_USB_PIPE_FLAGS_NEED_PING;
1212 pipe->device_addr = device_addr;
1213 pipe->endpoint_num = endpoint_num;
1214 pipe->device_speed = device_speed;
1215 pipe->max_packet = max_packet;
1216 pipe->transfer_type = transfer_type;
1217 pipe->transfer_dir = transfer_dir;
1218 INIT_LIST_HEAD(&pipe->transactions);
1219
1220
1221
1222
1223
1224 if (!interval)
1225 interval = 1;
1226 if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
1227 pipe->interval = interval*8;
1228
1229 pipe->next_tx_frame = ((usb->frame_number+7)&~7) + pipe->interval;
1230 } else {
1231 pipe->interval = interval;
1232 pipe->next_tx_frame = usb->frame_number + pipe->interval;
1233 }
1234 pipe->multi_count = multi_count;
1235 pipe->hub_device_addr = hub_device_addr;
1236 pipe->hub_port = hub_port;
1237 pipe->pid_toggle = 0;
1238 pipe->split_sc_frame = -1;
1239 list_add_tail(&pipe->node, &usb->idle_pipes);
1240
1241
1242
1243
1244
1245
1246 return pipe;
1247}
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257static void __cvmx_usb_poll_rx_fifo(struct cvmx_usb_state *usb)
1258{
1259 union cvmx_usbcx_grxstsph rx_status;
1260 int channel;
1261 int bytes;
1262 uint64_t address;
1263 uint32_t *ptr;
1264
1265 rx_status.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GRXSTSPH(usb->index));
1266
1267 if (rx_status.s.pktsts != 2)
1268 return;
1269
1270 if (!rx_status.s.bcnt)
1271 return;
1272
1273 channel = rx_status.s.chnum;
1274 bytes = rx_status.s.bcnt;
1275 if (!bytes)
1276 return;
1277
1278
1279 address = __cvmx_usb_read_csr64(usb, CVMX_USBNX_DMA0_INB_CHN0(usb->index) + channel*8);
1280 ptr = cvmx_phys_to_ptr(address);
1281 __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_INB_CHN0(usb->index) + channel*8, address + bytes);
1282
1283
1284 while (bytes > 0) {
1285 *ptr++ = __cvmx_usb_read_csr32(usb, USB_FIFO_ADDRESS(channel, usb->index));
1286 bytes -= 4;
1287 }
1288 CVMX_SYNCW;
1289
1290 return;
1291}
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305static int __cvmx_usb_fill_tx_hw(struct cvmx_usb_state *usb,
1306 struct cvmx_usb_tx_fifo *fifo, int available)
1307{
1308
1309
1310
1311
1312 while (available && (fifo->head != fifo->tail)) {
1313 int i = fifo->tail;
1314 const uint32_t *ptr = cvmx_phys_to_ptr(fifo->entry[i].address);
1315 uint64_t csr_address = USB_FIFO_ADDRESS(fifo->entry[i].channel, usb->index) ^ 4;
1316 int words = available;
1317
1318
1319 if (fifo->entry[i].size <= available) {
1320 words = fifo->entry[i].size;
1321 fifo->tail++;
1322 if (fifo->tail > MAX_CHANNELS)
1323 fifo->tail = 0;
1324 }
1325
1326
1327 available -= words;
1328 fifo->entry[i].address += words * 4;
1329 fifo->entry[i].size -= words;
1330
1331
1332
1333
1334
1335 while (words > 3) {
1336 cvmx_write64_uint32(csr_address, *ptr++);
1337 cvmx_write64_uint32(csr_address, *ptr++);
1338 cvmx_write64_uint32(csr_address, *ptr++);
1339 cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index));
1340 words -= 3;
1341 }
1342 cvmx_write64_uint32(csr_address, *ptr++);
1343 if (--words) {
1344 cvmx_write64_uint32(csr_address, *ptr++);
1345 if (--words)
1346 cvmx_write64_uint32(csr_address, *ptr++);
1347 }
1348 cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index));
1349 }
1350 return fifo->head != fifo->tail;
1351}
1352
1353
1354
1355
1356
1357
1358
1359static void __cvmx_usb_poll_tx_fifo(struct cvmx_usb_state *usb)
1360{
1361 if (usb->periodic.head != usb->periodic.tail) {
1362 union cvmx_usbcx_hptxsts tx_status;
1363 tx_status.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPTXSTS(usb->index));
1364 if (__cvmx_usb_fill_tx_hw(usb, &usb->periodic, tx_status.s.ptxfspcavail))
1365 USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk, ptxfempmsk, 1);
1366 else
1367 USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk, ptxfempmsk, 0);
1368 }
1369
1370 if (usb->nonperiodic.head != usb->nonperiodic.tail) {
1371 union cvmx_usbcx_gnptxsts tx_status;
1372 tx_status.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GNPTXSTS(usb->index));
1373 if (__cvmx_usb_fill_tx_hw(usb, &usb->nonperiodic, tx_status.s.nptxfspcavail))
1374 USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk, nptxfempmsk, 1);
1375 else
1376 USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk, nptxfempmsk, 0);
1377 }
1378
1379 return;
1380}
1381
1382
1383
1384
1385
1386
1387
1388
1389static void __cvmx_usb_fill_tx_fifo(struct cvmx_usb_state *usb, int channel)
1390{
1391 union cvmx_usbcx_hccharx hcchar;
1392 union cvmx_usbcx_hcspltx usbc_hcsplt;
1393 union cvmx_usbcx_hctsizx usbc_hctsiz;
1394 struct cvmx_usb_tx_fifo *fifo;
1395
1396
1397 hcchar.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index));
1398 if (hcchar.s.epdir != CVMX_USB_DIRECTION_OUT)
1399 return;
1400
1401
1402 usbc_hcsplt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCSPLTX(channel, usb->index));
1403 if (usbc_hcsplt.s.spltena && usbc_hcsplt.s.compsplt)
1404 return;
1405
1406
1407
1408
1409
1410 usbc_hctsiz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index));
1411 if (!usbc_hctsiz.s.xfersize)
1412 return;
1413
1414 if ((hcchar.s.eptype == CVMX_USB_TRANSFER_INTERRUPT) ||
1415 (hcchar.s.eptype == CVMX_USB_TRANSFER_ISOCHRONOUS))
1416 fifo = &usb->periodic;
1417 else
1418 fifo = &usb->nonperiodic;
1419
1420 fifo->entry[fifo->head].channel = channel;
1421 fifo->entry[fifo->head].address = __cvmx_usb_read_csr64(usb, CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8);
1422 fifo->entry[fifo->head].size = (usbc_hctsiz.s.xfersize+3)>>2;
1423 fifo->head++;
1424 if (fifo->head > MAX_CHANNELS)
1425 fifo->head = 0;
1426
1427 __cvmx_usb_poll_tx_fifo(usb);
1428
1429 return;
1430}
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441static void __cvmx_usb_start_channel_control(struct cvmx_usb_state *usb,
1442 int channel,
1443 struct cvmx_usb_pipe *pipe)
1444{
1445 struct cvmx_usb_transaction *transaction =
1446 list_first_entry(&pipe->transactions, typeof(*transaction),
1447 node);
1448 union cvmx_usb_control_header *header =
1449 cvmx_phys_to_ptr(transaction->control_header);
1450 int bytes_to_transfer = transaction->buffer_length - transaction->actual_bytes;
1451 int packets_to_transfer;
1452 union cvmx_usbcx_hctsizx usbc_hctsiz;
1453
1454 usbc_hctsiz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index));
1455
1456 switch (transaction->stage) {
1457 case CVMX_USB_STAGE_NON_CONTROL:
1458 case CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE:
1459 cvmx_dprintf("%s: ERROR - Non control stage\n", __FUNCTION__);
1460 break;
1461 case CVMX_USB_STAGE_SETUP:
1462 usbc_hctsiz.s.pid = 3;
1463 bytes_to_transfer = sizeof(*header);
1464
1465 USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), union cvmx_usbcx_hccharx, epdir, CVMX_USB_DIRECTION_OUT);
1466
1467
1468
1469
1470 __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8, transaction->control_header);
1471 break;
1472 case CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE:
1473 usbc_hctsiz.s.pid = 3;
1474 bytes_to_transfer = 0;
1475
1476 USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), union cvmx_usbcx_hccharx, epdir, CVMX_USB_DIRECTION_OUT);
1477 USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index), union cvmx_usbcx_hcspltx, compsplt, 1);
1478 break;
1479 case CVMX_USB_STAGE_DATA:
1480 usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
1481 if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
1482 if (header->s.request_type & 0x80)
1483 bytes_to_transfer = 0;
1484 else if (bytes_to_transfer > pipe->max_packet)
1485 bytes_to_transfer = pipe->max_packet;
1486 }
1487 USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index),
1488 union cvmx_usbcx_hccharx, epdir,
1489 ((header->s.request_type & 0x80) ?
1490 CVMX_USB_DIRECTION_IN :
1491 CVMX_USB_DIRECTION_OUT));
1492 break;
1493 case CVMX_USB_STAGE_DATA_SPLIT_COMPLETE:
1494 usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
1495 if (!(header->s.request_type & 0x80))
1496 bytes_to_transfer = 0;
1497 USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index),
1498 union cvmx_usbcx_hccharx, epdir,
1499 ((header->s.request_type & 0x80) ?
1500 CVMX_USB_DIRECTION_IN :
1501 CVMX_USB_DIRECTION_OUT));
1502 USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index), union cvmx_usbcx_hcspltx, compsplt, 1);
1503 break;
1504 case CVMX_USB_STAGE_STATUS:
1505 usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
1506 bytes_to_transfer = 0;
1507 USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), union cvmx_usbcx_hccharx, epdir,
1508 ((header->s.request_type & 0x80) ?
1509 CVMX_USB_DIRECTION_OUT :
1510 CVMX_USB_DIRECTION_IN));
1511 break;
1512 case CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE:
1513 usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
1514 bytes_to_transfer = 0;
1515 USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), union cvmx_usbcx_hccharx, epdir,
1516 ((header->s.request_type & 0x80) ?
1517 CVMX_USB_DIRECTION_OUT :
1518 CVMX_USB_DIRECTION_IN));
1519 USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index), union cvmx_usbcx_hcspltx, compsplt, 1);
1520 break;
1521 }
1522
1523
1524
1525
1526
1527 if (bytes_to_transfer > MAX_TRANSFER_BYTES) {
1528
1529 bytes_to_transfer = MAX_TRANSFER_BYTES / pipe->max_packet;
1530 bytes_to_transfer *= pipe->max_packet;
1531 }
1532
1533
1534
1535
1536
1537 packets_to_transfer = (bytes_to_transfer + pipe->max_packet - 1) / pipe->max_packet;
1538 if (packets_to_transfer == 0)
1539 packets_to_transfer = 1;
1540 else if ((packets_to_transfer > 1) && (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)) {
1541
1542
1543
1544
1545
1546 packets_to_transfer = 1;
1547 bytes_to_transfer = packets_to_transfer * pipe->max_packet;
1548 } else if (packets_to_transfer > MAX_TRANSFER_PACKETS) {
1549
1550
1551
1552
1553 packets_to_transfer = MAX_TRANSFER_PACKETS;
1554 bytes_to_transfer = packets_to_transfer * pipe->max_packet;
1555 }
1556
1557 usbc_hctsiz.s.xfersize = bytes_to_transfer;
1558 usbc_hctsiz.s.pktcnt = packets_to_transfer;
1559
1560 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index), usbc_hctsiz.u32);
1561 return;
1562}
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572static void __cvmx_usb_start_channel(struct cvmx_usb_state *usb,
1573 int channel,
1574 struct cvmx_usb_pipe *pipe)
1575{
1576 struct cvmx_usb_transaction *transaction =
1577 list_first_entry(&pipe->transactions, typeof(*transaction),
1578 node);
1579
1580
1581 CVMX_SYNCW;
1582
1583
1584 usb->pipe_for_channel[channel] = pipe;
1585 pipe->channel = channel;
1586 pipe->flags |= __CVMX_USB_PIPE_FLAGS_SCHEDULED;
1587
1588
1589 usb->idle_hardware_channels &= ~(1<<channel);
1590
1591
1592 {
1593 union cvmx_usbcx_hcintx usbc_hcint;
1594 union cvmx_usbcx_hcintmskx usbc_hcintmsk;
1595 union cvmx_usbcx_haintmsk usbc_haintmsk;
1596
1597
1598 usbc_hcint.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCINTX(channel, usb->index));
1599 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTX(channel, usb->index), usbc_hcint.u32);
1600
1601 usbc_hcintmsk.u32 = 0;
1602 usbc_hcintmsk.s.chhltdmsk = 1;
1603 if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA) {
1604
1605
1606
1607
1608 usbc_hcintmsk.s.datatglerrmsk = 1;
1609 usbc_hcintmsk.s.frmovrunmsk = 1;
1610 usbc_hcintmsk.s.bblerrmsk = 1;
1611 usbc_hcintmsk.s.xacterrmsk = 1;
1612 if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
1613
1614
1615
1616
1617 usbc_hcintmsk.s.nyetmsk = 1;
1618 usbc_hcintmsk.s.ackmsk = 1;
1619 }
1620 usbc_hcintmsk.s.nakmsk = 1;
1621 usbc_hcintmsk.s.stallmsk = 1;
1622 usbc_hcintmsk.s.xfercomplmsk = 1;
1623 }
1624 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), usbc_hcintmsk.u32);
1625
1626
1627 usbc_haintmsk.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HAINTMSK(usb->index));
1628 usbc_haintmsk.s.haintmsk |= 1<<channel;
1629 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HAINTMSK(usb->index), usbc_haintmsk.u32);
1630 }
1631
1632
1633 {
1634 uint64_t dma_address = transaction->buffer + transaction->actual_bytes;
1635 if (transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS)
1636 dma_address = transaction->buffer + transaction->iso_packets[0].offset + transaction->actual_bytes;
1637 __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8, dma_address);
1638 __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_INB_CHN0(usb->index) + channel*8, dma_address);
1639 }
1640
1641
1642 {
1643 union cvmx_usbcx_hcspltx usbc_hcsplt = {.u32 = 0};
1644 union cvmx_usbcx_hctsizx usbc_hctsiz = {.u32 = 0};
1645 int packets_to_transfer;
1646 int bytes_to_transfer = transaction->buffer_length - transaction->actual_bytes;
1647
1648
1649
1650
1651
1652 if (transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS)
1653 bytes_to_transfer = transaction->iso_packets[0].length - transaction->actual_bytes;
1654
1655
1656
1657
1658
1659 if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
1660
1661
1662
1663
1664
1665
1666 if ((transaction->stage&1) == 0) {
1667 if (transaction->type == CVMX_USB_TRANSFER_BULK)
1668 pipe->split_sc_frame = (usb->frame_number + 1) & 0x7f;
1669 else
1670 pipe->split_sc_frame = (usb->frame_number + 2) & 0x7f;
1671 } else
1672 pipe->split_sc_frame = -1;
1673
1674 usbc_hcsplt.s.spltena = 1;
1675 usbc_hcsplt.s.hubaddr = pipe->hub_device_addr;
1676 usbc_hcsplt.s.prtaddr = pipe->hub_port;
1677 usbc_hcsplt.s.compsplt = (transaction->stage == CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE);
1678
1679
1680
1681
1682
1683
1684 if (bytes_to_transfer > pipe->max_packet)
1685 bytes_to_transfer = pipe->max_packet;
1686
1687
1688
1689
1690
1691
1692 if (!usbc_hcsplt.s.compsplt &&
1693 (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT) &&
1694 (pipe->transfer_type == CVMX_USB_TRANSFER_ISOCHRONOUS)) {
1695
1696
1697
1698
1699 pipe->split_sc_frame = -1;
1700
1701
1702
1703
1704 if (transaction->actual_bytes == 0) {
1705
1706
1707
1708
1709 if (bytes_to_transfer <= 188)
1710
1711 usbc_hcsplt.s.xactpos = 3;
1712 else
1713
1714 usbc_hcsplt.s.xactpos = 2;
1715 } else {
1716
1717
1718
1719
1720 if (bytes_to_transfer <= 188)
1721
1722 usbc_hcsplt.s.xactpos = 1;
1723 else
1724
1725 usbc_hcsplt.s.xactpos = 0;
1726 }
1727
1728
1729
1730
1731 if (bytes_to_transfer > 188)
1732 bytes_to_transfer = 188;
1733 }
1734 }
1735
1736
1737
1738
1739
1740
1741 if (bytes_to_transfer > MAX_TRANSFER_BYTES) {
1742
1743
1744
1745
1746 bytes_to_transfer = MAX_TRANSFER_BYTES / pipe->max_packet;
1747 bytes_to_transfer *= pipe->max_packet;
1748 }
1749
1750
1751
1752
1753
1754 packets_to_transfer = (bytes_to_transfer + pipe->max_packet - 1) / pipe->max_packet;
1755 if (packets_to_transfer == 0)
1756 packets_to_transfer = 1;
1757 else if ((packets_to_transfer > 1) && (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)) {
1758
1759
1760
1761
1762
1763
1764 packets_to_transfer = 1;
1765 bytes_to_transfer = packets_to_transfer * pipe->max_packet;
1766 } else if (packets_to_transfer > MAX_TRANSFER_PACKETS) {
1767
1768
1769
1770
1771 packets_to_transfer = MAX_TRANSFER_PACKETS;
1772 bytes_to_transfer = packets_to_transfer * pipe->max_packet;
1773 }
1774
1775 usbc_hctsiz.s.xfersize = bytes_to_transfer;
1776 usbc_hctsiz.s.pktcnt = packets_to_transfer;
1777
1778
1779 usbc_hctsiz.s.pid = __cvmx_usb_get_data_pid(pipe);
1780
1781
1782
1783 if (pipe->flags & __CVMX_USB_PIPE_FLAGS_NEED_PING)
1784 usbc_hctsiz.s.dopng = 1;
1785
1786 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCSPLTX(channel, usb->index), usbc_hcsplt.u32);
1787 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index), usbc_hctsiz.u32);
1788 }
1789
1790
1791 {
1792 union cvmx_usbcx_hccharx usbc_hcchar = {.u32 = 0};
1793
1794
1795
1796
1797
1798 usbc_hcchar.s.oddfrm = usb->frame_number&1;
1799
1800
1801
1802
1803
1804
1805
1806 if (__cvmx_usb_pipe_needs_split(usb, pipe))
1807 usbc_hcchar.s.ec = 1;
1808 else if (pipe->multi_count < 1)
1809 usbc_hcchar.s.ec = 1;
1810 else if (pipe->multi_count > 3)
1811 usbc_hcchar.s.ec = 3;
1812 else
1813 usbc_hcchar.s.ec = pipe->multi_count;
1814
1815
1816 usbc_hcchar.s.devaddr = pipe->device_addr;
1817 usbc_hcchar.s.eptype = transaction->type;
1818 usbc_hcchar.s.lspddev = (pipe->device_speed == CVMX_USB_SPEED_LOW);
1819 usbc_hcchar.s.epdir = pipe->transfer_dir;
1820 usbc_hcchar.s.epnum = pipe->endpoint_num;
1821 usbc_hcchar.s.mps = pipe->max_packet;
1822 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index), usbc_hcchar.u32);
1823 }
1824
1825
1826 switch (transaction->type) {
1827 case CVMX_USB_TRANSFER_CONTROL:
1828 __cvmx_usb_start_channel_control(usb, channel, pipe);
1829 break;
1830 case CVMX_USB_TRANSFER_BULK:
1831 case CVMX_USB_TRANSFER_INTERRUPT:
1832 break;
1833 case CVMX_USB_TRANSFER_ISOCHRONOUS:
1834 if (!__cvmx_usb_pipe_needs_split(usb, pipe)) {
1835
1836
1837
1838
1839 if (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT) {
1840 if (pipe->multi_count < 2)
1841 USB_SET_FIELD32(CVMX_USBCX_HCTSIZX(channel, usb->index), union cvmx_usbcx_hctsizx, pid, 0);
1842 else
1843 USB_SET_FIELD32(CVMX_USBCX_HCTSIZX(channel, usb->index), union cvmx_usbcx_hctsizx, pid, 3);
1844 }
1845 }
1846 break;
1847 }
1848 {
1849 union cvmx_usbcx_hctsizx usbc_hctsiz = {.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index))};
1850 transaction->xfersize = usbc_hctsiz.s.xfersize;
1851 transaction->pktcnt = usbc_hctsiz.s.pktcnt;
1852 }
1853
1854 if (__cvmx_usb_pipe_needs_split(usb, pipe))
1855 usb->active_split = transaction;
1856 USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index), union cvmx_usbcx_hccharx, chena, 1);
1857 if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
1858 __cvmx_usb_fill_tx_fifo(usb, channel);
1859 return;
1860}
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872static struct cvmx_usb_pipe *__cvmx_usb_find_ready_pipe(struct cvmx_usb_state *usb, struct list_head *list, uint64_t current_frame)
1873{
1874 struct cvmx_usb_pipe *pipe;
1875
1876 list_for_each_entry(pipe, list, node) {
1877 struct cvmx_usb_transaction *t =
1878 list_first_entry(&pipe->transactions, typeof(*t), node);
1879 if (!(pipe->flags & __CVMX_USB_PIPE_FLAGS_SCHEDULED) && t &&
1880 (pipe->next_tx_frame <= current_frame) &&
1881 ((pipe->split_sc_frame == -1) || ((((int)current_frame - (int)pipe->split_sc_frame) & 0x7f) < 0x40)) &&
1882 (!usb->active_split || (usb->active_split == t))) {
1883 CVMX_PREFETCH(pipe, 128);
1884 CVMX_PREFETCH(t, 0);
1885 return pipe;
1886 }
1887 }
1888 return NULL;
1889}
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899static void __cvmx_usb_schedule(struct cvmx_usb_state *usb, int is_sof)
1900{
1901 int channel;
1902 struct cvmx_usb_pipe *pipe;
1903 int need_sof;
1904 enum cvmx_usb_transfer ttype;
1905
1906 if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA) {
1907
1908
1909
1910
1911 union cvmx_usbcx_hfnum hfnum = {.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index))};
1912 union cvmx_usbcx_hfir hfir = {.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFIR(usb->index))};
1913 if (hfnum.s.frrem < hfir.s.frint/4)
1914 goto done;
1915 }
1916
1917 while (usb->idle_hardware_channels) {
1918
1919 channel = __fls(usb->idle_hardware_channels);
1920 if (unlikely(channel > 7))
1921 break;
1922
1923
1924 pipe = NULL;
1925 if (is_sof) {
1926
1927
1928
1929
1930
1931 pipe = __cvmx_usb_find_ready_pipe(usb, usb->active_pipes + CVMX_USB_TRANSFER_ISOCHRONOUS, usb->frame_number);
1932 if (likely(!pipe))
1933 pipe = __cvmx_usb_find_ready_pipe(usb, usb->active_pipes + CVMX_USB_TRANSFER_INTERRUPT, usb->frame_number);
1934 }
1935 if (likely(!pipe)) {
1936 pipe = __cvmx_usb_find_ready_pipe(usb, usb->active_pipes + CVMX_USB_TRANSFER_CONTROL, usb->frame_number);
1937 if (likely(!pipe))
1938 pipe = __cvmx_usb_find_ready_pipe(usb, usb->active_pipes + CVMX_USB_TRANSFER_BULK, usb->frame_number);
1939 }
1940 if (!pipe)
1941 break;
1942
1943 __cvmx_usb_start_channel(usb, channel, pipe);
1944 }
1945
1946done:
1947
1948
1949
1950
1951 need_sof = 0;
1952 for (ttype = CVMX_USB_TRANSFER_CONTROL; ttype <= CVMX_USB_TRANSFER_INTERRUPT; ttype++) {
1953 list_for_each_entry(pipe, &usb->active_pipes[ttype], node) {
1954 if (pipe->next_tx_frame > usb->frame_number) {
1955 need_sof = 1;
1956 break;
1957 }
1958 }
1959 }
1960 USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk, sofmsk, need_sof);
1961 return;
1962}
1963
1964static inline struct octeon_hcd *cvmx_usb_to_octeon(struct cvmx_usb_state *p)
1965{
1966 return container_of(p, struct octeon_hcd, usb);
1967}
1968
1969static inline struct usb_hcd *octeon_to_hcd(struct octeon_hcd *p)
1970{
1971 return container_of((void *)p, struct usb_hcd, hcd_priv);
1972}
1973
1974static void octeon_usb_urb_complete_callback(struct cvmx_usb_state *usb,
1975 enum cvmx_usb_complete status,
1976 struct cvmx_usb_pipe *pipe,
1977 struct cvmx_usb_transaction
1978 *transaction,
1979 int bytes_transferred,
1980 struct urb *urb)
1981{
1982 struct octeon_hcd *priv = cvmx_usb_to_octeon(usb);
1983 struct usb_hcd *hcd = octeon_to_hcd(priv);
1984 struct device *dev = hcd->self.controller;
1985
1986 urb->actual_length = bytes_transferred;
1987 urb->hcpriv = NULL;
1988
1989 if (!list_empty(&urb->urb_list))
1990
1991
1992
1993
1994
1995
1996 list_del_init(&urb->urb_list);
1997
1998
1999
2000 if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
2001 int i;
2002
2003
2004
2005
2006 struct cvmx_usb_iso_packet *iso_packet =
2007 (struct cvmx_usb_iso_packet *) urb->setup_packet;
2008
2009 urb->actual_length = 0;
2010 for (i = 0; i < urb->number_of_packets; i++) {
2011 if (iso_packet[i].status == CVMX_USB_COMPLETE_SUCCESS) {
2012 urb->iso_frame_desc[i].status = 0;
2013 urb->iso_frame_desc[i].actual_length = iso_packet[i].length;
2014 urb->actual_length += urb->iso_frame_desc[i].actual_length;
2015 } else {
2016 dev_dbg(dev, "ISOCHRONOUS packet=%d of %d status=%d pipe=%p transaction=%p size=%d\n",
2017 i, urb->number_of_packets,
2018 iso_packet[i].status, pipe,
2019 transaction, iso_packet[i].length);
2020 urb->iso_frame_desc[i].status = -EREMOTEIO;
2021 }
2022 }
2023
2024 kfree(iso_packet);
2025 urb->setup_packet = NULL;
2026 }
2027
2028 switch (status) {
2029 case CVMX_USB_COMPLETE_SUCCESS:
2030 urb->status = 0;
2031 break;
2032 case CVMX_USB_COMPLETE_CANCEL:
2033 if (urb->status == 0)
2034 urb->status = -ENOENT;
2035 break;
2036 case CVMX_USB_COMPLETE_STALL:
2037 dev_dbg(dev, "status=stall pipe=%p transaction=%p size=%d\n",
2038 pipe, transaction, bytes_transferred);
2039 urb->status = -EPIPE;
2040 break;
2041 case CVMX_USB_COMPLETE_BABBLEERR:
2042 dev_dbg(dev, "status=babble pipe=%p transaction=%p size=%d\n",
2043 pipe, transaction, bytes_transferred);
2044 urb->status = -EPIPE;
2045 break;
2046 case CVMX_USB_COMPLETE_SHORT:
2047 dev_dbg(dev, "status=short pipe=%p transaction=%p size=%d\n",
2048 pipe, transaction, bytes_transferred);
2049 urb->status = -EREMOTEIO;
2050 break;
2051 case CVMX_USB_COMPLETE_ERROR:
2052 case CVMX_USB_COMPLETE_XACTERR:
2053 case CVMX_USB_COMPLETE_DATATGLERR:
2054 case CVMX_USB_COMPLETE_FRAMEERR:
2055 dev_dbg(dev, "status=%d pipe=%p transaction=%p size=%d\n",
2056 status, pipe, transaction, bytes_transferred);
2057 urb->status = -EPROTO;
2058 break;
2059 }
2060 spin_unlock(&priv->lock);
2061 usb_hcd_giveback_urb(octeon_to_hcd(priv), urb, urb->status);
2062 spin_lock(&priv->lock);
2063}
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076static void __cvmx_usb_perform_complete(struct cvmx_usb_state *usb,
2077 struct cvmx_usb_pipe *pipe,
2078 struct cvmx_usb_transaction *transaction,
2079 enum cvmx_usb_complete complete_code)
2080{
2081
2082 if (usb->active_split == transaction)
2083 usb->active_split = NULL;
2084
2085
2086
2087
2088
2089 if (unlikely(transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS)) {
2090
2091 transaction->iso_packets[0].length = transaction->actual_bytes;
2092 transaction->iso_packets[0].status = complete_code;
2093
2094
2095
2096
2097
2098 if ((transaction->iso_number_packets > 1) && (complete_code == CVMX_USB_COMPLETE_SUCCESS)) {
2099
2100 transaction->actual_bytes = 0;
2101
2102 transaction->iso_number_packets--;
2103
2104 transaction->iso_packets++;
2105 transaction->stage = CVMX_USB_STAGE_NON_CONTROL;
2106 goto done;
2107 }
2108 }
2109
2110
2111 list_del(&transaction->node);
2112 if (list_empty(&pipe->transactions))
2113 list_move_tail(&pipe->node, &usb->idle_pipes);
2114 octeon_usb_urb_complete_callback(usb, complete_code, pipe,
2115 transaction,
2116 transaction->actual_bytes,
2117 transaction->urb);
2118 kfree(transaction);
2119done:
2120 return;
2121}
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146static struct cvmx_usb_transaction *__cvmx_usb_submit_transaction(struct cvmx_usb_state *usb,
2147 struct cvmx_usb_pipe *pipe,
2148 enum cvmx_usb_transfer type,
2149 uint64_t buffer,
2150 int buffer_length,
2151 uint64_t control_header,
2152 int iso_start_frame,
2153 int iso_number_packets,
2154 struct cvmx_usb_iso_packet *iso_packets,
2155 struct urb *urb)
2156{
2157 struct cvmx_usb_transaction *transaction;
2158
2159 if (unlikely(pipe->transfer_type != type))
2160 return NULL;
2161
2162 transaction = kzalloc(sizeof(*transaction), GFP_ATOMIC);
2163 if (unlikely(!transaction))
2164 return NULL;
2165
2166 transaction->type = type;
2167 transaction->buffer = buffer;
2168 transaction->buffer_length = buffer_length;
2169 transaction->control_header = control_header;
2170
2171 transaction->iso_start_frame = iso_start_frame;
2172 transaction->iso_number_packets = iso_number_packets;
2173 transaction->iso_packets = iso_packets;
2174 transaction->urb = urb;
2175 if (transaction->type == CVMX_USB_TRANSFER_CONTROL)
2176 transaction->stage = CVMX_USB_STAGE_SETUP;
2177 else
2178 transaction->stage = CVMX_USB_STAGE_NON_CONTROL;
2179
2180 if (!list_empty(&pipe->transactions)) {
2181 list_add_tail(&transaction->node, &pipe->transactions);
2182 } else {
2183 list_add_tail(&transaction->node, &pipe->transactions);
2184 list_move_tail(&pipe->node,
2185 &usb->active_pipes[pipe->transfer_type]);
2186
2187
2188
2189
2190
2191 __cvmx_usb_schedule(usb, 0);
2192 }
2193
2194 return transaction;
2195}
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207static struct cvmx_usb_transaction *cvmx_usb_submit_bulk(struct cvmx_usb_state *usb,
2208 struct cvmx_usb_pipe *pipe,
2209 struct urb *urb)
2210{
2211 return __cvmx_usb_submit_transaction(usb, pipe, CVMX_USB_TRANSFER_BULK,
2212 urb->transfer_dma,
2213 urb->transfer_buffer_length,
2214 0,
2215 0,
2216 0,
2217 NULL,
2218 urb);
2219}
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231static struct cvmx_usb_transaction *cvmx_usb_submit_interrupt(struct cvmx_usb_state *usb,
2232 struct cvmx_usb_pipe *pipe,
2233 struct urb *urb)
2234{
2235 return __cvmx_usb_submit_transaction(usb, pipe,
2236 CVMX_USB_TRANSFER_INTERRUPT,
2237 urb->transfer_dma,
2238 urb->transfer_buffer_length,
2239 0,
2240 0,
2241 0,
2242 NULL,
2243 urb);
2244}
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256static struct cvmx_usb_transaction *cvmx_usb_submit_control(struct cvmx_usb_state *usb,
2257 struct cvmx_usb_pipe *pipe,
2258 struct urb *urb)
2259{
2260 int buffer_length = urb->transfer_buffer_length;
2261 uint64_t control_header = urb->setup_dma;
2262 union cvmx_usb_control_header *header =
2263 cvmx_phys_to_ptr(control_header);
2264
2265 if ((header->s.request_type & 0x80) == 0)
2266 buffer_length = le16_to_cpu(header->s.length);
2267
2268 return __cvmx_usb_submit_transaction(usb, pipe,
2269 CVMX_USB_TRANSFER_CONTROL,
2270 urb->transfer_dma, buffer_length,
2271 control_header,
2272 0,
2273 0,
2274 NULL,
2275 urb);
2276}
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288static struct cvmx_usb_transaction *cvmx_usb_submit_isochronous(struct cvmx_usb_state *usb,
2289 struct cvmx_usb_pipe *pipe,
2290 struct urb *urb)
2291{
2292 struct cvmx_usb_iso_packet *packets;
2293
2294 packets = (struct cvmx_usb_iso_packet *) urb->setup_packet;
2295 return __cvmx_usb_submit_transaction(usb, pipe,
2296 CVMX_USB_TRANSFER_ISOCHRONOUS,
2297 urb->transfer_dma,
2298 urb->transfer_buffer_length,
2299 0,
2300 urb->start_frame,
2301 urb->number_of_packets,
2302 packets, urb);
2303}
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319static int cvmx_usb_cancel(struct cvmx_usb_state *usb,
2320 struct cvmx_usb_pipe *pipe,
2321 struct cvmx_usb_transaction *transaction)
2322{
2323
2324
2325
2326
2327 if (list_first_entry(&pipe->transactions, typeof(*transaction), node) ==
2328 transaction && (pipe->flags & __CVMX_USB_PIPE_FLAGS_SCHEDULED)) {
2329 union cvmx_usbcx_hccharx usbc_hcchar;
2330
2331 usb->pipe_for_channel[pipe->channel] = NULL;
2332 pipe->flags &= ~__CVMX_USB_PIPE_FLAGS_SCHEDULED;
2333
2334 CVMX_SYNCW;
2335
2336 usbc_hcchar.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCCHARX(pipe->channel, usb->index));
2337
2338
2339
2340
2341 if (usbc_hcchar.s.chena) {
2342 usbc_hcchar.s.chdis = 1;
2343 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCCHARX(pipe->channel, usb->index), usbc_hcchar.u32);
2344 }
2345 }
2346 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_CANCEL);
2347 return 0;
2348}
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360static int cvmx_usb_cancel_all(struct cvmx_usb_state *usb,
2361 struct cvmx_usb_pipe *pipe)
2362{
2363 struct cvmx_usb_transaction *transaction, *next;
2364
2365
2366 list_for_each_entry_safe(transaction, next, &pipe->transactions, node) {
2367 int result = cvmx_usb_cancel(usb, pipe, transaction);
2368 if (unlikely(result != 0))
2369 return result;
2370 }
2371 return 0;
2372}
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384static int cvmx_usb_close_pipe(struct cvmx_usb_state *usb,
2385 struct cvmx_usb_pipe *pipe)
2386{
2387
2388 if (!list_empty(&pipe->transactions))
2389 return -EBUSY;
2390
2391 list_del(&pipe->node);
2392 kfree(pipe);
2393
2394 return 0;
2395}
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405static int cvmx_usb_get_frame_number(struct cvmx_usb_state *usb)
2406{
2407 int frame_number;
2408 union cvmx_usbcx_hfnum usbc_hfnum;
2409
2410 usbc_hfnum.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index));
2411 frame_number = usbc_hfnum.s.frnum;
2412
2413 return frame_number;
2414}
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
2426{
2427 union cvmx_usbcx_hcintx usbc_hcint;
2428 union cvmx_usbcx_hctsizx usbc_hctsiz;
2429 union cvmx_usbcx_hccharx usbc_hcchar;
2430 struct cvmx_usb_pipe *pipe;
2431 struct cvmx_usb_transaction *transaction;
2432 int bytes_this_transfer;
2433 int bytes_in_last_packet;
2434 int packets_processed;
2435 int buffer_space_left;
2436
2437
2438 usbc_hcint.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCINTX(channel, usb->index));
2439
2440 if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA) {
2441 usbc_hcchar.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index));
2442
2443 if (usbc_hcchar.s.chena && usbc_hcchar.s.chdis) {
2444
2445
2446
2447
2448
2449 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index), usbc_hcchar.u32);
2450 return 0;
2451 }
2452
2453
2454
2455
2456
2457 if (!usbc_hcint.s.chhltd) {
2458 if (usbc_hcchar.s.chena) {
2459 union cvmx_usbcx_hcintmskx hcintmsk;
2460
2461 hcintmsk.u32 = 0;
2462 hcintmsk.s.chhltdmsk = 1;
2463 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), hcintmsk.u32);
2464 usbc_hcchar.s.chdis = 1;
2465 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index), usbc_hcchar.u32);
2466 return 0;
2467 } else if (usbc_hcint.s.xfercompl) {
2468
2469
2470
2471
2472 } else {
2473 cvmx_dprintf("USB%d: Channel %d interrupt without halt\n", usb->index, channel);
2474 return 0;
2475 }
2476 }
2477 } else {
2478
2479
2480
2481
2482 if (!usbc_hcint.s.chhltd)
2483 return 0;
2484 }
2485
2486
2487 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), 0);
2488 usb->idle_hardware_channels |= (1<<channel);
2489
2490
2491 pipe = usb->pipe_for_channel[channel];
2492 CVMX_PREFETCH(pipe, 0);
2493 CVMX_PREFETCH(pipe, 128);
2494 if (!pipe)
2495 return 0;
2496 transaction = list_first_entry(&pipe->transactions, typeof(*transaction),
2497 node);
2498 CVMX_PREFETCH(transaction, 0);
2499
2500
2501
2502
2503
2504 usb->pipe_for_channel[channel] = NULL;
2505 pipe->flags &= ~__CVMX_USB_PIPE_FLAGS_SCHEDULED;
2506
2507
2508
2509
2510
2511 usbc_hcchar.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCCHARX(channel, usb->index));
2512 usbc_hctsiz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HCTSIZX(channel, usb->index));
2513
2514
2515
2516
2517
2518 packets_processed = transaction->pktcnt - usbc_hctsiz.s.pktcnt;
2519 if (usbc_hcchar.s.epdir) {
2520
2521
2522
2523
2524
2525
2526 bytes_this_transfer = transaction->xfersize - usbc_hctsiz.s.xfersize;
2527 } else {
2528
2529
2530
2531
2532
2533
2534 bytes_this_transfer = packets_processed * usbc_hcchar.s.mps;
2535
2536
2537
2538
2539 if (bytes_this_transfer > transaction->xfersize)
2540 bytes_this_transfer = transaction->xfersize;
2541 }
2542
2543 if (packets_processed)
2544 bytes_in_last_packet = bytes_this_transfer - (packets_processed-1) * usbc_hcchar.s.mps;
2545 else
2546 bytes_in_last_packet = bytes_this_transfer;
2547
2548
2549
2550
2551
2552
2553 if ((transaction->stage == CVMX_USB_STAGE_SETUP) ||
2554 (transaction->stage == CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE))
2555 bytes_this_transfer = 0;
2556
2557
2558
2559
2560
2561
2562 transaction->actual_bytes += bytes_this_transfer;
2563 if (transaction->type == CVMX_USB_TRANSFER_ISOCHRONOUS)
2564 buffer_space_left = transaction->iso_packets[0].length - transaction->actual_bytes;
2565 else
2566 buffer_space_left = transaction->buffer_length - transaction->actual_bytes;
2567
2568
2569
2570
2571
2572 pipe->pid_toggle = !(usbc_hctsiz.s.pid == 0);
2573
2574
2575
2576
2577
2578
2579 if ((pipe->device_speed == CVMX_USB_SPEED_HIGH) &&
2580 (pipe->transfer_type == CVMX_USB_TRANSFER_BULK) &&
2581 (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT))
2582 pipe->flags |= __CVMX_USB_PIPE_FLAGS_NEED_PING;
2583
2584 if (usbc_hcint.s.stall) {
2585
2586
2587
2588
2589
2590
2591 pipe->pid_toggle = 0;
2592 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_STALL);
2593 } else if (usbc_hcint.s.xacterr) {
2594
2595
2596
2597
2598 if (usbc_hcint.s.nak || usbc_hcint.s.ack)
2599 transaction->retries = 0;
2600 transaction->retries++;
2601 if (transaction->retries > MAX_RETRIES) {
2602
2603
2604
2605
2606
2607 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_XACTERR);
2608 } else {
2609
2610
2611
2612
2613 if (usb->active_split == transaction)
2614 usb->active_split = NULL;
2615
2616
2617
2618
2619 transaction->stage &= ~1;
2620 pipe->split_sc_frame = -1;
2621 pipe->next_tx_frame += pipe->interval;
2622 if (pipe->next_tx_frame < usb->frame_number)
2623 pipe->next_tx_frame = usb->frame_number + pipe->interval -
2624 (usb->frame_number - pipe->next_tx_frame) % pipe->interval;
2625 }
2626 } else if (usbc_hcint.s.bblerr) {
2627
2628 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_BABBLEERR);
2629 } else if (usbc_hcint.s.datatglerr) {
2630
2631 transaction->retries++;
2632 } else if (usbc_hcint.s.nyet) {
2633
2634
2635
2636
2637
2638
2639 if (!__cvmx_usb_pipe_needs_split(usb, pipe)) {
2640 transaction->retries = 0;
2641
2642
2643
2644
2645 if ((buffer_space_left == 0) || (bytes_in_last_packet < pipe->max_packet))
2646 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
2647 } else {
2648
2649
2650
2651
2652
2653 transaction->retries++;
2654 if ((transaction->retries & 0x3) == 0) {
2655
2656
2657
2658
2659 transaction->stage &= ~1;
2660 pipe->split_sc_frame = -1;
2661 }
2662 }
2663 } else if (usbc_hcint.s.ack) {
2664 transaction->retries = 0;
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676 pipe->flags &= ~__CVMX_USB_PIPE_FLAGS_NEED_PING;
2677
2678 switch (transaction->type) {
2679 case CVMX_USB_TRANSFER_CONTROL:
2680 switch (transaction->stage) {
2681 case CVMX_USB_STAGE_NON_CONTROL:
2682 case CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE:
2683
2684 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_ERROR);
2685 break;
2686 case CVMX_USB_STAGE_SETUP:
2687 pipe->pid_toggle = 1;
2688 if (__cvmx_usb_pipe_needs_split(usb, pipe))
2689 transaction->stage = CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE;
2690 else {
2691 union cvmx_usb_control_header *header =
2692 cvmx_phys_to_ptr(transaction->control_header);
2693 if (header->s.length)
2694 transaction->stage = CVMX_USB_STAGE_DATA;
2695 else
2696 transaction->stage = CVMX_USB_STAGE_STATUS;
2697 }
2698 break;
2699 case CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE:
2700 {
2701 union cvmx_usb_control_header *header =
2702 cvmx_phys_to_ptr(transaction->control_header);
2703 if (header->s.length)
2704 transaction->stage = CVMX_USB_STAGE_DATA;
2705 else
2706 transaction->stage = CVMX_USB_STAGE_STATUS;
2707 }
2708 break;
2709 case CVMX_USB_STAGE_DATA:
2710 if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
2711 transaction->stage = CVMX_USB_STAGE_DATA_SPLIT_COMPLETE;
2712
2713
2714
2715
2716
2717
2718 if (!usbc_hcchar.s.epdir) {
2719 if (buffer_space_left < pipe->max_packet)
2720 transaction->actual_bytes += buffer_space_left;
2721 else
2722 transaction->actual_bytes += pipe->max_packet;
2723 }
2724 } else if ((buffer_space_left == 0) || (bytes_in_last_packet < pipe->max_packet)) {
2725 pipe->pid_toggle = 1;
2726 transaction->stage = CVMX_USB_STAGE_STATUS;
2727 }
2728 break;
2729 case CVMX_USB_STAGE_DATA_SPLIT_COMPLETE:
2730 if ((buffer_space_left == 0) || (bytes_in_last_packet < pipe->max_packet)) {
2731 pipe->pid_toggle = 1;
2732 transaction->stage = CVMX_USB_STAGE_STATUS;
2733 } else {
2734 transaction->stage = CVMX_USB_STAGE_DATA;
2735 }
2736 break;
2737 case CVMX_USB_STAGE_STATUS:
2738 if (__cvmx_usb_pipe_needs_split(usb, pipe))
2739 transaction->stage = CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE;
2740 else
2741 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
2742 break;
2743 case CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE:
2744 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
2745 break;
2746 }
2747 break;
2748 case CVMX_USB_TRANSFER_BULK:
2749 case CVMX_USB_TRANSFER_INTERRUPT:
2750
2751
2752
2753
2754
2755
2756 if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
2757 if (transaction->stage == CVMX_USB_STAGE_NON_CONTROL)
2758 transaction->stage = CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE;
2759 else {
2760 if (buffer_space_left && (bytes_in_last_packet == pipe->max_packet))
2761 transaction->stage = CVMX_USB_STAGE_NON_CONTROL;
2762 else {
2763 if (transaction->type == CVMX_USB_TRANSFER_INTERRUPT)
2764 pipe->next_tx_frame += pipe->interval;
2765 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
2766 }
2767 }
2768 } else {
2769 if ((pipe->device_speed == CVMX_USB_SPEED_HIGH) &&
2770 (pipe->transfer_type == CVMX_USB_TRANSFER_BULK) &&
2771 (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT) &&
2772 (usbc_hcint.s.nak))
2773 pipe->flags |= __CVMX_USB_PIPE_FLAGS_NEED_PING;
2774 if (!buffer_space_left || (bytes_in_last_packet < pipe->max_packet)) {
2775 if (transaction->type == CVMX_USB_TRANSFER_INTERRUPT)
2776 pipe->next_tx_frame += pipe->interval;
2777 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
2778 }
2779 }
2780 break;
2781 case CVMX_USB_TRANSFER_ISOCHRONOUS:
2782 if (__cvmx_usb_pipe_needs_split(usb, pipe)) {
2783
2784
2785
2786
2787
2788
2789
2790
2791 if (pipe->transfer_dir == CVMX_USB_DIRECTION_OUT) {
2792
2793
2794
2795
2796
2797
2798 if (!buffer_space_left || (bytes_this_transfer < 188)) {
2799 pipe->next_tx_frame += pipe->interval;
2800 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
2801 }
2802 } else {
2803 if (transaction->stage == CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE) {
2804
2805
2806
2807
2808
2809
2810 if ((buffer_space_left == 0) || (bytes_in_last_packet < pipe->max_packet)) {
2811 pipe->next_tx_frame += pipe->interval;
2812 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
2813 }
2814 } else
2815 transaction->stage = CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE;
2816 }
2817 } else {
2818 pipe->next_tx_frame += pipe->interval;
2819 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
2820 }
2821 break;
2822 }
2823 } else if (usbc_hcint.s.nak) {
2824
2825
2826
2827 if (usb->active_split == transaction)
2828 usb->active_split = NULL;
2829
2830
2831
2832
2833
2834
2835 transaction->retries = 0;
2836 transaction->stage &= ~1;
2837 pipe->next_tx_frame += pipe->interval;
2838 if (pipe->next_tx_frame < usb->frame_number)
2839 pipe->next_tx_frame = usb->frame_number + pipe->interval -
2840 (usb->frame_number - pipe->next_tx_frame) % pipe->interval;
2841 } else {
2842 struct cvmx_usb_port_status port;
2843 port = cvmx_usb_get_status(usb);
2844 if (port.port_enabled) {
2845
2846 transaction->retries++;
2847 } else {
2848
2849
2850
2851
2852 __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_ERROR);
2853 }
2854 }
2855 return 0;
2856}
2857
2858static void octeon_usb_port_callback(struct cvmx_usb_state *usb)
2859{
2860 struct octeon_hcd *priv = cvmx_usb_to_octeon(usb);
2861
2862 spin_unlock(&priv->lock);
2863 usb_hcd_poll_rh_status(octeon_to_hcd(priv));
2864 spin_lock(&priv->lock);
2865}
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877static int cvmx_usb_poll(struct cvmx_usb_state *usb)
2878{
2879 union cvmx_usbcx_hfnum usbc_hfnum;
2880 union cvmx_usbcx_gintsts usbc_gintsts;
2881
2882 CVMX_PREFETCH(usb, 0);
2883 CVMX_PREFETCH(usb, 1*128);
2884 CVMX_PREFETCH(usb, 2*128);
2885 CVMX_PREFETCH(usb, 3*128);
2886 CVMX_PREFETCH(usb, 4*128);
2887
2888
2889 usbc_hfnum.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index));
2890 if ((usb->frame_number&0x3fff) > usbc_hfnum.s.frnum)
2891 usb->frame_number += 0x4000;
2892 usb->frame_number &= ~0x3fffull;
2893 usb->frame_number |= usbc_hfnum.s.frnum;
2894
2895
2896 usbc_gintsts.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GINTSTS(usb->index));
2897
2898
2899 __cvmx_usb_write_csr32(usb, CVMX_USBCX_GINTSTS(usb->index), usbc_gintsts.u32);
2900
2901 if (usbc_gintsts.s.rxflvl) {
2902
2903
2904
2905
2906
2907
2908
2909 if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
2910 __cvmx_usb_poll_rx_fifo(usb);
2911 }
2912 if (usbc_gintsts.s.ptxfemp || usbc_gintsts.s.nptxfemp) {
2913
2914 if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
2915 __cvmx_usb_poll_tx_fifo(usb);
2916 }
2917 if (usbc_gintsts.s.disconnint || usbc_gintsts.s.prtint) {
2918 union cvmx_usbcx_hprt usbc_hprt;
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933 octeon_usb_port_callback(usb);
2934
2935 usbc_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index));
2936 usbc_hprt.s.prtena = 0;
2937 __cvmx_usb_write_csr32(usb, CVMX_USBCX_HPRT(usb->index), usbc_hprt.u32);
2938 }
2939 if (usbc_gintsts.s.hchint) {
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952 union cvmx_usbcx_haint usbc_haint;
2953 usbc_haint.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HAINT(usb->index));
2954 while (usbc_haint.u32) {
2955 int channel;
2956
2957 channel = __fls(usbc_haint.u32);
2958 __cvmx_usb_poll_channel(usb, channel);
2959 usbc_haint.u32 ^= 1<<channel;
2960 }
2961 }
2962
2963 __cvmx_usb_schedule(usb, usbc_gintsts.s.sof);
2964
2965 return 0;
2966}
2967
2968
2969static inline struct octeon_hcd *hcd_to_octeon(struct usb_hcd *hcd)
2970{
2971 return (struct octeon_hcd *)(hcd->hcd_priv);
2972}
2973
2974static irqreturn_t octeon_usb_irq(struct usb_hcd *hcd)
2975{
2976 struct octeon_hcd *priv = hcd_to_octeon(hcd);
2977 unsigned long flags;
2978
2979 spin_lock_irqsave(&priv->lock, flags);
2980 cvmx_usb_poll(&priv->usb);
2981 spin_unlock_irqrestore(&priv->lock, flags);
2982 return IRQ_HANDLED;
2983}
2984
2985static int octeon_usb_start(struct usb_hcd *hcd)
2986{
2987 hcd->state = HC_STATE_RUNNING;
2988 return 0;
2989}
2990
2991static void octeon_usb_stop(struct usb_hcd *hcd)
2992{
2993 hcd->state = HC_STATE_HALT;
2994}
2995
2996static int octeon_usb_get_frame_number(struct usb_hcd *hcd)
2997{
2998 struct octeon_hcd *priv = hcd_to_octeon(hcd);
2999
3000 return cvmx_usb_get_frame_number(&priv->usb);
3001}
3002
3003static int octeon_usb_urb_enqueue(struct usb_hcd *hcd,
3004 struct urb *urb,
3005 gfp_t mem_flags)
3006{
3007 struct octeon_hcd *priv = hcd_to_octeon(hcd);
3008 struct device *dev = hcd->self.controller;
3009 struct cvmx_usb_transaction *transaction = NULL;
3010 struct cvmx_usb_pipe *pipe;
3011 unsigned long flags;
3012 struct cvmx_usb_iso_packet *iso_packet;
3013 struct usb_host_endpoint *ep = urb->ep;
3014
3015 urb->status = 0;
3016 INIT_LIST_HEAD(&urb->urb_list);
3017 spin_lock_irqsave(&priv->lock, flags);
3018
3019 if (!ep->hcpriv) {
3020 enum cvmx_usb_transfer transfer_type;
3021 enum cvmx_usb_speed speed;
3022 int split_device = 0;
3023 int split_port = 0;
3024 switch (usb_pipetype(urb->pipe)) {
3025 case PIPE_ISOCHRONOUS:
3026 transfer_type = CVMX_USB_TRANSFER_ISOCHRONOUS;
3027 break;
3028 case PIPE_INTERRUPT:
3029 transfer_type = CVMX_USB_TRANSFER_INTERRUPT;
3030 break;
3031 case PIPE_CONTROL:
3032 transfer_type = CVMX_USB_TRANSFER_CONTROL;
3033 break;
3034 default:
3035 transfer_type = CVMX_USB_TRANSFER_BULK;
3036 break;
3037 }
3038 switch (urb->dev->speed) {
3039 case USB_SPEED_LOW:
3040 speed = CVMX_USB_SPEED_LOW;
3041 break;
3042 case USB_SPEED_FULL:
3043 speed = CVMX_USB_SPEED_FULL;
3044 break;
3045 default:
3046 speed = CVMX_USB_SPEED_HIGH;
3047 break;
3048 }
3049
3050
3051
3052
3053
3054 if (speed != CVMX_USB_SPEED_HIGH) {
3055
3056
3057
3058
3059 struct usb_device *dev = urb->dev;
3060 while (dev->parent) {
3061
3062
3063
3064
3065 if (dev->parent->speed == USB_SPEED_HIGH) {
3066 split_device = dev->parent->devnum;
3067 split_port = dev->portnum;
3068 break;
3069 }
3070
3071
3072
3073
3074
3075
3076 dev = dev->parent;
3077 }
3078 }
3079 pipe = cvmx_usb_open_pipe(&priv->usb, usb_pipedevice(urb->pipe),
3080 usb_pipeendpoint(urb->pipe), speed,
3081 le16_to_cpu(ep->desc.wMaxPacketSize) & 0x7ff,
3082 transfer_type,
3083 usb_pipein(urb->pipe) ?
3084 CVMX_USB_DIRECTION_IN :
3085 CVMX_USB_DIRECTION_OUT,
3086 urb->interval,
3087 (le16_to_cpu(ep->desc.wMaxPacketSize) >> 11) & 0x3,
3088 split_device, split_port);
3089 if (!pipe) {
3090 spin_unlock_irqrestore(&priv->lock, flags);
3091 dev_dbg(dev, "Failed to create pipe\n");
3092 return -ENOMEM;
3093 }
3094 ep->hcpriv = pipe;
3095 } else {
3096 pipe = ep->hcpriv;
3097 }
3098
3099 switch (usb_pipetype(urb->pipe)) {
3100 case PIPE_ISOCHRONOUS:
3101 dev_dbg(dev, "Submit isochronous to %d.%d\n",
3102 usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe));
3103
3104
3105
3106
3107 iso_packet = kmalloc(urb->number_of_packets *
3108 sizeof(struct cvmx_usb_iso_packet),
3109 GFP_ATOMIC);
3110 if (iso_packet) {
3111 int i;
3112
3113 for (i = 0; i < urb->number_of_packets; i++) {
3114 iso_packet[i].offset = urb->iso_frame_desc[i].offset;
3115 iso_packet[i].length = urb->iso_frame_desc[i].length;
3116 iso_packet[i].status = CVMX_USB_COMPLETE_ERROR;
3117 }
3118
3119
3120
3121
3122
3123 urb->setup_packet = (char *)iso_packet;
3124 transaction = cvmx_usb_submit_isochronous(&priv->usb,
3125 pipe, urb);
3126
3127
3128
3129
3130 if (!transaction) {
3131 urb->setup_packet = NULL;
3132 kfree(iso_packet);
3133 }
3134 }
3135 break;
3136 case PIPE_INTERRUPT:
3137 dev_dbg(dev, "Submit interrupt to %d.%d\n",
3138 usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe));
3139 transaction = cvmx_usb_submit_interrupt(&priv->usb, pipe, urb);
3140 break;
3141 case PIPE_CONTROL:
3142 dev_dbg(dev, "Submit control to %d.%d\n",
3143 usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe));
3144 transaction = cvmx_usb_submit_control(&priv->usb, pipe, urb);
3145 break;
3146 case PIPE_BULK:
3147 dev_dbg(dev, "Submit bulk to %d.%d\n",
3148 usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe));
3149 transaction = cvmx_usb_submit_bulk(&priv->usb, pipe, urb);
3150 break;
3151 }
3152 if (!transaction) {
3153 spin_unlock_irqrestore(&priv->lock, flags);
3154 dev_dbg(dev, "Failed to submit\n");
3155 return -ENOMEM;
3156 }
3157 urb->hcpriv = transaction;
3158 spin_unlock_irqrestore(&priv->lock, flags);
3159 return 0;
3160}
3161
3162static void octeon_usb_urb_dequeue_work(unsigned long arg)
3163{
3164 struct urb *urb;
3165 struct urb *next;
3166 unsigned long flags;
3167 struct octeon_hcd *priv = (struct octeon_hcd *)arg;
3168
3169 spin_lock_irqsave(&priv->lock, flags);
3170
3171 list_for_each_entry_safe(urb, next, &priv->dequeue_list, urb_list) {
3172 list_del_init(&urb->urb_list);
3173 cvmx_usb_cancel(&priv->usb, urb->ep->hcpriv, urb->hcpriv);
3174 }
3175
3176 spin_unlock_irqrestore(&priv->lock, flags);
3177}
3178
3179static int octeon_usb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
3180{
3181 struct octeon_hcd *priv = hcd_to_octeon(hcd);
3182 unsigned long flags;
3183
3184 if (!urb->dev)
3185 return -EINVAL;
3186
3187 spin_lock_irqsave(&priv->lock, flags);
3188
3189 urb->status = status;
3190 list_add_tail(&urb->urb_list, &priv->dequeue_list);
3191
3192 spin_unlock_irqrestore(&priv->lock, flags);
3193
3194 tasklet_schedule(&priv->dequeue_tasklet);
3195
3196 return 0;
3197}
3198
3199static void octeon_usb_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
3200{
3201 struct device *dev = hcd->self.controller;
3202
3203 if (ep->hcpriv) {
3204 struct octeon_hcd *priv = hcd_to_octeon(hcd);
3205 struct cvmx_usb_pipe *pipe = ep->hcpriv;
3206 unsigned long flags;
3207 spin_lock_irqsave(&priv->lock, flags);
3208 cvmx_usb_cancel_all(&priv->usb, pipe);
3209 if (cvmx_usb_close_pipe(&priv->usb, pipe))
3210 dev_dbg(dev, "Closing pipe %p failed\n", pipe);
3211 spin_unlock_irqrestore(&priv->lock, flags);
3212 ep->hcpriv = NULL;
3213 }
3214}
3215
3216static int octeon_usb_hub_status_data(struct usb_hcd *hcd, char *buf)
3217{
3218 struct octeon_hcd *priv = hcd_to_octeon(hcd);
3219 struct cvmx_usb_port_status port_status;
3220 unsigned long flags;
3221
3222 spin_lock_irqsave(&priv->lock, flags);
3223 port_status = cvmx_usb_get_status(&priv->usb);
3224 spin_unlock_irqrestore(&priv->lock, flags);
3225 buf[0] = 0;
3226 buf[0] = port_status.connect_change << 1;
3227
3228 return (buf[0] != 0);
3229}
3230
3231static int octeon_usb_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength)
3232{
3233 struct octeon_hcd *priv = hcd_to_octeon(hcd);
3234 struct device *dev = hcd->self.controller;
3235 struct cvmx_usb_port_status usb_port_status;
3236 int port_status;
3237 struct usb_hub_descriptor *desc;
3238 unsigned long flags;
3239
3240 switch (typeReq) {
3241 case ClearHubFeature:
3242 dev_dbg(dev, "ClearHubFeature\n");
3243 switch (wValue) {
3244 case C_HUB_LOCAL_POWER:
3245 case C_HUB_OVER_CURRENT:
3246
3247 break;
3248 default:
3249 return -EINVAL;
3250 }
3251 break;
3252 case ClearPortFeature:
3253 dev_dbg(dev, "ClearPortFeature\n");
3254 if (wIndex != 1) {
3255 dev_dbg(dev, " INVALID\n");
3256 return -EINVAL;
3257 }
3258
3259 switch (wValue) {
3260 case USB_PORT_FEAT_ENABLE:
3261 dev_dbg(dev, " ENABLE\n");
3262 spin_lock_irqsave(&priv->lock, flags);
3263 cvmx_usb_disable(&priv->usb);
3264 spin_unlock_irqrestore(&priv->lock, flags);
3265 break;
3266 case USB_PORT_FEAT_SUSPEND:
3267 dev_dbg(dev, " SUSPEND\n");
3268
3269 break;
3270 case USB_PORT_FEAT_POWER:
3271 dev_dbg(dev, " POWER\n");
3272
3273 break;
3274 case USB_PORT_FEAT_INDICATOR:
3275 dev_dbg(dev, " INDICATOR\n");
3276
3277 break;
3278 case USB_PORT_FEAT_C_CONNECTION:
3279 dev_dbg(dev, " C_CONNECTION\n");
3280
3281 spin_lock_irqsave(&priv->lock, flags);
3282 priv->usb.port_status = cvmx_usb_get_status(&priv->usb);
3283 spin_unlock_irqrestore(&priv->lock, flags);
3284 break;
3285 case USB_PORT_FEAT_C_RESET:
3286 dev_dbg(dev, " C_RESET\n");
3287
3288
3289
3290 spin_lock_irqsave(&priv->lock, flags);
3291 priv->usb.port_status = cvmx_usb_get_status(&priv->usb);
3292 spin_unlock_irqrestore(&priv->lock, flags);
3293 break;
3294 case USB_PORT_FEAT_C_ENABLE:
3295 dev_dbg(dev, " C_ENABLE\n");
3296
3297
3298
3299
3300 spin_lock_irqsave(&priv->lock, flags);
3301 priv->usb.port_status = cvmx_usb_get_status(&priv->usb);
3302 spin_unlock_irqrestore(&priv->lock, flags);
3303 break;
3304 case USB_PORT_FEAT_C_SUSPEND:
3305 dev_dbg(dev, " C_SUSPEND\n");
3306
3307
3308
3309
3310
3311 break;
3312 case USB_PORT_FEAT_C_OVER_CURRENT:
3313 dev_dbg(dev, " C_OVER_CURRENT\n");
3314
3315 spin_lock_irqsave(&priv->lock, flags);
3316 priv->usb.port_status = cvmx_usb_get_status(&priv->usb);
3317 spin_unlock_irqrestore(&priv->lock, flags);
3318 break;
3319 default:
3320 dev_dbg(dev, " UNKNOWN\n");
3321 return -EINVAL;
3322 }
3323 break;
3324 case GetHubDescriptor:
3325 dev_dbg(dev, "GetHubDescriptor\n");
3326 desc = (struct usb_hub_descriptor *)buf;
3327 desc->bDescLength = 9;
3328 desc->bDescriptorType = 0x29;
3329 desc->bNbrPorts = 1;
3330 desc->wHubCharacteristics = 0x08;
3331 desc->bPwrOn2PwrGood = 1;
3332 desc->bHubContrCurrent = 0;
3333 desc->u.hs.DeviceRemovable[0] = 0;
3334 desc->u.hs.DeviceRemovable[1] = 0xff;
3335 break;
3336 case GetHubStatus:
3337 dev_dbg(dev, "GetHubStatus\n");
3338 *(__le32 *) buf = 0;
3339 break;
3340 case GetPortStatus:
3341 dev_dbg(dev, "GetPortStatus\n");
3342 if (wIndex != 1) {
3343 dev_dbg(dev, " INVALID\n");
3344 return -EINVAL;
3345 }
3346
3347 spin_lock_irqsave(&priv->lock, flags);
3348 usb_port_status = cvmx_usb_get_status(&priv->usb);
3349 spin_unlock_irqrestore(&priv->lock, flags);
3350 port_status = 0;
3351
3352 if (usb_port_status.connect_change) {
3353 port_status |= (1 << USB_PORT_FEAT_C_CONNECTION);
3354 dev_dbg(dev, " C_CONNECTION\n");
3355 }
3356
3357 if (usb_port_status.port_enabled) {
3358 port_status |= (1 << USB_PORT_FEAT_C_ENABLE);
3359 dev_dbg(dev, " C_ENABLE\n");
3360 }
3361
3362 if (usb_port_status.connected) {
3363 port_status |= (1 << USB_PORT_FEAT_CONNECTION);
3364 dev_dbg(dev, " CONNECTION\n");
3365 }
3366
3367 if (usb_port_status.port_enabled) {
3368 port_status |= (1 << USB_PORT_FEAT_ENABLE);
3369 dev_dbg(dev, " ENABLE\n");
3370 }
3371
3372 if (usb_port_status.port_over_current) {
3373 port_status |= (1 << USB_PORT_FEAT_OVER_CURRENT);
3374 dev_dbg(dev, " OVER_CURRENT\n");
3375 }
3376
3377 if (usb_port_status.port_powered) {
3378 port_status |= (1 << USB_PORT_FEAT_POWER);
3379 dev_dbg(dev, " POWER\n");
3380 }
3381
3382 if (usb_port_status.port_speed == CVMX_USB_SPEED_HIGH) {
3383 port_status |= USB_PORT_STAT_HIGH_SPEED;
3384 dev_dbg(dev, " HIGHSPEED\n");
3385 } else if (usb_port_status.port_speed == CVMX_USB_SPEED_LOW) {
3386 port_status |= (1 << USB_PORT_FEAT_LOWSPEED);
3387 dev_dbg(dev, " LOWSPEED\n");
3388 }
3389
3390 *((__le32 *) buf) = cpu_to_le32(port_status);
3391 break;
3392 case SetHubFeature:
3393 dev_dbg(dev, "SetHubFeature\n");
3394
3395 break;
3396 case SetPortFeature:
3397 dev_dbg(dev, "SetPortFeature\n");
3398 if (wIndex != 1) {
3399 dev_dbg(dev, " INVALID\n");
3400 return -EINVAL;
3401 }
3402
3403 switch (wValue) {
3404 case USB_PORT_FEAT_SUSPEND:
3405 dev_dbg(dev, " SUSPEND\n");
3406 return -EINVAL;
3407 case USB_PORT_FEAT_POWER:
3408 dev_dbg(dev, " POWER\n");
3409 return -EINVAL;
3410 case USB_PORT_FEAT_RESET:
3411 dev_dbg(dev, " RESET\n");
3412 spin_lock_irqsave(&priv->lock, flags);
3413 cvmx_usb_disable(&priv->usb);
3414 if (cvmx_usb_enable(&priv->usb))
3415 dev_dbg(dev, "Failed to enable the port\n");
3416 spin_unlock_irqrestore(&priv->lock, flags);
3417 return 0;
3418 case USB_PORT_FEAT_INDICATOR:
3419 dev_dbg(dev, " INDICATOR\n");
3420
3421 break;
3422 default:
3423 dev_dbg(dev, " UNKNOWN\n");
3424 return -EINVAL;
3425 }
3426 break;
3427 default:
3428 dev_dbg(dev, "Unknown root hub request\n");
3429 return -EINVAL;
3430 }
3431 return 0;
3432}
3433
3434
3435static const struct hc_driver octeon_hc_driver = {
3436 .description = "Octeon USB",
3437 .product_desc = "Octeon Host Controller",
3438 .hcd_priv_size = sizeof(struct octeon_hcd),
3439 .irq = octeon_usb_irq,
3440 .flags = HCD_MEMORY | HCD_USB2,
3441 .start = octeon_usb_start,
3442 .stop = octeon_usb_stop,
3443 .urb_enqueue = octeon_usb_urb_enqueue,
3444 .urb_dequeue = octeon_usb_urb_dequeue,
3445 .endpoint_disable = octeon_usb_endpoint_disable,
3446 .get_frame_number = octeon_usb_get_frame_number,
3447 .hub_status_data = octeon_usb_hub_status_data,
3448 .hub_control = octeon_usb_hub_control,
3449};
3450
3451
3452static int octeon_usb_driver_probe(struct device *dev)
3453{
3454 int status;
3455 int usb_num = to_platform_device(dev)->id;
3456 int irq = platform_get_irq(to_platform_device(dev), 0);
3457 struct octeon_hcd *priv;
3458 struct usb_hcd *hcd;
3459 unsigned long flags;
3460
3461
3462
3463
3464
3465 dev->coherent_dma_mask = ~0;
3466 dev->dma_mask = &dev->coherent_dma_mask;
3467
3468 hcd = usb_create_hcd(&octeon_hc_driver, dev, dev_name(dev));
3469 if (!hcd) {
3470 dev_dbg(dev, "Failed to allocate memory for HCD\n");
3471 return -1;
3472 }
3473 hcd->uses_new_polling = 1;
3474 priv = (struct octeon_hcd *)hcd->hcd_priv;
3475
3476 spin_lock_init(&priv->lock);
3477
3478 tasklet_init(&priv->dequeue_tasklet, octeon_usb_urb_dequeue_work, (unsigned long)priv);
3479 INIT_LIST_HEAD(&priv->dequeue_list);
3480
3481 status = cvmx_usb_initialize(&priv->usb, usb_num);
3482 if (status) {
3483 dev_dbg(dev, "USB initialization failed with %d\n", status);
3484 kfree(hcd);
3485 return -1;
3486 }
3487
3488
3489 mdelay(10);
3490
3491 spin_lock_irqsave(&priv->lock, flags);
3492 cvmx_usb_poll(&priv->usb);
3493 spin_unlock_irqrestore(&priv->lock, flags);
3494
3495 status = usb_add_hcd(hcd, irq, IRQF_SHARED);
3496 if (status) {
3497 dev_dbg(dev, "USB add HCD failed with %d\n", status);
3498 kfree(hcd);
3499 return -1;
3500 }
3501
3502 dev_dbg(dev, "Registered HCD for port %d on irq %d\n", usb_num, irq);
3503
3504 return 0;
3505}
3506
3507static int octeon_usb_driver_remove(struct device *dev)
3508{
3509 int status;
3510 struct usb_hcd *hcd = dev_get_drvdata(dev);
3511 struct octeon_hcd *priv = hcd_to_octeon(hcd);
3512 unsigned long flags;
3513
3514 usb_remove_hcd(hcd);
3515 tasklet_kill(&priv->dequeue_tasklet);
3516 spin_lock_irqsave(&priv->lock, flags);
3517 status = cvmx_usb_shutdown(&priv->usb);
3518 spin_unlock_irqrestore(&priv->lock, flags);
3519 if (status)
3520 dev_dbg(dev, "USB shutdown failed with %d\n", status);
3521
3522 kfree(hcd);
3523
3524 return 0;
3525}
3526
3527static struct device_driver octeon_usb_driver = {
3528 .name = "OcteonUSB",
3529 .bus = &platform_bus_type,
3530 .probe = octeon_usb_driver_probe,
3531 .remove = octeon_usb_driver_remove,
3532};
3533
3534
3535#define MAX_USB_PORTS 10
3536static struct platform_device *pdev_glob[MAX_USB_PORTS];
3537static int octeon_usb_registered;
3538static int __init octeon_usb_module_init(void)
3539{
3540 int num_devices = cvmx_usb_get_num_ports();
3541 int device;
3542
3543 if (usb_disabled() || num_devices == 0)
3544 return -ENODEV;
3545
3546 if (driver_register(&octeon_usb_driver))
3547 return -ENOMEM;
3548
3549 octeon_usb_registered = 1;
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562 if (OCTEON_IS_MODEL(OCTEON_CN52XX) || OCTEON_IS_MODEL(OCTEON_CN56XX)) {
3563 union cvmx_iob_n2c_l2c_pri_cnt pri_cnt;
3564
3565 pri_cnt.u64 = 0;
3566 pri_cnt.s.cnt_enb = 1;
3567 pri_cnt.s.cnt_val = 400;
3568 cvmx_write_csr(CVMX_IOB_N2C_L2C_PRI_CNT, pri_cnt.u64);
3569 }
3570
3571 for (device = 0; device < num_devices; device++) {
3572 struct resource irq_resource;
3573 struct platform_device *pdev;
3574 memset(&irq_resource, 0, sizeof(irq_resource));
3575 irq_resource.start = (device == 0) ? OCTEON_IRQ_USB0 : OCTEON_IRQ_USB1;
3576 irq_resource.end = irq_resource.start;
3577 irq_resource.flags = IORESOURCE_IRQ;
3578 pdev = platform_device_register_simple((char *)octeon_usb_driver. name, device, &irq_resource, 1);
3579 if (IS_ERR(pdev)) {
3580 driver_unregister(&octeon_usb_driver);
3581 octeon_usb_registered = 0;
3582 return PTR_ERR(pdev);
3583 }
3584 if (device < MAX_USB_PORTS)
3585 pdev_glob[device] = pdev;
3586
3587 }
3588 return 0;
3589}
3590
3591static void __exit octeon_usb_module_cleanup(void)
3592{
3593 int i;
3594
3595 for (i = 0; i < MAX_USB_PORTS; i++)
3596 if (pdev_glob[i]) {
3597 platform_device_unregister(pdev_glob[i]);
3598 pdev_glob[i] = NULL;
3599 }
3600 if (octeon_usb_registered)
3601 driver_unregister(&octeon_usb_driver);
3602}
3603
3604MODULE_LICENSE("GPL");
3605MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>");
3606MODULE_DESCRIPTION("Cavium Networks Octeon USB Host driver.");
3607module_init(octeon_usb_module_init);
3608module_exit(octeon_usb_module_cleanup);
3609