• Home
  • Raw
  • Download

Lines Matching +full:additional +full:- +full:devs

1 // SPDX-License-Identifier: GPL-2.0
14 #include "xhci-mtk.h"
18 /* table 5-5. High-speed Isoc Transaction Limits in usb_20 spec */
46 return "Can't schedule Start-Split in Y6"; in sch_error_string()
48 return "Can't find a suitable Start-Split location"; in sch_error_string()
50 return "The last Complete-Split is greater than 7"; in sch_error_string()
75 * SSport0-OUT, SSport0-IN, ..., SSportX-OUT, SSportX-IN, HSport0, ..., HSportY
83 virt_dev = xhci->devs[udev->slot_id]; in get_bw_index()
85 if (udev->speed >= USB_SPEED_SUPER) { in get_bw_index()
86 if (usb_endpoint_dir_out(&ep->desc)) in get_bw_index()
87 bw_index = (virt_dev->real_port - 1) * 2; in get_bw_index()
89 bw_index = (virt_dev->real_port - 1) * 2 + 1; in get_bw_index()
92 bw_index = virt_dev->real_port + xhci->usb3_rhub.num_ports - 1; in get_bw_index()
102 esit = 1 << CTX_TO_EP_INTERVAL(le32_to_cpu(ep_ctx->ep_info)); in get_esit()
111 struct usb_tt *utt = udev->tt; in find_tt()
125 if (utt->multi) { in find_tt()
126 tt_index = utt->hcpriv; in find_tt()
128 tt_index = kcalloc(utt->hub->maxchild, in find_tt()
131 return ERR_PTR(-ENOMEM); in find_tt()
132 utt->hcpriv = tt_index; in find_tt()
135 port = udev->ttport - 1; in find_tt()
139 ptt = (struct mu3h_sch_tt **) &utt->hcpriv; in find_tt()
147 utt->hcpriv = NULL; in find_tt()
150 return ERR_PTR(-ENOMEM); in find_tt()
152 INIT_LIST_HEAD(&tt->ep_list); in find_tt()
153 tt->usb_tt = utt; in find_tt()
154 tt->tt_port = port; in find_tt()
164 struct usb_tt *utt = udev->tt; in drop_tt()
168 if (!utt || !utt->hcpriv) in drop_tt()
172 if (utt->multi) { in drop_tt()
173 tt_index = utt->hcpriv; in drop_tt()
174 ptt = &tt_index[udev->ttport - 1]; in drop_tt()
176 for (i = 0; i < utt->hub->maxchild; ++i) in drop_tt()
180 ptt = (struct mu3h_sch_tt **)&utt->hcpriv; in drop_tt()
184 if (!tt || !list_empty(&tt->ep_list)) in drop_tt()
191 utt->hcpriv = NULL; in drop_tt()
204 if (is_fs_or_ls(udev->speed)) in create_sch_ep()
206 else if ((udev->speed >= USB_SPEED_SUPER) in create_sch_ep()
207 && usb_endpoint_xfer_isoc(&ep->desc)) in create_sch_ep()
216 return ERR_PTR(-ENOMEM); in create_sch_ep()
218 if (is_fs_or_ls(udev->speed)) { in create_sch_ep()
222 return ERR_PTR(-ENOMEM); in create_sch_ep()
226 sch_ep->sch_tt = tt; in create_sch_ep()
227 sch_ep->ep = ep; in create_sch_ep()
228 INIT_LIST_HEAD(&sch_ep->endpoint); in create_sch_ep()
229 INIT_LIST_HEAD(&sch_ep->tt_endpoint); in create_sch_ep()
243 u32 *bwb_table = sch_ep->bw_budget_table; in setup_sch_info()
246 ep_type = CTX_TO_EP_TYPE(le32_to_cpu(ep_ctx->ep_info2)); in setup_sch_info()
247 maxpkt = MAX_PACKET_DECODED(le32_to_cpu(ep_ctx->ep_info2)); in setup_sch_info()
248 max_burst = CTX_TO_MAX_BURST(le32_to_cpu(ep_ctx->ep_info2)); in setup_sch_info()
249 mult = CTX_TO_EP_MULT(le32_to_cpu(ep_ctx->ep_info)); in setup_sch_info()
252 le32_to_cpu(ep_ctx->ep_info)) << 16) | in setup_sch_info()
253 CTX_TO_MAX_ESIT_PAYLOAD(le32_to_cpu(ep_ctx->tx_info)); in setup_sch_info()
255 sch_ep->esit = get_esit(ep_ctx); in setup_sch_info()
256 sch_ep->ep_type = ep_type; in setup_sch_info()
257 sch_ep->maxpkt = maxpkt; in setup_sch_info()
258 sch_ep->offset = 0; in setup_sch_info()
259 sch_ep->burst_mode = 0; in setup_sch_info()
260 sch_ep->repeat = 0; in setup_sch_info()
262 if (udev->speed == USB_SPEED_HIGH) { in setup_sch_info()
263 sch_ep->cs_count = 0; in setup_sch_info()
270 sch_ep->num_budget_microframes = 1; in setup_sch_info()
274 * @max_burst is the number of additional transactions in setup_sch_info()
277 sch_ep->pkts = max_burst + 1; in setup_sch_info()
278 sch_ep->bw_cost_per_microframe = maxpkt * sch_ep->pkts; in setup_sch_info()
279 bwb_table[0] = sch_ep->bw_cost_per_microframe; in setup_sch_info()
280 } else if (udev->speed >= USB_SPEED_SUPER) { in setup_sch_info()
282 sch_ep->cs_count = 0; in setup_sch_info()
283 sch_ep->burst_mode = 1; in setup_sch_info()
294 sch_ep->pkts = esit_pkts; in setup_sch_info()
295 sch_ep->num_budget_microframes = 1; in setup_sch_info()
296 bwb_table[0] = maxpkt * sch_ep->pkts; in setup_sch_info()
302 if (sch_ep->esit == 1) in setup_sch_info()
303 sch_ep->pkts = esit_pkts; in setup_sch_info()
304 else if (esit_pkts <= sch_ep->esit) in setup_sch_info()
305 sch_ep->pkts = 1; in setup_sch_info()
307 sch_ep->pkts = roundup_pow_of_two(esit_pkts) in setup_sch_info()
308 / sch_ep->esit; in setup_sch_info()
310 sch_ep->num_budget_microframes = in setup_sch_info()
311 DIV_ROUND_UP(esit_pkts, sch_ep->pkts); in setup_sch_info()
313 sch_ep->repeat = !!(sch_ep->num_budget_microframes > 1); in setup_sch_info()
314 sch_ep->bw_cost_per_microframe = maxpkt * sch_ep->pkts; in setup_sch_info()
316 remainder = sch_ep->bw_cost_per_microframe; in setup_sch_info()
317 remainder *= sch_ep->num_budget_microframes; in setup_sch_info()
318 remainder -= (maxpkt * esit_pkts); in setup_sch_info()
319 for (i = 0; i < sch_ep->num_budget_microframes - 1; i++) in setup_sch_info()
320 bwb_table[i] = sch_ep->bw_cost_per_microframe; in setup_sch_info()
325 } else if (is_fs_or_ls(udev->speed)) { in setup_sch_info()
326 sch_ep->pkts = 1; /* at most one packet for each microframe */ in setup_sch_info()
332 sch_ep->cs_count = DIV_ROUND_UP(maxpkt, FS_PAYLOAD_MAX); in setup_sch_info()
333 sch_ep->num_budget_microframes = sch_ep->cs_count; in setup_sch_info()
334 sch_ep->bw_cost_per_microframe = in setup_sch_info()
339 for (i = 0; i < sch_ep->num_budget_microframes; i++) in setup_sch_info()
340 bwb_table[i] = sch_ep->bw_cost_per_microframe; in setup_sch_info()
343 bwb_table[0] = sch_ep->bw_cost_per_microframe; in setup_sch_info()
354 bwb_table[i] = sch_ep->bw_cost_per_microframe; in setup_sch_info()
369 num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; in get_max_bw()
371 u32 base = offset + i * sch_ep->esit; in get_max_bw()
373 for (j = 0; j < sch_ep->num_budget_microframes; j++) { in get_max_bw()
374 bw = sch_bw->bus_bw[base + j] + in get_max_bw()
375 sch_ep->bw_budget_table[j]; in get_max_bw()
391 num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; in update_bus_bw()
393 base = sch_ep->offset + i * sch_ep->esit; in update_bus_bw()
394 for (j = 0; j < sch_ep->num_budget_microframes; j++) { in update_bus_bw()
396 sch_bw->bus_bw[base + j] += in update_bus_bw()
397 sch_ep->bw_budget_table[j]; in update_bus_bw()
399 sch_bw->bus_bw[base + j] -= in update_bus_bw()
400 sch_ep->bw_budget_table[j]; in update_bus_bw()
407 struct mu3h_sch_tt *tt = sch_ep->sch_tt; in check_fs_bus_bw()
411 u8 uframes = DIV_ROUND_UP(sch_ep->maxpkt, FS_PAYLOAD_MAX); in check_fs_bus_bw()
413 num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; in check_fs_bus_bw()
415 if (sch_ep->ep_type == INT_IN_EP || sch_ep->ep_type == ISOC_IN_EP) in check_fs_bus_bw()
419 base = offset + i * sch_ep->esit; in check_fs_bus_bw()
422 tmp = tt->fs_bus_bw[base + j] + sch_ep->bw_cost_per_microframe; in check_fs_bus_bw()
424 return -ESCH_BW_OVERFLOW; in check_fs_bus_bw()
440 if (sch_ep->ep_type == ISOC_OUT_EP) { in check_sch_tt()
441 last_ss = start_ss + sch_ep->cs_count - 1; in check_sch_tt()
445 * must never schedule Start-Split in Y6 in check_sch_tt()
448 return -ESCH_SS_Y6; in check_sch_tt()
451 u32 cs_count = DIV_ROUND_UP(sch_ep->maxpkt, FS_PAYLOAD_MAX); in check_sch_tt()
455 * must never schedule Start-Split in Y6 in check_sch_tt()
458 return -ESCH_SS_Y6; in check_sch_tt()
462 last_cs = start_cs + cs_count - 1; in check_sch_tt()
465 return -ESCH_CS_OVERFLOW; in check_sch_tt()
467 if (sch_ep->ep_type == ISOC_IN_EP) in check_sch_tt()
476 sch_ep->cs_count = cs_count; in check_sch_tt()
478 sch_ep->num_budget_microframes = cs_count + 2; in check_sch_tt()
482 * than sch_ep->esit, will overstep boundary in check_sch_tt()
484 if (sch_ep->num_budget_microframes > sch_ep->esit) in check_sch_tt()
485 sch_ep->num_budget_microframes = sch_ep->esit; in check_sch_tt()
494 struct mu3h_sch_tt *tt = sch_ep->sch_tt; in update_sch_tt()
498 int offset = sch_ep->offset; in update_sch_tt()
499 u8 uframes = DIV_ROUND_UP(sch_ep->maxpkt, FS_PAYLOAD_MAX); in update_sch_tt()
501 num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; in update_sch_tt()
504 bw_updated = sch_ep->bw_cost_per_microframe; in update_sch_tt()
506 bw_updated = -sch_ep->bw_cost_per_microframe; in update_sch_tt()
508 if (sch_ep->ep_type == INT_IN_EP || sch_ep->ep_type == ISOC_IN_EP) in update_sch_tt()
512 base = offset + i * sch_ep->esit; in update_sch_tt()
515 tt->fs_bus_bw[base + j] += bw_updated; in update_sch_tt()
519 list_add_tail(&sch_ep->tt_endpoint, &tt->ep_list); in update_sch_tt()
521 list_del(&sch_ep->tt_endpoint); in update_sch_tt()
527 if (sch_ep->sch_tt) in load_ep_bw()
532 sch_ep->allocated = loaded; in load_ep_bw()
539 u32 boundary = sch_ep->esit; in get_esit_boundary()
541 if (sch_ep->sch_tt) { /* LS/FS with TT */ in get_esit_boundary()
547 if (sch_ep->ep_type == ISOC_OUT_EP && boundary > 1) in get_esit_boundary()
548 boundary--; in get_esit_boundary()
573 min_cs_count = sch_ep->cs_count; in check_sch_bw()
574 min_num_budget = sch_ep->num_budget_microframes; in check_sch_bw()
576 for (offset = 0; offset < sch_ep->esit; offset++) { in check_sch_bw()
577 if (sch_ep->sch_tt) { in check_sch_bw()
583 if ((offset + sch_ep->num_budget_microframes) > esit_boundary) in check_sch_bw()
590 min_cs_count = sch_ep->cs_count; in check_sch_bw()
591 min_num_budget = sch_ep->num_budget_microframes; in check_sch_bw()
597 if (udev->speed == USB_SPEED_SUPER_PLUS) in check_sch_bw()
599 else if (udev->speed == USB_SPEED_SUPER) in check_sch_bw()
606 return ret ? ret : -ESCH_BW_OVERFLOW; in check_sch_bw()
608 sch_ep->offset = min_index; in check_sch_bw()
609 sch_ep->cs_count = min_cs_count; in check_sch_bw()
610 sch_ep->num_budget_microframes = min_num_budget; in check_sch_bw()
619 if (sch_ep->allocated) in destroy_sch_ep()
622 if (sch_ep->sch_tt) in destroy_sch_ep()
625 list_del(&sch_ep->endpoint); in destroy_sch_ep()
633 if (usb_endpoint_xfer_control(&ep->desc) in need_bw_sch()
634 || usb_endpoint_xfer_bulk(&ep->desc)) in need_bw_sch()
639 * a TT are also ignored, root-hub will schedule them directly, in need_bw_sch()
646 if (usb_endpoint_maxp(&ep->desc) == 0) in need_bw_sch()
654 struct xhci_hcd *xhci = hcd_to_xhci(mtk->hcd); in xhci_mtk_sch_init()
660 num_usb_bus = xhci->usb3_rhub.num_ports * 2 + xhci->usb2_rhub.num_ports; in xhci_mtk_sch_init()
664 return -ENOMEM; in xhci_mtk_sch_init()
669 mtk->sch_array = sch_array; in xhci_mtk_sch_init()
671 INIT_LIST_HEAD(&mtk->bw_ep_chk_list); in xhci_mtk_sch_init()
679 kfree(mtk->sch_array); in xhci_mtk_sch_exit()
695 virt_dev = xhci->devs[udev->slot_id]; in xhci_mtk_add_ep_quirk()
696 ep_index = xhci_get_endpoint_index(&ep->desc); in xhci_mtk_add_ep_quirk()
697 slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); in xhci_mtk_add_ep_quirk()
698 ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); in xhci_mtk_add_ep_quirk()
701 __func__, usb_endpoint_type(&ep->desc), udev->speed, in xhci_mtk_add_ep_quirk()
702 usb_endpoint_maxp(&ep->desc), in xhci_mtk_add_ep_quirk()
703 usb_endpoint_dir_in(&ep->desc), ep); in xhci_mtk_add_ep_quirk()
705 if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT)) { in xhci_mtk_add_ep_quirk()
710 if (usb_endpoint_xfer_int(&ep->desc) in xhci_mtk_add_ep_quirk()
711 || usb_endpoint_xfer_isoc(&ep->desc)) in xhci_mtk_add_ep_quirk()
712 ep_ctx->reserved[0] = cpu_to_le32(EP_BPKTS(1)); in xhci_mtk_add_ep_quirk()
719 return -ENOMEM; in xhci_mtk_add_ep_quirk()
723 list_add_tail(&sch_ep->endpoint, &mtk->bw_ep_chk_list); in xhci_mtk_add_ep_quirk()
742 virt_dev = xhci->devs[udev->slot_id]; in xhci_mtk_drop_ep_quirk()
743 slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); in xhci_mtk_drop_ep_quirk()
744 sch_array = mtk->sch_array; in xhci_mtk_drop_ep_quirk()
747 __func__, usb_endpoint_type(&ep->desc), udev->speed, in xhci_mtk_drop_ep_quirk()
748 usb_endpoint_maxp(&ep->desc), in xhci_mtk_drop_ep_quirk()
749 usb_endpoint_dir_in(&ep->desc), ep); in xhci_mtk_drop_ep_quirk()
751 if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT)) in xhci_mtk_drop_ep_quirk()
757 list_for_each_entry_safe(sch_ep, tmp, &sch_bw->bw_ep_list, endpoint) { in xhci_mtk_drop_ep_quirk()
758 if (sch_ep->ep == ep) { in xhci_mtk_drop_ep_quirk()
770 struct xhci_virt_device *virt_dev = xhci->devs[udev->slot_id]; in xhci_mtk_check_bandwidth()
775 xhci_dbg(xhci, "%s() udev %s\n", __func__, dev_name(&udev->dev)); in xhci_mtk_check_bandwidth()
777 list_for_each_entry(sch_ep, &mtk->bw_ep_chk_list, endpoint) { in xhci_mtk_check_bandwidth()
778 bw_index = get_bw_index(xhci, udev, sch_ep->ep); in xhci_mtk_check_bandwidth()
779 sch_bw = &mtk->sch_array[bw_index]; in xhci_mtk_check_bandwidth()
784 sch_error_string(-ret)); in xhci_mtk_check_bandwidth()
785 return -ENOSPC; in xhci_mtk_check_bandwidth()
789 list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint) { in xhci_mtk_check_bandwidth()
791 struct usb_host_endpoint *ep = sch_ep->ep; in xhci_mtk_check_bandwidth()
792 unsigned int ep_index = xhci_get_endpoint_index(&ep->desc); in xhci_mtk_check_bandwidth()
795 sch_bw = &mtk->sch_array[bw_index]; in xhci_mtk_check_bandwidth()
797 list_move_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list); in xhci_mtk_check_bandwidth()
799 ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); in xhci_mtk_check_bandwidth()
800 ep_ctx->reserved[0] = cpu_to_le32(EP_BPKTS(sch_ep->pkts) in xhci_mtk_check_bandwidth()
801 | EP_BCSCOUNT(sch_ep->cs_count) in xhci_mtk_check_bandwidth()
802 | EP_BBM(sch_ep->burst_mode)); in xhci_mtk_check_bandwidth()
803 ep_ctx->reserved[1] = cpu_to_le32(EP_BOFFSET(sch_ep->offset) in xhci_mtk_check_bandwidth()
804 | EP_BREPEAT(sch_ep->repeat)); in xhci_mtk_check_bandwidth()
807 sch_ep->pkts, sch_ep->cs_count, sch_ep->burst_mode, in xhci_mtk_check_bandwidth()
808 sch_ep->offset, sch_ep->repeat); in xhci_mtk_check_bandwidth()
823 xhci_dbg(xhci, "%s() udev %s\n", __func__, dev_name(&udev->dev)); in xhci_mtk_reset_bandwidth()
825 list_for_each_entry_safe(sch_ep, tmp, &mtk->bw_ep_chk_list, endpoint) { in xhci_mtk_reset_bandwidth()
826 bw_index = get_bw_index(xhci, udev, sch_ep->ep); in xhci_mtk_reset_bandwidth()
827 sch_bw = &mtk->sch_array[bw_index]; in xhci_mtk_reset_bandwidth()