summaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc2
diff options
context:
space:
mode:
authorMinas Harutyunyan <Minas.Harutyunyan@synopsys.com>2018-05-03 09:24:28 -0400
committerFelipe Balbi <felipe.balbi@linux.intel.com>2018-05-15 03:16:19 -0400
commit729cac693eecfebdb9e152eaddddd358ae2decb7 (patch)
tree6002249f144d723d9491c7f36d4f66505cfe6747 /drivers/usb/dwc2
parentf39846824cd682c6662f90ec67bf136897cf60e8 (diff)
usb: dwc2: Change ISOC DDMA flow
Changed existing two descriptor-chain flow to one chain. In two-chain implementation BNA interrupt used for switching between two chains. BNA interrupt asserted because of returning to beginning of the chain based on L-bit of last descriptor. Because of that we lose packets. This issue resolved by using one desc-chain. Removed all staff related to two desc-chain flow from DDMA ISOC related functions. Removed request length checking from dwc2_gadget_fill_isoc_desc() function. Request length checking added to dwc2_hsotg_ep_queue() function. If request length greater than descriptor limits then request not added to queue. Additional checking done for High Bandwidth ISOC OUT's which not supported by driver. In dwc2_gadget_fill_isoc_desc() function also checked desc-chain status (full or not) to avoid of reusing not yet processed descriptors. In dwc2_gadget_start_isoc_ddma() function creation of desc-chain always started from descriptor 0. Before filling descriptors, they were initialized by HOST BUSY status. In dwc2_gadget_complete_isoc_request_ddma() added checking for desc-chain rollover. Also added checking completion status. Request completed successfully if DEV_DMA_STS is DEV_DMA_STS_SUCC, otherwise complete with actual=0. For systems with high IRQ latency added pointer compl_desc to next descriptor to be completed by XferCompl interrupt. This pointer replace descriptor index calculation based on DxEPDMA register. On descriptor completion interrupt processing all descriptors starting from compl_desc till descriptor which Buffer Status field not equal DMA_DONE status. Actually removed dwc2_gadget_start_next_isoc_ddma() function because now driver use only one desc-chain and instead that function added dwc2_gadget_handle_isoc_bna() function for handling BNA interrupts. Handling BNA interrupt done by flushing TxFIFOs for OUT EPs, completing request with actual=0 and resetting desc-chain number and target frame to initial values for restarting transfers. On handling NAK request completed with actual=0. Incremented target frame to allow fill desc chain and start transfers. In DDMA mode avoided of frame number incrementing, because tracking of frame number performed in dwc2_gadget_fill_isoc_desc() function. When core assert XferCompl along with BNA, we should ignore XferCompl in dwc2_hsotg_epint() function. On BNA interrupt replaced dwc2_gadget_start_next_isoc_ddma() by above mentioned BNA handler. In dwc2_hsotg_ep_enable() function added sanity check of bInterval for ISOC IN in DDMA mode, because HW doesn't supported EP's with bInterval more than 10 and check for mc for ISOC OUT transfers, because core doesn't support high bandwidth transfers. Signed-off-by: Minas Harutyunyan <hminas@synopsys.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Diffstat (limited to 'drivers/usb/dwc2')
-rw-r--r--drivers/usb/dwc2/core.h4
-rw-r--r--drivers/usb/dwc2/gadget.c279
2 files changed, 139 insertions, 144 deletions
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index d83be5651f87..274bf0a83ae4 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -178,8 +178,8 @@ struct dwc2_hsotg_req;
178 * @desc_list_dma: The DMA address of descriptor chain currently in use. 178 * @desc_list_dma: The DMA address of descriptor chain currently in use.
179 * @desc_list: Pointer to descriptor DMA chain head currently in use. 179 * @desc_list: Pointer to descriptor DMA chain head currently in use.
180 * @desc_count: Count of entries within the DMA descriptor chain of EP. 180 * @desc_count: Count of entries within the DMA descriptor chain of EP.
181 * @isoc_chain_num: Number of ISOC chain currently in use - either 0 or 1.
182 * @next_desc: index of next free descriptor in the ISOC chain under SW control. 181 * @next_desc: index of next free descriptor in the ISOC chain under SW control.
182 * @compl_desc: index of next descriptor to be completed by xFerComplete
183 * @total_data: The total number of data bytes done. 183 * @total_data: The total number of data bytes done.
184 * @fifo_size: The size of the FIFO (for periodic IN endpoints) 184 * @fifo_size: The size of the FIFO (for periodic IN endpoints)
185 * @fifo_load: The amount of data loaded into the FIFO (periodic IN) 185 * @fifo_load: The amount of data loaded into the FIFO (periodic IN)
@@ -231,8 +231,8 @@ struct dwc2_hsotg_ep {
231 struct dwc2_dma_desc *desc_list; 231 struct dwc2_dma_desc *desc_list;
232 u8 desc_count; 232 u8 desc_count;
233 233
234 unsigned char isoc_chain_num;
235 unsigned int next_desc; 234 unsigned int next_desc;
235 unsigned int compl_desc;
236 236
237 char name[10]; 237 char name[10];
238}; 238};
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
index 6c32bf26e48e..ec88f7e23f31 100644
--- a/drivers/usb/dwc2/gadget.c
+++ b/drivers/usb/dwc2/gadget.c
@@ -793,9 +793,7 @@ static void dwc2_gadget_config_nonisoc_xfer_ddma(struct dwc2_hsotg_ep *hs_ep,
793 * @dma_buff: usb requests dma buffer. 793 * @dma_buff: usb requests dma buffer.
794 * @len: usb request transfer length. 794 * @len: usb request transfer length.
795 * 795 *
796 * Finds out index of first free entry either in the bottom or up half of 796 * Fills next free descriptor with the data of the arrived usb request,
797 * descriptor chain depend on which is under SW control and not processed
798 * by HW. Then fills that descriptor with the data of the arrived usb request,
799 * frame info, sets Last and IOC bits increments next_desc. If filled 797 * frame info, sets Last and IOC bits increments next_desc. If filled
800 * descriptor is not the first one, removes L bit from the previous descriptor 798 * descriptor is not the first one, removes L bit from the previous descriptor
801 * status. 799 * status.
@@ -810,34 +808,17 @@ static int dwc2_gadget_fill_isoc_desc(struct dwc2_hsotg_ep *hs_ep,
810 u32 mask = 0; 808 u32 mask = 0;
811 809
812 maxsize = dwc2_gadget_get_desc_params(hs_ep, &mask); 810 maxsize = dwc2_gadget_get_desc_params(hs_ep, &mask);
813 if (len > maxsize) {
814 dev_err(hsotg->dev, "wrong len %d\n", len);
815 return -EINVAL;
816 }
817 811
818 /* 812 index = hs_ep->next_desc;
819 * If SW has already filled half of chain, then return and wait for 813 desc = &hs_ep->desc_list[index];
820 * the other chain to be processed by HW.
821 */
822 if (hs_ep->next_desc == MAX_DMA_DESC_NUM_GENERIC / 2)
823 return -EBUSY;
824
825 /* Increment frame number by interval for IN */
826 if (hs_ep->dir_in)
827 dwc2_gadget_incr_frame_num(hs_ep);
828
829 index = (MAX_DMA_DESC_NUM_GENERIC / 2) * hs_ep->isoc_chain_num +
830 hs_ep->next_desc;
831 814
832 /* Sanity check of calculated index */ 815 /* Check if descriptor chain full */
833 if ((hs_ep->isoc_chain_num && index > MAX_DMA_DESC_NUM_GENERIC) || 816 if ((desc->status >> DEV_DMA_BUFF_STS_SHIFT) ==
834 (!hs_ep->isoc_chain_num && index > MAX_DMA_DESC_NUM_GENERIC / 2)) { 817 DEV_DMA_BUFF_STS_HREADY) {
835 dev_err(hsotg->dev, "wrong index %d for iso chain\n", index); 818 dev_dbg(hsotg->dev, "%s: desc chain full\n", __func__);
836 return -EINVAL; 819 return 1;
837 } 820 }
838 821
839 desc = &hs_ep->desc_list[index];
840
841 /* Clear L bit of previous desc if more than one entries in the chain */ 822 /* Clear L bit of previous desc if more than one entries in the chain */
842 if (hs_ep->next_desc) 823 if (hs_ep->next_desc)
843 hs_ep->desc_list[index - 1].status &= ~DEV_DMA_L; 824 hs_ep->desc_list[index - 1].status &= ~DEV_DMA_L;
@@ -865,8 +846,14 @@ static int dwc2_gadget_fill_isoc_desc(struct dwc2_hsotg_ep *hs_ep,
865 desc->status &= ~DEV_DMA_BUFF_STS_MASK; 846 desc->status &= ~DEV_DMA_BUFF_STS_MASK;
866 desc->status |= (DEV_DMA_BUFF_STS_HREADY << DEV_DMA_BUFF_STS_SHIFT); 847 desc->status |= (DEV_DMA_BUFF_STS_HREADY << DEV_DMA_BUFF_STS_SHIFT);
867 848
849 /* Increment frame number by interval for IN */
850 if (hs_ep->dir_in)
851 dwc2_gadget_incr_frame_num(hs_ep);
852
868 /* Update index of last configured entry in the chain */ 853 /* Update index of last configured entry in the chain */
869 hs_ep->next_desc++; 854 hs_ep->next_desc++;
855 if (hs_ep->next_desc >= MAX_DMA_DESC_NUM_GENERIC)
856 hs_ep->next_desc = 0;
870 857
871 return 0; 858 return 0;
872} 859}
@@ -875,11 +862,8 @@ static int dwc2_gadget_fill_isoc_desc(struct dwc2_hsotg_ep *hs_ep,
875 * dwc2_gadget_start_isoc_ddma - start isochronous transfer in DDMA 862 * dwc2_gadget_start_isoc_ddma - start isochronous transfer in DDMA
876 * @hs_ep: The isochronous endpoint. 863 * @hs_ep: The isochronous endpoint.
877 * 864 *
878 * Prepare first descriptor chain for isochronous endpoints. Afterwards 865 * Prepare descriptor chain for isochronous endpoints. Afterwards
879 * write DMA address to HW and enable the endpoint. 866 * write DMA address to HW and enable the endpoint.
880 *
881 * Switch between descriptor chains via isoc_chain_num to give SW opportunity
882 * to prepare second descriptor chain while first one is being processed by HW.
883 */ 867 */
884static void dwc2_gadget_start_isoc_ddma(struct dwc2_hsotg_ep *hs_ep) 868static void dwc2_gadget_start_isoc_ddma(struct dwc2_hsotg_ep *hs_ep)
885{ 869{
@@ -887,24 +871,34 @@ static void dwc2_gadget_start_isoc_ddma(struct dwc2_hsotg_ep *hs_ep)
887 struct dwc2_hsotg_req *hs_req, *treq; 871 struct dwc2_hsotg_req *hs_req, *treq;
888 int index = hs_ep->index; 872 int index = hs_ep->index;
889 int ret; 873 int ret;
874 int i;
890 u32 dma_reg; 875 u32 dma_reg;
891 u32 depctl; 876 u32 depctl;
892 u32 ctrl; 877 u32 ctrl;
878 struct dwc2_dma_desc *desc;
893 879
894 if (list_empty(&hs_ep->queue)) { 880 if (list_empty(&hs_ep->queue)) {
895 dev_dbg(hsotg->dev, "%s: No requests in queue\n", __func__); 881 dev_dbg(hsotg->dev, "%s: No requests in queue\n", __func__);
896 return; 882 return;
897 } 883 }
898 884
885 /* Initialize descriptor chain by Host Busy status */
886 for (i = 0; i < MAX_DMA_DESC_NUM_GENERIC; i++) {
887 desc = &hs_ep->desc_list[i];
888 desc->status = 0;
889 desc->status |= (DEV_DMA_BUFF_STS_HBUSY
890 << DEV_DMA_BUFF_STS_SHIFT);
891 }
892
893 hs_ep->next_desc = 0;
899 list_for_each_entry_safe(hs_req, treq, &hs_ep->queue, queue) { 894 list_for_each_entry_safe(hs_req, treq, &hs_ep->queue, queue) {
900 ret = dwc2_gadget_fill_isoc_desc(hs_ep, hs_req->req.dma, 895 ret = dwc2_gadget_fill_isoc_desc(hs_ep, hs_req->req.dma,
901 hs_req->req.length); 896 hs_req->req.length);
902 if (ret) { 897 if (ret)
903 dev_dbg(hsotg->dev, "%s: desc chain full\n", __func__);
904 break; 898 break;
905 }
906 } 899 }
907 900
901 hs_ep->compl_desc = 0;
908 depctl = hs_ep->dir_in ? DIEPCTL(index) : DOEPCTL(index); 902 depctl = hs_ep->dir_in ? DIEPCTL(index) : DOEPCTL(index);
909 dma_reg = hs_ep->dir_in ? DIEPDMA(index) : DOEPDMA(index); 903 dma_reg = hs_ep->dir_in ? DIEPDMA(index) : DOEPDMA(index);
910 904
@@ -914,10 +908,6 @@ static void dwc2_gadget_start_isoc_ddma(struct dwc2_hsotg_ep *hs_ep)
914 ctrl = dwc2_readl(hsotg->regs + depctl); 908 ctrl = dwc2_readl(hsotg->regs + depctl);
915 ctrl |= DXEPCTL_EPENA | DXEPCTL_CNAK; 909 ctrl |= DXEPCTL_EPENA | DXEPCTL_CNAK;
916 dwc2_writel(ctrl, hsotg->regs + depctl); 910 dwc2_writel(ctrl, hsotg->regs + depctl);
917
918 /* Switch ISOC descriptor chain number being processed by SW*/
919 hs_ep->isoc_chain_num = (hs_ep->isoc_chain_num ^ 1) & 0x1;
920 hs_ep->next_desc = 0;
921} 911}
922 912
923/** 913/**
@@ -1291,6 +1281,9 @@ static int dwc2_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req,
1291 struct dwc2_hsotg *hs = hs_ep->parent; 1281 struct dwc2_hsotg *hs = hs_ep->parent;
1292 bool first; 1282 bool first;
1293 int ret; 1283 int ret;
1284 u32 maxsize = 0;
1285 u32 mask = 0;
1286
1294 1287
1295 dev_dbg(hs->dev, "%s: req %p: %d@%p, noi=%d, zero=%d, snok=%d\n", 1288 dev_dbg(hs->dev, "%s: req %p: %d@%p, noi=%d, zero=%d, snok=%d\n",
1296 ep->name, req, req->length, req->buf, req->no_interrupt, 1289 ep->name, req, req->length, req->buf, req->no_interrupt,
@@ -1308,6 +1301,24 @@ static int dwc2_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req,
1308 req->actual = 0; 1301 req->actual = 0;
1309 req->status = -EINPROGRESS; 1302 req->status = -EINPROGRESS;
1310 1303
1304 /* In DDMA mode for ISOC's don't queue request if length greater
1305 * than descriptor limits.
1306 */
1307 if (using_desc_dma(hs) && hs_ep->isochronous) {
1308 maxsize = dwc2_gadget_get_desc_params(hs_ep, &mask);
1309 if (hs_ep->dir_in && req->length > maxsize) {
1310 dev_err(hs->dev, "wrong length %d (maxsize=%d)\n",
1311 req->length, maxsize);
1312 return -EINVAL;
1313 }
1314
1315 if (!hs_ep->dir_in && req->length > hs_ep->ep.maxpacket) {
1316 dev_err(hs->dev, "ISOC OUT: wrong length %d (mps=%d)\n",
1317 req->length, hs_ep->ep.maxpacket);
1318 return -EINVAL;
1319 }
1320 }
1321
1311 ret = dwc2_hsotg_handle_unaligned_buf_start(hs, hs_ep, hs_req); 1322 ret = dwc2_hsotg_handle_unaligned_buf_start(hs, hs_ep, hs_req);
1312 if (ret) 1323 if (ret)
1313 return ret; 1324 return ret;
@@ -1330,17 +1341,15 @@ static int dwc2_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req,
1330 1341
1331 /* 1342 /*
1332 * Handle DDMA isochronous transfers separately - just add new entry 1343 * Handle DDMA isochronous transfers separately - just add new entry
1333 * to the half of descriptor chain that is not processed by HW. 1344 * to the descriptor chain.
1334 * Transfer will be started once SW gets either one of NAK or 1345 * Transfer will be started once SW gets either one of NAK or
1335 * OutTknEpDis interrupts. 1346 * OutTknEpDis interrupts.
1336 */ 1347 */
1337 if (using_desc_dma(hs) && hs_ep->isochronous && 1348 if (using_desc_dma(hs) && hs_ep->isochronous) {
1338 hs_ep->target_frame != TARGET_FRAME_INITIAL) { 1349 if (hs_ep->target_frame != TARGET_FRAME_INITIAL) {
1339 ret = dwc2_gadget_fill_isoc_desc(hs_ep, hs_req->req.dma, 1350 dwc2_gadget_fill_isoc_desc(hs_ep, hs_req->req.dma,
1340 hs_req->req.length); 1351 hs_req->req.length);
1341 if (ret) 1352 }
1342 dev_dbg(hs->dev, "%s: ISO desc chain full\n", __func__);
1343
1344 return 0; 1353 return 0;
1345 } 1354 }
1346 1355
@@ -2011,108 +2020,75 @@ static void dwc2_hsotg_complete_request(struct dwc2_hsotg *hsotg,
2011 * @hs_ep: The endpoint the request was on. 2020 * @hs_ep: The endpoint the request was on.
2012 * 2021 *
2013 * Get first request from the ep queue, determine descriptor on which complete 2022 * Get first request from the ep queue, determine descriptor on which complete
2014 * happened. SW based on isoc_chain_num discovers which half of the descriptor 2023 * happened. SW discovers which descriptor currently in use by HW, adjusts
2015 * chain is currently in use by HW, adjusts dma_address and calculates index 2024 * dma_address and calculates index of completed descriptor based on the value
2016 * of completed descriptor based on the value of DEPDMA register. Update actual 2025 * of DEPDMA register. Update actual length of request, giveback to gadget.
2017 * length of request, giveback to gadget.
2018 */ 2026 */
2019static void dwc2_gadget_complete_isoc_request_ddma(struct dwc2_hsotg_ep *hs_ep) 2027static void dwc2_gadget_complete_isoc_request_ddma(struct dwc2_hsotg_ep *hs_ep)
2020{ 2028{
2021 struct dwc2_hsotg *hsotg = hs_ep->parent; 2029 struct dwc2_hsotg *hsotg = hs_ep->parent;
2022 struct dwc2_hsotg_req *hs_req; 2030 struct dwc2_hsotg_req *hs_req;
2023 struct usb_request *ureq; 2031 struct usb_request *ureq;
2024 int index;
2025 dma_addr_t dma_addr;
2026 u32 dma_reg;
2027 u32 depdma;
2028 u32 desc_sts; 2032 u32 desc_sts;
2029 u32 mask; 2033 u32 mask;
2030 2034
2031 hs_req = get_ep_head(hs_ep); 2035 desc_sts = hs_ep->desc_list[hs_ep->compl_desc].status;
2032 if (!hs_req) {
2033 dev_warn(hsotg->dev, "%s: ISOC EP queue empty\n", __func__);
2034 return;
2035 }
2036 ureq = &hs_req->req;
2037 2036
2038 dma_addr = hs_ep->desc_list_dma; 2037 /* Process only descriptors with buffer status set to DMA done */
2038 while ((desc_sts & DEV_DMA_BUFF_STS_MASK) >>
2039 DEV_DMA_BUFF_STS_SHIFT == DEV_DMA_BUFF_STS_DMADONE) {
2039 2040
2040 /* 2041 hs_req = get_ep_head(hs_ep);
2041 * If lower half of descriptor chain is currently use by SW, 2042 if (!hs_req) {
2042 * that means higher half is being processed by HW, so shift 2043 dev_warn(hsotg->dev, "%s: ISOC EP queue empty\n", __func__);
2043 * DMA address to higher half of descriptor chain. 2044 return;
2044 */ 2045 }
2045 if (!hs_ep->isoc_chain_num) 2046 ureq = &hs_req->req;
2046 dma_addr += sizeof(struct dwc2_dma_desc) * 2047
2047 (MAX_DMA_DESC_NUM_GENERIC / 2); 2048 /* Check completion status */
2048 2049 if ((desc_sts & DEV_DMA_STS_MASK) >> DEV_DMA_STS_SHIFT ==
2049 dma_reg = hs_ep->dir_in ? DIEPDMA(hs_ep->index) : DOEPDMA(hs_ep->index); 2050 DEV_DMA_STS_SUCC) {
2050 depdma = dwc2_readl(hsotg->regs + dma_reg); 2051 mask = hs_ep->dir_in ? DEV_DMA_ISOC_TX_NBYTES_MASK :
2051 2052 DEV_DMA_ISOC_RX_NBYTES_MASK;
2052 index = (depdma - dma_addr) / sizeof(struct dwc2_dma_desc) - 1; 2053 ureq->actual = ureq->length - ((desc_sts & mask) >>
2053 desc_sts = hs_ep->desc_list[index].status; 2054 DEV_DMA_ISOC_NBYTES_SHIFT);
2054 2055
2055 mask = hs_ep->dir_in ? DEV_DMA_ISOC_TX_NBYTES_MASK : 2056 /* Adjust actual len for ISOC Out if len is
2056 DEV_DMA_ISOC_RX_NBYTES_MASK; 2057 * not align of 4
2057 ureq->actual = ureq->length - 2058 */
2058 ((desc_sts & mask) >> DEV_DMA_ISOC_NBYTES_SHIFT); 2059 if (!hs_ep->dir_in && ureq->length & 0x3)
2060 ureq->actual += 4 - (ureq->length & 0x3);
2061 }
2059 2062
2060 /* Adjust actual length for ISOC Out if length is not align of 4 */ 2063 dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, 0);
2061 if (!hs_ep->dir_in && ureq->length & 0x3)
2062 ureq->actual += 4 - (ureq->length & 0x3);
2063 2064
2064 dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, 0); 2065 hs_ep->compl_desc++;
2066 if (hs_ep->compl_desc > (MAX_DMA_DESC_NUM_GENERIC - 1))
2067 hs_ep->compl_desc = 0;
2068 desc_sts = hs_ep->desc_list[hs_ep->compl_desc].status;
2069 }
2065} 2070}
2066 2071
2067/* 2072/*
2068 * dwc2_gadget_start_next_isoc_ddma - start next isoc request, if any. 2073 * dwc2_gadget_handle_isoc_bna - handle BNA interrupt for ISOC.
2069 * @hs_ep: The isochronous endpoint to be re-enabled. 2074 * @hs_ep: The isochronous endpoint.
2070 * 2075 *
2071 * If ep has been disabled due to last descriptor servicing (IN endpoint) or 2076 * If EP ISOC OUT then need to flush RX FIFO to remove source of BNA
2072 * BNA (OUT endpoint) check the status of other half of descriptor chain that 2077 * interrupt. Reset target frame and next_desc to allow to start
2073 * was under SW control till HW was busy and restart the endpoint if needed. 2078 * ISOC's on NAK interrupt for IN direction or on OUTTKNEPDIS
2079 * interrupt for OUT direction.
2074 */ 2080 */
2075static void dwc2_gadget_start_next_isoc_ddma(struct dwc2_hsotg_ep *hs_ep) 2081static void dwc2_gadget_handle_isoc_bna(struct dwc2_hsotg_ep *hs_ep)
2076{ 2082{
2077 struct dwc2_hsotg *hsotg = hs_ep->parent; 2083 struct dwc2_hsotg *hsotg = hs_ep->parent;
2078 u32 depctl;
2079 u32 dma_reg;
2080 u32 ctrl;
2081 u32 dma_addr = hs_ep->desc_list_dma;
2082 unsigned char index = hs_ep->index;
2083
2084 dma_reg = hs_ep->dir_in ? DIEPDMA(index) : DOEPDMA(index);
2085 depctl = hs_ep->dir_in ? DIEPCTL(index) : DOEPCTL(index);
2086 2084
2087 ctrl = dwc2_readl(hsotg->regs + depctl); 2085 if (!hs_ep->dir_in)
2088 2086 dwc2_flush_rx_fifo(hsotg);
2089 /* 2087 dwc2_hsotg_complete_request(hsotg, hs_ep, get_ep_head(hs_ep), 0);
2090 * EP was disabled if HW has processed last descriptor or BNA was set.
2091 * So restart ep if SW has prepared new descriptor chain in ep_queue
2092 * routine while HW was busy.
2093 */
2094 if (!(ctrl & DXEPCTL_EPENA)) {
2095 if (!hs_ep->next_desc) {
2096 dev_dbg(hsotg->dev, "%s: No more ISOC requests\n",
2097 __func__);
2098 return;
2099 }
2100 2088
2101 dma_addr += sizeof(struct dwc2_dma_desc) * 2089 hs_ep->target_frame = TARGET_FRAME_INITIAL;
2102 (MAX_DMA_DESC_NUM_GENERIC / 2) * 2090 hs_ep->next_desc = 0;
2103 hs_ep->isoc_chain_num; 2091 hs_ep->compl_desc = 0;
2104 dwc2_writel(dma_addr, hsotg->regs + dma_reg);
2105
2106 ctrl |= DXEPCTL_EPENA | DXEPCTL_CNAK;
2107 dwc2_writel(ctrl, hsotg->regs + depctl);
2108
2109 /* Switch ISOC descriptor chain number being processed by SW*/
2110 hs_ep->isoc_chain_num = (hs_ep->isoc_chain_num ^ 1) & 0x1;
2111 hs_ep->next_desc = 0;
2112
2113 dev_dbg(hsotg->dev, "%s: Restarted isochronous endpoint\n",
2114 __func__);
2115 }
2116} 2092}
2117 2093
2118/** 2094/**
@@ -2763,7 +2739,7 @@ static void dwc2_gadget_handle_out_token_ep_disabled(struct dwc2_hsotg_ep *ep)
2763 */ 2739 */
2764 tmp = dwc2_hsotg_read_frameno(hsotg); 2740 tmp = dwc2_hsotg_read_frameno(hsotg);
2765 2741
2766 dwc2_hsotg_complete_request(hsotg, ep, get_ep_head(ep), -ENODATA); 2742 dwc2_hsotg_complete_request(hsotg, ep, get_ep_head(ep), 0);
2767 2743
2768 if (using_desc_dma(hsotg)) { 2744 if (using_desc_dma(hsotg)) {
2769 if (ep->target_frame == TARGET_FRAME_INITIAL) { 2745 if (ep->target_frame == TARGET_FRAME_INITIAL) {
@@ -2816,18 +2792,25 @@ static void dwc2_gadget_handle_nak(struct dwc2_hsotg_ep *hs_ep)
2816{ 2792{
2817 struct dwc2_hsotg *hsotg = hs_ep->parent; 2793 struct dwc2_hsotg *hsotg = hs_ep->parent;
2818 int dir_in = hs_ep->dir_in; 2794 int dir_in = hs_ep->dir_in;
2795 u32 tmp;
2819 2796
2820 if (!dir_in || !hs_ep->isochronous) 2797 if (!dir_in || !hs_ep->isochronous)
2821 return; 2798 return;
2822 2799
2823 if (hs_ep->target_frame == TARGET_FRAME_INITIAL) { 2800 if (hs_ep->target_frame == TARGET_FRAME_INITIAL) {
2824 hs_ep->target_frame = dwc2_hsotg_read_frameno(hsotg);
2825 2801
2802 tmp = dwc2_hsotg_read_frameno(hsotg);
2826 if (using_desc_dma(hsotg)) { 2803 if (using_desc_dma(hsotg)) {
2804 dwc2_hsotg_complete_request(hsotg, hs_ep,
2805 get_ep_head(hs_ep), 0);
2806
2807 hs_ep->target_frame = tmp;
2808 dwc2_gadget_incr_frame_num(hs_ep);
2827 dwc2_gadget_start_isoc_ddma(hs_ep); 2809 dwc2_gadget_start_isoc_ddma(hs_ep);
2828 return; 2810 return;
2829 } 2811 }
2830 2812
2813 hs_ep->target_frame = tmp;
2831 if (hs_ep->interval > 1) { 2814 if (hs_ep->interval > 1) {
2832 u32 ctrl = dwc2_readl(hsotg->regs + 2815 u32 ctrl = dwc2_readl(hsotg->regs +
2833 DIEPCTL(hs_ep->index)); 2816 DIEPCTL(hs_ep->index));
@@ -2843,7 +2826,8 @@ static void dwc2_gadget_handle_nak(struct dwc2_hsotg_ep *hs_ep)
2843 get_ep_head(hs_ep), 0); 2826 get_ep_head(hs_ep), 0);
2844 } 2827 }
2845 2828
2846 dwc2_gadget_incr_frame_num(hs_ep); 2829 if (!using_desc_dma(hsotg))
2830 dwc2_gadget_incr_frame_num(hs_ep);
2847} 2831}
2848 2832
2849/** 2833/**
@@ -2901,9 +2885,9 @@ static void dwc2_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx,
2901 2885
2902 /* In DDMA handle isochronous requests separately */ 2886 /* In DDMA handle isochronous requests separately */
2903 if (using_desc_dma(hsotg) && hs_ep->isochronous) { 2887 if (using_desc_dma(hsotg) && hs_ep->isochronous) {
2904 dwc2_gadget_complete_isoc_request_ddma(hs_ep); 2888 /* XferCompl set along with BNA */
2905 /* Try to start next isoc request */ 2889 if (!(ints & DXEPINT_BNAINTR))
2906 dwc2_gadget_start_next_isoc_ddma(hs_ep); 2890 dwc2_gadget_complete_isoc_request_ddma(hs_ep);
2907 } else if (dir_in) { 2891 } else if (dir_in) {
2908 /* 2892 /*
2909 * We get OutDone from the FIFO, so we only 2893 * We get OutDone from the FIFO, so we only
@@ -2978,15 +2962,8 @@ static void dwc2_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx,
2978 2962
2979 if (ints & DXEPINT_BNAINTR) { 2963 if (ints & DXEPINT_BNAINTR) {
2980 dev_dbg(hsotg->dev, "%s: BNA interrupt\n", __func__); 2964 dev_dbg(hsotg->dev, "%s: BNA interrupt\n", __func__);
2981
2982 /*
2983 * Try to start next isoc request, if any.
2984 * Sometimes the endpoint remains enabled after BNA interrupt
2985 * assertion, which is not expected, hence we can enter here
2986 * couple of times.
2987 */
2988 if (hs_ep->isochronous) 2965 if (hs_ep->isochronous)
2989 dwc2_gadget_start_next_isoc_ddma(hs_ep); 2966 dwc2_gadget_handle_isoc_bna(hs_ep);
2990 } 2967 }
2991 2968
2992 if (dir_in && !hs_ep->isochronous) { 2969 if (dir_in && !hs_ep->isochronous) {
@@ -3789,6 +3766,7 @@ static int dwc2_hsotg_ep_enable(struct usb_ep *ep,
3789 unsigned int dir_in; 3766 unsigned int dir_in;
3790 unsigned int i, val, size; 3767 unsigned int i, val, size;
3791 int ret = 0; 3768 int ret = 0;
3769 unsigned char ep_type;
3792 3770
3793 dev_dbg(hsotg->dev, 3771 dev_dbg(hsotg->dev,
3794 "%s: ep %s: a 0x%02x, attr 0x%02x, mps 0x%04x, intr %d\n", 3772 "%s: ep %s: a 0x%02x, attr 0x%02x, mps 0x%04x, intr %d\n",
@@ -3807,9 +3785,26 @@ static int dwc2_hsotg_ep_enable(struct usb_ep *ep,
3807 return -EINVAL; 3785 return -EINVAL;
3808 } 3786 }
3809 3787
3788 ep_type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
3810 mps = usb_endpoint_maxp(desc); 3789 mps = usb_endpoint_maxp(desc);
3811 mc = usb_endpoint_maxp_mult(desc); 3790 mc = usb_endpoint_maxp_mult(desc);
3812 3791
3792 /* ISOC IN in DDMA supported bInterval up to 10 */
3793 if (using_desc_dma(hsotg) && ep_type == USB_ENDPOINT_XFER_ISOC &&
3794 dir_in && desc->bInterval > 10) {
3795 dev_err(hsotg->dev,
3796 "%s: ISOC IN, DDMA: bInterval>10 not supported!\n", __func__);
3797 return -EINVAL;
3798 }
3799
3800 /* High bandwidth ISOC OUT in DDMA not supported */
3801 if (using_desc_dma(hsotg) && ep_type == USB_ENDPOINT_XFER_ISOC &&
3802 !dir_in && mc > 1) {
3803 dev_err(hsotg->dev,
3804 "%s: ISOC OUT, DDMA: HB not supported!\n", __func__);
3805 return -EINVAL;
3806 }
3807
3813 /* note, we handle this here instead of dwc2_hsotg_set_ep_maxpacket */ 3808 /* note, we handle this here instead of dwc2_hsotg_set_ep_maxpacket */
3814 3809
3815 epctrl_reg = dir_in ? DIEPCTL(index) : DOEPCTL(index); 3810 epctrl_reg = dir_in ? DIEPCTL(index) : DOEPCTL(index);
@@ -3850,15 +3845,15 @@ static int dwc2_hsotg_ep_enable(struct usb_ep *ep,
3850 hs_ep->halted = 0; 3845 hs_ep->halted = 0;
3851 hs_ep->interval = desc->bInterval; 3846 hs_ep->interval = desc->bInterval;
3852 3847
3853 switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { 3848 switch (ep_type) {
3854 case USB_ENDPOINT_XFER_ISOC: 3849 case USB_ENDPOINT_XFER_ISOC:
3855 epctrl |= DXEPCTL_EPTYPE_ISO; 3850 epctrl |= DXEPCTL_EPTYPE_ISO;
3856 epctrl |= DXEPCTL_SETEVENFR; 3851 epctrl |= DXEPCTL_SETEVENFR;
3857 hs_ep->isochronous = 1; 3852 hs_ep->isochronous = 1;
3858 hs_ep->interval = 1 << (desc->bInterval - 1); 3853 hs_ep->interval = 1 << (desc->bInterval - 1);
3859 hs_ep->target_frame = TARGET_FRAME_INITIAL; 3854 hs_ep->target_frame = TARGET_FRAME_INITIAL;
3860 hs_ep->isoc_chain_num = 0;
3861 hs_ep->next_desc = 0; 3855 hs_ep->next_desc = 0;
3856 hs_ep->compl_desc = 0;
3862 if (dir_in) { 3857 if (dir_in) {
3863 hs_ep->periodic = 1; 3858 hs_ep->periodic = 1;
3864 mask = dwc2_readl(hsotg->regs + DIEPMSK); 3859 mask = dwc2_readl(hsotg->regs + DIEPMSK);