Lines Matching +full:dev +full:- +full:ctrl
1 // SPDX-License-Identifier: GPL-2.0+
5 * Based on xHCI host controller driver in linux-kernel
38 flush_dcache_range(addr & ~(CACHELINE_SIZE - 1), in xhci_flush_cache()
53 invalidate_dcache_range(addr & ~(CACHELINE_SIZE - 1), in xhci_inval_cache()
66 free(seg->trbs); in xhci_segment_free()
67 seg->trbs = NULL; in xhci_segment_free()
85 first_seg = ring->first_seg; in xhci_ring_free()
86 seg = first_seg->next; in xhci_ring_free()
88 struct xhci_segment *next = seg->next; in xhci_ring_free()
100 * @ctrl host controller data structure
103 static void xhci_scratchpad_free(struct xhci_ctrl *ctrl) in xhci_scratchpad_free() argument
105 if (!ctrl->scratchpad) in xhci_scratchpad_free()
108 ctrl->dcbaa->dev_context_ptrs[0] = 0; in xhci_scratchpad_free()
110 free((void *)(uintptr_t)ctrl->scratchpad->sp_array[0]); in xhci_scratchpad_free()
111 free(ctrl->scratchpad->sp_array); in xhci_scratchpad_free()
112 free(ctrl->scratchpad); in xhci_scratchpad_free()
113 ctrl->scratchpad = NULL; in xhci_scratchpad_free()
124 free(ctx->bytes); in xhci_free_container_ctx()
134 static void xhci_free_virt_devices(struct xhci_ctrl *ctrl) in xhci_free_virt_devices() argument
145 virt_dev = ctrl->devs[slot_id]; in xhci_free_virt_devices()
149 ctrl->dcbaa->dev_context_ptrs[slot_id] = 0; in xhci_free_virt_devices()
152 if (virt_dev->eps[i].ring) in xhci_free_virt_devices()
153 xhci_ring_free(virt_dev->eps[i].ring); in xhci_free_virt_devices()
155 if (virt_dev->in_ctx) in xhci_free_virt_devices()
156 xhci_free_container_ctx(virt_dev->in_ctx); in xhci_free_virt_devices()
157 if (virt_dev->out_ctx) in xhci_free_virt_devices()
158 xhci_free_container_ctx(virt_dev->out_ctx); in xhci_free_virt_devices()
162 ctrl->devs[slot_id] = NULL; in xhci_free_virt_devices()
172 void xhci_cleanup(struct xhci_ctrl *ctrl) in xhci_cleanup() argument
174 xhci_ring_free(ctrl->event_ring); in xhci_cleanup()
175 xhci_ring_free(ctrl->cmd_ring); in xhci_cleanup()
176 xhci_scratchpad_free(ctrl); in xhci_cleanup()
177 xhci_free_virt_devices(ctrl); in xhci_cleanup()
178 free(ctrl->erst.entries); in xhci_cleanup()
179 free(ctrl->dcbaa); in xhci_cleanup()
180 memset(ctrl, '\0', sizeof(struct xhci_ctrl)); in xhci_cleanup()
222 prev->next = next; in xhci_link_segments()
224 val_64 = (uintptr_t)next->trbs; in xhci_link_segments()
225 prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr = val_64; in xhci_link_segments()
231 val = le32_to_cpu(prev->trbs[TRBS_PER_SEGMENT-1].link.control); in xhci_link_segments()
235 prev->trbs[TRBS_PER_SEGMENT-1].link.control = cpu_to_le32(val); in xhci_link_segments()
250 ring->enqueue = ring->first_seg->trbs; in xhci_initialize_ring_info()
251 ring->enq_seg = ring->first_seg; in xhci_initialize_ring_info()
252 ring->dequeue = ring->enqueue; in xhci_initialize_ring_info()
253 ring->deq_seg = ring->first_seg; in xhci_initialize_ring_info()
261 ring->cycle_state = 1; in xhci_initialize_ring_info()
280 seg->trbs = (union xhci_trb *)xhci_malloc(SEGMENT_SIZE); in xhci_segment_alloc()
282 seg->next = NULL; in xhci_segment_alloc()
289 * TODO: current code only uses one-time-allocated single-segment rings
313 ring->first_seg = xhci_segment_alloc(); in xhci_ring_alloc()
314 BUG_ON(!ring->first_seg); in xhci_ring_alloc()
316 num_segs--; in xhci_ring_alloc()
318 prev = ring->first_seg; in xhci_ring_alloc()
328 num_segs--; in xhci_ring_alloc()
330 xhci_link_segments(prev, ring->first_seg, link_trbs); in xhci_ring_alloc()
333 prev->trbs[TRBS_PER_SEGMENT-1].link.control |= in xhci_ring_alloc()
344 * @ctrl host controller data structure
345 * @return -ENOMEM if buffer allocation fails, 0 on success
347 static int xhci_scratchpad_alloc(struct xhci_ctrl *ctrl) in xhci_scratchpad_alloc() argument
349 struct xhci_hccr *hccr = ctrl->hccr; in xhci_scratchpad_alloc()
350 struct xhci_hcor *hcor = ctrl->hcor; in xhci_scratchpad_alloc()
357 num_sp = HCS_MAX_SCRATCHPAD(xhci_readl(&hccr->cr_hcsparams2)); in xhci_scratchpad_alloc()
364 ctrl->scratchpad = scratchpad; in xhci_scratchpad_alloc()
366 scratchpad->sp_array = xhci_malloc(num_sp * sizeof(u64)); in xhci_scratchpad_alloc()
367 if (!scratchpad->sp_array) in xhci_scratchpad_alloc()
369 ctrl->dcbaa->dev_context_ptrs[0] = in xhci_scratchpad_alloc()
370 cpu_to_le64((uintptr_t)scratchpad->sp_array); in xhci_scratchpad_alloc()
372 xhci_flush_cache((uintptr_t)&ctrl->dcbaa->dev_context_ptrs[0], in xhci_scratchpad_alloc()
373 sizeof(ctrl->dcbaa->dev_context_ptrs[0])); in xhci_scratchpad_alloc()
375 page_size = xhci_readl(&hcor->or_pagesize) & 0xffff; in xhci_scratchpad_alloc()
392 scratchpad->sp_array[i] = cpu_to_le64(ptr); in xhci_scratchpad_alloc()
398 free(scratchpad->sp_array); in xhci_scratchpad_alloc()
402 ctrl->scratchpad = NULL; in xhci_scratchpad_alloc()
405 return -ENOMEM; in xhci_scratchpad_alloc()
411 * @param ctrl Host controller data structure
416 *xhci_alloc_container_ctx(struct xhci_ctrl *ctrl, int type) in xhci_alloc_container_ctx() argument
425 ctx->type = type; in xhci_alloc_container_ctx()
426 ctx->size = (MAX_EP_CTX_NUM + 1) * in xhci_alloc_container_ctx()
427 CTX_SIZE(readl(&ctrl->hccr->cr_hccparams)); in xhci_alloc_container_ctx()
429 ctx->size += CTX_SIZE(readl(&ctrl->hccr->cr_hccparams)); in xhci_alloc_container_ctx()
431 ctx->bytes = (u8 *)xhci_malloc(ctx->size); in xhci_alloc_container_ctx()
440 * @return 0 on success else -1 on failure
442 int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, unsigned int slot_id) in xhci_alloc_virt_device() argument
448 if (ctrl->devs[slot_id]) { in xhci_alloc_virt_device()
449 printf("Virt dev for slot[%d] already allocated\n", slot_id); in xhci_alloc_virt_device()
450 return -EEXIST; in xhci_alloc_virt_device()
453 ctrl->devs[slot_id] = (struct xhci_virt_device *) in xhci_alloc_virt_device()
456 if (!ctrl->devs[slot_id]) { in xhci_alloc_virt_device()
458 return -ENOMEM; in xhci_alloc_virt_device()
461 memset(ctrl->devs[slot_id], 0, sizeof(struct xhci_virt_device)); in xhci_alloc_virt_device()
462 virt_dev = ctrl->devs[slot_id]; in xhci_alloc_virt_device()
465 virt_dev->out_ctx = xhci_alloc_container_ctx(ctrl, in xhci_alloc_virt_device()
467 if (!virt_dev->out_ctx) { in xhci_alloc_virt_device()
468 puts("Failed to allocate out context for virt dev\n"); in xhci_alloc_virt_device()
469 return -ENOMEM; in xhci_alloc_virt_device()
473 virt_dev->in_ctx = xhci_alloc_container_ctx(ctrl, in xhci_alloc_virt_device()
475 if (!virt_dev->in_ctx) { in xhci_alloc_virt_device()
476 puts("Failed to allocate in context for virt dev\n"); in xhci_alloc_virt_device()
477 return -ENOMEM; in xhci_alloc_virt_device()
481 virt_dev->eps[0].ring = xhci_ring_alloc(1, true); in xhci_alloc_virt_device()
483 byte_64 = (uintptr_t)(virt_dev->out_ctx->bytes); in xhci_alloc_virt_device()
486 ctrl->dcbaa->dev_context_ptrs[slot_id] = byte_64; in xhci_alloc_virt_device()
488 xhci_flush_cache((uintptr_t)&ctrl->dcbaa->dev_context_ptrs[slot_id], in xhci_alloc_virt_device()
497 * @param ctrl Host controller data structure
500 * @return 0 if successful else -1 on failure
502 int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr, in xhci_mem_init() argument
513 ctrl->dcbaa = (struct xhci_device_context_array *) in xhci_mem_init()
515 if (ctrl->dcbaa == NULL) { in xhci_mem_init()
517 return -ENOMEM; in xhci_mem_init()
520 val_64 = (uintptr_t)ctrl->dcbaa; in xhci_mem_init()
522 xhci_writeq(&hcor->or_dcbaap, val_64); in xhci_mem_init()
525 ctrl->cmd_ring = xhci_ring_alloc(1, true); in xhci_mem_init()
528 trb_64 = (uintptr_t)ctrl->cmd_ring->first_seg->trbs; in xhci_mem_init()
529 val_64 = xhci_readq(&hcor->or_crcr); in xhci_mem_init()
532 ctrl->cmd_ring->cycle_state; in xhci_mem_init()
533 xhci_writeq(&hcor->or_crcr, val_64); in xhci_mem_init()
536 val = xhci_readl(&hccr->cr_dboff); in xhci_mem_init()
538 ctrl->dba = (struct xhci_doorbell_array *)((char *)hccr + val); in xhci_mem_init()
541 val = xhci_readl(&hccr->cr_rtsoff); in xhci_mem_init()
543 ctrl->run_regs = (struct xhci_run_regs *)((char *)hccr + val); in xhci_mem_init()
546 ctrl->ir_set = &ctrl->run_regs->ir_set[0]; in xhci_mem_init()
549 ctrl->event_ring = xhci_ring_alloc(ERST_NUM_SEGS, false); in xhci_mem_init()
550 ctrl->erst.entries = (struct xhci_erst_entry *) in xhci_mem_init()
553 ctrl->erst.num_entries = ERST_NUM_SEGS; in xhci_mem_init()
555 for (val = 0, seg = ctrl->event_ring->first_seg; in xhci_mem_init()
559 trb_64 = (uintptr_t)seg->trbs; in xhci_mem_init()
560 struct xhci_erst_entry *entry = &ctrl->erst.entries[val]; in xhci_mem_init()
561 xhci_writeq(&entry->seg_addr, trb_64); in xhci_mem_init()
562 entry->seg_size = cpu_to_le32(TRBS_PER_SEGMENT); in xhci_mem_init()
563 entry->rsvd = 0; in xhci_mem_init()
564 seg = seg->next; in xhci_mem_init()
566 xhci_flush_cache((uintptr_t)ctrl->erst.entries, in xhci_mem_init()
569 deq = (unsigned long)ctrl->event_ring->dequeue; in xhci_mem_init()
572 xhci_writeq(&ctrl->ir_set->erst_dequeue, in xhci_mem_init()
576 val = xhci_readl(&ctrl->ir_set->erst_size); in xhci_mem_init()
579 xhci_writel(&ctrl->ir_set->erst_size, val); in xhci_mem_init()
582 val_64 = xhci_readq(&ctrl->ir_set->erst_base); in xhci_mem_init()
584 val_64 |= ((uintptr_t)(ctrl->erst.entries) & ~ERST_PTR_MASK); in xhci_mem_init()
586 xhci_writeq(&ctrl->ir_set->erst_base, val_64); in xhci_mem_init()
589 xhci_scratchpad_alloc(ctrl); in xhci_mem_init()
593 ctrl->devs[i] = NULL; in xhci_mem_init()
600 xhci_writel(&hcor->or_dnctrl, 0x0); in xhci_mem_init()
614 BUG_ON(ctx->type != XHCI_CTX_TYPE_INPUT); in xhci_get_input_control_ctx()
615 return (struct xhci_input_control_ctx *)ctx->bytes; in xhci_get_input_control_ctx()
621 * @param ctrl Host controller data structure
625 struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_ctrl *ctrl, in xhci_get_slot_ctx() argument
628 if (ctx->type == XHCI_CTX_TYPE_DEVICE) in xhci_get_slot_ctx()
629 return (struct xhci_slot_ctx *)ctx->bytes; in xhci_get_slot_ctx()
632 (ctx->bytes + CTX_SIZE(readl(&ctrl->hccr->cr_hccparams))); in xhci_get_slot_ctx()
638 * @param ctrl Host controller data structure
643 struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_ctrl *ctrl, in xhci_get_ep_ctx() argument
649 if (ctx->type == XHCI_CTX_TYPE_INPUT) in xhci_get_ep_ctx()
653 (ctx->bytes + in xhci_get_ep_ctx()
654 (ep_index * CTX_SIZE(readl(&ctrl->hccr->cr_hccparams)))); in xhci_get_ep_ctx()
662 * @param ctrl Host controller data structure
668 void xhci_endpoint_copy(struct xhci_ctrl *ctrl, in xhci_endpoint_copy() argument
676 out_ep_ctx = xhci_get_ep_ctx(ctrl, out_ctx, ep_index); in xhci_endpoint_copy()
677 in_ep_ctx = xhci_get_ep_ctx(ctrl, in_ctx, ep_index); in xhci_endpoint_copy()
679 in_ep_ctx->ep_info = out_ep_ctx->ep_info; in xhci_endpoint_copy()
680 in_ep_ctx->ep_info2 = out_ep_ctx->ep_info2; in xhci_endpoint_copy()
681 in_ep_ctx->deq = out_ep_ctx->deq; in xhci_endpoint_copy()
682 in_ep_ctx->tx_info = out_ep_ctx->tx_info; in xhci_endpoint_copy()
692 * @param ctrl Host controller data structure
697 void xhci_slot_copy(struct xhci_ctrl *ctrl, struct xhci_container_ctx *in_ctx, in xhci_slot_copy() argument
703 in_slot_ctx = xhci_get_slot_ctx(ctrl, in_ctx); in xhci_slot_copy()
704 out_slot_ctx = xhci_get_slot_ctx(ctrl, out_ctx); in xhci_slot_copy()
706 in_slot_ctx->dev_info = out_slot_ctx->dev_info; in xhci_slot_copy()
707 in_slot_ctx->dev_info2 = out_slot_ctx->dev_info2; in xhci_slot_copy()
708 in_slot_ctx->tt_info = out_slot_ctx->tt_info; in xhci_slot_copy()
709 in_slot_ctx->dev_state = out_slot_ctx->dev_state; in xhci_slot_copy()
718 void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl, in xhci_setup_addressable_virt_dev() argument
726 int slot_id = udev->slot_id; in xhci_setup_addressable_virt_dev()
727 int speed = udev->speed; in xhci_setup_addressable_virt_dev()
730 struct usb_device *dev = udev; in xhci_setup_addressable_virt_dev() local
734 virt_dev = ctrl->devs[slot_id]; in xhci_setup_addressable_virt_dev()
738 /* Extract the EP0 and Slot Ctrl */ in xhci_setup_addressable_virt_dev()
739 ep0_ctx = xhci_get_ep_ctx(ctrl, virt_dev->in_ctx, 0); in xhci_setup_addressable_virt_dev()
740 slot_ctx = xhci_get_slot_ctx(ctrl, virt_dev->in_ctx); in xhci_setup_addressable_virt_dev()
742 /* Only the control endpoint is valid - one endpoint context */ in xhci_setup_addressable_virt_dev()
743 slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1)); in xhci_setup_addressable_virt_dev()
747 port_num = dev->portnr; in xhci_setup_addressable_virt_dev()
748 while (!usb_hub_is_root_hub(dev->dev)) { in xhci_setup_addressable_virt_dev()
749 hub = dev_get_uclass_priv(dev->dev); in xhci_setup_addressable_virt_dev()
760 route |= port_num << (hub->hub_depth * 4); in xhci_setup_addressable_virt_dev()
761 dev = dev_get_parent_priv(dev->dev); in xhci_setup_addressable_virt_dev()
762 port_num = dev->portnr; in xhci_setup_addressable_virt_dev()
763 dev = dev_get_parent_priv(dev->dev->parent); in xhci_setup_addressable_virt_dev()
768 slot_ctx->dev_info |= route; in xhci_setup_addressable_virt_dev()
772 slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_SS); in xhci_setup_addressable_virt_dev()
775 slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_HS); in xhci_setup_addressable_virt_dev()
778 slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_FS); in xhci_setup_addressable_virt_dev()
781 slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_LS); in xhci_setup_addressable_virt_dev()
791 struct udevice *parent = udev->dev; in xhci_setup_addressable_virt_dev()
793 dev = udev; in xhci_setup_addressable_virt_dev()
795 port_num = dev->portnr; in xhci_setup_addressable_virt_dev()
796 dev = dev_get_parent_priv(parent); in xhci_setup_addressable_virt_dev()
797 if (usb_hub_is_root_hub(dev->dev)) in xhci_setup_addressable_virt_dev()
799 parent = dev->dev->parent; in xhci_setup_addressable_virt_dev()
800 } while (dev->speed != USB_SPEED_HIGH); in xhci_setup_addressable_virt_dev()
802 if (!usb_hub_is_root_hub(dev->dev)) { in xhci_setup_addressable_virt_dev()
803 hub = dev_get_uclass_priv(dev->dev); in xhci_setup_addressable_virt_dev()
804 if (hub->tt.multi) in xhci_setup_addressable_virt_dev()
805 slot_ctx->dev_info |= cpu_to_le32(DEV_MTT); in xhci_setup_addressable_virt_dev()
806 slot_ctx->tt_info |= cpu_to_le32(TT_PORT(port_num)); in xhci_setup_addressable_virt_dev()
807 slot_ctx->tt_info |= cpu_to_le32(TT_SLOT(dev->slot_id)); in xhci_setup_addressable_virt_dev()
815 slot_ctx->dev_info2 |= in xhci_setup_addressable_virt_dev()
819 /* Step 4 - ring already allocated */ in xhci_setup_addressable_virt_dev()
821 ep0_ctx->ep_info2 = cpu_to_le32(CTRL_EP << EP_TYPE_SHIFT); in xhci_setup_addressable_virt_dev()
826 ep0_ctx->ep_info2 |= cpu_to_le32(((512 & MAX_PACKET_MASK) << in xhci_setup_addressable_virt_dev()
831 /* USB core guesses at a 64-byte max packet first for FS devices */ in xhci_setup_addressable_virt_dev()
833 ep0_ctx->ep_info2 |= cpu_to_le32(((64 & MAX_PACKET_MASK) << in xhci_setup_addressable_virt_dev()
838 ep0_ctx->ep_info2 |= cpu_to_le32(((8 & MAX_PACKET_MASK) << in xhci_setup_addressable_virt_dev()
848 ep0_ctx->ep_info2 |= in xhci_setup_addressable_virt_dev()
852 trb_64 = (uintptr_t)virt_dev->eps[0].ring->first_seg->trbs; in xhci_setup_addressable_virt_dev()
853 ep0_ctx->deq = cpu_to_le64(trb_64 | virt_dev->eps[0].ring->cycle_state); in xhci_setup_addressable_virt_dev()
859 ep0_ctx->tx_info = cpu_to_le32(EP_AVG_TRB_LENGTH(8)); in xhci_setup_addressable_virt_dev()