summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jun <jun.li@nxp.com>2017-08-26 01:49:51 +0800
committerLi Jun <jun.li@nxp.com>2017-08-29 17:17:13 +0800
commit83f152efe31d7ab6c3e713acb389eddbabfb0234 (patch)
tree9bf509783c67b44fd69aa18dbda8d9801a65a05c
parent01011b12c5c21164a43bf68e8b1d3dfc758e0743 (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.c24
-rw-r--r--drivers/usb/dwc3/core.h2
-rw-r--r--include/dwc3-uboot.h1
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;