Skip to content

Commit 1637ea0

Browse files
committed
drivers: udc_dwc2: Rearm isochronous OUT endpoints during incompisoout
Rearm isochronous endpoints when handling incomplete iso out interrupt to make it possible to rearm the endpoint in time (before SOF), especially when operating at High-Speed. Signed-off-by: Tomasz Moń <[email protected]>
1 parent 397ae3c commit 1637ea0

File tree

1 file changed

+21
-0
lines changed

1 file changed

+21
-0
lines changed

drivers/usb/udc/udc_dwc2.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ struct udc_dwc2_data {
121121
/* Isochronous endpoint enabled (IN on bits 0-15, OUT on bits 16-31) */
122122
uint32_t iso_enabled;
123123
uint16_t iso_in_rearm;
124+
uint16_t iso_out_rearm;
124125
uint16_t ep_out_disable;
125126
uint16_t ep_out_stall;
126127
uint16_t txf_set;
@@ -2773,6 +2774,7 @@ static inline void dwc2_handle_oepint(const struct device *dev)
27732774
while (epint) {
27742775
uint8_t n = find_lsb_set(epint) - 1;
27752776
mem_addr_t doepint_reg = (mem_addr_t)&base->out_ep[n].doepint;
2777+
mem_addr_t doepctl_reg = (mem_addr_t)&base->out_ep[n].doepctl;
27762778
uint32_t doepint;
27772779
uint32_t status;
27782780

@@ -2825,7 +2827,20 @@ static inline void dwc2_handle_oepint(const struct device *dev)
28252827
}
28262828

28272829
if (status & USB_DWC2_DOEPINT_EPDISBLD) {
2830+
uint32_t doepctl = sys_read32(doepctl_reg);
2831+
28282832
k_event_post(&priv->ep_disabled, BIT(16 + n));
2833+
2834+
if ((usb_dwc2_get_depctl_eptype(doepctl) == USB_DWC2_DEPCTL_EPTYPE_ISO) &&
2835+
(priv->iso_out_rearm & BIT(n))) {
2836+
struct udc_ep_config *cfg;
2837+
2838+
/* Try to queue next packet before SOF */
2839+
cfg = udc_get_ep_cfg(dev, n | USB_EP_DIR_OUT);
2840+
dwc2_handle_xfer_next(dev, cfg);
2841+
2842+
priv->iso_out_rearm &= ~BIT(n);
2843+
}
28292844
}
28302845

28312846
epint &= ~BIT(n);
@@ -2910,6 +2925,7 @@ static void dwc2_handle_incompisoout(const struct device *dev)
29102925
((priv->sof_num & 1) ? USB_DWC2_DEPCTL_DPID : 0) |
29112926
USB_DWC2_DEPCTL_USBACTEP;
29122927
uint32_t eps = (priv->iso_enabled & 0xFFFF0000UL) >> 16;
2928+
uint16_t rearm = 0;
29132929

29142930
while (eps) {
29152931
uint8_t i = find_lsb_set(eps) - 1;
@@ -2932,12 +2948,17 @@ static void dwc2_handle_incompisoout(const struct device *dev)
29322948
buf = udc_buf_get(cfg);
29332949
if (buf) {
29342950
udc_submit_ep_event(dev, buf, 0);
2951+
2952+
rearm |= BIT(i);
29352953
}
29362954
}
29372955

29382956
eps &= ~BIT(i);
29392957
}
29402958

2959+
/* Mark endpoints to re-arm in EPDISBLD handler */
2960+
priv->iso_out_rearm = rearm;
2961+
29412962
sys_write32(USB_DWC2_GINTSTS_INCOMPISOOUT, gintsts_reg);
29422963
}
29432964

0 commit comments

Comments
 (0)