In dwc3_ref_clk_period, the computation fladj = div64_u64(125000ULL * NSEC_PER_SEC, (u64)rate * period); fladj -= 125000; could turn out to be zero. If fladj is zero, the following FIELD_PREP clears out that field and the user overridden value set in the DTS using "snps,quirk-frame-length-adjustment" is lost. Ensure to retain the user overridden value if the above evaluates to 0. Signed-off-by: Varadarajan Narayanan <quic_varada@xxxxxxxxxxx> --- drivers/usb/dwc3/core.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 476b636..63af83b 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -401,6 +401,33 @@ static void dwc3_ref_clk_period(struct dwc3 *dwc) fladj -= 125000; /* + * Since rate = NSEC_PER_SEC / period and period = NSEC_PER_SEC / rate + * above calculation could turn out to be zero. + * + * if (dwc->ref_clk) + * 125000 * NSEC_PER_SEC 125000 * NSEC_PER_SEC + * --------------------- => --------------------- + * rate * period rate * NSEC_PER_SEC + * ------------ + * rate + * else + * 125000 * NSEC_PER_SEC 125000 * NSEC_PER_SEC + * --------------------- => --------------------- + * rate * period NSEC_PER_SEC * period + * ------------ + * period + * Hence, the calculation + * div64_u64(125000ULL * NSEC_PER_SEC, (u64)rate * period) + * returns 125000ULL and fladj -= 125000 sets fladj to zero. + * If fladj is zero, the following FIELD_PREP clears out that + * field and the user overridden value set in the DTS using + * "snps,quirk-frame-length-adjustment" is lost. Ensure to retain + * the user overridden value if the above calculation evaluates to 0. + */ + if (fladj == 0) + fladj = FIELD_GET(DWC3_GFLADJ_REFCLK_FLADJ_MASK, dwc->fladj); + + /* * The documented 240MHz constant is scaled by 2 to get PLS1 as well. */ decr = 480000000 / rate; -- 2.7.4