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 SS_BW_BOUNDARY 51000 17 /* table 5-5. High-speed Isoc Transaction Limits in usb_20 spec */ 18 #define HS_BW_BOUNDARY 6144 19 /* usb2 spec section11.18.1: at most 188 FS bytes per microframe */ 20 #define FS_PAYLOAD_MAX 188 21 22 /* mtk scheduler bitmasks */ 23 #define EP_BPKTS(p) ((p) & 0x3f) 24 #define EP_BCSCOUNT(p) (((p) & 0x7) << 8) 25 #define EP_BBM(p) ((p) << 11) 26 #define EP_BOFFSET(p) ((p) & 0x3fff) 27 #define EP_BREPEAT(p) (((p) & 0x7fff) << 16) 28 29 static int is_fs_or_ls(enum usb_device_speed speed) 30 { 31 return speed == USB_SPEED_FULL || speed == USB_SPEED_LOW; 32 } 33 34 /* 35 * get the index of bandwidth domains array which @ep belongs to. 36 * 37 * the bandwidth domain array is saved to @sch_array of struct xhci_hcd_mtk, 38 * each HS root port is treated as a single bandwidth domain, 39 * but each SS root port is treated as two bandwidth domains, one for IN eps, 40 * one for OUT eps. 41 * @real_port value is defined as follow according to xHCI spec: 42 * 1 for SSport0, ..., N+1 for SSportN, N+2 for HSport0, N+3 for HSport1, etc 43 * so the bandwidth domain array is organized as follow for simplification: 44 * SSport0-OUT, SSport0-IN, ..., SSportX-OUT, SSportX-IN, HSport0, ..., HSportY 45 */ 46 static int get_bw_index(struct xhci_hcd *xhci, struct usb_device *udev, 47 struct usb_host_endpoint *ep) 48 { 49 struct xhci_virt_device *virt_dev; 50 int bw_index; 51 52 virt_dev = xhci->devs[udev->slot_id]; 53 54 if (udev->speed == USB_SPEED_SUPER) { 55 if (usb_endpoint_dir_out(&ep->desc)) 56 bw_index = (virt_dev->real_port - 1) * 2; 57 else 58 bw_index = (virt_dev->real_port - 1) * 2 + 1; 59 } else { 60 /* add one more for each SS port */ 61 bw_index = virt_dev->real_port + xhci->num_usb3_ports - 1; 62 } 63 64 return bw_index; 65 } 66 67 static void setup_sch_info(struct usb_device *udev, 68 struct xhci_ep_ctx *ep_ctx, struct mu3h_sch_ep_info *sch_ep) 69 { 70 u32 ep_type; 71 u32 ep_interval; 72 u32 max_packet_size; 73 u32 max_burst; 74 u32 mult; 75 u32 esit_pkts; 76 77 ep_type = CTX_TO_EP_TYPE(le32_to_cpu(ep_ctx->ep_info2)); 78 ep_interval = CTX_TO_EP_INTERVAL(le32_to_cpu(ep_ctx->ep_info)); 79 max_packet_size = MAX_PACKET_DECODED(le32_to_cpu(ep_ctx->ep_info2)); 80 max_burst = CTX_TO_MAX_BURST(le32_to_cpu(ep_ctx->ep_info2)); 81 mult = CTX_TO_EP_MULT(le32_to_cpu(ep_ctx->ep_info)); 82 83 sch_ep->esit = 1 << ep_interval; 84 sch_ep->offset = 0; 85 sch_ep->burst_mode = 0; 86 87 if (udev->speed == USB_SPEED_HIGH) { 88 sch_ep->cs_count = 0; 89 90 /* 91 * usb_20 spec section5.9 92 * a single microframe is enough for HS synchromous endpoints 93 * in a interval 94 */ 95 sch_ep->num_budget_microframes = 1; 96 sch_ep->repeat = 0; 97 98 /* 99 * xHCI spec section6.2.3.4 100 * @max_burst is the number of additional transactions 101 * opportunities per microframe 102 */ 103 sch_ep->pkts = max_burst + 1; 104 sch_ep->bw_cost_per_microframe = max_packet_size * sch_ep->pkts; 105 } else if (udev->speed == USB_SPEED_SUPER) { 106 /* usb3_r1 spec section4.4.7 & 4.4.8 */ 107 sch_ep->cs_count = 0; 108 esit_pkts = (mult + 1) * (max_burst + 1); 109 if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) { 110 sch_ep->pkts = esit_pkts; 111 sch_ep->num_budget_microframes = 1; 112 sch_ep->repeat = 0; 113 } 114 115 if (ep_type == ISOC_IN_EP || ep_type == ISOC_OUT_EP) { 116 if (esit_pkts <= sch_ep->esit) 117 sch_ep->pkts = 1; 118 else 119 sch_ep->pkts = roundup_pow_of_two(esit_pkts) 120 / sch_ep->esit; 121 122 sch_ep->num_budget_microframes = 123 DIV_ROUND_UP(esit_pkts, sch_ep->pkts); 124 125 if (sch_ep->num_budget_microframes > 1) 126 sch_ep->repeat = 1; 127 else 128 sch_ep->repeat = 0; 129 } 130 sch_ep->bw_cost_per_microframe = max_packet_size * sch_ep->pkts; 131 } else if (is_fs_or_ls(udev->speed)) { 132 133 /* 134 * usb_20 spec section11.18.4 135 * assume worst cases 136 */ 137 sch_ep->repeat = 0; 138 sch_ep->pkts = 1; /* at most one packet for each microframe */ 139 if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) { 140 sch_ep->cs_count = 3; /* at most need 3 CS*/ 141 /* one for SS and one for budgeted transaction */ 142 sch_ep->num_budget_microframes = sch_ep->cs_count + 2; 143 sch_ep->bw_cost_per_microframe = max_packet_size; 144 } 145 if (ep_type == ISOC_OUT_EP) { 146 147 /* 148 * the best case FS budget assumes that 188 FS bytes 149 * occur in each microframe 150 */ 151 sch_ep->num_budget_microframes = DIV_ROUND_UP( 152 max_packet_size, FS_PAYLOAD_MAX); 153 sch_ep->bw_cost_per_microframe = FS_PAYLOAD_MAX; 154 sch_ep->cs_count = sch_ep->num_budget_microframes; 155 } 156 if (ep_type == ISOC_IN_EP) { 157 /* at most need additional two CS. */ 158 sch_ep->cs_count = DIV_ROUND_UP( 159 max_packet_size, FS_PAYLOAD_MAX) + 2; 160 sch_ep->num_budget_microframes = sch_ep->cs_count + 2; 161 sch_ep->bw_cost_per_microframe = FS_PAYLOAD_MAX; 162 } 163 } 164 } 165 166 /* Get maximum bandwidth when we schedule at offset slot. */ 167 static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw, 168 struct mu3h_sch_ep_info *sch_ep, u32 offset) 169 { 170 u32 num_esit; 171 u32 max_bw = 0; 172 int i; 173 int j; 174 175 num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; 176 for (i = 0; i < num_esit; i++) { 177 u32 base = offset + i * sch_ep->esit; 178 179 for (j = 0; j < sch_ep->num_budget_microframes; j++) { 180 if (sch_bw->bus_bw[base + j] > max_bw) 181 max_bw = sch_bw->bus_bw[base + j]; 182 } 183 } 184 return max_bw; 185 } 186 187 static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw, 188 struct mu3h_sch_ep_info *sch_ep, int bw_cost) 189 { 190 u32 num_esit; 191 u32 base; 192 int i; 193 int j; 194 195 num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; 196 for (i = 0; i < num_esit; i++) { 197 base = sch_ep->offset + i * sch_ep->esit; 198 for (j = 0; j < sch_ep->num_budget_microframes; j++) 199 sch_bw->bus_bw[base + j] += bw_cost; 200 } 201 } 202 203 static int check_sch_bw(struct usb_device *udev, 204 struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep) 205 { 206 u32 offset; 207 u32 esit; 208 u32 num_budget_microframes; 209 u32 min_bw; 210 u32 min_index; 211 u32 worst_bw; 212 u32 bw_boundary; 213 214 if (sch_ep->esit > XHCI_MTK_MAX_ESIT) 215 sch_ep->esit = XHCI_MTK_MAX_ESIT; 216 217 esit = sch_ep->esit; 218 num_budget_microframes = sch_ep->num_budget_microframes; 219 220 /* 221 * Search through all possible schedule microframes. 222 * and find a microframe where its worst bandwidth is minimum. 223 */ 224 min_bw = ~0; 225 min_index = 0; 226 for (offset = 0; offset < esit; offset++) { 227 if ((offset + num_budget_microframes) > sch_ep->esit) 228 break; 229 230 /* 231 * usb_20 spec section11.18: 232 * must never schedule Start-Split in Y6 233 */ 234 if (is_fs_or_ls(udev->speed) && (offset % 8 == 6)) 235 continue; 236 237 worst_bw = get_max_bw(sch_bw, sch_ep, offset); 238 if (min_bw > worst_bw) { 239 min_bw = worst_bw; 240 min_index = offset; 241 } 242 if (min_bw == 0) 243 break; 244 } 245 sch_ep->offset = min_index; 246 247 bw_boundary = (udev->speed == USB_SPEED_SUPER) 248 ? SS_BW_BOUNDARY : HS_BW_BOUNDARY; 249 250 /* check bandwidth */ 251 if (min_bw + sch_ep->bw_cost_per_microframe > bw_boundary) 252 return -ERANGE; 253 254 /* update bus bandwidth info */ 255 update_bus_bw(sch_bw, sch_ep, sch_ep->bw_cost_per_microframe); 256 257 return 0; 258 } 259 260 static bool need_bw_sch(struct usb_host_endpoint *ep, 261 enum usb_device_speed speed, int has_tt) 262 { 263 /* only for periodic endpoints */ 264 if (usb_endpoint_xfer_control(&ep->desc) 265 || usb_endpoint_xfer_bulk(&ep->desc)) 266 return false; 267 268 /* 269 * for LS & FS periodic endpoints which its device is not behind 270 * a TT are also ignored, root-hub will schedule them directly, 271 * but need set @bpkts field of endpoint context to 1. 272 */ 273 if (is_fs_or_ls(speed) && !has_tt) 274 return false; 275 276 return true; 277 } 278 279 int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk) 280 { 281 struct xhci_hcd *xhci = hcd_to_xhci(mtk->hcd); 282 struct mu3h_sch_bw_info *sch_array; 283 int num_usb_bus; 284 int i; 285 286 /* ss IN and OUT are separated */ 287 num_usb_bus = xhci->num_usb3_ports * 2 + xhci->num_usb2_ports; 288 289 sch_array = kcalloc(num_usb_bus, sizeof(*sch_array), GFP_KERNEL); 290 if (sch_array == NULL) 291 return -ENOMEM; 292 293 for (i = 0; i < num_usb_bus; i++) 294 INIT_LIST_HEAD(&sch_array[i].bw_ep_list); 295 296 mtk->sch_array = sch_array; 297 298 return 0; 299 } 300 EXPORT_SYMBOL_GPL(xhci_mtk_sch_init); 301 302 void xhci_mtk_sch_exit(struct xhci_hcd_mtk *mtk) 303 { 304 kfree(mtk->sch_array); 305 } 306 EXPORT_SYMBOL_GPL(xhci_mtk_sch_exit); 307 308 int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, 309 struct usb_host_endpoint *ep) 310 { 311 struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd); 312 struct xhci_hcd *xhci; 313 struct xhci_ep_ctx *ep_ctx; 314 struct xhci_slot_ctx *slot_ctx; 315 struct xhci_virt_device *virt_dev; 316 struct mu3h_sch_bw_info *sch_bw; 317 struct mu3h_sch_ep_info *sch_ep; 318 struct mu3h_sch_bw_info *sch_array; 319 unsigned int ep_index; 320 int bw_index; 321 int ret = 0; 322 323 xhci = hcd_to_xhci(hcd); 324 virt_dev = xhci->devs[udev->slot_id]; 325 ep_index = xhci_get_endpoint_index(&ep->desc); 326 slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); 327 ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); 328 sch_array = mtk->sch_array; 329 330 xhci_dbg(xhci, "%s() type:%d, speed:%d, mpkt:%d, dir:%d, ep:%p\n", 331 __func__, usb_endpoint_type(&ep->desc), udev->speed, 332 usb_endpoint_maxp(&ep->desc), 333 usb_endpoint_dir_in(&ep->desc), ep); 334 335 if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT)) { 336 /* 337 * set @bpkts to 1 if it is LS or FS periodic endpoint, and its 338 * device does not connected through an external HS hub 339 */ 340 if (usb_endpoint_xfer_int(&ep->desc) 341 || usb_endpoint_xfer_isoc(&ep->desc)) 342 ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(1)); 343 344 return 0; 345 } 346 347 bw_index = get_bw_index(xhci, udev, ep); 348 sch_bw = &sch_array[bw_index]; 349 350 sch_ep = kzalloc(sizeof(struct mu3h_sch_ep_info), GFP_NOIO); 351 if (!sch_ep) 352 return -ENOMEM; 353 354 setup_sch_info(udev, ep_ctx, sch_ep); 355 356 ret = check_sch_bw(udev, sch_bw, sch_ep); 357 if (ret) { 358 xhci_err(xhci, "Not enough bandwidth!\n"); 359 kfree(sch_ep); 360 return -ENOSPC; 361 } 362 363 list_add_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list); 364 sch_ep->ep = ep; 365 366 ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(sch_ep->pkts) 367 | EP_BCSCOUNT(sch_ep->cs_count) | EP_BBM(sch_ep->burst_mode)); 368 ep_ctx->reserved[1] |= cpu_to_le32(EP_BOFFSET(sch_ep->offset) 369 | EP_BREPEAT(sch_ep->repeat)); 370 371 xhci_dbg(xhci, " PKTS:%x, CSCOUNT:%x, BM:%x, OFFSET:%x, REPEAT:%x\n", 372 sch_ep->pkts, sch_ep->cs_count, sch_ep->burst_mode, 373 sch_ep->offset, sch_ep->repeat); 374 375 return 0; 376 } 377 EXPORT_SYMBOL_GPL(xhci_mtk_add_ep_quirk); 378 379 void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, 380 struct usb_host_endpoint *ep) 381 { 382 struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd); 383 struct xhci_hcd *xhci; 384 struct xhci_slot_ctx *slot_ctx; 385 struct xhci_virt_device *virt_dev; 386 struct mu3h_sch_bw_info *sch_array; 387 struct mu3h_sch_bw_info *sch_bw; 388 struct mu3h_sch_ep_info *sch_ep; 389 int bw_index; 390 391 xhci = hcd_to_xhci(hcd); 392 virt_dev = xhci->devs[udev->slot_id]; 393 slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); 394 sch_array = mtk->sch_array; 395 396 xhci_dbg(xhci, "%s() type:%d, speed:%d, mpks:%d, dir:%d, ep:%p\n", 397 __func__, usb_endpoint_type(&ep->desc), udev->speed, 398 usb_endpoint_maxp(&ep->desc), 399 usb_endpoint_dir_in(&ep->desc), ep); 400 401 if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT)) 402 return; 403 404 bw_index = get_bw_index(xhci, udev, ep); 405 sch_bw = &sch_array[bw_index]; 406 407 list_for_each_entry(sch_ep, &sch_bw->bw_ep_list, endpoint) { 408 if (sch_ep->ep == ep) { 409 update_bus_bw(sch_bw, sch_ep, 410 -sch_ep->bw_cost_per_microframe); 411 list_del(&sch_ep->endpoint); 412 kfree(sch_ep); 413 break; 414 } 415 } 416 } 417 EXPORT_SYMBOL_GPL(xhci_mtk_drop_ep_quirk); 418