Skip site navigation (1)Skip section navigation (2)
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>