Lines Matching +full:companion +full:- +full:hub

1 // SPDX-License-Identifier: GPL-2.0+
5 * Based on xHCI host controller driver in linux-kernel
38 struct usb_hub_descriptor hub; member
47 0x2a, /* bDescriptorType: hub descriptor */
48 2, /* bNrPorts -- runtime modified */
102 0x30, /* ss_bDescriptorType: SS EP Companion */
121 for (dev = udev->dev; in xhci_get_ctrl()
123 dev = dev->parent) in xhci_get_ctrl()
127 return udev->controller; in xhci_get_ctrl()
149 return -ENODEV; in handshake()
153 usec--; in handshake()
157 return -ETIMEDOUT; in handshake()
172 temp = xhci_readl(&hcor->or_usbcmd); in xhci_start()
174 xhci_writel(&hcor->or_usbcmd, temp); in xhci_start()
180 ret = handshake(&hcor->or_usbsts, STS_HALT, 0, XHCI_MAX_HALT_USEC); in xhci_start()
192 * @return -EBUSY if XHCI Controller is not halted else status of handshake
202 state = xhci_readl(&hcor->or_usbsts) & STS_HALT; in xhci_reset()
204 cmd = xhci_readl(&hcor->or_usbcmd); in xhci_reset()
206 xhci_writel(&hcor->or_usbcmd, cmd); in xhci_reset()
209 ret = handshake(&hcor->or_usbsts, in xhci_reset()
214 return -EBUSY; in xhci_reset()
218 cmd = xhci_readl(&hcor->or_usbcmd); in xhci_reset()
220 xhci_writel(&hcor->or_usbcmd, cmd); in xhci_reset()
222 ret = handshake(&hcor->or_usbcmd, CMD_RESET, 0, XHCI_MAX_RESET_USEC); in xhci_reset()
230 return handshake(&hcor->or_usbsts, STS_CNR, 0, XHCI_MAX_RESET_USEC); in xhci_reset()
238 * Index = (epnum * 2) + direction - 1,
241 * index = (epnum * 2) + direction - 1 = (epnum * 2) + 1 - 1 = (epnum * 2)
253 index = (unsigned int)((usb_endpoint_num(desc) * 2) - in xhci_get_ep_index()
260 * Convert bInterval expressed in microframes (in 1-255 range) to exponent of
269 interval = fls(desc_interval) - 1; in xhci_microframes_to_exponent()
282 if (endpt_desc->bInterval == 0) in xhci_parse_microframe_interval()
285 return xhci_microframes_to_exponent(endpt_desc->bInterval, 0, 15); in xhci_parse_microframe_interval()
291 return xhci_microframes_to_exponent(endpt_desc->bInterval * 8, 3, 10); in xhci_parse_frame_interval()
295 * Convert interval expressed as 2^(bInterval - 1) == interval into
303 interval = clamp_val(endpt_desc->bInterval, 1, 16) - 1; in xhci_parse_exponent_interval()
304 if (interval != endpt_desc->bInterval - 1) in xhci_parse_exponent_interval()
305 debug("ep %#x - rounding interval to %d %sframes\n", in xhci_parse_exponent_interval()
306 endpt_desc->bEndpointAddress, 1 << interval, in xhci_parse_exponent_interval()
307 udev->speed == USB_SPEED_FULL ? "" : "micro"); in xhci_parse_exponent_interval()
309 if (udev->speed == USB_SPEED_FULL) { in xhci_parse_exponent_interval()
335 switch (udev->speed) { in xhci_get_endpoint_interval()
344 /* Fall through - SS and HS isoc/int have same decoding */ in xhci_get_endpoint_interval()
390 if (udev->speed < USB_SPEED_SUPER || in xhci_get_endpoint_mult()
394 return ss_ep_comp_desc->bmAttributes; in xhci_get_endpoint_mult()
401 /* Super speed and Plus have max burst in ep companion desc */ in xhci_get_endpoint_max_burst()
402 if (udev->speed >= USB_SPEED_SUPER) in xhci_get_endpoint_max_burst()
403 return ss_ep_comp_desc->bMaxBurst; in xhci_get_endpoint_max_burst()
405 if (udev->speed == USB_SPEED_HIGH && in xhci_get_endpoint_max_burst()
408 return usb_endpoint_maxp_mult(endpt_desc) - 1; in xhci_get_endpoint_max_burst()
431 if (udev->speed >= USB_SPEED_SUPER) in xhci_get_max_esit_payload()
432 return le16_to_cpu(ss_ep_comp_desc->wBytesPerInterval); in xhci_get_max_esit_payload()
447 * @return 0 on success, -1 on failure
456 virt_dev = ctrl->devs[udev->slot_id]; in xhci_configure_endpoints()
457 in_ctx = virt_dev->in_ctx; in xhci_configure_endpoints()
459 xhci_flush_cache((uintptr_t)in_ctx->bytes, in_ctx->size); in xhci_configure_endpoints()
460 xhci_queue_command(ctrl, in_ctx->bytes, udev->slot_id, 0, in xhci_configure_endpoints()
463 BUG_ON(TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags)) in xhci_configure_endpoints()
464 != udev->slot_id); in xhci_configure_endpoints()
466 switch (GET_COMP_CODE(le32_to_cpu(event->event_cmd.status))) { in xhci_configure_endpoints()
474 GET_COMP_CODE(le32_to_cpu(event->event_cmd.status))); in xhci_configure_endpoints()
475 return -EINVAL; in xhci_configure_endpoints()
505 int slot_id = udev->slot_id; in xhci_set_configuration()
506 struct xhci_virt_device *virt_dev = ctrl->devs[slot_id]; in xhci_set_configuration()
515 out_ctx = virt_dev->out_ctx; in xhci_set_configuration()
516 in_ctx = virt_dev->in_ctx; in xhci_set_configuration()
518 num_of_ep = udev->config.if_desc[0].no_of_ep; in xhci_set_configuration()
519 ifdesc = &udev->config.if_desc[0]; in xhci_set_configuration()
523 ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG); in xhci_set_configuration()
524 ctrl_ctx->drop_flags = 0; in xhci_set_configuration()
528 ep_flag = xhci_get_ep_index(&ifdesc->ep_desc[cur_ep]); in xhci_set_configuration()
529 ctrl_ctx->add_flags |= cpu_to_le32(1 << (ep_flag + 1)); in xhci_set_configuration()
534 xhci_inval_cache((uintptr_t)out_ctx->bytes, out_ctx->size); in xhci_set_configuration()
539 slot_ctx->dev_info &= ~(cpu_to_le32(LAST_CTX_MASK)); in xhci_set_configuration()
540 slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(max_ep_flag + 1) | 0); in xhci_set_configuration()
549 endpt_desc = &ifdesc->ep_desc[cur_ep]; in xhci_set_configuration()
550 ss_ep_comp_desc = &ifdesc->ss_ep_comp_desc[cur_ep]; in xhci_set_configuration()
573 virt_dev->eps[ep_index].ring = xhci_ring_alloc(1, true); in xhci_set_configuration()
574 if (!virt_dev->eps[ep_index].ring) in xhci_set_configuration()
575 return -ENOMEM; in xhci_set_configuration()
578 dir = (((endpt_desc->bEndpointAddress) & (0x80)) >> 7); in xhci_set_configuration()
579 ep_type = (((endpt_desc->bmAttributes) & (0x3)) | (dir << 2)); in xhci_set_configuration()
581 ep_ctx[ep_index]->ep_info = in xhci_set_configuration()
585 ep_ctx[ep_index]->ep_info2 = in xhci_set_configuration()
587 ep_ctx[ep_index]->ep_info2 |= in xhci_set_configuration()
589 (get_unaligned(&endpt_desc->wMaxPacketSize))); in xhci_set_configuration()
594 ep_ctx[ep_index]->ep_info2 |= in xhci_set_configuration()
599 virt_dev->eps[ep_index].ring->enqueue; in xhci_set_configuration()
600 ep_ctx[ep_index]->deq = cpu_to_le64(trb_64 | in xhci_set_configuration()
601 virt_dev->eps[ep_index].ring->cycle_state); in xhci_set_configuration()
609 ep_ctx[ep_index]->tx_info = in xhci_set_configuration()
631 int slot_id = udev->slot_id; in xhci_address_device()
634 virt_dev = ctrl->devs[slot_id]; in xhci_address_device()
637 * This is the first Set Address since device plug-in in xhci_address_device()
640 debug("Setting up addressable devices %p\n", ctrl->dcbaa); in xhci_address_device()
643 ctrl_ctx = xhci_get_input_control_ctx(virt_dev->in_ctx); in xhci_address_device()
644 ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG); in xhci_address_device()
645 ctrl_ctx->drop_flags = 0; in xhci_address_device()
649 BUG_ON(TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags)) != slot_id); in xhci_address_device()
651 switch (GET_COMP_CODE(le32_to_cpu(event->event_cmd.status))) { in xhci_address_device()
656 ret = -EINVAL; in xhci_address_device()
660 ret = -EPROTO; in xhci_address_device()
665 ret = -ENODEV; in xhci_address_device()
669 udev->status = 0; in xhci_address_device()
673 GET_COMP_CODE(le32_to_cpu(event->event_cmd.status))); in xhci_address_device()
674 ret = -EINVAL; in xhci_address_device()
687 xhci_inval_cache((uintptr_t)virt_dev->out_ctx->bytes, in xhci_address_device()
688 virt_dev->out_ctx->size); in xhci_address_device()
689 slot_ctx = xhci_get_slot_ctx(ctrl, virt_dev->out_ctx); in xhci_address_device()
692 le32_to_cpu(slot_ctx->dev_state) & DEV_ADDR_MASK); in xhci_address_device()
713 * Root hub will be first device to be initailized. in _xhci_alloc_device()
714 * If this device is root-hub, don't do any xHC related in _xhci_alloc_device()
717 if (ctrl->rootdev == 0) { in _xhci_alloc_device()
718 udev->speed = USB_SPEED_SUPER; in _xhci_alloc_device()
724 BUG_ON(GET_COMP_CODE(le32_to_cpu(event->event_cmd.status)) in _xhci_alloc_device()
727 udev->slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags)); in _xhci_alloc_device()
731 ret = xhci_alloc_virt_device(ctrl, udev->slot_id); in _xhci_alloc_device()
763 unsigned int slot_id = udev->slot_id; in xhci_check_maxpacket()
773 out_ctx = ctrl->devs[slot_id]->out_ctx; in xhci_check_maxpacket()
774 xhci_inval_cache((uintptr_t)out_ctx->bytes, out_ctx->size); in xhci_check_maxpacket()
777 hw_max_packet_size = MAX_PACKET_DECODED(le32_to_cpu(ep_ctx->ep_info2)); in xhci_check_maxpacket()
778 max_packet_size = udev->epmaxpacketin[0]; in xhci_check_maxpacket()
786 xhci_endpoint_copy(ctrl, ctrl->devs[slot_id]->in_ctx, in xhci_check_maxpacket()
787 ctrl->devs[slot_id]->out_ctx, ep_index); in xhci_check_maxpacket()
788 in_ctx = ctrl->devs[slot_id]->in_ctx; in xhci_check_maxpacket()
790 ep_ctx->ep_info2 &= cpu_to_le32(~((0xffff & MAX_PACKET_MASK) in xhci_check_maxpacket()
792 ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet_size)); in xhci_check_maxpacket()
796 * FIXME: This won't work if a non-default control endpoint in xhci_check_maxpacket()
800 ctrl_ctx->add_flags = cpu_to_le32(EP0_FLAG); in xhci_check_maxpacket()
801 ctrl_ctx->drop_flags = 0; in xhci_check_maxpacket()
834 port_change_bit = "over-current"; in xhci_clear_port_change_bit()
869 /* Save read-only status and port state */ in xhci_port_state_to_neutral()
879 * @return returns 0 if successful else -1 on failure
891 struct xhci_hccr *hccr = ctrl->hccr; in xhci_submit_root()
892 struct xhci_hcor *hcor = ctrl->hcor; in xhci_submit_root()
893 int max_ports = HCS_MAX_PORTS(xhci_readl(&hccr->cr_hcsparams1)); in xhci_submit_root()
895 if ((req->requesttype & USB_RT_PORT) && in xhci_submit_root()
896 le16_to_cpu(req->index) > max_ports) { in xhci_submit_root()
898 le16_to_cpu(req->index) - 1); in xhci_submit_root()
899 return -EINVAL; in xhci_submit_root()
903 (&hcor->portregs[le16_to_cpu(req->index) - 1].or_portsc); in xhci_submit_root()
906 typeReq = req->request | req->requesttype << 8; in xhci_submit_root()
910 switch (le16_to_cpu(req->value) >> 8) { in xhci_submit_root()
923 switch (le16_to_cpu(req->value) & 0xff) { in xhci_submit_root()
929 srcptr = "\16\3U\0-\0B\0o\0o\0t\0"; in xhci_submit_root()
940 le16_to_cpu(req->value)); in xhci_submit_root()
945 printf("unknown value %x\n", le16_to_cpu(req->value)); in xhci_submit_root()
950 switch (le16_to_cpu(req->value) >> 8) { in xhci_submit_root()
954 srcptr = &descriptor.hub; in xhci_submit_root()
958 printf("unknown value %x\n", le16_to_cpu(req->value)); in xhci_submit_root()
964 ctrl->rootdev = le16_to_cpu(req->value); in xhci_submit_root()
1008 * XXX: This Port power bit (for USB 3.0 hub) in xhci_submit_root()
1009 * we are faking in USB 2.0 hub port status; in xhci_submit_root()
1032 switch (le16_to_cpu(req->value)) { in xhci_submit_root()
1046 printf("unknown feature %x\n", le16_to_cpu(req->value)); in xhci_submit_root()
1053 switch (le16_to_cpu(req->value)) { in xhci_submit_root()
1064 xhci_clear_port_change_bit((le16_to_cpu(req->value)), in xhci_submit_root()
1065 le16_to_cpu(req->index), in xhci_submit_root()
1069 printf("unknown feature %x\n", le16_to_cpu(req->value)); in xhci_submit_root()
1079 debug("scrlen = %d\n req->length = %d\n", in xhci_submit_root()
1080 srclen, le16_to_cpu(req->length)); in xhci_submit_root()
1082 len = min(srclen, (int)le16_to_cpu(req->length)); in xhci_submit_root()
1089 udev->act_len = len; in xhci_submit_root()
1090 udev->status = 0; in xhci_submit_root()
1095 udev->act_len = 0; in xhci_submit_root()
1096 udev->status = USB_ST_STALLED; in xhci_submit_root()
1098 return -ENODEV; in xhci_submit_root()
1115 printf("non-interrupt pipe (type=%lu)", usb_pipetype(pipe)); in _xhci_submit_int_msg()
1116 return -EINVAL; in _xhci_submit_int_msg()
1135 * @return returns 0 if successful else -1 on failure
1141 printf("non-bulk pipe (type=%lu)", usb_pipetype(pipe)); in _xhci_submit_bulk_msg()
1142 return -EINVAL; in _xhci_submit_bulk_msg()
1149 * submit the control type of request to the Root hub/Device based on the devnum
1157 * @return returns 0 if successful else -1 on failure
1167 printf("non-control pipe (type=%lu)", usb_pipetype(pipe)); in _xhci_submit_control_msg()
1168 return -EINVAL; in _xhci_submit_control_msg()
1171 if (usb_pipedevice(pipe) == ctrl->rootdev) in _xhci_submit_control_msg()
1174 if (setup->request == USB_REQ_SET_ADDRESS && in _xhci_submit_control_msg()
1175 (setup->requesttype & USB_TYPE_MASK) == USB_TYPE_STANDARD) in _xhci_submit_control_msg()
1178 if (setup->request == USB_REQ_SET_CONFIGURATION && in _xhci_submit_control_msg()
1179 (setup->requesttype & USB_TYPE_MASK) == USB_TYPE_STANDARD) { in _xhci_submit_control_msg()
1198 hccr = ctrl->hccr; in xhci_lowlevel_init()
1199 hcor = ctrl->hcor; in xhci_lowlevel_init()
1204 val = (xhci_readl(&hccr->cr_hcsparams1) & HCS_SLOTS_MASK); in xhci_lowlevel_init()
1205 val2 = xhci_readl(&hcor->or_config); in xhci_lowlevel_init()
1207 xhci_writel(&hcor->or_config, val); in xhci_lowlevel_init()
1211 return -ENOMEM; in xhci_lowlevel_init()
1213 reg = xhci_readl(&hccr->cr_hcsparams1); in xhci_lowlevel_init()
1214 descriptor.hub.bNbrPorts = ((reg & HCS_MAX_PORTS_MASK) >> in xhci_lowlevel_init()
1216 printf("Register %x NbrPorts %d\n", reg, descriptor.hub.bNbrPorts); in xhci_lowlevel_init()
1219 reg = xhci_readl(&hccr->cr_hccparams); in xhci_lowlevel_init()
1221 put_unaligned(get_unaligned(&descriptor.hub.wHubCharacteristics) in xhci_lowlevel_init()
1222 | 0x80, &descriptor.hub.wHubCharacteristics); in xhci_lowlevel_init()
1226 put_unaligned(get_unaligned(&descriptor.hub.wHubCharacteristics) in xhci_lowlevel_init()
1227 | 0x01, &descriptor.hub.wHubCharacteristics); in xhci_lowlevel_init()
1231 return -ENODEV; in xhci_lowlevel_init()
1235 xhci_writel(&ctrl->ir_set->irq_control, 0x0); in xhci_lowlevel_init()
1236 xhci_writel(&ctrl->ir_set->irq_pending, 0x0); in xhci_lowlevel_init()
1238 reg = HC_VERSION(xhci_readl(&hccr->cr_capbase)); in xhci_lowlevel_init()
1248 xhci_reset(ctrl->hcor); in xhci_lowlevel_stop()
1251 temp = xhci_readl(&ctrl->hcor->or_usbsts); in xhci_lowlevel_stop()
1252 xhci_writel(&ctrl->hcor->or_usbsts, temp & ~STS_EINT); in xhci_lowlevel_stop()
1253 temp = xhci_readl(&ctrl->ir_set->irq_pending); in xhci_lowlevel_stop()
1254 xhci_writel(&ctrl->ir_set->irq_pending, ER_IRQ_DISABLE(temp)); in xhci_lowlevel_stop()
1265 if (hop->parent) in submit_control_msg()
1266 while (hop->parent->parent) in submit_control_msg()
1267 hop = hop->parent; in submit_control_msg()
1270 hop->portnr); in submit_control_msg()
1302 return -ENODEV; in usb_lowlevel_init()
1305 return -ENODEV; in usb_lowlevel_init()
1309 ctrl->hccr = hccr; in usb_lowlevel_init()
1310 ctrl->hcor = hcor; in usb_lowlevel_init()
1315 ctrl->hccr = NULL; in usb_lowlevel_init()
1316 ctrl->hcor = NULL; in usb_lowlevel_init()
1335 if (ctrl->hcor) { in usb_lowlevel_stop()
1352 struct udevice *hub; in xhci_submit_control_msg() local
1355 debug("%s: dev='%s', udev=%p, udev->dev='%s', portnr=%d\n", __func__, in xhci_submit_control_msg()
1356 dev->name, udev, udev->dev->name, udev->portnr); in xhci_submit_control_msg()
1357 hub = udev->dev; in xhci_submit_control_msg()
1358 if (device_get_uclass_id(hub) == UCLASS_USB_HUB) { in xhci_submit_control_msg()
1359 /* Figure out our port number on the root hub */ in xhci_submit_control_msg()
1360 if (usb_hub_is_root_hub(hub)) { in xhci_submit_control_msg()
1361 root_portnr = udev->portnr; in xhci_submit_control_msg()
1363 while (!usb_hub_is_root_hub(hub->parent)) in xhci_submit_control_msg()
1364 hub = hub->parent; in xhci_submit_control_msg()
1365 uhop = dev_get_parent_priv(hub); in xhci_submit_control_msg()
1366 root_portnr = uhop->portnr; in xhci_submit_control_msg()
1372 if (hop->parent) in xhci_submit_control_msg()
1373 while (hop->parent->parent) in xhci_submit_control_msg()
1374 hop = hop->parent; in xhci_submit_control_msg()
1383 debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev); in xhci_submit_bulk_msg()
1391 debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev); in xhci_submit_int_msg()
1397 debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev); in xhci_alloc_device()
1404 struct usb_hub_device *hub = dev_get_uclass_priv(udev->dev); in xhci_update_hub_device() local
1410 int slot_id = udev->slot_id; in xhci_update_hub_device()
1413 debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev); in xhci_update_hub_device()
1416 if (usb_hub_is_root_hub(udev->dev)) in xhci_update_hub_device()
1419 virt_dev = ctrl->devs[slot_id]; in xhci_update_hub_device()
1422 out_ctx = virt_dev->out_ctx; in xhci_update_hub_device()
1423 in_ctx = virt_dev->in_ctx; in xhci_update_hub_device()
1427 ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG); in xhci_update_hub_device()
1428 ctrl_ctx->drop_flags = 0; in xhci_update_hub_device()
1430 xhci_inval_cache((uintptr_t)out_ctx->bytes, out_ctx->size); in xhci_update_hub_device()
1436 /* Update hub related fields */ in xhci_update_hub_device()
1437 slot_ctx->dev_info |= cpu_to_le32(DEV_HUB); in xhci_update_hub_device()
1439 * refer to section 6.2.2: MTT should be 0 for full speed hub, in xhci_update_hub_device()
1443 if (hub->tt.multi) in xhci_update_hub_device()
1444 slot_ctx->dev_info |= cpu_to_le32(DEV_MTT); in xhci_update_hub_device()
1445 else if (udev->speed == USB_SPEED_FULL) in xhci_update_hub_device()
1446 slot_ctx->dev_info &= cpu_to_le32(~DEV_MTT); in xhci_update_hub_device()
1447 slot_ctx->dev_info2 |= cpu_to_le32(XHCI_MAX_PORTS(udev->maxchild)); in xhci_update_hub_device()
1449 * Set TT think time - convert from ns to FS bit times. in xhci_update_hub_device()
1455 * This field shall be 0 if the device is not a high-spped hub. in xhci_update_hub_device()
1457 think_time = hub->tt.think_time; in xhci_update_hub_device()
1459 think_time = (think_time / 666) - 1; in xhci_update_hub_device()
1460 if (udev->speed == USB_SPEED_HIGH) in xhci_update_hub_device()
1461 slot_ctx->tt_info |= cpu_to_le32(TT_THINK_TIME(think_time)); in xhci_update_hub_device()
1462 slot_ctx->dev_state = 0; in xhci_update_hub_device()
1476 *size = (TRBS_PER_SEGMENT - 2) * TRB_MAX_BUFF_SIZE; in xhci_get_max_xfer_size()
1488 debug("%s: dev='%s', ctrl=%p, hccr=%p, hcor=%p\n", __func__, dev->name, in xhci_register()
1491 ctrl->dev = dev; in xhci_register()
1499 priv->desc_before_addr = false; in xhci_register()
1505 ctrl->hccr = hccr; in xhci_register()
1506 ctrl->hcor = hcor; in xhci_register()