Date: Fri, 16 May 2014 10:30:30 +0000 (UTC) From: Hans Petter Selasky <hselasky@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r266214 - head/sys/dev/usb/controller Message-ID: <201405161030.s4GAUUCE062010@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: hselasky Date: Fri May 16 10:30:30 2014 New Revision: 266214 URL: http://svnweb.freebsd.org/changeset/base/266214 Log: - Correct some programming details for the SAF1761 driver. - Add some more register details. Sponsored by: DARPA, AFRL Modified: head/sys/dev/usb/controller/saf1761_dci.c head/sys/dev/usb/controller/saf1761_dci.h head/sys/dev/usb/controller/saf1761_dci_reg.h Modified: head/sys/dev/usb/controller/saf1761_dci.c ============================================================================== --- head/sys/dev/usb/controller/saf1761_dci.c Fri May 16 05:11:15 2014 (r266213) +++ head/sys/dev/usb/controller/saf1761_dci.c Fri May 16 10:30:30 2014 (r266214) @@ -163,8 +163,6 @@ saf1761_dci_pull_up(struct saf1761_dci_s DPRINTF("\n"); sc->sc_flags.d_pulled_up = 1; - - SAF1761_WRITE_2(sc, SOTG_CTRL_SET, SOTG_CTRL_DP_PULL_UP); } } @@ -177,8 +175,6 @@ saf1761_dci_pull_down(struct saf1761_dci DPRINTF("\n"); sc->sc_flags.d_pulled_up = 0; - - SAF1761_WRITE_2(sc, SOTG_CTRL_CLR, SOTG_CTRL_DP_PULL_UP); } } @@ -212,13 +208,15 @@ saf1761_dci_set_address(struct saf1761_d static void saf1761_read_fifo(struct saf1761_dci_softc *sc, void *buf, uint32_t len) { - bus_space_read_multi_1((sc)->sc_io_tag, (sc)->sc_io_hdl, SOTG_DATA_PORT, buf, len); + bus_space_read_multi_1((sc)->sc_io_tag, (sc)->sc_io_hdl, + SOTG_DATA_PORT, buf, len); } static void saf1761_write_fifo(struct saf1761_dci_softc *sc, void *buf, uint32_t len) { - bus_space_write_multi_1((sc)->sc_io_tag, (sc)->sc_io_hdl, SOTG_DATA_PORT, buf, len); + bus_space_write_multi_1((sc)->sc_io_tag, (sc)->sc_io_hdl, + SOTG_DATA_PORT, buf, len); } static uint8_t @@ -270,6 +268,7 @@ saf1761_dci_setup_rx(struct saf1761_dci_ if ((req.bmRequestType == UT_WRITE_DEVICE) && (req.bRequest == UR_SET_ADDRESS)) { sc->sc_dv_addr = req.wValue[0] & 0x7F; + DPRINTF("Set address %d\n", sc->sc_dv_addr); } else { sc->sc_dv_addr = 0xFF; } @@ -563,10 +562,16 @@ saf1761_dci_wait_suspend(struct saf1761_ static void saf1761_dci_update_vbus(struct saf1761_dci_softc *sc) { - if (SAF1761_READ_4(sc, SOTG_MODE) & SOTG_MODE_VBUSSTAT) { - DPRINTFN(4, "VBUS ON\n"); + uint16_t status; + + /* read fresh status */ + status = SAF1761_READ_2(sc, SOTG_STATUS); - /* VBUS present */ + DPRINTFN(4, "STATUS=0x%04x\n", status); + + if ((status & SOTG_STATUS_VBUS_VLD) && + (status & SOTG_STATUS_ID)) { + /* VBUS present and device mode */ if (!sc->sc_flags.status_vbus) { sc->sc_flags.status_vbus = 1; @@ -574,9 +579,7 @@ saf1761_dci_update_vbus(struct saf1761_d saf1761_dci_root_intr(sc); } } else { - DPRINTFN(4, "VBUS OFF\n"); - - /* VBUS not-present */ + /* VBUS not-present or host mode */ if (sc->sc_flags.status_vbus) { sc->sc_flags.status_vbus = 0; sc->sc_flags.status_bus_reset = 0; @@ -602,11 +605,23 @@ saf1761_dci_interrupt(struct saf1761_dci /* acknowledge all interrupts */ SAF1761_WRITE_4(sc, SOTG_DCINTERRUPT, status); + DPRINTF("DCINTERRUPT=0x%08x SOF=0x%04x\n", status, + SAF1761_READ_2(sc, SOTG_FRAME_NUM)); + + /* update VBUS and ID bits, if any */ if (status & SOTG_DCINTERRUPT_IEVBUS) { - /* update VBUS bit */ saf1761_dci_update_vbus(sc); } + if (status & SOTG_DCINTERRUPT_IEBRST) { + /* unlock device */ + SAF1761_WRITE_2(sc, SOTG_UNLOCK_DEVICE, + SOTG_UNLOCK_DEVICE_CODE); + + /* Enable device address */ + SAF1761_WRITE_1(sc, SOTG_ADDRESS, + SOTG_ADDRESS_ENABLE); + sc->sc_flags.status_bus_reset = 1; sc->sc_flags.status_suspend = 0; sc->sc_flags.change_suspend = 0; @@ -623,6 +638,10 @@ saf1761_dci_interrupt(struct saf1761_dci * at least 3 milliseconds of inactivity on the USB BUS: */ if (status & SOTG_DCINTERRUPT_IERESM) { + /* unlock device */ + SAF1761_WRITE_2(sc, SOTG_UNLOCK_DEVICE, + SOTG_UNLOCK_DEVICE_CODE); + if (sc->sc_flags.status_suspend) { sc->sc_flags.status_suspend = 0; sc->sc_flags.change_suspend = 1; @@ -833,7 +852,7 @@ saf1761_dci_intr_set(struct usb_xfer *xf uint8_t ep_no = (xfer->endpointno & UE_ADDR); uint32_t mask; - DPRINTFN(15, "endpoint 0x%02x\n", xfer->endpointno); + DPRINTFN(15, "endpoint=%d set=%d\n", xfer->endpointno, set); if (ep_no == 0) { mask = SOTG_DCINTERRUPT_IEPRX(0) | @@ -1121,7 +1140,7 @@ saf1761_dci_init(struct saf1761_dci_soft const struct usb_hw_ep_profile *pf; uint8_t x; - DPRINTF("start\n"); + DPRINTF("\n"); /* set up the bus structure */ sc->sc_bus.usbrev = USB_REV_2_0; @@ -1129,6 +1148,19 @@ saf1761_dci_init(struct saf1761_dci_soft USB_BUS_LOCK(&sc->sc_bus); + /* Enable interrupts */ + sc->sc_hw_mode |= SOTG_HW_MODE_CTRL_GLOBAL_INTR_EN | + SOTG_HW_MODE_CTRL_COMN_INT; + + /* + * Set correct hardware mode, must be written twice if bus + * width is changed: + */ + SAF1761_WRITE_2(sc, SOTG_HW_MODE_CTRL, sc->sc_hw_mode); + SAF1761_WRITE_4(sc, SOTG_HW_MODE_CTRL, sc->sc_hw_mode); + + DPRINTF("DCID=0x%08x\n", SAF1761_READ_4(sc, SOTG_DCCHIP_ID)); + /* reset device */ SAF1761_WRITE_2(sc, SOTG_MODE, SOTG_MODE_SFRESET); SAF1761_WRITE_2(sc, SOTG_MODE, 0); @@ -1142,7 +1174,7 @@ saf1761_dci_init(struct saf1761_dci_soft /* wait 10ms for pulldown to stabilise */ usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 100); - for (x = 0;; x++) { + for (x = 1;; x++) { saf1761_dci_get_hw_ep_profile(NULL, &pf, x); if (pf == NULL) @@ -1156,10 +1188,6 @@ saf1761_dci_init(struct saf1761_dci_soft /* select the maximum packet size */ SAF1761_WRITE_2(sc, SOTG_EP_MAXPACKET, pf->max_in_frame_size); - if (x == 0) { - /* enable control endpoint */ - SAF1761_WRITE_2(sc, SOTG_EP_TYPE, SOTG_EP_TYPE_ENABLE); - } /* select the correct endpoint */ SAF1761_WRITE_1(sc, SOTG_EP_INDEX, (x << SOTG_EP_INDEX_ENDP_INDEX_SHIFT) | @@ -1167,20 +1195,35 @@ saf1761_dci_init(struct saf1761_dci_soft /* select the maximum packet size */ SAF1761_WRITE_2(sc, SOTG_EP_MAXPACKET, pf->max_out_frame_size); - - if (x == 0) { - /* enable control endpoint */ - SAF1761_WRITE_2(sc, SOTG_EP_TYPE, SOTG_EP_TYPE_ENABLE); - } } /* enable interrupts */ - SAF1761_WRITE_2(sc, SOTG_MODE, SOTG_MODE_GLINTENA); + SAF1761_WRITE_2(sc, SOTG_MODE, SOTG_MODE_GLINTENA | + SOTG_MODE_CLKAON | SOTG_MODE_WKUPCS); + + /* set default values */ + SAF1761_WRITE_1(sc, SOTG_INTERRUPT_CFG, + SOTG_INTERRUPT_CFG_CDBGMOD | + SOTG_INTERRUPT_CFG_DDBGMODIN | + SOTG_INTERRUPT_CFG_DDBGMODOUT); + + /* enable VBUS and ID interrupt */ + SAF1761_WRITE_2(sc, SOTG_IRQ_ENABLE_CLR, 0xFFFF); + SAF1761_WRITE_2(sc, SOTG_IRQ_ENABLE_SET, + SOTG_IRQ_ID | SOTG_IRQ_VBUS_VLD); /* enable interrupts */ - sc->sc_intr_enable = SOTG_DCINTERRUPT_EN, SOTG_DCINTERRUPT_IEVBUS | + sc->sc_intr_enable = SOTG_DCINTERRUPT_IEVBUS | SOTG_DCINTERRUPT_IEBRST | SOTG_DCINTERRUPT_IESUSP; - SAF1761_WRITE_2(sc, SOTG_DCINTERRUPT_EN, sc->sc_intr_enable); + SAF1761_WRITE_4(sc, SOTG_DCINTERRUPT_EN, sc->sc_intr_enable); + + /* connect ATX port 1 to device controller */ + SAF1761_WRITE_2(sc, SOTG_CTRL_CLR, 0xFFFF); + SAF1761_WRITE_2(sc, SOTG_CTRL_SET, SOTG_CTRL_SW_SEL_HC_DC | + SOTG_CTRL_BDIS_ACON_EN); + + /* disable device address */ + SAF1761_WRITE_1(sc, SOTG_ADDRESS, 0); /* poll initial VBUS status */ saf1761_dci_update_vbus(sc); Modified: head/sys/dev/usb/controller/saf1761_dci.h ============================================================================== --- head/sys/dev/usb/controller/saf1761_dci.h Fri May 16 05:11:15 2014 (r266213) +++ head/sys/dev/usb/controller/saf1761_dci.h Fri May 16 10:30:30 2014 (r266214) @@ -107,7 +107,6 @@ struct saf1761_dci_flags { uint8_t port_powered:1; uint8_t port_enabled:1; uint8_t d_pulled_up:1; - uint8_t mcsr_feat:1; }; struct saf1761_dci_softc { @@ -123,6 +122,7 @@ struct saf1761_dci_softc { bus_space_handle_t sc_io_hdl; uint32_t sc_intr_enable; /* enabled interrupts */ + uint32_t sc_hw_mode; /* hardware mode */ uint8_t sc_rt_addr; /* root HUB address */ uint8_t sc_dv_addr; /* device address */ Modified: head/sys/dev/usb/controller/saf1761_dci_reg.h ============================================================================== --- head/sys/dev/usb/controller/saf1761_dci_reg.h Fri May 16 05:11:15 2014 (r266213) +++ head/sys/dev/usb/controller/saf1761_dci_reg.h Fri May 16 10:30:30 2014 (r266214) @@ -102,6 +102,17 @@ #define SOTG_DEBUG_SET (1 << 0) #define SOTG_DCINTERRUPT_EN 0x214 #define SOTG_HW_MODE_CTRL 0x300 +#define SOTG_HW_MODE_CTRL_ALL_ATX_RESET (1 << 31) +#define SOTG_HW_MODE_CTRL_ANA_DIGI_OC (1 << 15) +#define SOTG_HW_MODE_CTRL_DEV_DMA (1 << 11) +#define SOTG_HW_MODE_CTRL_COMN_INT (1 << 10) +#define SOTG_HW_MODE_CTRL_COMN_DMA (1 << 9) +#define SOTG_HW_MODE_CTRL_DATA_BUS_WIDTH (1 << 8) +#define SOTG_HW_MODE_CTRL_DACK_POL (1 << 6) +#define SOTG_HW_MODE_CTRL_DREQ_POL (1 << 5) +#define SOTG_HW_MODE_CTRL_INTR_POL (1 << 2) +#define SOTG_HW_MODE_CTRL_INTR_LEVEL (1 << 1) +#define SOTG_HW_MODE_CTRL_GLOBAL_INTR_EN (1 << 0) #define SOTG_OTG_CTRL 0x374 #define SOTG_EP_INDEX 0x22c #define SOTG_EP_INDEX_EP0SETUP (1 << 5) @@ -155,5 +166,29 @@ #define SOTG_UNLOCK_DEVICE_CODE 0xAA37 #define SOTG_IRQ_PULSE_WIDTH 0x280 #define SOTG_TEST_MODE 0x284 +#define SOTG_TEST_MODE_FORCEHS (1 << 7) +#define SOTG_TEST_MODE_FORCEFS (1 << 4) +#define SOTG_TEST_MODE_PRBS (1 << 3) +#define SOTG_TEST_MODE_KSTATE (1 << 2) +#define SOTG_TEST_MODE_JSTATE (1 << 1) +#define SOTG_TEST_MODE_SE0_NAK (1 << 0) + +/* Host controller specific registers */ + +#define SOTG_CONFIGFLAG 0x0060 +#define SOTG_CONFIGFLAG_ENABLE (1 << 0) +#define SOTG_PORTSC1 0x0064 +#define SOTG_PORTSC1_PO (1 << 13) +#define SOTG_PORTSC1_PP (1 << 12) +#define SOTG_PORTSC1_PR (1 << 8) +#define SOTG_PORTSC1_SUSP (1 << 7) +#define SOTG_PORTSC1_FPR (1 << 6) +#define SOTG_PORTSC1_PED (1 << 2) +#define SOTG_PORTSC1_ECSC (1 << 1) +#define SOTG_PORTSC1_ECCS (1 << 0) +#define SOTG_ASYNC_PDT(x) (0x400 + (60 * 1024) + ((x) * 32)) +#define SOTG_INTR_PDT(x) (0x400 + (61 * 1024) + ((x) * 32)) +#define SOTG_ISOC_PDT(x) (0x400 + (62 * 1024) + ((x) * 32)) +#define SOTG_HC_MEMORY_ADDR(x) (((x) - 0x400) >> 3) #endif /* _SAF1761_DCI_REG_H_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201405161030.s4GAUUCE062010>