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#ifndef __DWC2_HCD_H__
37#define __DWC2_HCD_H__
38
39
40
41
42
43
44
45
46
47
48
49struct dwc2_qh;
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115struct dwc2_host_chan {
116 u8 hc_num;
117
118 unsigned dev_addr:7;
119 unsigned ep_num:4;
120 unsigned ep_is_in:1;
121 unsigned speed:4;
122 unsigned ep_type:2;
123 unsigned max_packet:11;
124 unsigned data_pid_start:2;
125#define DWC2_HC_PID_DATA0 (TSIZ_SC_MC_PID_DATA0 >> TSIZ_SC_MC_PID_SHIFT)
126#define DWC2_HC_PID_DATA2 (TSIZ_SC_MC_PID_DATA2 >> TSIZ_SC_MC_PID_SHIFT)
127#define DWC2_HC_PID_DATA1 (TSIZ_SC_MC_PID_DATA1 >> TSIZ_SC_MC_PID_SHIFT)
128#define DWC2_HC_PID_MDATA (TSIZ_SC_MC_PID_MDATA >> TSIZ_SC_MC_PID_SHIFT)
129#define DWC2_HC_PID_SETUP (TSIZ_SC_MC_PID_SETUP >> TSIZ_SC_MC_PID_SHIFT)
130
131 unsigned multi_count:2;
132
133 u8 *xfer_buf;
134 dma_addr_t xfer_dma;
135 dma_addr_t align_buf;
136 u32 xfer_len;
137 u32 xfer_count;
138 u16 start_pkt_count;
139 u8 xfer_started;
140 u8 do_ping;
141 u8 error_state;
142 u8 halt_on_queue;
143 u8 halt_pending;
144 u8 do_split;
145 u8 complete_split;
146 u8 hub_addr;
147 u8 hub_port;
148 u8 xact_pos;
149#define DWC2_HCSPLT_XACTPOS_MID (HCSPLT_XACTPOS_MID >> HCSPLT_XACTPOS_SHIFT)
150#define DWC2_HCSPLT_XACTPOS_END (HCSPLT_XACTPOS_END >> HCSPLT_XACTPOS_SHIFT)
151#define DWC2_HCSPLT_XACTPOS_BEGIN (HCSPLT_XACTPOS_BEGIN >> HCSPLT_XACTPOS_SHIFT)
152#define DWC2_HCSPLT_XACTPOS_ALL (HCSPLT_XACTPOS_ALL >> HCSPLT_XACTPOS_SHIFT)
153
154 u8 requests;
155 u8 schinfo;
156 u16 ntd;
157 enum dwc2_halt_status halt_status;
158 u32 hcint;
159 struct dwc2_qh *qh;
160 struct list_head hc_list_entry;
161 dma_addr_t desc_list_addr;
162};
163
164struct dwc2_hcd_pipe_info {
165 u8 dev_addr;
166 u8 ep_num;
167 u8 pipe_type;
168 u8 pipe_dir;
169 u16 mps;
170};
171
172struct dwc2_hcd_iso_packet_desc {
173 u32 offset;
174 u32 length;
175 u32 actual_length;
176 u32 status;
177};
178
179struct dwc2_qtd;
180
181struct dwc2_hcd_urb {
182 void *priv;
183 struct dwc2_qtd *qtd;
184 void *buf;
185 dma_addr_t dma;
186 void *setup_packet;
187 dma_addr_t setup_dma;
188 u32 length;
189 u32 actual_length;
190 u32 status;
191 u32 error_count;
192 u32 packet_count;
193 u32 flags;
194 u16 interval;
195 struct dwc2_hcd_pipe_info pipe_info;
196 struct dwc2_hcd_iso_packet_desc iso_descs[0];
197};
198
199
200enum dwc2_control_phase {
201 DWC2_CONTROL_SETUP,
202 DWC2_CONTROL_DATA,
203 DWC2_CONTROL_STATUS,
204};
205
206
207enum dwc2_transaction_type {
208 DWC2_TRANSACTION_NONE,
209 DWC2_TRANSACTION_PERIODIC,
210 DWC2_TRANSACTION_NON_PERIODIC,
211 DWC2_TRANSACTION_ALL,
212};
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261struct dwc2_qh {
262 u8 ep_type;
263 u8 ep_is_in;
264 u16 maxp;
265 u8 dev_speed;
266 u8 data_toggle;
267 u8 ping_state;
268 u8 do_split;
269 struct list_head qtd_list;
270 struct dwc2_host_chan *channel;
271 u16 usecs;
272 u16 interval;
273 u16 sched_frame;
274 u16 start_split_frame;
275 u8 *dw_align_buf;
276 dma_addr_t dw_align_buf_dma;
277 struct list_head qh_list_entry;
278 struct dwc2_hcd_dma_desc *desc_list;
279 dma_addr_t desc_list_dma;
280 u32 *n_bytes;
281 u16 ntd;
282 u8 td_first;
283 u8 td_last;
284 unsigned tt_buffer_dirty:1;
285};
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331struct dwc2_qtd {
332 enum dwc2_control_phase control_phase;
333 u8 in_process;
334 u8 data_toggle;
335 u8 complete_split;
336 u8 isoc_split_pos;
337 u16 isoc_frame_index;
338 u16 isoc_split_offset;
339 u32 ssplit_out_xfer_count;
340 u8 error_count;
341 u8 n_desc;
342 u16 isoc_frame_index_last;
343 struct dwc2_hcd_urb *urb;
344 struct dwc2_qh *qh;
345 struct list_head qtd_list_entry;
346};
347
348#ifdef DEBUG
349struct hc_xfer_info {
350 struct dwc2_hsotg *hsotg;
351 struct dwc2_host_chan *chan;
352};
353#endif
354
355
356static inline struct usb_hcd *dwc2_hsotg_to_hcd(struct dwc2_hsotg *hsotg)
357{
358 return (struct usb_hcd *)hsotg->priv;
359}
360
361
362
363
364
365
366
367
368static inline void disable_hc_int(struct dwc2_hsotg *hsotg, int chnum, u32 intr)
369{
370 u32 mask = readl(hsotg->regs + HCINTMSK(chnum));
371
372 mask &= ~intr;
373 writel(mask, hsotg->regs + HCINTMSK(chnum));
374}
375
376
377
378
379static inline int dwc2_is_host_mode(struct dwc2_hsotg *hsotg)
380{
381 return (readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) != 0;
382}
383static inline int dwc2_is_device_mode(struct dwc2_hsotg *hsotg)
384{
385 return (readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) == 0;
386}
387
388
389
390
391
392static inline u32 dwc2_read_hprt0(struct dwc2_hsotg *hsotg)
393{
394 u32 hprt0 = readl(hsotg->regs + HPRT0);
395
396 hprt0 &= ~(HPRT0_ENA | HPRT0_CONNDET | HPRT0_ENACHG | HPRT0_OVRCURRCHG);
397 return hprt0;
398}
399
400static inline u8 dwc2_hcd_get_ep_num(struct dwc2_hcd_pipe_info *pipe)
401{
402 return pipe->ep_num;
403}
404
405static inline u8 dwc2_hcd_get_pipe_type(struct dwc2_hcd_pipe_info *pipe)
406{
407 return pipe->pipe_type;
408}
409
410static inline u16 dwc2_hcd_get_mps(struct dwc2_hcd_pipe_info *pipe)
411{
412 return pipe->mps;
413}
414
415static inline u8 dwc2_hcd_get_dev_addr(struct dwc2_hcd_pipe_info *pipe)
416{
417 return pipe->dev_addr;
418}
419
420static inline u8 dwc2_hcd_is_pipe_isoc(struct dwc2_hcd_pipe_info *pipe)
421{
422 return pipe->pipe_type == USB_ENDPOINT_XFER_ISOC;
423}
424
425static inline u8 dwc2_hcd_is_pipe_int(struct dwc2_hcd_pipe_info *pipe)
426{
427 return pipe->pipe_type == USB_ENDPOINT_XFER_INT;
428}
429
430static inline u8 dwc2_hcd_is_pipe_bulk(struct dwc2_hcd_pipe_info *pipe)
431{
432 return pipe->pipe_type == USB_ENDPOINT_XFER_BULK;
433}
434
435static inline u8 dwc2_hcd_is_pipe_control(struct dwc2_hcd_pipe_info *pipe)
436{
437 return pipe->pipe_type == USB_ENDPOINT_XFER_CONTROL;
438}
439
440static inline u8 dwc2_hcd_is_pipe_in(struct dwc2_hcd_pipe_info *pipe)
441{
442 return pipe->pipe_dir == USB_DIR_IN;
443}
444
445static inline u8 dwc2_hcd_is_pipe_out(struct dwc2_hcd_pipe_info *pipe)
446{
447 return !dwc2_hcd_is_pipe_in(pipe);
448}
449
450extern int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq,
451 const struct dwc2_core_params *params);
452extern void dwc2_hcd_remove(struct dwc2_hsotg *hsotg);
453extern int dwc2_set_parameters(struct dwc2_hsotg *hsotg,
454 const struct dwc2_core_params *params);
455extern void dwc2_set_all_params(struct dwc2_core_params *params, int value);
456
457
458extern enum dwc2_transaction_type dwc2_hcd_select_transactions(
459 struct dwc2_hsotg *hsotg);
460extern void dwc2_hcd_queue_transactions(struct dwc2_hsotg *hsotg,
461 enum dwc2_transaction_type tr_type);
462
463
464
465extern void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
466extern int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
467extern void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
468extern void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
469 int sched_csplit);
470
471extern void dwc2_hcd_qtd_init(struct dwc2_qtd *qtd, struct dwc2_hcd_urb *urb);
472extern int dwc2_hcd_qtd_add(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd,
473 struct dwc2_qh **qh, gfp_t mem_flags);
474
475
476static inline void dwc2_hcd_qtd_unlink_and_free(struct dwc2_hsotg *hsotg,
477 struct dwc2_qtd *qtd,
478 struct dwc2_qh *qh)
479{
480 list_del(&qtd->qtd_list_entry);
481 kfree(qtd);
482}
483
484
485extern void dwc2_hcd_start_xfer_ddma(struct dwc2_hsotg *hsotg,
486 struct dwc2_qh *qh);
487extern void dwc2_hcd_complete_xfer_ddma(struct dwc2_hsotg *hsotg,
488 struct dwc2_host_chan *chan, int chnum,
489 enum dwc2_halt_status halt_status);
490
491extern int dwc2_hcd_qh_init_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
492 gfp_t mem_flags);
493extern void dwc2_hcd_qh_free_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
494
495
496#define dwc2_qh_is_non_per(_qh_ptr_) \
497 ((_qh_ptr_)->ep_type == USB_ENDPOINT_XFER_BULK || \
498 (_qh_ptr_)->ep_type == USB_ENDPOINT_XFER_CONTROL)
499
500#ifdef CONFIG_USB_DWC2_DEBUG_PERIODIC
501static inline bool dbg_hc(struct dwc2_host_chan *hc) { return true; }
502static inline bool dbg_qh(struct dwc2_qh *qh) { return true; }
503static inline bool dbg_urb(struct urb *urb) { return true; }
504static inline bool dbg_perio(void) { return true; }
505#else
506static inline bool dbg_hc(struct dwc2_host_chan *hc)
507{
508 return hc->ep_type == USB_ENDPOINT_XFER_BULK ||
509 hc->ep_type == USB_ENDPOINT_XFER_CONTROL;
510}
511
512static inline bool dbg_qh(struct dwc2_qh *qh)
513{
514 return qh->ep_type == USB_ENDPOINT_XFER_BULK ||
515 qh->ep_type == USB_ENDPOINT_XFER_CONTROL;
516}
517
518static inline bool dbg_urb(struct urb *urb)
519{
520 return usb_pipetype(urb->pipe) == PIPE_BULK ||
521 usb_pipetype(urb->pipe) == PIPE_CONTROL;
522}
523
524static inline bool dbg_perio(void) { return false; }
525#endif
526
527
528#define dwc2_hb_mult(wmaxpacketsize) (1 + (((wmaxpacketsize) >> 11) & 0x03))
529
530
531#define dwc2_max_packet(wmaxpacketsize) ((wmaxpacketsize) & 0x07ff)
532
533
534
535
536
537
538static inline int dwc2_frame_num_le(u16 frame1, u16 frame2)
539{
540 return ((frame2 - frame1) & HFNUM_MAX_FRNUM) <= (HFNUM_MAX_FRNUM >> 1);
541}
542
543
544
545
546
547
548static inline int dwc2_frame_num_gt(u16 frame1, u16 frame2)
549{
550 return (frame1 != frame2) &&
551 ((frame1 - frame2) & HFNUM_MAX_FRNUM) < (HFNUM_MAX_FRNUM >> 1);
552}
553
554
555
556
557
558static inline u16 dwc2_frame_num_inc(u16 frame, u16 inc)
559{
560 return (frame + inc) & HFNUM_MAX_FRNUM;
561}
562
563static inline u16 dwc2_full_frame_num(u16 frame)
564{
565 return (frame & HFNUM_MAX_FRNUM) >> 3;
566}
567
568static inline u16 dwc2_micro_frame_num(u16 frame)
569{
570 return frame & 0x7;
571}
572
573
574
575
576
577static inline u32 dwc2_read_core_intr(struct dwc2_hsotg *hsotg)
578{
579 return readl(hsotg->regs + GINTSTS) & readl(hsotg->regs + GINTMSK);
580}
581
582static inline u32 dwc2_hcd_urb_get_status(struct dwc2_hcd_urb *dwc2_urb)
583{
584 return dwc2_urb->status;
585}
586
587static inline u32 dwc2_hcd_urb_get_actual_length(
588 struct dwc2_hcd_urb *dwc2_urb)
589{
590 return dwc2_urb->actual_length;
591}
592
593static inline u32 dwc2_hcd_urb_get_error_count(struct dwc2_hcd_urb *dwc2_urb)
594{
595 return dwc2_urb->error_count;
596}
597
598static inline void dwc2_hcd_urb_set_iso_desc_params(
599 struct dwc2_hcd_urb *dwc2_urb, int desc_num, u32 offset,
600 u32 length)
601{
602 dwc2_urb->iso_descs[desc_num].offset = offset;
603 dwc2_urb->iso_descs[desc_num].length = length;
604}
605
606static inline u32 dwc2_hcd_urb_get_iso_desc_status(
607 struct dwc2_hcd_urb *dwc2_urb, int desc_num)
608{
609 return dwc2_urb->iso_descs[desc_num].status;
610}
611
612static inline u32 dwc2_hcd_urb_get_iso_desc_actual_length(
613 struct dwc2_hcd_urb *dwc2_urb, int desc_num)
614{
615 return dwc2_urb->iso_descs[desc_num].actual_length;
616}
617
618static inline int dwc2_hcd_is_bandwidth_allocated(struct dwc2_hsotg *hsotg,
619 struct usb_host_endpoint *ep)
620{
621 struct dwc2_qh *qh = ep->hcpriv;
622
623 if (qh && !list_empty(&qh->qh_list_entry))
624 return 1;
625
626 return 0;
627}
628
629static inline u16 dwc2_hcd_get_ep_bandwidth(struct dwc2_hsotg *hsotg,
630 struct usb_host_endpoint *ep)
631{
632 struct dwc2_qh *qh = ep->hcpriv;
633
634 if (!qh) {
635 WARN_ON(1);
636 return 0;
637 }
638
639 return qh->usecs;
640}
641
642extern void dwc2_hcd_save_data_toggle(struct dwc2_hsotg *hsotg,
643 struct dwc2_host_chan *chan, int chnum,
644 struct dwc2_qtd *qtd);
645
646
647
648
649
650
651
652
653
654
655
656extern irqreturn_t dwc2_handle_hcd_intr(struct dwc2_hsotg *hsotg);
657
658
659
660
661
662
663extern void dwc2_hcd_stop(struct dwc2_hsotg *hsotg);
664
665extern void dwc2_hcd_start(struct dwc2_hsotg *hsotg);
666extern void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg);
667
668
669
670
671
672
673
674extern int dwc2_hcd_is_b_host(struct dwc2_hsotg *hsotg);
675
676
677
678
679
680
681extern int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg);
682
683
684
685
686
687
688
689
690
691extern void dwc2_hcd_dump_state(struct dwc2_hsotg *hsotg);
692
693
694
695
696
697
698
699
700
701
702
703
704extern void dwc2_hcd_dump_frrem(struct dwc2_hsotg *hsotg);
705
706
707
708
709#define URB_GIVEBACK_ASAP 0x1
710#define URB_SEND_ZERO_PACKET 0x2
711
712
713
714extern void dwc2_host_start(struct dwc2_hsotg *hsotg);
715extern void dwc2_host_disconnect(struct dwc2_hsotg *hsotg);
716extern void dwc2_host_hub_info(struct dwc2_hsotg *hsotg, void *context,
717 int *hub_addr, int *hub_port);
718extern int dwc2_host_get_speed(struct dwc2_hsotg *hsotg, void *context);
719extern void dwc2_host_complete(struct dwc2_hsotg *hsotg, void *context,
720 struct dwc2_hcd_urb *dwc2_urb, int status);
721
722#ifdef DEBUG
723
724
725
726
727
728
729
730
731
732#define dwc2_sample_frrem(_hcd_, _qh_, _letter_) \
733do { \
734 struct hfnum_data _hfnum_; \
735 struct dwc2_qtd *_qtd_; \
736 \
737 _qtd_ = list_entry((_qh_)->qtd_list.next, struct dwc2_qtd, \
738 qtd_list_entry); \
739 if (usb_pipeint(_qtd_->urb->pipe) && \
740 (_qh_)->start_split_frame != 0 && !_qtd_->complete_split) { \
741 _hfnum_.d32 = readl((_hcd_)->regs + HFNUM); \
742 switch (_hfnum_.b.frnum & 0x7) { \
743 case 7: \
744 (_hcd_)->hfnum_7_samples_##_letter_++; \
745 (_hcd_)->hfnum_7_frrem_accum_##_letter_ += \
746 _hfnum_.b.frrem; \
747 break; \
748 case 0: \
749 (_hcd_)->hfnum_0_samples_##_letter_++; \
750 (_hcd_)->hfnum_0_frrem_accum_##_letter_ += \
751 _hfnum_.b.frrem; \
752 break; \
753 default: \
754 (_hcd_)->hfnum_other_samples_##_letter_++; \
755 (_hcd_)->hfnum_other_frrem_accum_##_letter_ += \
756 _hfnum_.b.frrem; \
757 break; \
758 } \
759 } \
760} while (0)
761#else
762#define dwc2_sample_frrem(_hcd_, _qh_, _letter_) do {} while (0)
763#endif
764
765#endif
766