Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / drivers / usb / host / xhci-mtk-sch.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2015 MediaTek Inc.
4  * Author:
5  *  Zhigang.Wei <zhigang.wei@mediatek.com>
6  *  Chunfeng.Yun <chunfeng.yun@mediatek.com>
7  */
8
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/slab.h>
12
13 #include "xhci.h"
14 #include "xhci-mtk.h"
15
16 #define SSP_BW_BOUNDARY 130000
17 #define SS_BW_BOUNDARY  51000
18 /* table 5-5. High-speed Isoc Transaction Limits in usb_20 spec */
19 #define HS_BW_BOUNDARY  6144
20 /* usb2 spec section11.18.1: at most 188 FS bytes per microframe */
21 #define FS_PAYLOAD_MAX 188
22 /*
23  * max number of microframes for split transfer,
24  * for fs isoc in : 1 ss + 1 idle + 7 cs
25  */
26 #define TT_MICROFRAMES_MAX 9
27
28 /* mtk scheduler bitmasks */
29 #define EP_BPKTS(p)     ((p) & 0x7f)
30 #define EP_BCSCOUNT(p)  (((p) & 0x7) << 8)
31 #define EP_BBM(p)       ((p) << 11)
32 #define EP_BOFFSET(p)   ((p) & 0x3fff)
33 #define EP_BREPEAT(p)   (((p) & 0x7fff) << 16)
34
35 static int is_fs_or_ls(enum usb_device_speed speed)
36 {
37         return speed == USB_SPEED_FULL || speed == USB_SPEED_LOW;
38 }
39
40 /*
41 * get the index of bandwidth domains array which @ep belongs to.
42 *
43 * the bandwidth domain array is saved to @sch_array of struct xhci_hcd_mtk,
44 * each HS root port is treated as a single bandwidth domain,
45 * but each SS root port is treated as two bandwidth domains, one for IN eps,
46 * one for OUT eps.
47 * @real_port value is defined as follow according to xHCI spec:
48 * 1 for SSport0, ..., N+1 for SSportN, N+2 for HSport0, N+3 for HSport1, etc
49 * so the bandwidth domain array is organized as follow for simplification:
50 * SSport0-OUT, SSport0-IN, ..., SSportX-OUT, SSportX-IN, HSport0, ..., HSportY
51 */
52 static int get_bw_index(struct xhci_hcd *xhci, struct usb_device *udev,
53         struct usb_host_endpoint *ep)
54 {
55         struct xhci_virt_device *virt_dev;
56         int bw_index;
57
58         virt_dev = xhci->devs[udev->slot_id];
59
60         if (udev->speed >= USB_SPEED_SUPER) {
61                 if (usb_endpoint_dir_out(&ep->desc))
62                         bw_index = (virt_dev->real_port - 1) * 2;
63                 else
64                         bw_index = (virt_dev->real_port - 1) * 2 + 1;
65         } else {
66                 /* add one more for each SS port */
67                 bw_index = virt_dev->real_port + xhci->usb3_rhub.num_ports - 1;
68         }
69
70         return bw_index;
71 }
72
73 static u32 get_esit(struct xhci_ep_ctx *ep_ctx)
74 {
75         u32 esit;
76
77         esit = 1 << CTX_TO_EP_INTERVAL(le32_to_cpu(ep_ctx->ep_info));
78         if (esit > XHCI_MTK_MAX_ESIT)
79                 esit = XHCI_MTK_MAX_ESIT;
80
81         return esit;
82 }
83
84 static struct mu3h_sch_tt *find_tt(struct usb_device *udev)
85 {
86         struct usb_tt *utt = udev->tt;
87         struct mu3h_sch_tt *tt, **tt_index, **ptt;
88         unsigned int port;
89         bool allocated_index = false;
90
91         if (!utt)
92                 return NULL;    /* Not below a TT */
93
94         /*
95          * Find/create our data structure.
96          * For hubs with a single TT, we get it directly.
97          * For hubs with multiple TTs, there's an extra level of pointers.
98          */
99         tt_index = NULL;
100         if (utt->multi) {
101                 tt_index = utt->hcpriv;
102                 if (!tt_index) {        /* Create the index array */
103                         tt_index = kcalloc(utt->hub->maxchild,
104                                         sizeof(*tt_index), GFP_KERNEL);
105                         if (!tt_index)
106                                 return ERR_PTR(-ENOMEM);
107                         utt->hcpriv = tt_index;
108                         allocated_index = true;
109                 }
110                 port = udev->ttport - 1;
111                 ptt = &tt_index[port];
112         } else {
113                 port = 0;
114                 ptt = (struct mu3h_sch_tt **) &utt->hcpriv;
115         }
116
117         tt = *ptt;
118         if (!tt) {      /* Create the mu3h_sch_tt */
119                 tt = kzalloc(sizeof(*tt), GFP_KERNEL);
120                 if (!tt) {
121                         if (allocated_index) {
122                                 utt->hcpriv = NULL;
123                                 kfree(tt_index);
124                         }
125                         return ERR_PTR(-ENOMEM);
126                 }
127                 INIT_LIST_HEAD(&tt->ep_list);
128                 tt->usb_tt = utt;
129                 tt->tt_port = port;
130                 *ptt = tt;
131         }
132
133         return tt;
134 }
135
136 /* Release the TT above udev, if it's not in use */
137 static void drop_tt(struct usb_device *udev)
138 {
139         struct usb_tt *utt = udev->tt;
140         struct mu3h_sch_tt *tt, **tt_index, **ptt;
141         int i, cnt;
142
143         if (!utt || !utt->hcpriv)
144                 return;         /* Not below a TT, or never allocated */
145
146         cnt = 0;
147         if (utt->multi) {
148                 tt_index = utt->hcpriv;
149                 ptt = &tt_index[udev->ttport - 1];
150                 /*  How many entries are left in tt_index? */
151                 for (i = 0; i < utt->hub->maxchild; ++i)
152                         cnt += !!tt_index[i];
153         } else {
154                 tt_index = NULL;
155                 ptt = (struct mu3h_sch_tt **)&utt->hcpriv;
156         }
157
158         tt = *ptt;
159         if (!tt || !list_empty(&tt->ep_list))
160                 return;         /* never allocated , or still in use*/
161
162         *ptt = NULL;
163         kfree(tt);
164
165         if (cnt == 1) {
166                 utt->hcpriv = NULL;
167                 kfree(tt_index);
168         }
169 }
170
171 static struct mu3h_sch_ep_info *create_sch_ep(struct usb_device *udev,
172         struct usb_host_endpoint *ep, struct xhci_ep_ctx *ep_ctx)
173 {
174         struct mu3h_sch_ep_info *sch_ep;
175         struct mu3h_sch_tt *tt = NULL;
176         u32 len_bw_budget_table;
177         size_t mem_size;
178
179         if (is_fs_or_ls(udev->speed))
180                 len_bw_budget_table = TT_MICROFRAMES_MAX;
181         else if ((udev->speed >= USB_SPEED_SUPER)
182                         && usb_endpoint_xfer_isoc(&ep->desc))
183                 len_bw_budget_table = get_esit(ep_ctx);
184         else
185                 len_bw_budget_table = 1;
186
187         mem_size = sizeof(struct mu3h_sch_ep_info) +
188                         len_bw_budget_table * sizeof(u32);
189         sch_ep = kzalloc(mem_size, GFP_KERNEL);
190         if (!sch_ep)
191                 return ERR_PTR(-ENOMEM);
192
193         if (is_fs_or_ls(udev->speed)) {
194                 tt = find_tt(udev);
195                 if (IS_ERR(tt)) {
196                         kfree(sch_ep);
197                         return ERR_PTR(-ENOMEM);
198                 }
199         }
200
201         sch_ep->sch_tt = tt;
202         sch_ep->ep = ep;
203
204         return sch_ep;
205 }
206
207 static void setup_sch_info(struct usb_device *udev,
208                 struct xhci_ep_ctx *ep_ctx, struct mu3h_sch_ep_info *sch_ep)
209 {
210         u32 ep_type;
211         u32 maxpkt;
212         u32 max_burst;
213         u32 mult;
214         u32 esit_pkts;
215         u32 max_esit_payload;
216         u32 *bwb_table = sch_ep->bw_budget_table;
217         int i;
218
219         ep_type = CTX_TO_EP_TYPE(le32_to_cpu(ep_ctx->ep_info2));
220         maxpkt = MAX_PACKET_DECODED(le32_to_cpu(ep_ctx->ep_info2));
221         max_burst = CTX_TO_MAX_BURST(le32_to_cpu(ep_ctx->ep_info2));
222         mult = CTX_TO_EP_MULT(le32_to_cpu(ep_ctx->ep_info));
223         max_esit_payload =
224                 (CTX_TO_MAX_ESIT_PAYLOAD_HI(
225                         le32_to_cpu(ep_ctx->ep_info)) << 16) |
226                  CTX_TO_MAX_ESIT_PAYLOAD(le32_to_cpu(ep_ctx->tx_info));
227
228         sch_ep->esit = get_esit(ep_ctx);
229         sch_ep->ep_type = ep_type;
230         sch_ep->maxpkt = maxpkt;
231         sch_ep->offset = 0;
232         sch_ep->burst_mode = 0;
233         sch_ep->repeat = 0;
234
235         if (udev->speed == USB_SPEED_HIGH) {
236                 sch_ep->cs_count = 0;
237
238                 /*
239                  * usb_20 spec section5.9
240                  * a single microframe is enough for HS synchromous endpoints
241                  * in a interval
242                  */
243                 sch_ep->num_budget_microframes = 1;
244
245                 /*
246                  * xHCI spec section6.2.3.4
247                  * @max_burst is the number of additional transactions
248                  * opportunities per microframe
249                  */
250                 sch_ep->pkts = max_burst + 1;
251                 sch_ep->bw_cost_per_microframe = maxpkt * sch_ep->pkts;
252                 bwb_table[0] = sch_ep->bw_cost_per_microframe;
253         } else if (udev->speed >= USB_SPEED_SUPER) {
254                 /* usb3_r1 spec section4.4.7 & 4.4.8 */
255                 sch_ep->cs_count = 0;
256                 sch_ep->burst_mode = 1;
257                 /*
258                  * some device's (d)wBytesPerInterval is set as 0,
259                  * then max_esit_payload is 0, so evaluate esit_pkts from
260                  * mult and burst
261                  */
262                 esit_pkts = DIV_ROUND_UP(max_esit_payload, maxpkt);
263                 if (esit_pkts == 0)
264                         esit_pkts = (mult + 1) * (max_burst + 1);
265
266                 if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) {
267                         sch_ep->pkts = esit_pkts;
268                         sch_ep->num_budget_microframes = 1;
269                         bwb_table[0] = maxpkt * sch_ep->pkts;
270                 }
271
272                 if (ep_type == ISOC_IN_EP || ep_type == ISOC_OUT_EP) {
273                         u32 remainder;
274
275                         if (sch_ep->esit == 1)
276                                 sch_ep->pkts = esit_pkts;
277                         else if (esit_pkts <= sch_ep->esit)
278                                 sch_ep->pkts = 1;
279                         else
280                                 sch_ep->pkts = roundup_pow_of_two(esit_pkts)
281                                         / sch_ep->esit;
282
283                         sch_ep->num_budget_microframes =
284                                 DIV_ROUND_UP(esit_pkts, sch_ep->pkts);
285
286                         sch_ep->repeat = !!(sch_ep->num_budget_microframes > 1);
287                         sch_ep->bw_cost_per_microframe = maxpkt * sch_ep->pkts;
288
289                         remainder = sch_ep->bw_cost_per_microframe;
290                         remainder *= sch_ep->num_budget_microframes;
291                         remainder -= (maxpkt * esit_pkts);
292                         for (i = 0; i < sch_ep->num_budget_microframes - 1; i++)
293                                 bwb_table[i] = sch_ep->bw_cost_per_microframe;
294
295                         /* last one <= bw_cost_per_microframe */
296                         bwb_table[i] = remainder;
297                 }
298         } else if (is_fs_or_ls(udev->speed)) {
299                 sch_ep->pkts = 1; /* at most one packet for each microframe */
300
301                 /*
302                  * num_budget_microframes and cs_count will be updated when
303                  * check TT for INT_OUT_EP, ISOC/INT_IN_EP type
304                  */
305                 sch_ep->cs_count = DIV_ROUND_UP(maxpkt, FS_PAYLOAD_MAX);
306                 sch_ep->num_budget_microframes = sch_ep->cs_count;
307                 sch_ep->bw_cost_per_microframe =
308                         (maxpkt < FS_PAYLOAD_MAX) ? maxpkt : FS_PAYLOAD_MAX;
309
310                 /* init budget table */
311                 if (ep_type == ISOC_OUT_EP) {
312                         for (i = 0; i < sch_ep->num_budget_microframes; i++)
313                                 bwb_table[i] =  sch_ep->bw_cost_per_microframe;
314                 } else if (ep_type == INT_OUT_EP) {
315                         /* only first one consumes bandwidth, others as zero */
316                         bwb_table[0] = sch_ep->bw_cost_per_microframe;
317                 } else { /* INT_IN_EP or ISOC_IN_EP */
318                         bwb_table[0] = 0; /* start split */
319                         bwb_table[1] = 0; /* idle */
320                         /*
321                          * due to cs_count will be updated according to cs
322                          * position, assign all remainder budget array
323                          * elements as @bw_cost_per_microframe, but only first
324                          * @num_budget_microframes elements will be used later
325                          */
326                         for (i = 2; i < TT_MICROFRAMES_MAX; i++)
327                                 bwb_table[i] =  sch_ep->bw_cost_per_microframe;
328                 }
329         }
330 }
331
332 /* Get maximum bandwidth when we schedule at offset slot. */
333 static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw,
334         struct mu3h_sch_ep_info *sch_ep, u32 offset)
335 {
336         u32 num_esit;
337         u32 max_bw = 0;
338         u32 bw;
339         int i;
340         int j;
341
342         num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
343         for (i = 0; i < num_esit; i++) {
344                 u32 base = offset + i * sch_ep->esit;
345
346                 for (j = 0; j < sch_ep->num_budget_microframes; j++) {
347                         bw = sch_bw->bus_bw[base + j] +
348                                         sch_ep->bw_budget_table[j];
349                         if (bw > max_bw)
350                                 max_bw = bw;
351                 }
352         }
353         return max_bw;
354 }
355
356 static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw,
357         struct mu3h_sch_ep_info *sch_ep, bool used)
358 {
359         u32 num_esit;
360         u32 base;
361         int i;
362         int j;
363
364         num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
365         for (i = 0; i < num_esit; i++) {
366                 base = sch_ep->offset + i * sch_ep->esit;
367                 for (j = 0; j < sch_ep->num_budget_microframes; j++) {
368                         if (used)
369                                 sch_bw->bus_bw[base + j] +=
370                                         sch_ep->bw_budget_table[j];
371                         else
372                                 sch_bw->bus_bw[base + j] -=
373                                         sch_ep->bw_budget_table[j];
374                 }
375         }
376 }
377
378 static int check_sch_tt(struct usb_device *udev,
379         struct mu3h_sch_ep_info *sch_ep, u32 offset)
380 {
381         struct mu3h_sch_tt *tt = sch_ep->sch_tt;
382         u32 extra_cs_count;
383         u32 fs_budget_start;
384         u32 start_ss, last_ss;
385         u32 start_cs, last_cs;
386         int i;
387
388         start_ss = offset % 8;
389         fs_budget_start = (start_ss + 1) % 8;
390
391         if (sch_ep->ep_type == ISOC_OUT_EP) {
392                 last_ss = start_ss + sch_ep->cs_count - 1;
393
394                 /*
395                  * usb_20 spec section11.18:
396                  * must never schedule Start-Split in Y6
397                  */
398                 if (!(start_ss == 7 || last_ss < 6))
399                         return -ERANGE;
400
401                 for (i = 0; i < sch_ep->cs_count; i++)
402                         if (test_bit(offset + i, tt->split_bit_map))
403                                 return -ERANGE;
404
405         } else {
406                 u32 cs_count = DIV_ROUND_UP(sch_ep->maxpkt, FS_PAYLOAD_MAX);
407
408                 /*
409                  * usb_20 spec section11.18:
410                  * must never schedule Start-Split in Y6
411                  */
412                 if (start_ss == 6)
413                         return -ERANGE;
414
415                 /* one uframe for ss + one uframe for idle */
416                 start_cs = (start_ss + 2) % 8;
417                 last_cs = start_cs + cs_count - 1;
418
419                 if (last_cs > 7)
420                         return -ERANGE;
421
422                 if (sch_ep->ep_type == ISOC_IN_EP)
423                         extra_cs_count = (last_cs == 7) ? 1 : 2;
424                 else /*  ep_type : INTR IN / INTR OUT */
425                         extra_cs_count = (fs_budget_start == 6) ? 1 : 2;
426
427                 cs_count += extra_cs_count;
428                 if (cs_count > 7)
429                         cs_count = 7; /* HW limit */
430
431                 for (i = 0; i < cs_count + 2; i++) {
432                         if (test_bit(offset + i, tt->split_bit_map))
433                                 return -ERANGE;
434                 }
435
436                 sch_ep->cs_count = cs_count;
437                 /* one for ss, the other for idle */
438                 sch_ep->num_budget_microframes = cs_count + 2;
439
440                 /*
441                  * if interval=1, maxp >752, num_budge_micoframe is larger
442                  * than sch_ep->esit, will overstep boundary
443                  */
444                 if (sch_ep->num_budget_microframes > sch_ep->esit)
445                         sch_ep->num_budget_microframes = sch_ep->esit;
446         }
447
448         return 0;
449 }
450
451 static void update_sch_tt(struct usb_device *udev,
452         struct mu3h_sch_ep_info *sch_ep)
453 {
454         struct mu3h_sch_tt *tt = sch_ep->sch_tt;
455         u32 base, num_esit;
456         int i, j;
457
458         num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
459         for (i = 0; i < num_esit; i++) {
460                 base = sch_ep->offset + i * sch_ep->esit;
461                 for (j = 0; j < sch_ep->num_budget_microframes; j++)
462                         set_bit(base + j, tt->split_bit_map);
463         }
464
465         list_add_tail(&sch_ep->tt_endpoint, &tt->ep_list);
466 }
467
468 static int check_sch_bw(struct usb_device *udev,
469         struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep)
470 {
471         u32 offset;
472         u32 esit;
473         u32 min_bw;
474         u32 min_index;
475         u32 worst_bw;
476         u32 bw_boundary;
477         u32 min_num_budget;
478         u32 min_cs_count;
479         bool tt_offset_ok = false;
480         int ret;
481
482         esit = sch_ep->esit;
483
484         /*
485          * Search through all possible schedule microframes.
486          * and find a microframe where its worst bandwidth is minimum.
487          */
488         min_bw = ~0;
489         min_index = 0;
490         min_cs_count = sch_ep->cs_count;
491         min_num_budget = sch_ep->num_budget_microframes;
492         for (offset = 0; offset < esit; offset++) {
493                 if (is_fs_or_ls(udev->speed)) {
494                         ret = check_sch_tt(udev, sch_ep, offset);
495                         if (ret)
496                                 continue;
497                         else
498                                 tt_offset_ok = true;
499                 }
500
501                 if ((offset + sch_ep->num_budget_microframes) > sch_ep->esit)
502                         break;
503
504                 worst_bw = get_max_bw(sch_bw, sch_ep, offset);
505                 if (min_bw > worst_bw) {
506                         min_bw = worst_bw;
507                         min_index = offset;
508                         min_cs_count = sch_ep->cs_count;
509                         min_num_budget = sch_ep->num_budget_microframes;
510                 }
511                 if (min_bw == 0)
512                         break;
513         }
514
515         if (udev->speed == USB_SPEED_SUPER_PLUS)
516                 bw_boundary = SSP_BW_BOUNDARY;
517         else if (udev->speed == USB_SPEED_SUPER)
518                 bw_boundary = SS_BW_BOUNDARY;
519         else
520                 bw_boundary = HS_BW_BOUNDARY;
521
522         /* check bandwidth */
523         if (min_bw > bw_boundary)
524                 return -ERANGE;
525
526         sch_ep->offset = min_index;
527         sch_ep->cs_count = min_cs_count;
528         sch_ep->num_budget_microframes = min_num_budget;
529
530         if (is_fs_or_ls(udev->speed)) {
531                 /* all offset for tt is not ok*/
532                 if (!tt_offset_ok)
533                         return -ERANGE;
534
535                 update_sch_tt(udev, sch_ep);
536         }
537
538         /* update bus bandwidth info */
539         update_bus_bw(sch_bw, sch_ep, 1);
540
541         return 0;
542 }
543
544 static bool need_bw_sch(struct usb_host_endpoint *ep,
545         enum usb_device_speed speed, int has_tt)
546 {
547         /* only for periodic endpoints */
548         if (usb_endpoint_xfer_control(&ep->desc)
549                 || usb_endpoint_xfer_bulk(&ep->desc))
550                 return false;
551
552         /*
553          * for LS & FS periodic endpoints which its device is not behind
554          * a TT are also ignored, root-hub will schedule them directly,
555          * but need set @bpkts field of endpoint context to 1.
556          */
557         if (is_fs_or_ls(speed) && !has_tt)
558                 return false;
559
560         return true;
561 }
562
563 int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk)
564 {
565         struct xhci_hcd *xhci = hcd_to_xhci(mtk->hcd);
566         struct mu3h_sch_bw_info *sch_array;
567         int num_usb_bus;
568         int i;
569
570         /* ss IN and OUT are separated */
571         num_usb_bus = xhci->usb3_rhub.num_ports * 2 + xhci->usb2_rhub.num_ports;
572
573         sch_array = kcalloc(num_usb_bus, sizeof(*sch_array), GFP_KERNEL);
574         if (sch_array == NULL)
575                 return -ENOMEM;
576
577         for (i = 0; i < num_usb_bus; i++)
578                 INIT_LIST_HEAD(&sch_array[i].bw_ep_list);
579
580         mtk->sch_array = sch_array;
581
582         return 0;
583 }
584 EXPORT_SYMBOL_GPL(xhci_mtk_sch_init);
585
586 void xhci_mtk_sch_exit(struct xhci_hcd_mtk *mtk)
587 {
588         kfree(mtk->sch_array);
589 }
590 EXPORT_SYMBOL_GPL(xhci_mtk_sch_exit);
591
592 int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
593                 struct usb_host_endpoint *ep)
594 {
595         struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
596         struct xhci_hcd *xhci;
597         struct xhci_ep_ctx *ep_ctx;
598         struct xhci_slot_ctx *slot_ctx;
599         struct xhci_virt_device *virt_dev;
600         struct mu3h_sch_bw_info *sch_bw;
601         struct mu3h_sch_ep_info *sch_ep;
602         struct mu3h_sch_bw_info *sch_array;
603         unsigned int ep_index;
604         int bw_index;
605         int ret = 0;
606
607         xhci = hcd_to_xhci(hcd);
608         virt_dev = xhci->devs[udev->slot_id];
609         ep_index = xhci_get_endpoint_index(&ep->desc);
610         slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
611         ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
612         sch_array = mtk->sch_array;
613
614         xhci_dbg(xhci, "%s() type:%d, speed:%d, mpkt:%d, dir:%d, ep:%p\n",
615                 __func__, usb_endpoint_type(&ep->desc), udev->speed,
616                 usb_endpoint_maxp(&ep->desc),
617                 usb_endpoint_dir_in(&ep->desc), ep);
618
619         if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT)) {
620                 /*
621                  * set @bpkts to 1 if it is LS or FS periodic endpoint, and its
622                  * device does not connected through an external HS hub
623                  */
624                 if (usb_endpoint_xfer_int(&ep->desc)
625                         || usb_endpoint_xfer_isoc(&ep->desc))
626                         ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(1));
627
628                 return 0;
629         }
630
631         bw_index = get_bw_index(xhci, udev, ep);
632         sch_bw = &sch_array[bw_index];
633
634         sch_ep = create_sch_ep(udev, ep, ep_ctx);
635         if (IS_ERR_OR_NULL(sch_ep))
636                 return -ENOMEM;
637
638         setup_sch_info(udev, ep_ctx, sch_ep);
639
640         ret = check_sch_bw(udev, sch_bw, sch_ep);
641         if (ret) {
642                 xhci_err(xhci, "Not enough bandwidth!\n");
643                 if (is_fs_or_ls(udev->speed))
644                         drop_tt(udev);
645
646                 kfree(sch_ep);
647                 return -ENOSPC;
648         }
649
650         list_add_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list);
651
652         ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(sch_ep->pkts)
653                 | EP_BCSCOUNT(sch_ep->cs_count) | EP_BBM(sch_ep->burst_mode));
654         ep_ctx->reserved[1] |= cpu_to_le32(EP_BOFFSET(sch_ep->offset)
655                 | EP_BREPEAT(sch_ep->repeat));
656
657         xhci_dbg(xhci, " PKTS:%x, CSCOUNT:%x, BM:%x, OFFSET:%x, REPEAT:%x\n",
658                         sch_ep->pkts, sch_ep->cs_count, sch_ep->burst_mode,
659                         sch_ep->offset, sch_ep->repeat);
660
661         return 0;
662 }
663 EXPORT_SYMBOL_GPL(xhci_mtk_add_ep_quirk);
664
665 void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
666                 struct usb_host_endpoint *ep)
667 {
668         struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
669         struct xhci_hcd *xhci;
670         struct xhci_slot_ctx *slot_ctx;
671         struct xhci_virt_device *virt_dev;
672         struct mu3h_sch_bw_info *sch_array;
673         struct mu3h_sch_bw_info *sch_bw;
674         struct mu3h_sch_ep_info *sch_ep;
675         int bw_index;
676
677         xhci = hcd_to_xhci(hcd);
678         virt_dev = xhci->devs[udev->slot_id];
679         slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
680         sch_array = mtk->sch_array;
681
682         xhci_dbg(xhci, "%s() type:%d, speed:%d, mpks:%d, dir:%d, ep:%p\n",
683                 __func__, usb_endpoint_type(&ep->desc), udev->speed,
684                 usb_endpoint_maxp(&ep->desc),
685                 usb_endpoint_dir_in(&ep->desc), ep);
686
687         if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT))
688                 return;
689
690         bw_index = get_bw_index(xhci, udev, ep);
691         sch_bw = &sch_array[bw_index];
692
693         list_for_each_entry(sch_ep, &sch_bw->bw_ep_list, endpoint) {
694                 if (sch_ep->ep == ep) {
695                         update_bus_bw(sch_bw, sch_ep, 0);
696                         list_del(&sch_ep->endpoint);
697                         if (is_fs_or_ls(udev->speed)) {
698                                 list_del(&sch_ep->tt_endpoint);
699                                 drop_tt(udev);
700                         }
701                         kfree(sch_ep);
702                         break;
703                 }
704         }
705 }
706 EXPORT_SYMBOL_GPL(xhci_mtk_drop_ep_quirk);