@@ -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;
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@quicinc.com> --- drivers/usb/dwc3/core.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)