diff options
author | Michael Walle | 2021-10-15 15:15:21 +0200 |
---|---|---|
committer | Priyanka Jain | 2021-11-09 17:18:23 +0530 |
commit | d274cbbc1cef8909d47b3f797fef3667bc170620 (patch) | |
tree | 69095e884b667cd388bf4f11c6f82eb15938e1b9 /drivers/usb/dwc3/core.c | |
parent | 7f79a2c2357d16fc9dd08e761e931a4f2169d625 (diff) |
usb: dwc3: Add frame length adjustment quirk
[backport from linux commit db2be4e9e30c6e43e48c5749d3fc74cee0a6bbb3]
Add adjust_frame_length_quirk for writing to fladj register
which adjusts (micro)frame length to value provided by
"snps,quirk-frame-length-adjustment" property thus avoiding
USB 2.0 devices to time-out over a longer run
Signed-off-by: Michael Walle <michael@walle.cc>
Reviewed-by: Priyanka Jain <priyanka.jain@nxp.com>
Diffstat (limited to 'drivers/usb/dwc3/core.c')
-rw-r--r-- | drivers/usb/dwc3/core.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index dfd7cf683f7..4fb6b59d50b 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -93,6 +93,27 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc) return 0; } +/* + * dwc3_frame_length_adjustment - Adjusts frame length if required + * @dwc3: Pointer to our controller context structure + * @fladj: Value of GFLADJ_30MHZ to adjust frame length + */ +static void dwc3_frame_length_adjustment(struct dwc3 *dwc, u32 fladj) +{ + u32 reg; + + if (dwc->revision < DWC3_REVISION_250A) + return; + + if (fladj == 0) + return; + + reg = dwc3_readl(dwc->regs, DWC3_GFLADJ); + reg &= ~DWC3_GFLADJ_30MHZ_MASK; + reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | fladj; + dwc3_writel(dwc->regs, DWC3_GFLADJ, reg); +} + /** * dwc3_free_one_event_buffer - Frees one event buffer * @dwc: Pointer to our controller context structure @@ -569,6 +590,9 @@ static int dwc3_core_init(struct dwc3 *dwc) if (ret) goto err1; + /* Adjust Frame Length */ + dwc3_frame_length_adjustment(dwc, dwc->fladj); + return 0; err1: @@ -958,6 +982,8 @@ void dwc3_of_parse(struct dwc3 *dwc) dwc->hird_threshold = hird_threshold | (dwc->is_utmi_l1_suspend << 4); + + dev_read_u32(dev, "snps,quirk-frame-length-adjustment", &dwc->fladj); } int dwc3_init(struct dwc3 *dwc) |