summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2017-08-03 13:45:26 +0000
committerhselasky <hselasky@FreeBSD.org>2017-08-03 13:45:26 +0000
commit0a535ce11fb2d83eca2b1dcbd567ef7923ab3968 (patch)
treeea1a398af4cf69c7e721d990aebe42efa5e67185
parentcfc3e00a8e6f494c977d5453cbd629e7710ad40b (diff)
downloadFreeBSD-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.c29
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);
OpenPOWER on IntegriCloud