|
@@ -227,10 +227,27 @@ int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
|
|
|
struct dwc3_ep *dep = dwc->eps[ep];
|
|
|
u32 timeout = 500;
|
|
|
u32 reg;
|
|
|
+
|
|
|
+ int susphy = false;
|
|
|
int ret = -EINVAL;
|
|
|
|
|
|
trace_dwc3_gadget_ep_cmd(dep, cmd, params);
|
|
|
|
|
|
+ /*
|
|
|
+ * Synopsys Databook 2.60a states, on section 6.3.2.5.[1-8], that if
|
|
|
+ * we're issuing an endpoint command, we must check if
|
|
|
+ * GUSB2PHYCFG.SUSPHY bit is set. If it is, then we need to clear it.
|
|
|
+ *
|
|
|
+ * We will also set SUSPHY bit to what it was before returning as stated
|
|
|
+ * by the same section on Synopsys databook.
|
|
|
+ */
|
|
|
+ reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
|
|
|
+ if (unlikely(reg & DWC3_GUSB2PHYCFG_SUSPHY)) {
|
|
|
+ susphy = true;
|
|
|
+ reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
|
|
|
+ dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
|
|
|
+ }
|
|
|
+
|
|
|
dwc3_writel(dwc->regs, DWC3_DEPCMDPAR0(ep), params->param0);
|
|
|
dwc3_writel(dwc->regs, DWC3_DEPCMDPAR1(ep), params->param1);
|
|
|
dwc3_writel(dwc->regs, DWC3_DEPCMDPAR2(ep), params->param2);
|
|
@@ -263,6 +280,12 @@ int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
|
|
|
udelay(1);
|
|
|
} while (1);
|
|
|
|
|
|
+ if (unlikely(susphy)) {
|
|
|
+ reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
|
|
|
+ reg |= DWC3_GUSB2PHYCFG_SUSPHY;
|
|
|
+ dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
|
|
|
+ }
|
|
|
+
|
|
|
return ret;
|
|
|
}
|
|
|
|