Skip to content

Commit 163e855

Browse files
committed
[nrf fromtree] 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]> (cherry picked from commit 6eb2fa8)
1 parent df8e4c1 commit 163e855

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;
@@ -2776,6 +2777,7 @@ static inline void dwc2_handle_oepint(const struct device *dev)
27762777
while (epint) {
27772778
uint8_t n = find_lsb_set(epint) - 1;
27782779
mem_addr_t doepint_reg = (mem_addr_t)&base->out_ep[n].doepint;
2780+
mem_addr_t doepctl_reg = (mem_addr_t)&base->out_ep[n].doepctl;
27792781
uint32_t doepint;
27802782
uint32_t status;
27812783

@@ -2828,7 +2830,20 @@ static inline void dwc2_handle_oepint(const struct device *dev)
28282830
}
28292831

28302832
if (status & USB_DWC2_DOEPINT_EPDISBLD) {
2833+
uint32_t doepctl = sys_read32(doepctl_reg);
2834+
28312835
k_event_post(&priv->ep_disabled, BIT(16 + n));
2836+
2837+
if ((usb_dwc2_get_depctl_eptype(doepctl) == USB_DWC2_DEPCTL_EPTYPE_ISO) &&
2838+
(priv->iso_out_rearm & BIT(n))) {
2839+
struct udc_ep_config *cfg;
2840+
2841+
/* Try to queue next packet before SOF */
2842+
cfg = udc_get_ep_cfg(dev, n | USB_EP_DIR_OUT);
2843+
dwc2_handle_xfer_next(dev, cfg);
2844+
2845+
priv->iso_out_rearm &= ~BIT(n);
2846+
}
28322847
}
28332848

28342849
epint &= ~BIT(n);
@@ -2913,6 +2928,7 @@ static void dwc2_handle_incompisoout(const struct device *dev)
29132928
((priv->sof_num & 1) ? USB_DWC2_DEPCTL_DPID : 0) |
29142929
USB_DWC2_DEPCTL_USBACTEP;
29152930
uint32_t eps = (priv->iso_enabled & 0xFFFF0000UL) >> 16;
2931+
uint16_t rearm = 0;
29162932

29172933
while (eps) {
29182934
uint8_t i = find_lsb_set(eps) - 1;
@@ -2935,12 +2951,17 @@ static void dwc2_handle_incompisoout(const struct device *dev)
29352951
buf = udc_buf_get(cfg);
29362952
if (buf) {
29372953
udc_submit_ep_event(dev, buf, 0);
2954+
2955+
rearm |= BIT(i);
29382956
}
29392957
}
29402958

29412959
eps &= ~BIT(i);
29422960
}
29432961

2962+
/* Mark endpoints to re-arm in EPDISBLD handler */
2963+
priv->iso_out_rearm = rearm;
2964+
29442965
sys_write32(USB_DWC2_GINTSTS_INCOMPISOOUT, gintsts_reg);
29452966
}
29462967

0 commit comments

Comments
 (0)