diff options
author | Andrey Smirnov <andrew.smirnov@gmail.com> | 2019-03-13 00:25:19 -0700 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2019-03-18 09:03:31 +0100 |
commit | eb1e8358f49ed6d78b5395857767296934decd3b (patch) | |
tree | 44226736adb5fa925ee35f61ce325923a346f4fa | |
parent | d696289d6eba0b578b3a9ba506fc23cdc507b025 (diff) | |
download | barebox-eb1e8358f49ed6d78b5395857767296934decd3b.tar.gz barebox-eb1e8358f49ed6d78b5395857767296934decd3b.tar.xz |
usb: dwc3: Toggle GCTL.CORESOFTRESET as a first step
Toggle GCTL.CORESOFTRESET before trying to access any of the block's
registers. Without this additional step, first read of DWC3_GHWPARAMS*
that follows results in assertion of GSTS.CSRTIMEOUT and IP block
stuck in a non-functional state.
Note that all above has only been observerd on i.MX8MQ (ZII Zest
board) for USB1 controller. USB2 doesn't seem to be affected by this.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r-- | drivers/usb/dwc3/core.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 2e7031a348..60fd6318db 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -663,6 +663,25 @@ static void dwc3_check_params(struct dwc3 *dwc) } } +static void dwc3_coresoft_reset(struct dwc3 *dwc) +{ + u32 reg; + + reg = dwc3_readl(dwc->regs, DWC3_GCTL); + reg |= DWC3_GCTL_CORESOFTRESET; + dwc3_writel(dwc->regs, DWC3_GCTL, reg); + + /* + * Similar reset sequence in U-Boot has a 100ms delay here. In + * practice reset sequence seem to work as expected even + * without a delay. + */ + + reg = dwc3_readl(dwc->regs, DWC3_GCTL); + reg &= ~DWC3_GCTL_CORESOFTRESET; + dwc3_writel(dwc->regs, DWC3_GCTL, reg); +} + static int dwc3_probe(struct device_d *dev) { struct dwc3 *dwc; @@ -695,6 +714,8 @@ static int dwc3_probe(struct device_d *dev) if (ret) return ret; + dwc3_coresoft_reset(dwc); + dwc3_cache_hwparams(dwc); ret = dwc3_core_init(dwc); |