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
126#define DWC2_HC_PID_DATA2 TSIZ_SC_MC_PID_DATA2
127#define DWC2_HC_PID_DATA1 TSIZ_SC_MC_PID_DATA1
128#define DWC2_HC_PID_MDATA TSIZ_SC_MC_PID_MDATA
129#define DWC2_HC_PID_SETUP TSIZ_SC_MC_PID_SETUP
130
131 unsigned multi_count:2;
132
133 u8 *xfer_buf;
134 dma_addr_t xfer_dma;
135 u32 xfer_len;
136 u32 xfer_count;
137 u16 start_pkt_count;
138 u8 xfer_started;
139 u8 do_ping;
140 u8 error_state;
141 u8 halt_on_queue;
142 u8 halt_pending;
143 u8 do_split;
144 u8 complete_split;
145 u8 hub_addr;
146 u8 hub_port;
147 u8 xact_pos;
148#define DWC2_HCSPLT_XACTPOS_MID HCSPLT_XACTPOS_MID
149#define DWC2_HCSPLT_XACTPOS_END HCSPLT_XACTPOS_END
150#define DWC2_HCSPLT_XACTPOS_BEGIN HCSPLT_XACTPOS_BEGIN
151#define DWC2_HCSPLT_XACTPOS_ALL HCSPLT_XACTPOS_ALL
152
153 u8 requests;
154 u8 schinfo;
155 u16 ntd;
156 enum dwc2_halt_status halt_status;
157 u32 hcint;
158 struct dwc2_qh *qh;
159 struct list_head hc_list_entry;
160 dma_addr_t desc_list_addr;
161 u32 desc_list_sz;
162 struct list_head split_order_list_entry;
163};
164
165struct dwc2_hcd_pipe_info {
166 u8 dev_addr;
167 u8 ep_num;
168 u8 pipe_type;
169 u8 pipe_dir;
170 u16 mps;
171};
172
173struct dwc2_hcd_iso_packet_desc {
174 u32 offset;
175 u32 length;
176 u32 actual_length;
177 u32 status;
178};
179
180struct dwc2_qtd;
181
182struct dwc2_hcd_urb {
183 void *priv;
184 struct dwc2_qtd *qtd;
185 void *buf;
186 dma_addr_t dma;
187 void *setup_packet;
188 dma_addr_t setup_dma;
189 u32 length;
190 u32 actual_length;
191 u32 status;
192 u32 error_count;
193 u32 packet_count;
194 u32 flags;
195 u16 interval;
196 struct dwc2_hcd_pipe_info pipe_info;
197 struct dwc2_hcd_iso_packet_desc iso_descs[0];
198};
199
200
201enum dwc2_control_phase {
202 DWC2_CONTROL_SETUP,
203 DWC2_CONTROL_DATA,
204 DWC2_CONTROL_STATUS,
205};
206
207
208enum dwc2_transaction_type {
209 DWC2_TRANSACTION_NONE,
210 DWC2_TRANSACTION_PERIODIC,
211 DWC2_TRANSACTION_NON_PERIODIC,
212 DWC2_TRANSACTION_ALL,
213};
214
215
216#define DWC2_ELEMENTS_PER_LS_BITMAP DIV_ROUND_UP(DWC2_LS_SCHEDULE_SLICES, \
217 BITS_PER_LONG)
218
219
220
221
222
223
224
225
226
227
228
229
230struct dwc2_tt {
231 int refcount;
232 struct usb_tt *usb_tt;
233 unsigned long periodic_bitmaps[];
234};
235
236
237
238
239
240
241
242
243
244
245
246
247struct dwc2_hs_transfer_time {
248 u32 start_schedule_us;
249 u16 duration_us;
250};
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
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
327struct dwc2_qh {
328 struct dwc2_hsotg *hsotg;
329 u8 ep_type;
330 u8 ep_is_in;
331 u16 maxp;
332 u8 dev_speed;
333 u8 data_toggle;
334 u8 ping_state;
335 u8 do_split;
336 u8 td_first;
337 u8 td_last;
338 u16 host_us;
339 u16 device_us;
340 u16 host_interval;
341 u16 device_interval;
342 u16 next_active_frame;
343 u16 start_active_frame;
344 s16 num_hs_transfers;
345 struct dwc2_hs_transfer_time hs_transfers[DWC2_HS_SCHEDULE_UFRAMES];
346 u32 ls_start_schedule_slice;
347 u16 ntd;
348 struct list_head qtd_list;
349 struct dwc2_host_chan *channel;
350 struct list_head qh_list_entry;
351 struct dwc2_hcd_dma_desc *desc_list;
352 dma_addr_t desc_list_dma;
353 u32 desc_list_sz;
354 u32 *n_bytes;
355 struct timer_list unreserve_timer;
356 struct dwc2_tt *dwc_tt;
357 int ttport;
358 unsigned tt_buffer_dirty:1;
359 unsigned unreserve_pending:1;
360 unsigned schedule_low_speed:1;
361};
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407struct dwc2_qtd {
408 enum dwc2_control_phase control_phase;
409 u8 in_process;
410 u8 data_toggle;
411 u8 complete_split;
412 u8 isoc_split_pos;
413 u16 isoc_frame_index;
414 u16 isoc_split_offset;
415 u16 isoc_td_last;
416 u16 isoc_td_first;
417 u32 ssplit_out_xfer_count;
418 u8 error_count;
419 u8 n_desc;
420 u16 isoc_frame_index_last;
421 struct dwc2_hcd_urb *urb;
422 struct dwc2_qh *qh;
423 struct list_head qtd_list_entry;
424};
425
426#ifdef DEBUG
427struct hc_xfer_info {
428 struct dwc2_hsotg *hsotg;
429 struct dwc2_host_chan *chan;
430};
431#endif
432
433u32 dwc2_calc_frame_interval(struct dwc2_hsotg *hsotg);
434
435
436static inline struct usb_hcd *dwc2_hsotg_to_hcd(struct dwc2_hsotg *hsotg)
437{
438 return (struct usb_hcd *)hsotg->priv;
439}
440
441
442
443
444
445
446
447
448static inline void disable_hc_int(struct dwc2_hsotg *hsotg, int chnum, u32 intr)
449{
450 u32 mask = dwc2_readl(hsotg->regs + HCINTMSK(chnum));
451
452 mask &= ~intr;
453 dwc2_writel(mask, hsotg->regs + HCINTMSK(chnum));
454}
455
456void dwc2_hc_cleanup(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan);
457void dwc2_hc_halt(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan,
458 enum dwc2_halt_status halt_status);
459void dwc2_hc_start_transfer_ddma(struct dwc2_hsotg *hsotg,
460 struct dwc2_host_chan *chan);
461
462
463
464
465
466static inline u32 dwc2_read_hprt0(struct dwc2_hsotg *hsotg)
467{
468 u32 hprt0 = dwc2_readl(hsotg->regs + HPRT0);
469
470 hprt0 &= ~(HPRT0_ENA | HPRT0_CONNDET | HPRT0_ENACHG | HPRT0_OVRCURRCHG);
471 return hprt0;
472}
473
474static inline u8 dwc2_hcd_get_ep_num(struct dwc2_hcd_pipe_info *pipe)
475{
476 return pipe->ep_num;
477}
478
479static inline u8 dwc2_hcd_get_pipe_type(struct dwc2_hcd_pipe_info *pipe)
480{
481 return pipe->pipe_type;
482}
483
484static inline u16 dwc2_hcd_get_mps(struct dwc2_hcd_pipe_info *pipe)
485{
486 return pipe->mps;
487}
488
489static inline u8 dwc2_hcd_get_dev_addr(struct dwc2_hcd_pipe_info *pipe)
490{
491 return pipe->dev_addr;
492}
493
494static inline u8 dwc2_hcd_is_pipe_isoc(struct dwc2_hcd_pipe_info *pipe)
495{
496 return pipe->pipe_type == USB_ENDPOINT_XFER_ISOC;
497}
498
499static inline u8 dwc2_hcd_is_pipe_int(struct dwc2_hcd_pipe_info *pipe)
500{
501 return pipe->pipe_type == USB_ENDPOINT_XFER_INT;
502}
503
504static inline u8 dwc2_hcd_is_pipe_bulk(struct dwc2_hcd_pipe_info *pipe)
505{
506 return pipe->pipe_type == USB_ENDPOINT_XFER_BULK;
507}
508
509static inline u8 dwc2_hcd_is_pipe_control(struct dwc2_hcd_pipe_info *pipe)
510{
511 return pipe->pipe_type == USB_ENDPOINT_XFER_CONTROL;
512}
513
514static inline u8 dwc2_hcd_is_pipe_in(struct dwc2_hcd_pipe_info *pipe)
515{
516 return pipe->pipe_dir == USB_DIR_IN;
517}
518
519static inline u8 dwc2_hcd_is_pipe_out(struct dwc2_hcd_pipe_info *pipe)
520{
521 return !dwc2_hcd_is_pipe_in(pipe);
522}
523
524extern int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq);
525extern void dwc2_hcd_remove(struct dwc2_hsotg *hsotg);
526
527
528extern enum dwc2_transaction_type dwc2_hcd_select_transactions(
529 struct dwc2_hsotg *hsotg);
530extern void dwc2_hcd_queue_transactions(struct dwc2_hsotg *hsotg,
531 enum dwc2_transaction_type tr_type);
532
533
534
535extern struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg,
536 struct dwc2_hcd_urb *urb,
537 gfp_t mem_flags);
538extern void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
539extern int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
540extern void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
541extern void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
542 int sched_csplit);
543
544extern void dwc2_hcd_qtd_init(struct dwc2_qtd *qtd, struct dwc2_hcd_urb *urb);
545extern int dwc2_hcd_qtd_add(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd,
546 struct dwc2_qh *qh);
547
548
549static inline void dwc2_hcd_qtd_unlink_and_free(struct dwc2_hsotg *hsotg,
550 struct dwc2_qtd *qtd,
551 struct dwc2_qh *qh)
552{
553 list_del(&qtd->qtd_list_entry);
554 kfree(qtd);
555}
556
557
558extern void dwc2_hcd_start_xfer_ddma(struct dwc2_hsotg *hsotg,
559 struct dwc2_qh *qh);
560extern void dwc2_hcd_complete_xfer_ddma(struct dwc2_hsotg *hsotg,
561 struct dwc2_host_chan *chan, int chnum,
562 enum dwc2_halt_status halt_status);
563
564extern int dwc2_hcd_qh_init_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
565 gfp_t mem_flags);
566extern void dwc2_hcd_qh_free_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
567
568
569#define dwc2_qh_is_non_per(_qh_ptr_) \
570 ((_qh_ptr_)->ep_type == USB_ENDPOINT_XFER_BULK || \
571 (_qh_ptr_)->ep_type == USB_ENDPOINT_XFER_CONTROL)
572
573#ifdef CONFIG_USB_DWC2_DEBUG_PERIODIC
574static inline bool dbg_hc(struct dwc2_host_chan *hc) { return true; }
575static inline bool dbg_qh(struct dwc2_qh *qh) { return true; }
576static inline bool dbg_urb(struct urb *urb) { return true; }
577static inline bool dbg_perio(void) { return true; }
578#else
579static inline bool dbg_hc(struct dwc2_host_chan *hc)
580{
581 return hc->ep_type == USB_ENDPOINT_XFER_BULK ||
582 hc->ep_type == USB_ENDPOINT_XFER_CONTROL;
583}
584
585static inline bool dbg_qh(struct dwc2_qh *qh)
586{
587 return qh->ep_type == USB_ENDPOINT_XFER_BULK ||
588 qh->ep_type == USB_ENDPOINT_XFER_CONTROL;
589}
590
591static inline bool dbg_urb(struct urb *urb)
592{
593 return usb_pipetype(urb->pipe) == PIPE_BULK ||
594 usb_pipetype(urb->pipe) == PIPE_CONTROL;
595}
596
597static inline bool dbg_perio(void) { return false; }
598#endif
599
600
601#define dwc2_hb_mult(wmaxpacketsize) (1 + (((wmaxpacketsize) >> 11) & 0x03))
602
603
604#define dwc2_max_packet(wmaxpacketsize) ((wmaxpacketsize) & 0x07ff)
605
606
607
608
609
610
611static inline bool dwc2_frame_idx_num_gt(u16 fr_idx1, u16 fr_idx2)
612{
613 u16 diff = fr_idx1 - fr_idx2;
614 u16 sign = diff & (FRLISTEN_64_SIZE >> 1);
615
616 return diff && !sign;
617}
618
619
620
621
622
623
624static inline int dwc2_frame_num_le(u16 frame1, u16 frame2)
625{
626 return ((frame2 - frame1) & HFNUM_MAX_FRNUM) <= (HFNUM_MAX_FRNUM >> 1);
627}
628
629
630
631
632
633
634static inline int dwc2_frame_num_gt(u16 frame1, u16 frame2)
635{
636 return (frame1 != frame2) &&
637 ((frame1 - frame2) & HFNUM_MAX_FRNUM) < (HFNUM_MAX_FRNUM >> 1);
638}
639
640
641
642
643
644static inline u16 dwc2_frame_num_inc(u16 frame, u16 inc)
645{
646 return (frame + inc) & HFNUM_MAX_FRNUM;
647}
648
649static inline u16 dwc2_frame_num_dec(u16 frame, u16 dec)
650{
651 return (frame + HFNUM_MAX_FRNUM + 1 - dec) & HFNUM_MAX_FRNUM;
652}
653
654static inline u16 dwc2_full_frame_num(u16 frame)
655{
656 return (frame & HFNUM_MAX_FRNUM) >> 3;
657}
658
659static inline u16 dwc2_micro_frame_num(u16 frame)
660{
661 return frame & 0x7;
662}
663
664
665
666
667
668static inline u32 dwc2_read_core_intr(struct dwc2_hsotg *hsotg)
669{
670 return dwc2_readl(hsotg->regs + GINTSTS) &
671 dwc2_readl(hsotg->regs + GINTMSK);
672}
673
674static inline u32 dwc2_hcd_urb_get_status(struct dwc2_hcd_urb *dwc2_urb)
675{
676 return dwc2_urb->status;
677}
678
679static inline u32 dwc2_hcd_urb_get_actual_length(
680 struct dwc2_hcd_urb *dwc2_urb)
681{
682 return dwc2_urb->actual_length;
683}
684
685static inline u32 dwc2_hcd_urb_get_error_count(struct dwc2_hcd_urb *dwc2_urb)
686{
687 return dwc2_urb->error_count;
688}
689
690static inline void dwc2_hcd_urb_set_iso_desc_params(
691 struct dwc2_hcd_urb *dwc2_urb, int desc_num, u32 offset,
692 u32 length)
693{
694 dwc2_urb->iso_descs[desc_num].offset = offset;
695 dwc2_urb->iso_descs[desc_num].length = length;
696}
697
698static inline u32 dwc2_hcd_urb_get_iso_desc_status(
699 struct dwc2_hcd_urb *dwc2_urb, int desc_num)
700{
701 return dwc2_urb->iso_descs[desc_num].status;
702}
703
704static inline u32 dwc2_hcd_urb_get_iso_desc_actual_length(
705 struct dwc2_hcd_urb *dwc2_urb, int desc_num)
706{
707 return dwc2_urb->iso_descs[desc_num].actual_length;
708}
709
710static inline int dwc2_hcd_is_bandwidth_allocated(struct dwc2_hsotg *hsotg,
711 struct usb_host_endpoint *ep)
712{
713 struct dwc2_qh *qh = ep->hcpriv;
714
715 if (qh && !list_empty(&qh->qh_list_entry))
716 return 1;
717
718 return 0;
719}
720
721static inline u16 dwc2_hcd_get_ep_bandwidth(struct dwc2_hsotg *hsotg,
722 struct usb_host_endpoint *ep)
723{
724 struct dwc2_qh *qh = ep->hcpriv;
725
726 if (!qh) {
727 WARN_ON(1);
728 return 0;
729 }
730
731 return qh->host_us;
732}
733
734extern void dwc2_hcd_save_data_toggle(struct dwc2_hsotg *hsotg,
735 struct dwc2_host_chan *chan, int chnum,
736 struct dwc2_qtd *qtd);
737
738
739
740
741
742
743
744
745
746
747
748extern irqreturn_t dwc2_handle_hcd_intr(struct dwc2_hsotg *hsotg);
749
750
751
752
753
754
755extern void dwc2_hcd_stop(struct dwc2_hsotg *hsotg);
756
757
758
759
760
761
762
763extern int dwc2_hcd_is_b_host(struct dwc2_hsotg *hsotg);
764
765
766
767
768
769
770
771
772
773extern void dwc2_hcd_dump_state(struct dwc2_hsotg *hsotg);
774
775
776
777
778
779
780
781
782
783
784
785
786extern void dwc2_hcd_dump_frrem(struct dwc2_hsotg *hsotg);
787
788
789
790
791#define URB_GIVEBACK_ASAP 0x1
792#define URB_SEND_ZERO_PACKET 0x2
793
794
795
796extern void dwc2_host_start(struct dwc2_hsotg *hsotg);
797extern void dwc2_host_disconnect(struct dwc2_hsotg *hsotg);
798extern void dwc2_host_hub_info(struct dwc2_hsotg *hsotg, void *context,
799 int *hub_addr, int *hub_port);
800extern struct dwc2_tt *dwc2_host_get_tt_info(struct dwc2_hsotg *hsotg,
801 void *context, gfp_t mem_flags,
802 int *ttport);
803
804extern void dwc2_host_put_tt_info(struct dwc2_hsotg *hsotg,
805 struct dwc2_tt *dwc_tt);
806extern int dwc2_host_get_speed(struct dwc2_hsotg *hsotg, void *context);
807extern void dwc2_host_complete(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd,
808 int status);
809
810#ifdef DEBUG
811
812
813
814
815
816
817
818
819
820#define dwc2_sample_frrem(_hcd_, _qh_, _letter_) \
821do { \
822 struct hfnum_data _hfnum_; \
823 struct dwc2_qtd *_qtd_; \
824 \
825 _qtd_ = list_entry((_qh_)->qtd_list.next, struct dwc2_qtd, \
826 qtd_list_entry); \
827 if (usb_pipeint(_qtd_->urb->pipe) && \
828 (_qh_)->start_active_frame != 0 && !_qtd_->complete_split) { \
829 _hfnum_.d32 = dwc2_readl((_hcd_)->regs + HFNUM); \
830 switch (_hfnum_.b.frnum & 0x7) { \
831 case 7: \
832 (_hcd_)->hfnum_7_samples_##_letter_++; \
833 (_hcd_)->hfnum_7_frrem_accum_##_letter_ += \
834 _hfnum_.b.frrem; \
835 break; \
836 case 0: \
837 (_hcd_)->hfnum_0_samples_##_letter_++; \
838 (_hcd_)->hfnum_0_frrem_accum_##_letter_ += \
839 _hfnum_.b.frrem; \
840 break; \
841 default: \
842 (_hcd_)->hfnum_other_samples_##_letter_++; \
843 (_hcd_)->hfnum_other_frrem_accum_##_letter_ += \
844 _hfnum_.b.frrem; \
845 break; \
846 } \
847 } \
848} while (0)
849#else
850#define dwc2_sample_frrem(_hcd_, _qh_, _letter_) do {} while (0)
851#endif
852
853#endif
854