usb: dwc3: ulpi: conditionally resume ULPI PHY
authorFelipe Balbi <felipe.balbi@linux.intel.com>
Mon, 5 Jun 2017 14:01:22 +0000 (17:01 +0300)
committerFelipe Balbi <felipe.balbi@linux.intel.com>
Tue, 13 Jun 2017 10:21:05 +0000 (13:21 +0300)
If PHY is suspended by the time we want to issue ULPI transfers, we
will observe timeouts on the ULPI interface. In order to avoid such
issue, let's make sure PHY is resumed before issuing a ULPI transfer.

Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
drivers/usb/dwc3/ulpi.c

index bd86f84f37901da174cc87229504d9d895b2b0e9..e87ce8e9edee90825283b7a06f56fbc00168da3c 100644 (file)
@@ -41,6 +41,12 @@ static int dwc3_ulpi_read(struct device *dev, u8 addr)
        u32 reg;
        int ret;
 
+       reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+       if (reg & DWC3_GUSB2PHYCFG_SUSPHY) {
+               reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
+               dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+       }
+
        reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr);
        dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg);
 
@@ -58,6 +64,12 @@ static int dwc3_ulpi_write(struct device *dev, u8 addr, u8 val)
        struct dwc3 *dwc = dev_get_drvdata(dev);
        u32 reg;
 
+       reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+       if (reg & DWC3_GUSB2PHYCFG_SUSPHY) {
+               reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
+               dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+       }
+
        reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr);
        reg |= DWC3_GUSB2PHYACC_WRITE | val;
        dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg);