From owner-svn-src-all@FreeBSD.ORG Tue May 20 14:15:04 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 5791DEC7; Tue, 20 May 2014 14:15:04 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 2A4F22A01; Tue, 20 May 2014 14:15:04 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s4KEF4mx070532; Tue, 20 May 2014 14:15:04 GMT (envelope-from hselasky@svn.freebsd.org) Received: (from hselasky@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s4KEF3wx070529; Tue, 20 May 2014 14:15:03 GMT (envelope-from hselasky@svn.freebsd.org) Message-Id: <201405201415.s4KEF3wx070529@svn.freebsd.org> From: Hans Petter Selasky Date: Tue, 20 May 2014 14:15:03 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r266467 - head/sys/dev/usb/controller X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 20 May 2014 14:15:04 -0000 Author: hselasky Date: Tue May 20 14:15:03 2014 New Revision: 266467 URL: http://svnweb.freebsd.org/changeset/base/266467 Log: Correct some programming details. The layout of the PDTs were different from what was initially thought. Fix re-programming of hardware mode register after reset. Sponsored by: DARPA, AFRL Modified: head/sys/dev/usb/controller/saf1761_otg.c head/sys/dev/usb/controller/saf1761_otg_reg.h Modified: head/sys/dev/usb/controller/saf1761_otg.c ============================================================================== --- head/sys/dev/usb/controller/saf1761_otg.c Tue May 20 12:22:53 2014 (r266466) +++ head/sys/dev/usb/controller/saf1761_otg.c Tue May 20 14:15:03 2014 (r266467) @@ -227,7 +227,7 @@ saf1761_host_channel_alloc(struct saf176 if (sc->sc_host_isoc_map & (1 << x)) continue; sc->sc_host_isoc_map |= (1 << x); - td->channel = 64 + x; + td->channel = x; return (0); } break; @@ -236,7 +236,7 @@ saf1761_host_channel_alloc(struct saf176 if (sc->sc_host_async_map & (1 << x)) continue; sc->sc_host_async_map |= (1 << x); - td->channel = x; + td->channel = 64 + x; return (0); } break; @@ -253,8 +253,8 @@ saf1761_host_channel_free(struct saf1761 return; /* disable channel */ - SAF1761_WRITE_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 3), 0); - SAF1761_WRITE_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 0), 0); + SAF1761_WRITE_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 3), 0); + SAF1761_WRITE_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 0), 0); switch (td->ep_type) { case UE_INTERRUPT: @@ -263,7 +263,7 @@ saf1761_host_channel_free(struct saf1761 td->channel = SOTG_HOST_CHANNEL_MAX; break; case UE_ISOCHRONOUS: - x = td->channel - 64; + x = td->channel; sc->sc_host_isoc_map &= ~(1 << x); td->channel = SOTG_HOST_CHANNEL_MAX; break; @@ -276,19 +276,23 @@ saf1761_host_channel_free(struct saf1761 } static void -saf1761_read_host_fifo_1(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td, - void *buf, uint32_t len) +saf1761_read_host_memory_4(struct saf1761_otg_softc *sc, uint32_t offset, + void *buf, uint32_t count) { - bus_space_read_region_1((sc)->sc_io_tag, (sc)->sc_io_hdl, - SOTG_DATA_ADDR(td->channel), buf, len); + if (count == 0) + return; + SAF1761_WRITE_4(sc, SOTG_MEMORY_REG, SOTG_HC_MEMORY_ADDR(offset)); + DELAY(1); /* read prefetch time is 90ns */ + bus_space_read_region_4((sc)->sc_io_tag, (sc)->sc_io_hdl, offset, buf, count); } static void -saf1761_write_host_fifo_1(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td, - void *buf, uint32_t len) +saf1761_write_host_memory_4(struct saf1761_otg_softc *sc, uint32_t offset, + void *buf, uint32_t count) { - bus_space_write_region_1((sc)->sc_io_tag, (sc)->sc_io_hdl, - SOTG_DATA_ADDR(td->channel), buf, len); + if (count == 0) + return; + bus_space_write_region_4((sc)->sc_io_tag, (sc)->sc_io_hdl, offset, buf, count); } static uint8_t @@ -299,7 +303,7 @@ saf1761_host_setup_tx(struct saf1761_otg uint32_t count; if (td->channel < SOTG_HOST_CHANNEL_MAX) { - status = SAF1761_READ_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 3)); + status = SAF1761_READ_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 3)); if (status & (1 << 31)) { goto busy; } else if (status & (1 << 30)) { @@ -325,23 +329,24 @@ saf1761_host_setup_tx(struct saf1761_otg usbd_copy_out(td->pc, 0, &req, count); - saf1761_write_host_fifo_1(sc, td, &req, count); + saf1761_write_host_memory_4(sc, SOTG_DATA_ADDR(td->channel), + &req, (count + 3) / 4); - SAF1761_WRITE_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 7), 0); - SAF1761_WRITE_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 6), 0); - SAF1761_WRITE_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 5), 0); - SAF1761_WRITE_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 4), 0); - SAF1761_WRITE_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 3), + SAF1761_WRITE_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 7), 0); + SAF1761_WRITE_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 6), 0); + SAF1761_WRITE_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 5), 0); + SAF1761_WRITE_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 4), 0); + SAF1761_WRITE_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 3), (1 << 31) | (td->toggle << 25) | (3 << 23)); - SAF1761_WRITE_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 2), + SAF1761_WRITE_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 2), SOTG_HC_MEMORY_ADDR(SOTG_DATA_ADDR(td->channel)) << 8); - SAF1761_WRITE_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 1), + SAF1761_WRITE_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 1), td->dw1_value | (2 << 10) /* SETUP PID */ | (td->ep_index >> 1)); - SAF1761_WRITE_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 0), + SAF1761_WRITE_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 0), (td->ep_index << 31) | (1 << 29) /* pkt-multiplier */ | (td->max_packet_size << 18) /* wMaxPacketSize */ | @@ -365,7 +370,7 @@ saf1761_host_bulk_data_rx(struct saf1761 uint32_t count; uint8_t got_short; - status = SAF1761_READ_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 3)); + status = SAF1761_READ_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 3)); if (status & (1 << 31)) { goto busy; @@ -401,8 +406,9 @@ saf1761_host_bulk_data_rx(struct saf1761 goto complete; } - saf1761_read_host_fifo_1(sc, td, - sc->sc_bounce_buffer, count); + saf1761_read_host_memory_4(sc, SOTG_DATA_ADDR(td->channel), + sc->sc_bounce_buffer, (count + 3) / 4); + usbd_copy_in(td->pc, td->offset, sc->sc_bounce_buffer, count); @@ -429,21 +435,21 @@ saf1761_host_bulk_data_rx(struct saf1761 /* receive one more packet */ - SAF1761_WRITE_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 7), 0); - SAF1761_WRITE_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 6), 0); - SAF1761_WRITE_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 5), 0); - SAF1761_WRITE_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 4), 0); - SAF1761_WRITE_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 3), + SAF1761_WRITE_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 7), 0); + SAF1761_WRITE_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 6), 0); + SAF1761_WRITE_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 5), 0); + SAF1761_WRITE_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 4), 0); + SAF1761_WRITE_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 3), (1 << 31) | (td->toggle << 25) | (3 << 23)); - SAF1761_WRITE_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 2), + SAF1761_WRITE_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 2), SOTG_HC_MEMORY_ADDR(SOTG_DATA_ADDR(td->channel)) << 8); - SAF1761_WRITE_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 1), + SAF1761_WRITE_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 1), td->dw1_value | (1 << 10) /* IN-PID */ | (td->ep_index >> 1)); - SAF1761_WRITE_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 0), + SAF1761_WRITE_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 0), (td->ep_index << 31) | (1 << 29) /* pkt-multiplier */ | (td->max_packet_size << 18) /* wMaxPacketSize */ | @@ -463,7 +469,7 @@ saf1761_host_bulk_data_tx(struct saf1761 if (td->channel < SOTG_HOST_CHANNEL_MAX) { uint32_t status; - status = SAF1761_READ_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 3)); + status = SAF1761_READ_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 3)); if (status & (1 << 31)) { goto busy; } else if (status & (1 << 30)) { @@ -493,7 +499,8 @@ saf1761_host_bulk_data_tx(struct saf1761 } usbd_copy_out(td->pc, td->offset, sc->sc_bounce_buffer, count); - saf1761_write_host_fifo_1(sc, td, sc->sc_bounce_buffer, count); + saf1761_write_host_memory_4(sc, SOTG_DATA_ADDR(td->channel), + sc->sc_bounce_buffer, (count + 3) / 4); /* set toggle, if any */ if (td->set_toggle) { @@ -501,21 +508,21 @@ saf1761_host_bulk_data_tx(struct saf1761 td->toggle = 1; } - SAF1761_WRITE_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 7), 0); - SAF1761_WRITE_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 6), 0); - SAF1761_WRITE_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 5), 0); - SAF1761_WRITE_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 4), 0); - SAF1761_WRITE_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 3), + SAF1761_WRITE_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 7), 0); + SAF1761_WRITE_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 6), 0); + SAF1761_WRITE_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 5), 0); + SAF1761_WRITE_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 4), 0); + SAF1761_WRITE_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 3), (1 << 31) | (td->toggle << 25) | (3 << 23)); - SAF1761_WRITE_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 2), + SAF1761_WRITE_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 2), SOTG_HC_MEMORY_ADDR(SOTG_DATA_ADDR(td->channel)) << 8); - SAF1761_WRITE_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 1), + SAF1761_WRITE_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 1), td->dw1_value | (0 << 10) /* OUT-PID */ | (td->ep_index >> 1)); - SAF1761_WRITE_4(sc, SOTG_ASYNC_PDT(td->channel) + (4 * 0), + SAF1761_WRITE_4(sc, SOTG_ISOC_PDT(td->channel) + (4 * 0), (td->ep_index << 31) | (1 << 29) /* pkt-multiplier */ | (td->max_packet_size << 18) /* wMaxPacketSize */ | @@ -566,6 +573,8 @@ saf1761_otg_set_address(struct saf1761_o static void saf1761_read_device_fifo_1(struct saf1761_otg_softc *sc, void *buf, uint32_t len) { + if (len == 0) + return; bus_space_read_multi_1((sc)->sc_io_tag, (sc)->sc_io_hdl, SOTG_DATA_PORT, buf, len); } @@ -573,6 +582,8 @@ saf1761_read_device_fifo_1(struct saf176 static void saf1761_write_device_fifo_1(struct saf1761_otg_softc *sc, void *buf, uint32_t len) { + if (len == 0) + return; bus_space_write_multi_1((sc)->sc_io_tag, (sc)->sc_io_hdl, SOTG_DATA_PORT, buf, len); } @@ -1614,10 +1625,29 @@ saf1761_otg_init(struct saf1761_otg_soft USB_BUS_LOCK(&sc->sc_bus); + /* Reset Host controller, including HW mode */ + SAF1761_WRITE_2(sc, SOTG_SW_RESET, SOTG_SW_RESET_ALL); + + DELAY(1000); + + /* Reset Host controller, including HW mode */ + SAF1761_WRITE_2(sc, SOTG_SW_RESET, SOTG_SW_RESET_HC); + + /* wait a bit */ + DELAY(1000); + + SAF1761_WRITE_2(sc, SOTG_SW_RESET, 0); + + /* wait a bit */ + DELAY(1000); + /* Enable interrupts */ sc->sc_hw_mode |= SOTG_HW_MODE_CTRL_GLOBAL_INTR_EN | SOTG_HW_MODE_CTRL_COMN_INT; + /* unlock device */ + SAF1761_WRITE_2(sc, SOTG_UNLOCK_DEVICE, SOTG_UNLOCK_DEVICE_CODE); + /* * Set correct hardware mode, must be written twice if bus * width is changed: @@ -1625,7 +1655,14 @@ saf1761_otg_init(struct saf1761_otg_soft 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)); + SAF1761_WRITE_4(sc, SOTG_DCSCRATCH, 0xdeadbeef); + + DPRINTF("DCID=0x%08x VEND=0x%04x PROD=0x%04x HWMODE=0x%08x SCRATCH=0x%08x\n", + SAF1761_READ_4(sc, SOTG_DCCHIP_ID), + SAF1761_READ_2(sc, SOTG_VEND_ID), + SAF1761_READ_2(sc, SOTG_PROD_ID), + SAF1761_READ_4(sc, SOTG_HW_MODE_CTRL), + SAF1761_READ_4(sc, SOTG_DCSCRATCH)); /* reset device controller */ SAF1761_WRITE_2(sc, SOTG_MODE, SOTG_MODE_SFRESET); @@ -1635,14 +1672,22 @@ saf1761_otg_init(struct saf1761_otg_soft DELAY(1000); /* reset host controller */ - SAF1761_WRITE_4(sc, SOTG_SW_RESET, SOTG_SW_RESET_HC); SAF1761_WRITE_4(sc, SOTG_USBCMD, SOTG_USBCMD_HCRESET); + /* wait for reset to clear */ + for (x = 0; x != 10; x++) { + if ((SAF1761_READ_4(sc, SOTG_USBCMD) & SOTG_USBCMD_HCRESET) == 0) + break; + usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 10); + } + + SAF1761_WRITE_4(sc, SOTG_HW_MODE_CTRL, sc->sc_hw_mode | + SOTG_HW_MODE_CTRL_ALL_ATX_RESET); + /* wait a bit */ DELAY(1000); - SAF1761_WRITE_4(sc, SOTG_SW_RESET, 0); - SAF1761_WRITE_4(sc, SOTG_USBCMD, 0); + SAF1761_WRITE_4(sc, SOTG_HW_MODE_CTRL, sc->sc_hw_mode); /* wait a bit */ DELAY(1000); @@ -1696,10 +1741,14 @@ saf1761_otg_init(struct saf1761_otg_soft SOTG_DCINTERRUPT_IEBRST | SOTG_DCINTERRUPT_IESUSP; SAF1761_WRITE_4(sc, SOTG_DCINTERRUPT_EN, sc->sc_intr_enable); - /* connect ATX port 1 to device controller */ + /* + * Connect ATX port 1 to device controller, select external + * charge pump and driver VBUS to +5V: + */ 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); + SOTG_CTRL_BDIS_ACON_EN | SOTG_CTRL_SEL_CP_EXT | + SOTG_CTRL_VBUS_DRV); /* disable device address */ SAF1761_WRITE_1(sc, SOTG_ADDRESS, 0); @@ -1720,6 +1769,8 @@ saf1761_otg_init(struct saf1761_otg_soft /* start the HC */ SAF1761_WRITE_4(sc, SOTG_USBCMD, SOTG_USBCMD_RS); + DPRINTF("USBCMD=0x%08x\n", SAF1761_READ_4(sc, SOTG_USBCMD)); + /* enable HC interrupts */ SAF1761_WRITE_4(sc, SOTG_HCINTERRUPT_ENABLE, SOTG_HCINTERRUPT_OTG_IRQ | @@ -2477,7 +2528,8 @@ tr_handle_get_port_status_host: temp = SAF1761_READ_4(sc, SOTG_PORTSC1); - DPRINTFN(9, "port status=0x%04x\n", temp); + DPRINTFN(9, "UR_GET_PORT_STATUS on port %d = 0x%08x\n", index, temp); + i = UPS_HIGH_SPEED; if (temp & SOTG_PORTSC1_ECCS) Modified: head/sys/dev/usb/controller/saf1761_otg_reg.h ============================================================================== --- head/sys/dev/usb/controller/saf1761_otg_reg.h Tue May 20 12:22:53 2014 (r266466) +++ head/sys/dev/usb/controller/saf1761_otg_reg.h Tue May 20 14:15:03 2014 (r266467) @@ -78,6 +78,7 @@ #define SOTG_TIMER_HIGH_SET 0x38C #define SOTG_TIMER_HIGH_CLR 0x38E #define SOTG_TIMER_START_TMR (1U << 15) +#define SOTG_MEMORY_REG 0x33c /* Peripheral controller specific registers */ @@ -188,10 +189,10 @@ #define SOTG_PORTSC1_PED (1 << 2) #define SOTG_PORTSC1_ECSC (1 << 1) #define SOTG_PORTSC1_ECCS (1 << 0) -#define SOTG_DATA_ADDR(x) (0x400 + (512 * (x))) -#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_DATA_ADDR(x) (0x1000 + (512 * (x))) +#define SOTG_ASYNC_PDT(x) (0xC00 + ((x) * 32)) +#define SOTG_INTR_PDT(x) (0x800 + ((x) * 32)) +#define SOTG_ISOC_PDT(x) (0x400 + ((x) * 32)) #define SOTG_HC_MEMORY_ADDR(x) (((x) - 0x400) >> 3) #define SOTG_SW_RESET 0x30C #define SOTG_SW_RESET_HC (1 << 1) @@ -210,6 +211,7 @@ #define SOTG_USBCMD_LHCR (1 << 7) #define SOTG_USBCMD_HCRESET (1 << 1) #define SOTG_USBCMD_RS (1 << 0) +#define SOTG_HCSCRATCH 0x308 #define SOTG_HCINTERRUPT 0x310 #define SOTG_HCINTERRUPT_OTG_IRQ (1 << 10) #define SOTG_HCINTERRUPT_ISO_IRQ (1 << 9)