diff options
author | Li Jun <jun.li@nxp.com> | 2017-08-26 01:49:51 +0800 |
---|---|---|
committer | Li Jun <jun.li@nxp.com> | 2017-08-29 17:17:13 +0800 |
commit | 83f152efe31d7ab6c3e713acb389eddbabfb0234 (patch) | |
tree | 9bf509783c67b44fd69aa18dbda8d9801a65a05c | |
parent | 01011b12c5c21164a43bf68e8b1d3dfc758e0743 (diff) |
MLK-16273-1 usb: dwc3: add suspend clock setting interface
Some dwc3 based USB3 IP may have a wrong default suspend clk
setting, so add an interface to correct it by board setting.
Acked-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Li Jun <jun.li@nxp.com>
-rw-r--r-- | drivers/usb/dwc3/core.c | 24 | ||||
-rw-r--r-- | drivers/usb/dwc3/core.h | 2 | ||||
-rw-r--r-- | include/dwc3-uboot.h | 1 |
3 files changed, 27 insertions, 0 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 87b9c87edf..8390c28d04 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -395,6 +395,25 @@ static void dwc3_phy_setup(struct dwc3 *dwc) mdelay(100); } +void dwc3_set_suspend_clk(struct dwc3 *dwc) +{ + u32 reg; + + /* + * 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. + */ + reg = dwc3_readl(dwc->regs, DWC3_GCTL); + reg &= ~(DWC3_GCTL_PWRDNSCALE(0x1fff)); + reg |= DWC3_GCTL_PWRDNSCALE(dwc->power_down_scale); + dwc3_writel(dwc->regs, DWC3_GCTL, reg); +} + /** * dwc3_core_init - Low-level initialization of DWC3 Core * @dwc: Pointer to our controller context structure @@ -443,6 +462,9 @@ static int dwc3_core_init(struct dwc3 *dwc) if (ret) goto err0; + if (dwc->power_down_scale) + dwc3_set_suspend_clk(dwc); + reg = dwc3_readl(dwc->regs, DWC3_GCTL); reg &= ~DWC3_GCTL_SCALEDOWN_MASK; @@ -672,6 +694,8 @@ int dwc3_uboot_init(struct dwc3_device *dwc3_dev) if (dwc3_dev->tx_de_emphasis) tx_de_emphasis = dwc3_dev->tx_de_emphasis; + dwc->power_down_scale = dwc3_dev->power_down_scale; + /* default to superspeed if no maximum_speed passed */ if (dwc->maximum_speed == USB_SPEED_UNKNOWN) dwc->maximum_speed = USB_SPEED_SUPER; diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 72d2fcdd3f..030a471be3 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -643,6 +643,7 @@ struct dwc3_scratchpad_array { * @dr_mode: requested mode of operation * @dcfg: saved contents of DCFG register * @gctl: saved contents of GCTL register + * @power_down_scale: 16KHz clock periods for suspend_clk * @isoch_delay: wValue from Set Isochronous Delay request; * @u2sel: parameter from Set SEL request. * @u2pel: parameter from Set SEL request. @@ -763,6 +764,7 @@ struct dwc3 { enum dwc3_ep0_state ep0state; enum dwc3_link_state link_state; + u16 power_down_scale; u16 isoch_delay; u16 u2sel; u16 u2pel; diff --git a/include/dwc3-uboot.h b/include/dwc3-uboot.h index 7af2ad11e4..e75f3985df 100644 --- a/include/dwc3-uboot.h +++ b/include/dwc3-uboot.h @@ -16,6 +16,7 @@ struct dwc3_device { unsigned long base; enum usb_dr_mode dr_mode; u32 maximum_speed; + u16 power_down_scale; unsigned tx_fifo_resize:1; unsigned has_lpm_erratum; u8 lpm_nyet_threshold; |