diff options
author | hselasky <hselasky@FreeBSD.org> | 2017-08-03 13:45:26 +0000 |
---|---|---|
committer | hselasky <hselasky@FreeBSD.org> | 2017-08-03 13:45:26 +0000 |
commit | 0a535ce11fb2d83eca2b1dcbd567ef7923ab3968 (patch) | |
tree | ea1a398af4cf69c7e721d990aebe42efa5e67185 | |
parent | cfc3e00a8e6f494c977d5453cbd629e7710ad40b (diff) | |
download | FreeBSD-src-0a535ce11fb2d83eca2b1dcbd567ef7923ab3968.zip FreeBSD-src-0a535ce11fb2d83eca2b1dcbd567ef7923ab3968.tar.gz |
MFC r320773:
Implement fix for BULK IN-token retry mechanism. When the hardware is
programmed for infinite IN token retry after NAK, the SAF1761
hardware, however, does not retry the IN-token. This problem is
described in the SAF1761 errata, section 18.1.1.
While at it:
- Add some minor chip specific initialization for RTEMS.
- Add debug print for status registers in the interrupt filter.
Submitted by: Christian Mauderer <christian.mauderer@embedded-brains.de>
-rw-r--r-- | sys/dev/usb/controller/saf1761_otg.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/sys/dev/usb/controller/saf1761_otg.c b/sys/dev/usb/controller/saf1761_otg.c index d28f41e..b559ac8 100644 --- a/sys/dev/usb/controller/saf1761_otg.c +++ b/sys/dev/usb/controller/saf1761_otg.c @@ -516,7 +516,25 @@ saf1761_host_bulk_data_rx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *t DPRINTFN(5, "STATUS=0x%08x\n", status); if (status & SOTG_PTD_DW3_ACTIVE) { - goto busy; + temp = saf1761_peek_host_status_le_4(sc, + pdt_addr + SOTG_PTD_DW0); + if (temp & SOTG_PTD_DW0_VALID) { + goto busy; + } else { + status = saf1761_peek_host_status_le_4(sc, + pdt_addr + SOTG_PTD_DW3); + + /* check if still active */ + if (status & SOTG_PTD_DW3_ACTIVE) { + saf1761_host_channel_free(sc, td); + goto retry; + } else if (status & SOTG_PTD_DW3_HALTED) { + if (!(status & SOTG_PTD_DW3_ERRORS)) + td->error_stall = 1; + td->error_any = 1; + goto complete; + } + } } else if (status & SOTG_PTD_DW3_HALTED) { if (!(status & SOTG_PTD_DW3_ERRORS)) td->error_stall = 1; @@ -560,6 +578,7 @@ saf1761_host_bulk_data_rx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *t } saf1761_host_channel_free(sc, td); } +retry: if (saf1761_host_channel_alloc(sc, td)) goto busy; @@ -1589,6 +1608,8 @@ saf1761_otg_filter_interrupt(void *arg) (void) SAF1761_READ_LE_4(sc, SOTG_INT_PTD_DONE_PTD); (void) SAF1761_READ_LE_4(sc, SOTG_ISO_PTD_DONE_PTD); + DPRINTFN(9, "HCINTERRUPT=0x%08x DCINTERRUPT=0x%08x\n", hcstat, status); + if (status & SOTG_DCINTERRUPT_IEPSOF) { if ((sc->sc_host_async_busy_map[1] | sc->sc_host_async_busy_map[0] | sc->sc_host_intr_busy_map[1] | sc->sc_host_intr_busy_map[0] | @@ -2446,11 +2467,15 @@ saf1761_otg_init(struct saf1761_otg_softc *sc) */ SAF1761_WRITE_LE_4(sc, SOTG_CTRL_SET_CLR, SOTG_CTRL_CLR(0xFFFF)); +#ifdef __rtems__ + SAF1761_WRITE_LE_4(sc, SOTG_CTRL_SET_CLR, + SOTG_CTRL_SET(SOTG_CTRL_SEL_CP_EXT | SOTG_CTRL_VBUS_DRV)); +#else SAF1761_WRITE_LE_4(sc, SOTG_CTRL_SET_CLR, SOTG_CTRL_SET(SOTG_CTRL_SW_SEL_HC_DC | SOTG_CTRL_BDIS_ACON_EN | SOTG_CTRL_SEL_CP_EXT | SOTG_CTRL_VBUS_DRV)); - +#endif /* disable device address */ SAF1761_WRITE_LE_4(sc, SOTG_ADDRESS, 0); |