MLK-16013-4 usb: dwc3: add suspend_clk setting interface
authorLi Jun <jun.li@nxp.com>
Thu, 13 Apr 2017 15:00:00 +0000 (23:00 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 20:33:55 +0000 (15:33 -0500)
Some dwc3 based USB3 IP may have a wrong default suspend clk
setting, so add an interface to correct it by dts property.

Reviewed-by: Peter Chen <peter.chen@nxp.com>
Signed-off-by: Li Jun <jun.li@nxp.com>
drivers/usb/dwc3/core.c
drivers/usb/dwc3/core.h

index fea4469..b34c8ce 100644 (file)
@@ -110,6 +110,30 @@ void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
        dwc3_writel(dwc->regs, DWC3_GCTL, reg);
 }
 
+static int dwc3_set_suspend_clk(struct dwc3 *dwc)
+{
+       u32 reg, scale;
+
+       /*
+        * DWC3_GCTL.PWRDNSCALE: The USB3 suspend_clk input replaces
+        * pipe3_rx_pclk as a clock source to a small part of the USB3
+        * core that operates when the SS PHY is in its lowest power
+        * (P3) state, and therefore does not provide a clock.
+        * The Power Down Scale field specifies how many suspend_clk
+        * periods fit into a 16 kHz clock period. When performing the
+        * division, round up the remainder.
+        */
+       if (!device_property_read_u32(dwc->dev, "snps,power-down-scale",
+                                                               &scale)) {
+               reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+               reg &= ~(DWC3_GCTL_PWRDNSCALE_MASK);
+               reg |= DWC3_GCTL_PWRDNSCALE(scale);
+               dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+       }
+
+       return 0;
+}
+
 u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type)
 {
        struct dwc3             *dwc = dep->dwc;
@@ -643,6 +667,9 @@ static int dwc3_core_init(struct dwc3 *dwc)
        if (ret)
                goto err0;
 
+       /* Set suspend_clk */
+       dwc3_set_suspend_clk(dwc);
+
        ret = dwc3_phy_setup(dwc);
        if (ret)
                goto err0;
index 884c437..6f53692 100644 (file)
 
 /* Global Configuration Register */
 #define DWC3_GCTL_PWRDNSCALE(n)        ((n) << 19)
+#define DWC3_GCTL_PWRDNSCALE_MASK      DWC3_GCTL_PWRDNSCALE(0x1fff)
 #define DWC3_GCTL_U2RSTECN     (1 << 16)
 #define DWC3_GCTL_RAMCLKSEL(x) (((x) & DWC3_GCTL_CLK_MASK) << 6)
 #define DWC3_GCTL_CLK_BUS      (0)