|
@@ -233,6 +233,7 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc);
|
|
|
int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd,
|
|
|
struct dwc3_gadget_ep_cmd_params *params)
|
|
|
{
|
|
|
+ const struct usb_endpoint_descriptor *desc = dep->endpoint.desc;
|
|
|
struct dwc3 *dwc = dep->dwc;
|
|
|
u32 timeout = 500;
|
|
|
u32 reg;
|
|
@@ -276,7 +277,28 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd,
|
|
|
dwc3_writel(dep->regs, DWC3_DEPCMDPAR1, params->param1);
|
|
|
dwc3_writel(dep->regs, DWC3_DEPCMDPAR2, params->param2);
|
|
|
|
|
|
- dwc3_writel(dep->regs, DWC3_DEPCMD, cmd | DWC3_DEPCMD_CMDACT);
|
|
|
+ /*
|
|
|
+ * Synopsys Databook 2.60a states in section 6.3.2.5.6 of that if we're
|
|
|
+ * not relying on XferNotReady, we can make use of a special "No
|
|
|
+ * Response Update Transfer" command where we should clear both CmdAct
|
|
|
+ * and CmdIOC bits.
|
|
|
+ *
|
|
|
+ * With this, we don't need to wait for command completion and can
|
|
|
+ * straight away issue further commands to the endpoint.
|
|
|
+ *
|
|
|
+ * NOTICE: We're making an assumption that control endpoints will never
|
|
|
+ * make use of Update Transfer command. This is a safe assumption
|
|
|
+ * because we can never have more than one request at a time with
|
|
|
+ * Control Endpoints. If anybody changes that assumption, this chunk
|
|
|
+ * needs to be updated accordingly.
|
|
|
+ */
|
|
|
+ if (DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_UPDATETRANSFER &&
|
|
|
+ !usb_endpoint_xfer_isoc(desc))
|
|
|
+ cmd &= ~(DWC3_DEPCMD_CMDIOC | DWC3_DEPCMD_CMDACT);
|
|
|
+ else
|
|
|
+ cmd |= DWC3_DEPCMD_CMDACT;
|
|
|
+
|
|
|
+ dwc3_writel(dep->regs, DWC3_DEPCMD, cmd);
|
|
|
do {
|
|
|
reg = dwc3_readl(dep->regs, DWC3_DEPCMD);
|
|
|
if (!(reg & DWC3_DEPCMD_CMDACT)) {
|