Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb: dwc3: Add ENDXFER command polling

ENDXFER polling is available on version 3.10a and later of the
DWC_usb3 (USB 3.0) controller. With this feature, the software can poll
the CMDACT bit in the DEPCMD register after issuing an ENDXFER command.
This feature is enabled by writing GUCTL2[14].

This feature is NOT available on the DWC_usb31 (USB 3.1) IP.

Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>

authored by

John Youn and committed by
Felipe Balbi
06281d46 da605f5f

+30 -1
+11
drivers/usb/dwc3/core.c
··· 704 704 break; 705 705 } 706 706 707 + /* 708 + * ENDXFER polling is available on version 3.10a and later of 709 + * the DWC_usb3 controller. It is NOT available in the 710 + * DWC_usb31 controller. 711 + */ 712 + if (!dwc3_is_usb31(dwc) && dwc->revision >= DWC3_REVISION_310A) { 713 + reg = dwc3_readl(dwc->regs, DWC3_GUCTL2); 714 + reg |= DWC3_GUCTL2_RST_ACTBITLATER; 715 + dwc3_writel(dwc->regs, DWC3_GUCTL2, reg); 716 + } 717 + 707 718 return 0; 708 719 709 720 err4:
+4
drivers/usb/dwc3/core.h
··· 109 109 #define DWC3_GPRTBIMAP_HS1 0xc184 110 110 #define DWC3_GPRTBIMAP_FS0 0xc188 111 111 #define DWC3_GPRTBIMAP_FS1 0xc18c 112 + #define DWC3_GUCTL2 0xc19c 112 113 113 114 #define DWC3_VER_NUMBER 0xc1a0 114 115 #define DWC3_VER_TYPE 0xc1a4 ··· 288 287 /* Global Frame Length Adjustment Register */ 289 288 #define DWC3_GFLADJ_30MHZ_SDBND_SEL (1 << 7) 290 289 #define DWC3_GFLADJ_30MHZ_MASK 0x3f 290 + 291 + /* Global User Control Register 2 */ 292 + #define DWC3_GUCTL2_RST_ACTBITLATER (1 << 14) 291 293 292 294 /* Device Configuration Register */ 293 295 #define DWC3_DCFG_DEVADDR(addr) ((addr) << 3)
+15 -1
drivers/usb/dwc3/gadget.c
··· 2228 2228 * 2229 2229 * - Issue EndTransfer WITH CMDIOC bit set 2230 2230 * - Wait 100us 2231 + * 2232 + * As of IP version 3.10a of the DWC_usb3 IP, the controller 2233 + * supports a mode to work around the above limitation. The 2234 + * software can poll the CMDACT bit in the DEPCMD register 2235 + * after issuing a EndTransfer command. This mode is enabled 2236 + * by writing GUCTL2[14]. This polling is already done in the 2237 + * dwc3_send_gadget_ep_cmd() function so if the mode is 2238 + * enabled, the EndTransfer command will have completed upon 2239 + * returning from this function and we don't need to delay for 2240 + * 100us. 2241 + * 2242 + * This mode is NOT available on the DWC_usb31 IP. 2231 2243 */ 2232 2244 2233 2245 cmd = DWC3_DEPCMD_ENDTRANSFER; ··· 2251 2239 WARN_ON_ONCE(ret); 2252 2240 dep->resource_index = 0; 2253 2241 dep->flags &= ~DWC3_EP_BUSY; 2254 - udelay(100); 2242 + 2243 + if (dwc3_is_usb31(dwc) || dwc->revision < DWC3_REVISION_310A) 2244 + udelay(100); 2255 2245 } 2256 2246 2257 2247 static void dwc3_stop_active_transfers(struct dwc3 *dwc)