usb: dwc3: gadget: Give some time to schedule isoc
authorThinh Nguyen <Thinh.Nguyen@synopsys.com>
Tue, 8 Mar 2022 02:59:56 +0000 (18:59 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 15 Mar 2022 14:42:24 +0000 (15:42 +0100)
Currently the driver will schedule isoc transfers immediately on the
next interval, which is quite aggressive when the interval is 125us.
There's report that some platforms may need more time to process the
transfer, otherwise the controller may miss the first interval. Let's
keep it simple and give the controller at least 500us to schedule the
isoc transfer.

Link: https://lore.kernel.org/linux-usb/20220302143539.GI11577@pengutronix.de/
Tested-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Link: https://lore.kernel.org/r/deb8146b8e1f7f8495ef2d5647017270934cb2d8.1646708142.git.Thinh.Nguyen@synopsys.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/dwc3/gadget.c

index a0c883f19a417c3df0b76ff0eedc0f9ef134da8d..eb88ef5dd16ff0c412133be6820293e0ee4c62f6 100644 (file)
@@ -1830,7 +1830,13 @@ static int __dwc3_gadget_start_isoc(struct dwc3_ep *dep)
        }
 
        for (i = 0; i < DWC3_ISOC_MAX_RETRIES; i++) {
-               dep->frame_number = DWC3_ALIGN_FRAME(dep, i + 1);
+               int future_interval = i + 1;
+
+               /* Give the controller at least 500us to schedule transfers */
+               if (desc->bInterval < 3)
+                       future_interval += 3 - desc->bInterval;
+
+               dep->frame_number = DWC3_ALIGN_FRAME(dep, future_interval);
 
                ret = __dwc3_gadget_kick_transfer(dep);
                if (ret != -EAGAIN)