diff options
author | Minas Harutyunyan <Minas.Harutyunyan@synopsys.com> | 2020-05-21 10:05:44 +0400 |
---|---|---|
committer | Felipe Balbi <balbi@kernel.org> | 2020-05-25 11:09:44 +0300 |
commit | 65dc2e725286106f99c6f6b78e3d9c52c15f3a9c (patch) | |
tree | 267a2f9b4db38c3354448e3ad17a5774896b188b /drivers/usb/dwc2/core.c | |
parent | 4cda340a455b425f7df9657aaaa78a75757d940d (diff) |
usb: dwc2: Update Core Reset programming flow.
Starting from core version 4.20a Core Reset flow is changed.
Introduced new bit in GRSTCTL register - GRSTCTL_CSFTRST_DONE.
Core Reset new programming flow steps are follow:
1. Set GRSTCTL_CSFTRST bit.
2. Wait for bit GRSTCTL_CSFTRST_DONE is set.
3. Clear GRSTCTL_CSFTRST and GRSTCTL_CSFTRST_DONE bits.
Check core version functionality separated from dwc2_get_hwparams() to
new dwc2_check_core_version() function because Core Reset flow depend
on SNPSID.
Signed-off-by: Minas Harutyunyan <hminas@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
Diffstat (limited to 'drivers/usb/dwc2/core.c')
-rw-r--r-- | drivers/usb/dwc2/core.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 78a4925aa118..fec17a2d2447 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -524,10 +524,25 @@ int dwc2_core_reset(struct dwc2_hsotg *hsotg, bool skip_wait) greset |= GRSTCTL_CSFTRST; dwc2_writel(hsotg, greset, GRSTCTL); - if (dwc2_hsotg_wait_bit_clear(hsotg, GRSTCTL, GRSTCTL_CSFTRST, 10000)) { - dev_warn(hsotg->dev, "%s: HANG! Soft Reset timeout GRSTCTL GRSTCTL_CSFTRST\n", - __func__); - return -EBUSY; + if ((hsotg->hw_params.snpsid & DWC2_CORE_REV_MASK) < + (DWC2_CORE_REV_4_20a & DWC2_CORE_REV_MASK)) { + if (dwc2_hsotg_wait_bit_clear(hsotg, GRSTCTL, + GRSTCTL_CSFTRST, 10000)) { + dev_warn(hsotg->dev, "%s: HANG! Soft Reset timeout GRSTCTL_CSFTRST\n", + __func__); + return -EBUSY; + } + } else { + if (dwc2_hsotg_wait_bit_set(hsotg, GRSTCTL, + GRSTCTL_CSFTRST_DONE, 10000)) { + dev_warn(hsotg->dev, "%s: HANG! Soft Reset timeout GRSTCTL_CSFTRST_DONE\n", + __func__); + return -EBUSY; + } + greset = dwc2_readl(hsotg, GRSTCTL); + greset &= ~GRSTCTL_CSFTRST; + greset |= GRSTCTL_CSFTRST_DONE; + dwc2_writel(hsotg, greset, GRSTCTL); } /* Wait for AHB master IDLE state */ |