Lines Matching +full:ring +full:- +full:disable +full:- +full:pullup

1 // SPDX-License-Identifier: GPL-2.0
3 * gadget.c - DesignWare USB3 DRD Controller Gadget Framework Link
5 * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com
10 * Taken from Linux Kernel v3.19-rc1 (drivers/usb/dwc3/gadget.c) and ported
13 * commit 8e74475b0e : usb: dwc3: gadget: use udc-core's reset notifier
18 #include <asm/dma-mapping.h>
29 #include "linux-compat.h"
32 * dwc3_gadget_set_test_mode - Enables USB2 Test Modes
37 * return 0 on success or -EINVAL if wrong Test Selector
44 reg = dwc3_readl(dwc->regs, DWC3_DCTL); in dwc3_gadget_set_test_mode()
56 return -EINVAL; in dwc3_gadget_set_test_mode()
59 dwc3_writel(dwc->regs, DWC3_DCTL, reg); in dwc3_gadget_set_test_mode()
65 * dwc3_gadget_get_link_state - Gets current state of USB Link
69 * return the link state on success (>= 0) or -ETIMEDOUT.
75 reg = dwc3_readl(dwc->regs, DWC3_DSTS); in dwc3_gadget_get_link_state()
81 * dwc3_gadget_set_link_state - Sets USB Link to a particular State
86 * return 0 on success or -ETIMEDOUT.
97 if (dwc->revision >= DWC3_REVISION_194A) { in dwc3_gadget_set_link_state()
98 while (--retries) { in dwc3_gadget_set_link_state()
99 reg = dwc3_readl(dwc->regs, DWC3_DSTS); in dwc3_gadget_set_link_state()
107 return -ETIMEDOUT; in dwc3_gadget_set_link_state()
110 reg = dwc3_readl(dwc->regs, DWC3_DCTL); in dwc3_gadget_set_link_state()
115 dwc3_writel(dwc->regs, DWC3_DCTL, reg); in dwc3_gadget_set_link_state()
121 if (dwc->revision >= DWC3_REVISION_194A) in dwc3_gadget_set_link_state()
126 while (--retries) { in dwc3_gadget_set_link_state()
127 reg = dwc3_readl(dwc->regs, DWC3_DSTS); in dwc3_gadget_set_link_state()
135 dev_vdbg(dwc->dev, "link state change request timed out\n"); in dwc3_gadget_set_link_state()
137 return -ETIMEDOUT; in dwc3_gadget_set_link_state()
141 * dwc3_gadget_resize_tx_fifos - reallocate fifo spaces for current use-case
149 * on the configured size for RAM1 - which contains TxFifo -,
156 * ((512 + 2 * MDWIDTH-Bytes) + (Number of IN Endpoints - 1) * \
157 * (3 * (1024 + MDWIDTH-Bytes) + MDWIDTH-Bytes)) / MDWIDTH-Bytes
168 if (!dwc->needs_fifo_resize) in dwc3_gadget_resize_tx_fifos()
171 mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0); in dwc3_gadget_resize_tx_fifos()
182 for (num = 0; num < dwc->num_in_eps; num++) { in dwc3_gadget_resize_tx_fifos()
184 struct dwc3_ep *dep = dwc->eps[(num << 1) | 1]; in dwc3_gadget_resize_tx_fifos()
188 if (!(dep->flags & DWC3_EP_ENABLED)) in dwc3_gadget_resize_tx_fifos()
191 if (usb_endpoint_xfer_bulk(dep->endpoint.desc) in dwc3_gadget_resize_tx_fifos()
192 || usb_endpoint_xfer_isoc(dep->endpoint.desc)) in dwc3_gadget_resize_tx_fifos()
206 tmp = mult * (dep->endpoint.maxpacket + mdwidth); in dwc3_gadget_resize_tx_fifos()
213 dev_vdbg(dwc->dev, "%s: Fifo Addr %04x Size %d\n", in dwc3_gadget_resize_tx_fifos()
214 dep->name, last_fifo_depth, fifo_size & 0xffff); in dwc3_gadget_resize_tx_fifos()
216 dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(num), fifo_size); in dwc3_gadget_resize_tx_fifos()
227 struct dwc3 *dwc = dep->dwc; in dwc3_gadget_giveback()
229 if (req->queued) { in dwc3_gadget_giveback()
230 dep->busy_slot++; in dwc3_gadget_giveback()
232 * Skip LINK TRB. We can't use req->trb and check for in dwc3_gadget_giveback()
236 if (((dep->busy_slot & DWC3_TRB_MASK) == in dwc3_gadget_giveback()
237 DWC3_TRB_NUM- 1) && in dwc3_gadget_giveback()
238 usb_endpoint_xfer_isoc(dep->endpoint.desc)) in dwc3_gadget_giveback()
239 dep->busy_slot++; in dwc3_gadget_giveback()
240 req->queued = false; in dwc3_gadget_giveback()
243 list_del(&req->list); in dwc3_gadget_giveback()
244 req->trb = NULL; in dwc3_gadget_giveback()
245 dwc3_flush_cache((uintptr_t)req->request.dma, req->request.length); in dwc3_gadget_giveback()
247 if (req->request.status == -EINPROGRESS) in dwc3_gadget_giveback()
248 req->request.status = status; in dwc3_gadget_giveback()
250 if (dwc->ep0_bounced && dep->number == 0) in dwc3_gadget_giveback()
251 dwc->ep0_bounced = false; in dwc3_gadget_giveback()
253 usb_gadget_unmap_request(&dwc->gadget, &req->request, in dwc3_gadget_giveback()
254 req->direction); in dwc3_gadget_giveback()
256 dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n", in dwc3_gadget_giveback()
257 req, dep->name, req->request.actual, in dwc3_gadget_giveback()
258 req->request.length, status); in dwc3_gadget_giveback()
260 spin_unlock(&dwc->lock); in dwc3_gadget_giveback()
261 usb_gadget_giveback_request(&dep->endpoint, &req->request); in dwc3_gadget_giveback()
262 spin_lock(&dwc->lock); in dwc3_gadget_giveback()
270 dwc3_writel(dwc->regs, DWC3_DGCMDPAR, param); in dwc3_send_gadget_generic_command()
271 dwc3_writel(dwc->regs, DWC3_DGCMD, cmd | DWC3_DGCMD_CMDACT); in dwc3_send_gadget_generic_command()
274 reg = dwc3_readl(dwc->regs, DWC3_DGCMD); in dwc3_send_gadget_generic_command()
276 dev_vdbg(dwc->dev, "Command Complete --> %d\n", in dwc3_send_gadget_generic_command()
285 timeout--; in dwc3_send_gadget_generic_command()
287 return -ETIMEDOUT; in dwc3_send_gadget_generic_command()
298 dwc3_writel(dwc->regs, DWC3_DEPCMDPAR0(ep), params->param0); in dwc3_send_gadget_ep_cmd()
299 dwc3_writel(dwc->regs, DWC3_DEPCMDPAR1(ep), params->param1); in dwc3_send_gadget_ep_cmd()
300 dwc3_writel(dwc->regs, DWC3_DEPCMDPAR2(ep), params->param2); in dwc3_send_gadget_ep_cmd()
302 dwc3_writel(dwc->regs, DWC3_DEPCMD(ep), cmd | DWC3_DEPCMD_CMDACT); in dwc3_send_gadget_ep_cmd()
304 reg = dwc3_readl(dwc->regs, DWC3_DEPCMD(ep)); in dwc3_send_gadget_ep_cmd()
306 dev_vdbg(dwc->dev, "Command Complete --> %d\n", in dwc3_send_gadget_ep_cmd()
315 timeout--; in dwc3_send_gadget_ep_cmd()
317 return -ETIMEDOUT; in dwc3_send_gadget_ep_cmd()
326 u32 offset = (char *) trb - (char *) dep->trb_pool; in dwc3_trb_dma_offset()
328 return dep->trb_pool_dma + offset; in dwc3_trb_dma_offset()
333 if (dep->trb_pool) in dwc3_alloc_trb_pool()
336 if (dep->number == 0 || dep->number == 1) in dwc3_alloc_trb_pool()
339 dep->trb_pool = dma_alloc_coherent(sizeof(struct dwc3_trb) * in dwc3_alloc_trb_pool()
341 (unsigned long *)&dep->trb_pool_dma); in dwc3_alloc_trb_pool()
342 if (!dep->trb_pool) { in dwc3_alloc_trb_pool()
343 dev_err(dep->dwc->dev, "failed to allocate trb pool for %s\n", in dwc3_alloc_trb_pool()
344 dep->name); in dwc3_alloc_trb_pool()
345 return -ENOMEM; in dwc3_alloc_trb_pool()
353 dma_free_coherent(dep->trb_pool); in dwc3_free_trb_pool()
355 dep->trb_pool = NULL; in dwc3_free_trb_pool()
356 dep->trb_pool_dma = 0; in dwc3_free_trb_pool()
366 if (dep->number != 1) { in dwc3_gadget_start_config()
369 if (dep->number > 1) { in dwc3_gadget_start_config()
370 if (dwc->start_config_issued) in dwc3_gadget_start_config()
372 dwc->start_config_issued = true; in dwc3_gadget_start_config()
395 if (dwc->gadget.speed == USB_SPEED_SUPER) { in dwc3_gadget_set_ep_config()
396 u32 burst = dep->endpoint.maxburst - 1; in dwc3_gadget_set_ep_config()
406 params.param2 |= dep->saved_state; in dwc3_gadget_set_ep_config()
415 dep->stream_capable = true; in dwc3_gadget_set_ep_config()
427 params.param1 |= DWC3_DEPCFG_EP_NUMBER(dep->number); in dwc3_gadget_set_ep_config()
433 if (dep->direction) in dwc3_gadget_set_ep_config()
434 params.param0 |= DWC3_DEPCFG_FIFO_NUMBER(dep->number >> 1); in dwc3_gadget_set_ep_config()
436 if (desc->bInterval) { in dwc3_gadget_set_ep_config()
437 params.param1 |= DWC3_DEPCFG_BINTERVAL_M1(desc->bInterval - 1); in dwc3_gadget_set_ep_config()
438 dep->interval = 1 << (desc->bInterval - 1); in dwc3_gadget_set_ep_config()
441 return dwc3_send_gadget_ep_cmd(dwc, dep->number, in dwc3_gadget_set_ep_config()
453 return dwc3_send_gadget_ep_cmd(dwc, dep->number, in dwc3_gadget_set_xfer_resource()
458 * __dwc3_gadget_ep_enable - Initializes a HW endpoint
469 struct dwc3 *dwc = dep->dwc; in __dwc3_gadget_ep_enable()
473 dev_vdbg(dwc->dev, "Enabling %s\n", dep->name); in __dwc3_gadget_ep_enable()
475 if (!(dep->flags & DWC3_EP_ENABLED)) { in __dwc3_gadget_ep_enable()
486 if (!(dep->flags & DWC3_EP_ENABLED)) { in __dwc3_gadget_ep_enable()
494 dep->endpoint.desc = desc; in __dwc3_gadget_ep_enable()
495 dep->comp_desc = comp_desc; in __dwc3_gadget_ep_enable()
496 dep->type = usb_endpoint_type(desc); in __dwc3_gadget_ep_enable()
497 dep->flags |= DWC3_EP_ENABLED; in __dwc3_gadget_ep_enable()
499 reg = dwc3_readl(dwc->regs, DWC3_DALEPENA); in __dwc3_gadget_ep_enable()
500 reg |= DWC3_DALEPENA_EP(dep->number); in __dwc3_gadget_ep_enable()
501 dwc3_writel(dwc->regs, DWC3_DALEPENA, reg); in __dwc3_gadget_ep_enable()
507 trb_st_hw = &dep->trb_pool[0]; in __dwc3_gadget_ep_enable()
509 trb_link = &dep->trb_pool[DWC3_TRB_NUM - 1]; in __dwc3_gadget_ep_enable()
512 trb_link->bpl = lower_32_bits(dwc3_trb_dma_offset(dep, trb_st_hw)); in __dwc3_gadget_ep_enable()
513 trb_link->bph = upper_32_bits(dwc3_trb_dma_offset(dep, trb_st_hw)); in __dwc3_gadget_ep_enable()
514 trb_link->ctrl |= DWC3_TRBCTL_LINK_TRB; in __dwc3_gadget_ep_enable()
515 trb_link->ctrl |= DWC3_TRB_CTRL_HWO; in __dwc3_gadget_ep_enable()
526 if (!list_empty(&dep->req_queued)) { in dwc3_remove_requests()
527 dwc3_stop_active_transfer(dwc, dep->number, true); in dwc3_remove_requests()
529 /* - giveback all requests to gadget driver */ in dwc3_remove_requests()
530 while (!list_empty(&dep->req_queued)) { in dwc3_remove_requests()
531 req = next_request(&dep->req_queued); in dwc3_remove_requests()
533 dwc3_gadget_giveback(dep, req, -ESHUTDOWN); in dwc3_remove_requests()
537 while (!list_empty(&dep->request_list)) { in dwc3_remove_requests()
538 req = next_request(&dep->request_list); in dwc3_remove_requests()
540 dwc3_gadget_giveback(dep, req, -ESHUTDOWN); in dwc3_remove_requests()
545 * __dwc3_gadget_ep_disable - Disables a HW endpoint
546 * @dep: the endpoint to disable
554 struct dwc3 *dwc = dep->dwc; in __dwc3_gadget_ep_disable()
560 if (dep->flags & DWC3_EP_STALL) in __dwc3_gadget_ep_disable()
563 reg = dwc3_readl(dwc->regs, DWC3_DALEPENA); in __dwc3_gadget_ep_disable()
564 reg &= ~DWC3_DALEPENA_EP(dep->number); in __dwc3_gadget_ep_disable()
565 dwc3_writel(dwc->regs, DWC3_DALEPENA, reg); in __dwc3_gadget_ep_disable()
567 dep->stream_capable = false; in __dwc3_gadget_ep_disable()
568 dep->endpoint.desc = NULL; in __dwc3_gadget_ep_disable()
569 dep->comp_desc = NULL; in __dwc3_gadget_ep_disable()
570 dep->type = 0; in __dwc3_gadget_ep_disable()
571 dep->flags = 0; in __dwc3_gadget_ep_disable()
576 /* -------------------------------------------------------------------------- */
581 return -EINVAL; in dwc3_gadget_ep0_enable()
586 return -EINVAL; in dwc3_gadget_ep0_disable()
589 /* -------------------------------------------------------------------------- */
598 if (!ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) { in dwc3_gadget_ep_enable()
600 return -EINVAL; in dwc3_gadget_ep_enable()
603 if (!desc->wMaxPacketSize) { in dwc3_gadget_ep_enable()
605 return -EINVAL; in dwc3_gadget_ep_enable()
610 if (dep->flags & DWC3_EP_ENABLED) { in dwc3_gadget_ep_enable()
612 dep->name); in dwc3_gadget_ep_enable()
618 strlcat(dep->name, "-control", sizeof(dep->name)); in dwc3_gadget_ep_enable()
621 strlcat(dep->name, "-isoc", sizeof(dep->name)); in dwc3_gadget_ep_enable()
624 strlcat(dep->name, "-bulk", sizeof(dep->name)); in dwc3_gadget_ep_enable()
627 strlcat(dep->name, "-int", sizeof(dep->name)); in dwc3_gadget_ep_enable()
630 dev_err(dwc->dev, "invalid endpoint transfer type\n"); in dwc3_gadget_ep_enable()
633 spin_lock_irqsave(&dwc->lock, flags); in dwc3_gadget_ep_enable()
634 ret = __dwc3_gadget_ep_enable(dep, desc, ep->comp_desc, false, false); in dwc3_gadget_ep_enable()
635 spin_unlock_irqrestore(&dwc->lock, flags); in dwc3_gadget_ep_enable()
648 return -EINVAL; in dwc3_gadget_ep_disable()
653 if (!(dep->flags & DWC3_EP_ENABLED)) { in dwc3_gadget_ep_disable()
655 dep->name); in dwc3_gadget_ep_disable()
659 snprintf(dep->name, sizeof(dep->name), "ep%d%s", in dwc3_gadget_ep_disable()
660 dep->number >> 1, in dwc3_gadget_ep_disable()
661 (dep->number & 1) ? "in" : "out"); in dwc3_gadget_ep_disable()
663 spin_lock_irqsave(&dwc->lock, flags); in dwc3_gadget_ep_disable()
665 spin_unlock_irqrestore(&dwc->lock, flags); in dwc3_gadget_ep_disable()
680 req->epnum = dep->number; in dwc3_gadget_ep_alloc_request()
681 req->dep = dep; in dwc3_gadget_ep_alloc_request()
683 return &req->request; in dwc3_gadget_ep_alloc_request()
695 * dwc3_prepare_one_trb - setup one TRB from one request
705 dev_vdbg(dwc->dev, "%s: req %p dma %08llx length %d%s%s\n", in dwc3_prepare_one_trb()
706 dep->name, req, (unsigned long long) dma, in dwc3_prepare_one_trb()
711 trb = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK]; in dwc3_prepare_one_trb()
713 if (!req->trb) { in dwc3_prepare_one_trb()
715 req->trb = trb; in dwc3_prepare_one_trb()
716 req->trb_dma = dwc3_trb_dma_offset(dep, trb); in dwc3_prepare_one_trb()
717 req->start_slot = dep->free_slot & DWC3_TRB_MASK; in dwc3_prepare_one_trb()
720 dep->free_slot++; in dwc3_prepare_one_trb()
721 /* Skip the LINK-TRB on ISOC */ in dwc3_prepare_one_trb()
722 if (((dep->free_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) && in dwc3_prepare_one_trb()
723 usb_endpoint_xfer_isoc(dep->endpoint.desc)) in dwc3_prepare_one_trb()
724 dep->free_slot++; in dwc3_prepare_one_trb()
726 trb->size = DWC3_TRB_SIZE_LENGTH(length); in dwc3_prepare_one_trb()
727 trb->bpl = lower_32_bits(dma); in dwc3_prepare_one_trb()
728 trb->bph = upper_32_bits(dma); in dwc3_prepare_one_trb()
730 switch (usb_endpoint_type(dep->endpoint.desc)) { in dwc3_prepare_one_trb()
732 trb->ctrl = DWC3_TRBCTL_CONTROL_SETUP; in dwc3_prepare_one_trb()
737 trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST; in dwc3_prepare_one_trb()
739 trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS; in dwc3_prepare_one_trb()
744 trb->ctrl = DWC3_TRBCTL_NORMAL; in dwc3_prepare_one_trb()
754 if (!req->request.no_interrupt && !chain) in dwc3_prepare_one_trb()
755 trb->ctrl |= DWC3_TRB_CTRL_IOC; in dwc3_prepare_one_trb()
757 if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { in dwc3_prepare_one_trb()
758 trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI; in dwc3_prepare_one_trb()
759 trb->ctrl |= DWC3_TRB_CTRL_CSP; in dwc3_prepare_one_trb()
761 trb->ctrl |= DWC3_TRB_CTRL_LST; in dwc3_prepare_one_trb()
765 trb->ctrl |= DWC3_TRB_CTRL_CHN; in dwc3_prepare_one_trb()
767 if (usb_endpoint_xfer_bulk(dep->endpoint.desc) && dep->stream_capable) in dwc3_prepare_one_trb()
768 trb->ctrl |= DWC3_TRB_CTRL_SID_SOFN(req->request.stream_id); in dwc3_prepare_one_trb()
770 trb->ctrl |= DWC3_TRB_CTRL_HWO; in dwc3_prepare_one_trb()
777 * dwc3_prepare_trbs - setup TRBs from requests
794 trbs_left = (dep->busy_slot - dep->free_slot) & DWC3_TRB_MASK; in dwc3_prepare_trbs()
796 /* Can't wrap around on a non-isoc EP since there's no link TRB */ in dwc3_prepare_trbs()
797 if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) { in dwc3_prepare_trbs()
798 max = DWC3_TRB_NUM - (dep->free_slot & DWC3_TRB_MASK); in dwc3_prepare_trbs()
814 * starting from slot 1. This is done because we use ring in dwc3_prepare_trbs()
819 * Other transfer types don't use the ring buffer and are in dwc3_prepare_trbs()
823 if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { in dwc3_prepare_trbs()
824 dep->busy_slot = 1; in dwc3_prepare_trbs()
825 dep->free_slot = 1; in dwc3_prepare_trbs()
827 dep->busy_slot = 0; in dwc3_prepare_trbs()
828 dep->free_slot = 0; in dwc3_prepare_trbs()
833 if ((trbs_left <= 1) && usb_endpoint_xfer_isoc(dep->endpoint.desc)) in dwc3_prepare_trbs()
836 list_for_each_entry_safe(req, n, &dep->request_list, list) { in dwc3_prepare_trbs()
840 dma = req->request.dma; in dwc3_prepare_trbs()
841 length = req->request.length; in dwc3_prepare_trbs()
855 struct dwc3 *dwc = dep->dwc; in __dwc3_gadget_kick_transfer()
859 if (start_new && (dep->flags & DWC3_EP_BUSY)) { in __dwc3_gadget_kick_transfer()
860 dev_vdbg(dwc->dev, "%s: endpoint busy\n", dep->name); in __dwc3_gadget_kick_transfer()
861 return -EBUSY; in __dwc3_gadget_kick_transfer()
863 dep->flags &= ~DWC3_EP_PENDING_REQUEST; in __dwc3_gadget_kick_transfer()
866 * If we are getting here after a short-out-packet we don't enqueue any in __dwc3_gadget_kick_transfer()
870 if (list_empty(&dep->req_queued)) in __dwc3_gadget_kick_transfer()
874 req = next_request(&dep->req_queued); in __dwc3_gadget_kick_transfer()
881 req = next_request(&dep->req_queued); in __dwc3_gadget_kick_transfer()
884 dep->flags |= DWC3_EP_PENDING_REQUEST; in __dwc3_gadget_kick_transfer()
891 params.param0 = upper_32_bits(req->trb_dma); in __dwc3_gadget_kick_transfer()
892 params.param1 = lower_32_bits(req->trb_dma); in __dwc3_gadget_kick_transfer()
899 ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, &params); in __dwc3_gadget_kick_transfer()
901 dev_dbg(dwc->dev, "failed to send STARTTRANSFER command\n"); in __dwc3_gadget_kick_transfer()
908 usb_gadget_unmap_request(&dwc->gadget, &req->request, in __dwc3_gadget_kick_transfer()
909 req->direction); in __dwc3_gadget_kick_transfer()
910 list_del(&req->list); in __dwc3_gadget_kick_transfer()
914 dep->flags |= DWC3_EP_BUSY; in __dwc3_gadget_kick_transfer()
917 dep->resource_index = dwc3_gadget_ep_get_transfer_index(dwc, in __dwc3_gadget_kick_transfer()
918 dep->number); in __dwc3_gadget_kick_transfer()
919 WARN_ON_ONCE(!dep->resource_index); in __dwc3_gadget_kick_transfer()
930 if (list_empty(&dep->request_list)) { in __dwc3_gadget_start_isoc()
931 dev_vdbg(dwc->dev, "ISOC ep %s run out for requests.\n", in __dwc3_gadget_start_isoc()
932 dep->name); in __dwc3_gadget_start_isoc()
933 dep->flags |= DWC3_EP_PENDING_REQUEST; in __dwc3_gadget_start_isoc()
938 uf = cur_uf + dep->interval * 4; in __dwc3_gadget_start_isoc()
948 mask = ~(dep->interval - 1); in dwc3_gadget_start_isoc()
949 cur_uf = event->parameters & mask; in dwc3_gadget_start_isoc()
956 struct dwc3 *dwc = dep->dwc; in __dwc3_gadget_ep_queue()
959 req->request.actual = 0; in __dwc3_gadget_ep_queue()
960 req->request.status = -EINPROGRESS; in __dwc3_gadget_ep_queue()
961 req->direction = dep->direction; in __dwc3_gadget_ep_queue()
962 req->epnum = dep->number; in __dwc3_gadget_ep_queue()
968 if (dep->direction == 0 && in __dwc3_gadget_ep_queue()
969 req->request.length < dep->endpoint.maxpacket) in __dwc3_gadget_ep_queue()
970 req->request.length = dep->endpoint.maxpacket; in __dwc3_gadget_ep_queue()
984 ret = usb_gadget_map_request(&dwc->gadget, &req->request, in __dwc3_gadget_ep_queue()
985 dep->direction); in __dwc3_gadget_ep_queue()
989 list_add_tail(&req->list, &dep->request_list); in __dwc3_gadget_ep_queue()
1002 if (dep->flags & DWC3_EP_PENDING_REQUEST) { in __dwc3_gadget_ep_queue()
1009 if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { in __dwc3_gadget_ep_queue()
1010 if (list_empty(&dep->req_queued)) { in __dwc3_gadget_ep_queue()
1011 dwc3_stop_active_transfer(dwc, dep->number, true); in __dwc3_gadget_ep_queue()
1012 dep->flags = DWC3_EP_ENABLED; in __dwc3_gadget_ep_queue()
1018 if (ret && ret != -EBUSY) in __dwc3_gadget_ep_queue()
1019 dev_dbg(dwc->dev, "%s: failed to kick transfers\n", in __dwc3_gadget_ep_queue()
1020 dep->name); in __dwc3_gadget_ep_queue()
1029 if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && in __dwc3_gadget_ep_queue()
1030 (dep->flags & DWC3_EP_BUSY) && in __dwc3_gadget_ep_queue()
1031 !(dep->flags & DWC3_EP_MISSED_ISOC)) { in __dwc3_gadget_ep_queue()
1032 WARN_ON_ONCE(!dep->resource_index); in __dwc3_gadget_ep_queue()
1033 ret = __dwc3_gadget_kick_transfer(dep, dep->resource_index, in __dwc3_gadget_ep_queue()
1035 if (ret && ret != -EBUSY) in __dwc3_gadget_ep_queue()
1036 dev_dbg(dwc->dev, "%s: failed to kick transfers\n", in __dwc3_gadget_ep_queue()
1037 dep->name); in __dwc3_gadget_ep_queue()
1046 if (dep->stream_capable) { in __dwc3_gadget_ep_queue()
1050 if (ret && ret != -EBUSY) { in __dwc3_gadget_ep_queue()
1051 dev_dbg(dwc->dev, "%s: failed to kick transfers\n", in __dwc3_gadget_ep_queue()
1052 dep->name); in __dwc3_gadget_ep_queue()
1069 spin_lock_irqsave(&dwc->lock, flags); in dwc3_gadget_ep_queue()
1070 if (!dep->endpoint.desc) { in dwc3_gadget_ep_queue()
1071 dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n", in dwc3_gadget_ep_queue()
1072 request, ep->name); in dwc3_gadget_ep_queue()
1073 ret = -ESHUTDOWN; in dwc3_gadget_ep_queue()
1077 if (req->dep != dep) { in dwc3_gadget_ep_queue()
1079 request, req->dep->name); in dwc3_gadget_ep_queue()
1080 ret = -EINVAL; in dwc3_gadget_ep_queue()
1084 dev_vdbg(dwc->dev, "queing request %p to %s length %d\n", in dwc3_gadget_ep_queue()
1085 request, ep->name, request->length); in dwc3_gadget_ep_queue()
1090 spin_unlock_irqrestore(&dwc->lock, flags); in dwc3_gadget_ep_queue()
1102 struct dwc3 *dwc = dep->dwc; in dwc3_gadget_ep_dequeue()
1107 spin_lock_irqsave(&dwc->lock, flags); in dwc3_gadget_ep_dequeue()
1109 list_for_each_entry(r, &dep->request_list, list) { in dwc3_gadget_ep_dequeue()
1115 list_for_each_entry(r, &dep->req_queued, list) { in dwc3_gadget_ep_dequeue()
1121 dwc3_stop_active_transfer(dwc, dep->number, true); in dwc3_gadget_ep_dequeue()
1124 dev_err(dwc->dev, "request %p was not queued to %s\n", in dwc3_gadget_ep_dequeue()
1125 request, ep->name); in dwc3_gadget_ep_dequeue()
1126 ret = -EINVAL; in dwc3_gadget_ep_dequeue()
1132 dwc3_gadget_giveback(dep, req, -ECONNRESET); in dwc3_gadget_ep_dequeue()
1135 spin_unlock_irqrestore(&dwc->lock, flags); in dwc3_gadget_ep_dequeue()
1143 struct dwc3 *dwc = dep->dwc; in __dwc3_gadget_ep_set_halt()
1146 if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { in __dwc3_gadget_ep_set_halt()
1147 dev_err(dwc->dev, "%s is of Isochronous type\n", dep->name); in __dwc3_gadget_ep_set_halt()
1148 return -EINVAL; in __dwc3_gadget_ep_set_halt()
1154 if (!protocol && ((dep->direction && dep->flags & DWC3_EP_BUSY) || in __dwc3_gadget_ep_set_halt()
1155 (!list_empty(&dep->req_queued) || in __dwc3_gadget_ep_set_halt()
1156 !list_empty(&dep->request_list)))) { in __dwc3_gadget_ep_set_halt()
1157 dev_dbg(dwc->dev, "%s: pending request, cannot halt\n", in __dwc3_gadget_ep_set_halt()
1158 dep->name); in __dwc3_gadget_ep_set_halt()
1159 return -EAGAIN; in __dwc3_gadget_ep_set_halt()
1162 ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, in __dwc3_gadget_ep_set_halt()
1165 dev_err(dwc->dev, "failed to set STALL on %s\n", in __dwc3_gadget_ep_set_halt()
1166 dep->name); in __dwc3_gadget_ep_set_halt()
1168 dep->flags |= DWC3_EP_STALL; in __dwc3_gadget_ep_set_halt()
1170 ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, in __dwc3_gadget_ep_set_halt()
1173 dev_err(dwc->dev, "failed to clear STALL on %s\n", in __dwc3_gadget_ep_set_halt()
1174 dep->name); in __dwc3_gadget_ep_set_halt()
1176 dep->flags &= ~(DWC3_EP_STALL | DWC3_EP_WEDGE); in __dwc3_gadget_ep_set_halt()
1190 spin_lock_irqsave(&dwc->lock, flags); in dwc3_gadget_ep_set_halt()
1192 spin_unlock_irqrestore(&dwc->lock, flags); in dwc3_gadget_ep_set_halt()
1203 spin_lock_irqsave(&dwc->lock, flags); in dwc3_gadget_ep_set_wedge()
1204 dep->flags |= DWC3_EP_WEDGE; in dwc3_gadget_ep_set_wedge()
1206 if (dep->number == 0 || dep->number == 1) in dwc3_gadget_ep_set_wedge()
1210 spin_unlock_irqrestore(&dwc->lock, flags); in dwc3_gadget_ep_set_wedge()
1215 /* -------------------------------------------------------------------------- */
1225 .disable = dwc3_gadget_ep0_disable,
1236 .disable = dwc3_gadget_ep_disable,
1245 /* -------------------------------------------------------------------------- */
1252 reg = dwc3_readl(dwc->regs, DWC3_DSTS); in dwc3_gadget_get_frame()
1270 spin_lock_irqsave(&dwc->lock, flags); in dwc3_gadget_wakeup()
1278 reg = dwc3_readl(dwc->regs, DWC3_DSTS); in dwc3_gadget_wakeup()
1282 dev_dbg(dwc->dev, "no wakeup on SuperSpeed\n"); in dwc3_gadget_wakeup()
1283 ret = -EINVAL; in dwc3_gadget_wakeup()
1294 dev_dbg(dwc->dev, "can't wakeup from link state %d\n", in dwc3_gadget_wakeup()
1296 ret = -EINVAL; in dwc3_gadget_wakeup()
1302 dev_err(dwc->dev, "failed to put link in Recovery\n"); in dwc3_gadget_wakeup()
1307 if (dwc->revision < DWC3_REVISION_194A) { in dwc3_gadget_wakeup()
1309 reg = dwc3_readl(dwc->regs, DWC3_DCTL); in dwc3_gadget_wakeup()
1311 dwc3_writel(dwc->regs, DWC3_DCTL, reg); in dwc3_gadget_wakeup()
1317 while (timeout--) { in dwc3_gadget_wakeup()
1318 reg = dwc3_readl(dwc->regs, DWC3_DSTS); in dwc3_gadget_wakeup()
1326 dev_err(dwc->dev, "failed to send remote wakeup\n"); in dwc3_gadget_wakeup()
1327 ret = -EINVAL; in dwc3_gadget_wakeup()
1331 spin_unlock_irqrestore(&dwc->lock, flags); in dwc3_gadget_wakeup()
1342 spin_lock_irqsave(&dwc->lock, flags); in dwc3_gadget_set_selfpowered()
1343 dwc->is_selfpowered = !!is_selfpowered; in dwc3_gadget_set_selfpowered()
1344 spin_unlock_irqrestore(&dwc->lock, flags); in dwc3_gadget_set_selfpowered()
1354 reg = dwc3_readl(dwc->regs, DWC3_DCTL); in dwc3_gadget_run_stop()
1356 if (dwc->revision <= DWC3_REVISION_187A) { in dwc3_gadget_run_stop()
1361 if (dwc->revision >= DWC3_REVISION_194A) in dwc3_gadget_run_stop()
1365 if (dwc->has_hibernation) in dwc3_gadget_run_stop()
1368 dwc->pullups_connected = true; in dwc3_gadget_run_stop()
1372 if (dwc->has_hibernation && !suspend) in dwc3_gadget_run_stop()
1375 dwc->pullups_connected = false; in dwc3_gadget_run_stop()
1378 dwc3_writel(dwc->regs, DWC3_DCTL, reg); in dwc3_gadget_run_stop()
1381 reg = dwc3_readl(dwc->regs, DWC3_DSTS); in dwc3_gadget_run_stop()
1389 timeout--; in dwc3_gadget_run_stop()
1391 return -ETIMEDOUT; in dwc3_gadget_run_stop()
1395 dev_vdbg(dwc->dev, "gadget %s data soft-%s\n", in dwc3_gadget_run_stop()
1396 dwc->gadget_driver in dwc3_gadget_run_stop()
1397 ? dwc->gadget_driver->function : "no-function", in dwc3_gadget_run_stop()
1411 spin_lock_irqsave(&dwc->lock, flags); in dwc3_gadget_pullup()
1413 spin_unlock_irqrestore(&dwc->lock, flags); in dwc3_gadget_pullup()
1433 dwc3_writel(dwc->regs, DWC3_DEVTEN, reg); in dwc3_gadget_enable_irq()
1439 dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00); in dwc3_gadget_disable_irq()
1451 spin_lock_irqsave(&dwc->lock, flags); in dwc3_gadget_start()
1453 if (dwc->gadget_driver) { in dwc3_gadget_start()
1454 dev_err(dwc->dev, "%s is already bound to %s\n", in dwc3_gadget_start()
1455 dwc->gadget.name, in dwc3_gadget_start()
1456 dwc->gadget_driver->function); in dwc3_gadget_start()
1457 ret = -EBUSY; in dwc3_gadget_start()
1461 dwc->gadget_driver = driver; in dwc3_gadget_start()
1463 reg = dwc3_readl(dwc->regs, DWC3_DCFG); in dwc3_gadget_start()
1469 * bit if we try to force the IP to USB2-only mode. in dwc3_gadget_start()
1479 if (dwc->revision < DWC3_REVISION_220A) { in dwc3_gadget_start()
1482 switch (dwc->maximum_speed) { in dwc3_gadget_start()
1498 dwc3_writel(dwc->regs, DWC3_DCFG, reg); in dwc3_gadget_start()
1500 dwc->start_config_issued = false; in dwc3_gadget_start()
1505 dep = dwc->eps[0]; in dwc3_gadget_start()
1509 dev_err(dwc->dev, "failed to enable %s\n", dep->name); in dwc3_gadget_start()
1513 dep = dwc->eps[1]; in dwc3_gadget_start()
1517 dev_err(dwc->dev, "failed to enable %s\n", dep->name); in dwc3_gadget_start()
1522 dwc->ep0state = EP0_SETUP_PHASE; in dwc3_gadget_start()
1527 spin_unlock_irqrestore(&dwc->lock, flags); in dwc3_gadget_start()
1532 __dwc3_gadget_ep_disable(dwc->eps[0]); in dwc3_gadget_start()
1535 dwc->gadget_driver = NULL; in dwc3_gadget_start()
1538 spin_unlock_irqrestore(&dwc->lock, flags); in dwc3_gadget_start()
1548 spin_lock_irqsave(&dwc->lock, flags); in dwc3_gadget_stop()
1551 __dwc3_gadget_ep_disable(dwc->eps[0]); in dwc3_gadget_stop()
1552 __dwc3_gadget_ep_disable(dwc->eps[1]); in dwc3_gadget_stop()
1554 dwc->gadget_driver = NULL; in dwc3_gadget_stop()
1556 spin_unlock_irqrestore(&dwc->lock, flags); in dwc3_gadget_stop()
1565 .pullup = dwc3_gadget_pullup,
1570 /* -------------------------------------------------------------------------- */
1583 return -ENOMEM; in dwc3_gadget_init_hw_endpoints()
1585 dep->dwc = dwc; in dwc3_gadget_init_hw_endpoints()
1586 dep->number = epnum; in dwc3_gadget_init_hw_endpoints()
1587 dep->direction = !!direction; in dwc3_gadget_init_hw_endpoints()
1588 dwc->eps[epnum] = dep; in dwc3_gadget_init_hw_endpoints()
1590 snprintf(dep->name, sizeof(dep->name), "ep%d%s", epnum >> 1, in dwc3_gadget_init_hw_endpoints()
1593 dep->endpoint.name = dep->name; in dwc3_gadget_init_hw_endpoints()
1595 dev_vdbg(dwc->dev, "initializing %s\n", dep->name); in dwc3_gadget_init_hw_endpoints()
1598 usb_ep_set_maxpacket_limit(&dep->endpoint, 512); in dwc3_gadget_init_hw_endpoints()
1599 dep->endpoint.maxburst = 1; in dwc3_gadget_init_hw_endpoints()
1600 dep->endpoint.ops = &dwc3_gadget_ep0_ops; in dwc3_gadget_init_hw_endpoints()
1602 dwc->gadget.ep0 = &dep->endpoint; in dwc3_gadget_init_hw_endpoints()
1606 usb_ep_set_maxpacket_limit(&dep->endpoint, 512); in dwc3_gadget_init_hw_endpoints()
1607 dep->endpoint.max_streams = 15; in dwc3_gadget_init_hw_endpoints()
1608 dep->endpoint.ops = &dwc3_gadget_ep_ops; in dwc3_gadget_init_hw_endpoints()
1609 list_add_tail(&dep->endpoint.ep_list, in dwc3_gadget_init_hw_endpoints()
1610 &dwc->gadget.ep_list); in dwc3_gadget_init_hw_endpoints()
1617 INIT_LIST_HEAD(&dep->request_list); in dwc3_gadget_init_hw_endpoints()
1618 INIT_LIST_HEAD(&dep->req_queued); in dwc3_gadget_init_hw_endpoints()
1628 INIT_LIST_HEAD(&dwc->gadget.ep_list); in dwc3_gadget_init_endpoints()
1630 ret = dwc3_gadget_init_hw_endpoints(dwc, dwc->num_out_eps, 0); in dwc3_gadget_init_endpoints()
1632 dev_vdbg(dwc->dev, "failed to allocate OUT endpoints\n"); in dwc3_gadget_init_endpoints()
1636 ret = dwc3_gadget_init_hw_endpoints(dwc, dwc->num_in_eps, 1); in dwc3_gadget_init_endpoints()
1638 dev_vdbg(dwc->dev, "failed to allocate IN endpoints\n"); in dwc3_gadget_init_endpoints()
1651 dep = dwc->eps[epnum]; in dwc3_gadget_free_endpoints()
1656 * bi-directional USB endpoint 0. in dwc3_gadget_free_endpoints()
1665 list_del(&dep->endpoint.ep_list); in dwc3_gadget_free_endpoints()
1672 /* -------------------------------------------------------------------------- */
1682 if ((trb->ctrl & DWC3_TRB_CTRL_HWO) && status != -ESHUTDOWN) in __dwc3_cleanup_done_trbs()
1687 * while since we use them in a ring buffer. A BUG() in __dwc3_cleanup_done_trbs()
1691 dev_err(dwc->dev, "%s's TRB (%p) still owned by HW\n", in __dwc3_cleanup_done_trbs()
1692 dep->name, trb); in __dwc3_cleanup_done_trbs()
1693 count = trb->size & DWC3_TRB_SIZE_MASK; in __dwc3_cleanup_done_trbs()
1695 if (dep->direction) { in __dwc3_cleanup_done_trbs()
1697 trb_status = DWC3_TRB_SIZE_TRBSTS(trb->size); in __dwc3_cleanup_done_trbs()
1699 dev_dbg(dwc->dev, "incomplete IN transfer %s\n", in __dwc3_cleanup_done_trbs()
1700 dep->name); in __dwc3_cleanup_done_trbs()
1716 dep->flags |= DWC3_EP_MISSED_ISOC; in __dwc3_cleanup_done_trbs()
1718 dev_err(dwc->dev, "incomplete IN transfer %s\n", in __dwc3_cleanup_done_trbs()
1719 dep->name); in __dwc3_cleanup_done_trbs()
1720 status = -ECONNRESET; in __dwc3_cleanup_done_trbs()
1723 dep->flags &= ~DWC3_EP_MISSED_ISOC; in __dwc3_cleanup_done_trbs()
1726 if (count && (event->status & DEPEVT_STATUS_SHORT)) in __dwc3_cleanup_done_trbs()
1737 req->request.actual += req->request.length - count; in __dwc3_cleanup_done_trbs()
1740 if ((event->status & DEPEVT_STATUS_LST) && in __dwc3_cleanup_done_trbs()
1741 (trb->ctrl & (DWC3_TRB_CTRL_LST | in __dwc3_cleanup_done_trbs()
1744 if ((event->status & DEPEVT_STATUS_IOC) && in __dwc3_cleanup_done_trbs()
1745 (trb->ctrl & DWC3_TRB_CTRL_IOC)) in __dwc3_cleanup_done_trbs()
1757 req = next_request(&dep->req_queued); in dwc3_cleanup_done_reqs()
1763 slot = req->start_slot; in dwc3_cleanup_done_reqs()
1764 if ((slot == DWC3_TRB_NUM - 1) && in dwc3_cleanup_done_reqs()
1765 usb_endpoint_xfer_isoc(dep->endpoint.desc)) in dwc3_cleanup_done_reqs()
1768 trb = &dep->trb_pool[slot]; in dwc3_cleanup_done_reqs()
1774 if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && in dwc3_cleanup_done_reqs()
1775 list_empty(&dep->req_queued)) { in dwc3_cleanup_done_reqs()
1776 if (list_empty(&dep->request_list)) { in dwc3_cleanup_done_reqs()
1783 dep->flags = DWC3_EP_PENDING_REQUEST; in dwc3_cleanup_done_reqs()
1785 dwc3_stop_active_transfer(dwc, dep->number, true); in dwc3_cleanup_done_reqs()
1786 dep->flags = DWC3_EP_ENABLED; in dwc3_cleanup_done_reqs()
1800 if (event->status & DEPEVT_STATUS_BUSERR) in dwc3_endpoint_transfer_complete()
1801 status = -ECONNRESET; in dwc3_endpoint_transfer_complete()
1805 dep->flags &= ~DWC3_EP_BUSY; in dwc3_endpoint_transfer_complete()
1808 * WORKAROUND: This is the 2nd half of U1/U2 -> U0 workaround. in dwc3_endpoint_transfer_complete()
1811 if (dwc->revision < DWC3_REVISION_183A) { in dwc3_endpoint_transfer_complete()
1816 dep = dwc->eps[i]; in dwc3_endpoint_transfer_complete()
1818 if (!(dep->flags & DWC3_EP_ENABLED)) in dwc3_endpoint_transfer_complete()
1821 if (!list_empty(&dep->req_queued)) in dwc3_endpoint_transfer_complete()
1825 reg = dwc3_readl(dwc->regs, DWC3_DCTL); in dwc3_endpoint_transfer_complete()
1826 reg |= dwc->u1u2; in dwc3_endpoint_transfer_complete()
1827 dwc3_writel(dwc->regs, DWC3_DCTL, reg); in dwc3_endpoint_transfer_complete()
1829 dwc->u1u2 = 0; in dwc3_endpoint_transfer_complete()
1837 u8 epnum = event->endpoint_number; in dwc3_endpoint_interrupt()
1839 dep = dwc->eps[epnum]; in dwc3_endpoint_interrupt()
1841 if (!(dep->flags & DWC3_EP_ENABLED)) in dwc3_endpoint_interrupt()
1849 switch (event->endpoint_event) { in dwc3_endpoint_interrupt()
1851 dep->resource_index = 0; in dwc3_endpoint_interrupt()
1853 if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { in dwc3_endpoint_interrupt()
1854 dev_dbg(dwc->dev, "%s is an Isochronous endpoint\n", in dwc3_endpoint_interrupt()
1855 dep->name); in dwc3_endpoint_interrupt()
1865 if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { in dwc3_endpoint_interrupt()
1870 dev_vdbg(dwc->dev, "%s: reason %s\n", in dwc3_endpoint_interrupt()
1871 dep->name, event->status & in dwc3_endpoint_interrupt()
1877 if (!ret || ret == -EBUSY) in dwc3_endpoint_interrupt()
1880 dev_dbg(dwc->dev, "%s: failed to kick transfers\n", in dwc3_endpoint_interrupt()
1881 dep->name); in dwc3_endpoint_interrupt()
1886 if (!usb_endpoint_xfer_bulk(dep->endpoint.desc)) { in dwc3_endpoint_interrupt()
1887 dev_err(dwc->dev, "Stream event for non-Bulk %s\n", in dwc3_endpoint_interrupt()
1888 dep->name); in dwc3_endpoint_interrupt()
1892 switch (event->status) { in dwc3_endpoint_interrupt()
1894 dev_vdbg(dwc->dev, "Stream %d found and started\n", in dwc3_endpoint_interrupt()
1895 event->parameters); in dwc3_endpoint_interrupt()
1901 dev_dbg(dwc->dev, "Couldn't find suitable stream\n"); in dwc3_endpoint_interrupt()
1905 dev_dbg(dwc->dev, "%s FIFO Overrun\n", dep->name); in dwc3_endpoint_interrupt()
1908 dev_vdbg(dwc->dev, "Endpoint Command Complete\n"); in dwc3_endpoint_interrupt()
1915 if (dwc->gadget_driver && dwc->gadget_driver->disconnect) { in dwc3_disconnect_gadget()
1916 spin_unlock(&dwc->lock); in dwc3_disconnect_gadget()
1917 dwc->gadget_driver->disconnect(&dwc->gadget); in dwc3_disconnect_gadget()
1918 spin_lock(&dwc->lock); in dwc3_disconnect_gadget()
1924 if (dwc->gadget_driver && dwc->gadget_driver->suspend) { in dwc3_suspend_gadget()
1925 spin_unlock(&dwc->lock); in dwc3_suspend_gadget()
1926 dwc->gadget_driver->suspend(&dwc->gadget); in dwc3_suspend_gadget()
1927 spin_lock(&dwc->lock); in dwc3_suspend_gadget()
1933 if (dwc->gadget_driver && dwc->gadget_driver->resume) { in dwc3_resume_gadget()
1934 spin_unlock(&dwc->lock); in dwc3_resume_gadget()
1935 dwc->gadget_driver->resume(&dwc->gadget); in dwc3_resume_gadget()
1941 if (!dwc->gadget_driver) in dwc3_reset_gadget()
1944 if (dwc->gadget.speed != USB_SPEED_UNKNOWN) { in dwc3_reset_gadget()
1945 spin_unlock(&dwc->lock); in dwc3_reset_gadget()
1946 usb_gadget_udc_reset(&dwc->gadget, dwc->gadget_driver); in dwc3_reset_gadget()
1947 spin_lock(&dwc->lock); in dwc3_reset_gadget()
1958 dep = dwc->eps[epnum]; in dwc3_stop_active_transfer()
1960 if (!dep->resource_index) in dwc3_stop_active_transfer()
1978 * - Issue EndTransfer WITH CMDIOC bit set in dwc3_stop_active_transfer()
1979 * - Wait 100us in dwc3_stop_active_transfer()
1985 cmd |= DWC3_DEPCMD_PARAM(dep->resource_index); in dwc3_stop_active_transfer()
1987 ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, &params); in dwc3_stop_active_transfer()
1989 dep->resource_index = 0; in dwc3_stop_active_transfer()
1990 dep->flags &= ~DWC3_EP_BUSY; in dwc3_stop_active_transfer()
2001 dep = dwc->eps[epnum]; in dwc3_stop_active_transfers()
2005 if (!(dep->flags & DWC3_EP_ENABLED)) in dwc3_stop_active_transfers()
2021 dep = dwc->eps[epnum]; in dwc3_clear_stall_all_ep()
2025 if (!(dep->flags & DWC3_EP_STALL)) in dwc3_clear_stall_all_ep()
2028 dep->flags &= ~DWC3_EP_STALL; in dwc3_clear_stall_all_ep()
2031 ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, in dwc3_clear_stall_all_ep()
2041 reg = dwc3_readl(dwc->regs, DWC3_DCTL); in dwc3_gadget_disconnect_interrupt()
2043 dwc3_writel(dwc->regs, DWC3_DCTL, reg); in dwc3_gadget_disconnect_interrupt()
2046 dwc3_writel(dwc->regs, DWC3_DCTL, reg); in dwc3_gadget_disconnect_interrupt()
2049 dwc->start_config_issued = false; in dwc3_gadget_disconnect_interrupt()
2051 dwc->gadget.speed = USB_SPEED_UNKNOWN; in dwc3_gadget_disconnect_interrupt()
2052 dwc->setup_packet_pending = false; in dwc3_gadget_disconnect_interrupt()
2053 usb_gadget_set_state(&dwc->gadget, USB_STATE_NOTATTACHED); in dwc3_gadget_disconnect_interrupt()
2086 if (dwc->revision < DWC3_REVISION_188A) { in dwc3_gadget_reset_interrupt()
2087 if (dwc->setup_packet_pending) in dwc3_gadget_reset_interrupt()
2093 reg = dwc3_readl(dwc->regs, DWC3_DCTL); in dwc3_gadget_reset_interrupt()
2095 dwc3_writel(dwc->regs, DWC3_DCTL, reg); in dwc3_gadget_reset_interrupt()
2096 dwc->test_mode = false; in dwc3_gadget_reset_interrupt()
2100 dwc->start_config_issued = false; in dwc3_gadget_reset_interrupt()
2103 reg = dwc3_readl(dwc->regs, DWC3_DCFG); in dwc3_gadget_reset_interrupt()
2105 dwc3_writel(dwc->regs, DWC3_DCFG, reg); in dwc3_gadget_reset_interrupt()
2128 reg = dwc3_readl(dwc->regs, DWC3_GCTL); in dwc3_update_ram_clk_sel()
2130 dwc3_writel(dwc->regs, DWC3_GCTL, reg); in dwc3_update_ram_clk_sel()
2140 reg = dwc3_readl(dwc->regs, DWC3_DSTS); in dwc3_gadget_conndone_interrupt()
2142 dwc->speed = speed; in dwc3_gadget_conndone_interrupt()
2161 if (dwc->revision < DWC3_REVISION_190A) in dwc3_gadget_conndone_interrupt()
2165 dwc->gadget.ep0->maxpacket = 512; in dwc3_gadget_conndone_interrupt()
2166 dwc->gadget.speed = USB_SPEED_SUPER; in dwc3_gadget_conndone_interrupt()
2170 dwc->gadget.ep0->maxpacket = 64; in dwc3_gadget_conndone_interrupt()
2171 dwc->gadget.speed = USB_SPEED_HIGH; in dwc3_gadget_conndone_interrupt()
2176 dwc->gadget.ep0->maxpacket = 64; in dwc3_gadget_conndone_interrupt()
2177 dwc->gadget.speed = USB_SPEED_FULL; in dwc3_gadget_conndone_interrupt()
2181 dwc->gadget.ep0->maxpacket = 8; in dwc3_gadget_conndone_interrupt()
2182 dwc->gadget.speed = USB_SPEED_LOW; in dwc3_gadget_conndone_interrupt()
2188 if ((dwc->revision > DWC3_REVISION_194A) in dwc3_gadget_conndone_interrupt()
2190 reg = dwc3_readl(dwc->regs, DWC3_DCFG); in dwc3_gadget_conndone_interrupt()
2192 dwc3_writel(dwc->regs, DWC3_DCFG, reg); in dwc3_gadget_conndone_interrupt()
2194 reg = dwc3_readl(dwc->regs, DWC3_DCTL); in dwc3_gadget_conndone_interrupt()
2197 reg |= DWC3_DCTL_HIRD_THRES(dwc->hird_threshold); in dwc3_gadget_conndone_interrupt()
2205 if (dwc->revision < DWC3_REVISION_240A && dwc->has_lpm_erratum) in dwc3_gadget_conndone_interrupt()
2208 if (dwc->has_lpm_erratum && dwc->revision >= DWC3_REVISION_240A) in dwc3_gadget_conndone_interrupt()
2209 reg |= DWC3_DCTL_LPM_ERRATA(dwc->lpm_nyet_threshold); in dwc3_gadget_conndone_interrupt()
2211 dwc3_writel(dwc->regs, DWC3_DCTL, reg); in dwc3_gadget_conndone_interrupt()
2213 reg = dwc3_readl(dwc->regs, DWC3_DCTL); in dwc3_gadget_conndone_interrupt()
2215 dwc3_writel(dwc->regs, DWC3_DCTL, reg); in dwc3_gadget_conndone_interrupt()
2218 dep = dwc->eps[0]; in dwc3_gadget_conndone_interrupt()
2222 dev_err(dwc->dev, "failed to enable %s\n", dep->name); in dwc3_gadget_conndone_interrupt()
2226 dep = dwc->eps[1]; in dwc3_gadget_conndone_interrupt()
2230 dev_err(dwc->dev, "failed to enable %s\n", dep->name); in dwc3_gadget_conndone_interrupt()
2250 dwc->gadget_driver->resume(&dwc->gadget); in dwc3_gadget_wakeup_interrupt()
2262 * host-initiated U3 exit. in dwc3_gadget_linksts_change_interrupt()
2273 * STAR#9000570034 RTL: SS Resume event generated in non-Hibernation in dwc3_gadget_linksts_change_interrupt()
2276 pwropt = DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams1); in dwc3_gadget_linksts_change_interrupt()
2277 if ((dwc->revision < DWC3_REVISION_250A) && in dwc3_gadget_linksts_change_interrupt()
2279 if ((dwc->link_state == DWC3_LINK_STATE_U3) && in dwc3_gadget_linksts_change_interrupt()
2281 dev_vdbg(dwc->dev, "ignoring transition U3 -> Resume\n"); in dwc3_gadget_linksts_change_interrupt()
2292 * suggested workaround is to disable DCTL[12:9] bits if we're in dwc3_gadget_linksts_change_interrupt()
2301 * STAR#9000446952: RTL: Device SS : if U1/U2 ->U0 takes >128us in dwc3_gadget_linksts_change_interrupt()
2304 if (dwc->revision < DWC3_REVISION_183A) { in dwc3_gadget_linksts_change_interrupt()
2309 switch (dwc->link_state) { in dwc3_gadget_linksts_change_interrupt()
2312 reg = dwc3_readl(dwc->regs, DWC3_DCTL); in dwc3_gadget_linksts_change_interrupt()
2318 if (!dwc->u1u2) in dwc3_gadget_linksts_change_interrupt()
2319 dwc->u1u2 = reg & u1u2; in dwc3_gadget_linksts_change_interrupt()
2323 dwc3_writel(dwc->regs, DWC3_DCTL, reg); in dwc3_gadget_linksts_change_interrupt()
2334 if (dwc->speed == USB_SPEED_SUPER) in dwc3_gadget_linksts_change_interrupt()
2349 dwc->link_state = next; in dwc3_gadget_linksts_change_interrupt()
2370 if (is_ss ^ (dwc->speed == USB_SPEED_SUPER)) in dwc3_gadget_hibernation_interrupt()
2379 switch (event->type) { in dwc3_gadget_interrupt()
2393 if (!dwc->has_hibernation) { in dwc3_gadget_interrupt()
2397 dwc3_gadget_hibernation_interrupt(dwc, event->event_info); in dwc3_gadget_interrupt()
2400 dwc3_gadget_linksts_change_interrupt(dwc, event->event_info); in dwc3_gadget_interrupt()
2403 dev_vdbg(dwc->dev, "End of Periodic Frame\n"); in dwc3_gadget_interrupt()
2406 dev_vdbg(dwc->dev, "Start of Periodic Frame\n"); in dwc3_gadget_interrupt()
2409 dev_vdbg(dwc->dev, "Erratic Error\n"); in dwc3_gadget_interrupt()
2412 dev_vdbg(dwc->dev, "Command Complete\n"); in dwc3_gadget_interrupt()
2415 dev_vdbg(dwc->dev, "Overflow\n"); in dwc3_gadget_interrupt()
2418 dev_dbg(dwc->dev, "UNKNOWN IRQ %d\n", event->type); in dwc3_gadget_interrupt()
2426 if (event->type.is_devspec == 0) { in dwc3_process_event_entry()
2428 return dwc3_endpoint_interrupt(dwc, &event->depevt); in dwc3_process_event_entry()
2431 switch (event->type.type) { in dwc3_process_event_entry()
2433 dwc3_gadget_interrupt(dwc, &event->devt); in dwc3_process_event_entry()
2437 dev_err(dwc->dev, "UNKNOWN IRQ type %d\n", event->raw); in dwc3_process_event_entry()
2448 evt = dwc->ev_buffs[buf]; in dwc3_process_event_buf()
2449 left = evt->count; in dwc3_process_event_buf()
2451 if (!(evt->flags & DWC3_EVENT_PENDING)) in dwc3_process_event_buf()
2457 event.raw = *(u32 *) (evt->buf + evt->lpos); in dwc3_process_event_buf()
2470 evt->lpos = (evt->lpos + 4) % DWC3_EVENT_BUFFERS_SIZE; in dwc3_process_event_buf()
2471 left -= 4; in dwc3_process_event_buf()
2473 dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(buf), 4); in dwc3_process_event_buf()
2476 evt->count = 0; in dwc3_process_event_buf()
2477 evt->flags &= ~DWC3_EVENT_PENDING; in dwc3_process_event_buf()
2481 reg = dwc3_readl(dwc->regs, DWC3_GEVNTSIZ(buf)); in dwc3_process_event_buf()
2483 dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(buf), reg); in dwc3_process_event_buf()
2495 spin_lock_irqsave(&dwc->lock, flags); in dwc3_thread_interrupt()
2497 for (i = 0; i < dwc->num_event_buffers; i++) in dwc3_thread_interrupt()
2500 spin_unlock_irqrestore(&dwc->lock, flags); in dwc3_thread_interrupt()
2511 evt = dwc->ev_buffs[buf]; in dwc3_check_event_buf()
2513 count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(buf)); in dwc3_check_event_buf()
2518 evt->count = count; in dwc3_check_event_buf()
2519 evt->flags |= DWC3_EVENT_PENDING; in dwc3_check_event_buf()
2522 reg = dwc3_readl(dwc->regs, DWC3_GEVNTSIZ(buf)); in dwc3_check_event_buf()
2524 dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(buf), reg); in dwc3_check_event_buf()
2535 spin_lock(&dwc->lock); in dwc3_interrupt()
2537 for (i = 0; i < dwc->num_event_buffers; i++) { in dwc3_interrupt()
2545 spin_unlock(&dwc->lock); in dwc3_interrupt()
2551 * dwc3_gadget_init - Initializes gadget related registers
2560 dwc->ctrl_req = dma_alloc_coherent(sizeof(*dwc->ctrl_req), in dwc3_gadget_init()
2561 (unsigned long *)&dwc->ctrl_req_addr); in dwc3_gadget_init()
2562 if (!dwc->ctrl_req) { in dwc3_gadget_init()
2563 dev_err(dwc->dev, "failed to allocate ctrl request\n"); in dwc3_gadget_init()
2564 ret = -ENOMEM; in dwc3_gadget_init()
2568 dwc->ep0_trb = dma_alloc_coherent(sizeof(*dwc->ep0_trb) * 2, in dwc3_gadget_init()
2569 (unsigned long *)&dwc->ep0_trb_addr); in dwc3_gadget_init()
2570 if (!dwc->ep0_trb) { in dwc3_gadget_init()
2571 dev_err(dwc->dev, "failed to allocate ep0 trb\n"); in dwc3_gadget_init()
2572 ret = -ENOMEM; in dwc3_gadget_init()
2576 dwc->setup_buf = memalign(CONFIG_SYS_CACHELINE_SIZE, in dwc3_gadget_init()
2578 if (!dwc->setup_buf) { in dwc3_gadget_init()
2579 ret = -ENOMEM; in dwc3_gadget_init()
2583 dwc->ep0_bounce = dma_alloc_coherent(DWC3_EP0_BOUNCE_SIZE, in dwc3_gadget_init()
2584 (unsigned long *)&dwc->ep0_bounce_addr); in dwc3_gadget_init()
2585 if (!dwc->ep0_bounce) { in dwc3_gadget_init()
2586 dev_err(dwc->dev, "failed to allocate ep0 bounce buffer\n"); in dwc3_gadget_init()
2587 ret = -ENOMEM; in dwc3_gadget_init()
2591 dwc->gadget.ops = &dwc3_gadget_ops; in dwc3_gadget_init()
2592 dwc->gadget.max_speed = USB_SPEED_SUPER; in dwc3_gadget_init()
2593 dwc->gadget.speed = USB_SPEED_UNKNOWN; in dwc3_gadget_init()
2594 dwc->gadget.name = "dwc3-gadget"; in dwc3_gadget_init()
2600 dwc->gadget.quirk_ep_out_aligned_size = true; in dwc3_gadget_init()
2611 ret = usb_add_gadget_udc((struct device *)dwc->dev, &dwc->gadget); in dwc3_gadget_init()
2613 dev_err(dwc->dev, "failed to register udc\n"); in dwc3_gadget_init()
2621 dma_free_coherent(dwc->ep0_bounce); in dwc3_gadget_init()
2624 kfree(dwc->setup_buf); in dwc3_gadget_init()
2627 dma_free_coherent(dwc->ep0_trb); in dwc3_gadget_init()
2630 dma_free_coherent(dwc->ctrl_req); in dwc3_gadget_init()
2636 /* -------------------------------------------------------------------------- */
2640 usb_del_gadget_udc(&dwc->gadget); in dwc3_gadget_exit()
2644 dma_free_coherent(dwc->ep0_bounce); in dwc3_gadget_exit()
2646 kfree(dwc->setup_buf); in dwc3_gadget_exit()
2648 dma_free_coherent(dwc->ep0_trb); in dwc3_gadget_exit()
2650 dma_free_coherent(dwc->ctrl_req); in dwc3_gadget_exit()
2654 * dwc3_gadget_uboot_handle_interrupt - handle dwc3 gadget interrupt
2672 for (i = 0; i < dwc->num_event_buffers; i++) { in dwc3_gadget_uboot_handle_interrupt()
2673 evt = dwc->ev_buffs[i]; in dwc3_gadget_uboot_handle_interrupt()
2674 dwc3_flush_cache((uintptr_t)evt->buf, evt->length); in dwc3_gadget_uboot_handle_interrupt()