|
@@ -67,23 +67,9 @@ void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
|
|
|
static int dwc3_core_soft_reset(struct dwc3 *dwc)
|
|
|
{
|
|
|
u32 reg;
|
|
|
+ int retries = 1000;
|
|
|
int ret;
|
|
|
|
|
|
- /* Before Resetting PHY, put Core in Reset */
|
|
|
- reg = dwc3_readl(dwc->regs, DWC3_GCTL);
|
|
|
- reg |= DWC3_GCTL_CORESOFTRESET;
|
|
|
- dwc3_writel(dwc->regs, DWC3_GCTL, reg);
|
|
|
-
|
|
|
- /* Assert USB3 PHY reset */
|
|
|
- reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
|
|
|
- reg |= DWC3_GUSB3PIPECTL_PHYSOFTRST;
|
|
|
- dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
|
|
|
-
|
|
|
- /* Assert USB2 PHY reset */
|
|
|
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
|
|
|
- reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST;
|
|
|
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
|
|
|
-
|
|
|
usb_phy_init(dwc->usb2_phy);
|
|
|
usb_phy_init(dwc->usb3_phy);
|
|
|
ret = phy_init(dwc->usb2_generic_phy);
|
|
@@ -95,26 +81,28 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
|
|
|
phy_exit(dwc->usb2_generic_phy);
|
|
|
return ret;
|
|
|
}
|
|
|
- mdelay(100);
|
|
|
|
|
|
- /* Clear USB3 PHY reset */
|
|
|
- reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
|
|
|
- reg &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST;
|
|
|
- dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
|
|
|
+ /*
|
|
|
+ * We're resetting only the device side because, if we're in host mode,
|
|
|
+ * XHCI driver will reset the host block. If dwc3 was configured for
|
|
|
+ * host-only mode, then we can return early.
|
|
|
+ */
|
|
|
+ if (dwc->dr_mode == USB_DR_MODE_HOST)
|
|
|
+ return 0;
|
|
|
|
|
|
- /* Clear USB2 PHY reset */
|
|
|
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
|
|
|
- reg &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST;
|
|
|
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
|
|
|
+ reg = dwc3_readl(dwc->regs, DWC3_DCTL);
|
|
|
+ reg |= DWC3_DCTL_CSFTRST;
|
|
|
+ dwc3_writel(dwc->regs, DWC3_DCTL, reg);
|
|
|
|
|
|
- mdelay(100);
|
|
|
+ do {
|
|
|
+ reg = dwc3_readl(dwc->regs, DWC3_DCTL);
|
|
|
+ if (!(reg & DWC3_DCTL_CSFTRST))
|
|
|
+ return 0;
|
|
|
|
|
|
- /* After PHYs are stable we can take Core out of reset state */
|
|
|
- reg = dwc3_readl(dwc->regs, DWC3_GCTL);
|
|
|
- reg &= ~DWC3_GCTL_CORESOFTRESET;
|
|
|
- dwc3_writel(dwc->regs, DWC3_GCTL, reg);
|
|
|
+ udelay(1);
|
|
|
+ } while (--retries);
|
|
|
|
|
|
- return 0;
|
|
|
+ return -ETIMEDOUT;
|
|
|
}
|
|
|
|
|
|
/**
|