From c60aeaf2e6079dd85d2783f308b87dd8043b795e Mon Sep 17 00:00:00 2001 From: Jonathan Bell Date: Wed, 11 Jun 2025 13:51:00 +0100 Subject: [PATCH] usb: dwc2: return correct frame counts with high-speed host The HFNUM register increments on every microframe in HS mode, and USB device drivers expect the returned frame count to relate to the overall frame. Right-shift the returned value by 3 to drop the microframe bits. Signed-off-by: Jonathan Bell --- drivers/usb/dwc2/hcd.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 30eb8506617c..c64c2dee7e59 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -3775,12 +3775,17 @@ static int dwc2_hcd_is_status_changed(struct dwc2_hsotg *hsotg, int port) int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg) { u32 hfnum = dwc2_readl(hsotg, HFNUM); + u32 hprt0 = dwc2_readl(hsotg, HPRT0); #ifdef DWC2_DEBUG_SOF dev_vdbg(hsotg->dev, "DWC OTG HCD GET FRAME NUMBER %d\n", (hfnum & HFNUM_FRNUM_MASK) >> HFNUM_FRNUM_SHIFT); #endif - return (hfnum & HFNUM_FRNUM_MASK) >> HFNUM_FRNUM_SHIFT; + /* HS root port counts microframes, not frames */ + if ((hprt0 & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT == HPRT0_SPD_HIGH_SPEED) + return (hfnum & HFNUM_FRNUM_MASK) >> (3 + HFNUM_FRNUM_SHIFT); + else + return (hfnum & HFNUM_FRNUM_MASK) >> HFNUM_FRNUM_SHIFT; } int dwc2_hcd_get_future_frame_number(struct dwc2_hsotg *hsotg, int us)