Module Name: src Committed By: matt Date: Wed Dec 12 00:33:45 UTC 2012
Modified Files: src/sys/arch/arm/omap: files.omap2 omap2_gpio.c omap2_reg.h omap3_ehci.c src/sys/arch/evbarm/beagle: beagle_machdep.c Added Files: src/sys/arch/arm/omap: omap2_gpio.h omap3_uhhreg.h omap3_usbtllreg.h Log Message: Improved USB EHCI support OMAP3 variants. >From jmcneill. To generate a diff of this commit: cvs rdiff -u -r1.17 -r1.18 src/sys/arch/arm/omap/files.omap2 cvs rdiff -u -r1.13 -r1.14 src/sys/arch/arm/omap/omap2_gpio.c \ src/sys/arch/arm/omap/omap2_reg.h cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/omap/omap2_gpio.h \ src/sys/arch/arm/omap/omap3_uhhreg.h \ src/sys/arch/arm/omap/omap3_usbtllreg.h cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/omap/omap3_ehci.c cvs rdiff -u -r1.24 -r1.25 src/sys/arch/evbarm/beagle/beagle_machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/omap/files.omap2 diff -u src/sys/arch/arm/omap/files.omap2:1.17 src/sys/arch/arm/omap/files.omap2:1.18 --- src/sys/arch/arm/omap/files.omap2:1.17 Tue Dec 11 19:21:05 2012 +++ src/sys/arch/arm/omap/files.omap2 Wed Dec 12 00:33:45 2012 @@ -1,4 +1,4 @@ -# $NetBSD: files.omap2,v 1.17 2012/12/11 19:21:05 riastradh Exp $ +# $NetBSD: files.omap2,v 1.18 2012/12/12 00:33:45 matt Exp $ # # Configuration info for Texas Instruments OMAP2/OMAP3 CPU support # Based on xscale/files.pxa2x0 @@ -112,8 +112,8 @@ file arch/arm/omap/am335x_prcm.c ti_am3 attach ohci at obio with obioohci file arch/arm/omap/obio_ohci.c obioohci -attach ehci at obio with obioehci -file arch/arm/omap/omap3_ehci.c obioehci +attach ehci at obio with omap3_ehci +file arch/arm/omap/omap3_ehci.c omap3_ehci device omapfb: rasops16, rasops8, wsemuldisplaydev, vcons attach omapfb at obio Index: src/sys/arch/arm/omap/omap2_gpio.c diff -u src/sys/arch/arm/omap/omap2_gpio.c:1.13 src/sys/arch/arm/omap/omap2_gpio.c:1.14 --- src/sys/arch/arm/omap/omap2_gpio.c:1.13 Tue Dec 11 01:54:42 2012 +++ src/sys/arch/arm/omap/omap2_gpio.c Wed Dec 12 00:33:45 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: omap2_gpio.c,v 1.13 2012/12/11 01:54:42 khorben Exp $ */ +/* $NetBSD: omap2_gpio.c,v 1.14 2012/12/12 00:33:45 matt Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. * All rights reserved. @@ -28,7 +28,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: omap2_gpio.c,v 1.13 2012/12/11 01:54:42 khorben Exp $"); +__KERNEL_RCSID(0, "$NetBSD: omap2_gpio.c,v 1.14 2012/12/12 00:33:45 matt Exp $"); #define _INTR_PRIVATE @@ -52,6 +52,7 @@ __KERNEL_RCSID(0, "$NetBSD: omap2_gpio.c #include <arm/omap/omap2_reg.h> #include <arm/omap/omap2_obiovar.h> +#include <arm/omap/omap2_gpio.h> #include <arm/pic/picvar.h> #if NGPIO > 0 @@ -277,7 +278,7 @@ omap2gpio_pin_ctl(void *arg, int pin, in } static void -gpio_defer(device_t self) +gpio_attach1(device_t self) { struct gpio_softc * const gpio = device_private(self); struct gpio_chipset_tag * const gp = &gpio->gpio_chipset; @@ -430,6 +431,61 @@ gpio_attach(device_t parent, device_t se } aprint_normal("\n"); #if NGPIO > 0 - config_interrupts(self, gpio_defer); +#if 0 + config_interrupts(self, gpio_attach1); +#else + gpio_attach1(self); +#endif #endif } + +#if NGPIO > 0 + +extern struct cfdriver omapgpio_cd; + +#define GPIO_MODULE(pin) ((pin) / 32) +#define GPIO_PIN(pin) ((pin) % 32) + +u_int +omap2_gpio_read(u_int gpio) +{ + struct gpio_softc *sc; + + sc = device_lookup_private(&omapgpio_cd, GPIO_MODULE(gpio)); + if (sc == NULL) + panic("omap2gpio: GPIO Module for pin %d not configured.", gpio); + + return omap2gpio_pin_read(sc, GPIO_PIN(gpio)); +} + +void +omap2_gpio_write(u_int gpio, u_int value) +{ + struct gpio_softc *sc; + + sc = device_lookup_private(&omapgpio_cd, GPIO_MODULE(gpio)); + if (sc == NULL) + panic("omap2gpio: GPIO Module for pin %d not configured.", gpio); + + omap2gpio_pin_write(sc, GPIO_PIN(gpio), value); +} + +void +omap2_gpio_ctl(u_int gpio, int flags) +{ + struct gpio_softc *sc; + + sc = device_lookup_private(&omapgpio_cd, GPIO_MODULE(gpio)); + if (sc == NULL) + panic("omap2gpio: GPIO Module for pin %d not configured.", gpio); + + omap2gpio_pin_ctl(sc, GPIO_PIN(gpio), flags); +} + +bool +omap2_gpio_has_pin(u_int gpio) +{ + return device_lookup_private(&omapgpio_cd, GPIO_MODULE(gpio)) != NULL; +} + +#endif Index: src/sys/arch/arm/omap/omap2_reg.h diff -u src/sys/arch/arm/omap/omap2_reg.h:1.13 src/sys/arch/arm/omap/omap2_reg.h:1.14 --- src/sys/arch/arm/omap/omap2_reg.h:1.13 Tue Dec 11 19:24:38 2012 +++ src/sys/arch/arm/omap/omap2_reg.h Wed Dec 12 00:33:45 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: omap2_reg.h,v 1.13 2012/12/11 19:24:38 riastradh Exp $ */ +/* $NetBSD: omap2_reg.h,v 1.14 2012/12/12 00:33:45 matt Exp $ */ /* * Copyright (c) 2007 Microsoft @@ -32,6 +32,8 @@ #ifndef _ARM_OMAP_OMAP2_REG_H_ #define _ARM_OMAP_OMAP2_REG_H_ +#include "opt_omap.h" + /* * Header for misc. omap2/3/4 registers */ Index: src/sys/arch/arm/omap/omap3_ehci.c diff -u src/sys/arch/arm/omap/omap3_ehci.c:1.4 src/sys/arch/arm/omap/omap3_ehci.c:1.5 --- src/sys/arch/arm/omap/omap3_ehci.c:1.4 Sat Oct 27 17:17:40 2012 +++ src/sys/arch/arm/omap/omap3_ehci.c Wed Dec 12 00:33:45 2012 @@ -1,197 +1,420 @@ -/* $Id: omap3_ehci.c,v 1.4 2012/10/27 17:17:40 chs Exp $ */ +/* $NetBSD: omap3_ehci.c,v 1.5 2012/12/12 00:33:45 matt Exp $ */ -/* adapted from: */ -/* $NetBSD: omap3_ehci.c,v 1.4 2012/10/27 17:17:40 chs Exp $ */ -/* $OpenBSD: pxa2x0_ehci.c,v 1.19 2005/04/08 02:32:54 dlg Exp $ */ - -/* - * Copyright (c) 2005 David Gwynne <d...@openbsd.org> +/*- + * Copyright (c) 2010-2012 Jared D. McNeill <jmcne...@invisible.ca> + * All rights reserved. * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ -#include "opt_omap.h" - #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: omap3_ehci.c,v 1.4 2012/10/27 17:17:40 chs Exp $"); +__KERNEL_RCSID(0, "$NetBSD: omap3_ehci.c,v 1.5 2012/12/12 00:33:45 matt Exp $"); + +#include "locators.h" + +#include "opt_omap.h" #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/intr.h> -#include <sys/bus.h> #include <sys/device.h> -#include <sys/kernel.h> +#include <sys/bus.h> +#include <sys/gpio.h> + +#include <machine/intr.h> + +#include <dev/pci/pcidevs.h> #include <dev/usb/usb.h> #include <dev/usb/usbdi.h> #include <dev/usb/usbdivar.h> #include <dev/usb/usb_mem.h> - #include <dev/usb/ehcireg.h> #include <dev/usb/ehcivar.h> -#include <arm/omap/omap2_reg.h> -#include <arm/omap/omap2_obiovar.h> +#include <arm/omap/omap2_gpio.h> #include <arm/omap/omap2_obioreg.h> +#include <arm/omap/omap2_obiovar.h> +#include <arm/omap/omap2_reg.h> +#include <arm/omap/omap3_usbtllreg.h> +#include <arm/omap/omap3_uhhreg.h> -#include "locators.h" +/* CORE_CM */ +#define CORE_CM_BASE (OMAP2_CM_BASE + 0x0a00) +#define CORE_CM_SIZE 0x2000 + +/* CORE_CM registers */ +#define CM_FCLKEN1_CORE 0x00 +#define CM_FCLKEN3_CORE 0x08 +#define EN_USBTLL 4 /* USB TLL clock enable */ + /* also valid for CM_ICLKEN3_CORE */ +#define CM_ICLKEN1_CORE 0x10 +#define CM_ICLKEN3_CORE 0x18 +#define CM_IDLEST1_CORE 0x20 +#define CM_IDLEST3_CORE 0x28 +#define CM_AUTOIDLE1_CORE 0x30 +#define CM_AUTOIDLE3_CORE 0x38 +#define AUTO_USBTLL 4 /* USB TLL auto enable/disable */ +#define CM_CLKSEL_CORE 0x40 +#define CM_CLKSTCTRL_CORE 0x48 +#define CM_CLKSTST_CORE 0x4c + +/* Clock_Control_Reg_CM */ +#define CCR_CM_BASE (OMAP2_CM_BASE + 0x0d00) +#define CCR_CM_SIZE 0x800 + +/* DPLL clock control registers */ +#define CM_CLKEN2_PLL 0x04 +#define CM_IDLEST2_CKGEN 0x24 +#define ST_PERIPH2_CLK 1 /* DPLL5 is locked */ +#define CM_CLKSEL4_PLL 0x4c +#define CM_CLKSEL5_PLL 0x50 +#define CM_AUTOIDLE2_PLL 0x34 +#define AUTO_PERIPH2_DPLL 1 /* DPLL5 automatic control */ + +/* USBHOST_CM */ +#define USBHOST_CM_BASE (OMAP2_CM_BASE + 0x1400) +#define USBHOST_CM_SIZE 0x2000 + +/* USBHOST_CM registers */ +#define CM_FCLKEN_USBHOST 0x00 +#define EN_USBHOST1 1 /* USB HOST 48 MHz clock enable */ +#define EN_USBHOST2 2 /* USB HOST 1280 MHz clock enable */ +#define CM_ICLKEN_USBHOST 0x10 +#define EN_USBHOST 1 /* USB HOST clock enable */ +#define CM_IDLEST_USBHOST 0x20 +#define CM_AUTOIDLE_USBHOST 0x30 +#define CM_SLEEPDEP_USBHOST 0x44 +#define CM_CLKSTCTRL_USBHOST 0x48 +#define CM_CLKSTST_USBHOST 0x4c + +/* USBTLL module */ +#define USBTLL_BASE 0x48062000 +#define USBTLL_SIZE 0x1000 + +/* HS USB HOST module */ +#define UHH_BASE 0x48064000 +#define UHH_SIZE 0x1000 + +enum omap3_ehci_port_mode { + OMAP3_EHCI_PORT_MODE_NONE, + OMAP3_EHCI_PORT_MODE_PHY, + OMAP3_EHCI_PORT_MODE_TLL, +}; -struct obioehci_softc { +struct omap3_ehci_softc { ehci_softc_t sc; - void *sc_ih; - bus_addr_t sc_addr; - bus_size_t sc_size; + + bus_space_handle_t sc_ioh_usbtll; + bus_size_t sc_usbtll_size; + + bus_space_handle_t sc_ioh_uhh; + bus_size_t sc_uhh_size; + + bool sc_phy_reset; + struct { + enum omap3_ehci_port_mode mode; + int gpio; + } sc_portconfig[3]; + struct { + uint16_t m, n, m2; + } sc_dpll5; }; -static int obioehci_match(device_t, cfdata_t, void *); -static void obioehci_attach(device_t, device_t, void *); -static int obioehci_detach(device_t, int); - -CFATTACH_DECL_NEW(obioehci, sizeof(struct obioehci_softc), - obioehci_match, obioehci_attach, obioehci_detach, ehci_activate); - -static void obioehci_clkinit(struct obio_attach_args *); -static void obioehci_enable(struct obioehci_softc *); -static void obioehci_disable(struct obioehci_softc *); +static void dpll5_init(struct omap3_ehci_softc *); +static void usbhost_init(struct omap3_ehci_softc *, int); +static void usbtll_reset(struct omap3_ehci_softc *); +static void usbtll_power(struct omap3_ehci_softc *, bool); +static void usbtll_init(struct omap3_ehci_softc *, int); +static void uhh_power(struct omap3_ehci_softc *, bool); +static void uhh_portconfig(struct omap3_ehci_softc *); + +#define USBTLL_READ4(sc, reg) bus_space_read_4((sc)->sc.iot, (sc)->sc_ioh_usbtll, (reg)) +#define USBTLL_WRITE4(sc, reg, v) bus_space_write_4((sc)->sc.iot, (sc)->sc_ioh_usbtll, (reg), (v)) +#define UHH_READ4(sc, reg) bus_space_read_4((sc)->sc.iot, (sc)->sc_ioh_uhh, (reg)) +#define UHH_WRITE4(sc, reg, v) bus_space_write_4((sc)->sc.iot, (sc)->sc_ioh_uhh, (reg), (v)) + +/* Table 23-55 "EHCI Registers Mapping Summary" */ +#define EHCI_INSNREG00 0x90 +#define EHCI_INSNREG01 0x94 +#define EHCI_INSNREG02 0x98 +#define EHCI_INSNREG03 0x9c +#define EHCI_INSNREG04 0xa0 +#define EHCI_INSNREG05_ULPI 0xa4 +#define ULPI_CONTROL (1 << 31) +#define ULPI_PORTSEL_SHIFT 24 +#define ULPI_PORTSEL_MASK 0xf +#define ULPI_OPSEL_SHIFT 22 +#define ULPI_OPSEL_MASK 0x3 +#define ULPI_OPSEL_WRITE 0x2 +#define ULPI_OPSEL_READ 0x3 +#define ULPI_REGADD_SHIFT 16 +#define ULPI_REGADD_MASK 0x3f +#define ULPI_WRDATA_SHIFT 0 +#define ULPI_WRDATA_MASK 0xff +#define EHCI_INSNREG05_ITMI 0xa4 + +static void +omap3_ehci_phy_reset(struct omap3_ehci_softc *sc, unsigned int port) +{ + uint32_t reg, v; + int retry = 1000; + + reg = ULPI_FUNCTION_CTRL_RESET | + (5 << ULPI_REGADD_SHIFT) | + (ULPI_OPSEL_WRITE << ULPI_OPSEL_SHIFT) | + (((port + 1) & ULPI_PORTSEL_MASK) << ULPI_PORTSEL_SHIFT) | + ULPI_CONTROL; + EOWRITE4(&sc->sc, EHCI_INSNREG05_ULPI, reg); + + v = EOREAD4(&sc->sc, EHCI_INSNREG05_ULPI); + while (v & (1 << 31) && --retry > 0) { + delay(10000); + v = EOREAD4(&sc->sc, EHCI_INSNREG05_ULPI); + } + if (retry == 0) + aprint_error_dev(sc->sc.sc_dev, "phy reset timeout, port = %d\n", port); +} -#define HREAD4(sc,r) bus_space_read_4((sc)->sc.iot, (sc)->sc.ioh, (r)) -#define HWRITE4(sc,r,v) bus_space_write_4((sc)->sc.iot, (sc)->sc.ioh, (r), (v)) +static void +omap3_ehci_find_companions(struct omap3_ehci_softc *sc) +{ + device_t dv; + deviter_t di; -static int -obioehci_match(device_t parent, cfdata_t cf, void *aux) + sc->sc.sc_ncomp = 0; + for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); + dv != NULL; + dv = deviter_next(&di)) { + if (device_is_a(dv, "ohci") && + device_parent(dv) == device_parent(sc->sc.sc_dev)) { + printf(" adding companion '%s'\n", device_xname(dv)); + sc->sc.sc_comps[sc->sc.sc_ncomp++] = dv; + } + } + deviter_release(&di); +} + +static void +omap3_ehci_attach1(device_t self) { + struct omap3_ehci_softc *sc = device_private(self); + usbd_status err; + int i; + + for (i = 0; sc->sc_phy_reset && i < 3; i++) { + if (sc->sc_portconfig[i].gpio != -1) { + if (!omap2_gpio_has_pin(sc->sc_portconfig[i].gpio)) { + aprint_error_dev(self, "WARNING: " + "gpio pin %d not available\n", + sc->sc_portconfig[i].gpio); + continue; + } + omap2_gpio_ctl(sc->sc_portconfig[i].gpio, GPIO_PIN_OUTPUT); + omap2_gpio_write(sc->sc_portconfig[i].gpio, 0); + delay(10); + } + } - struct obio_attach_args *obio = aux; + usbtll_power(sc, true); + usbtll_init(sc, 3); - if (obio->obio_addr == OBIOCF_ADDR_DEFAULT - || obio->obio_size == OBIOCF_SIZE_DEFAULT - || obio->obio_intr == OBIOCF_INTR_DEFAULT) - return 0; + uhh_power(sc, true); + uhh_portconfig(sc); -#ifdef OMAP_3530 - if (obio->obio_addr != EHCI1_BASE_3530) - return 0; -#endif + for (i = 0; i < 3; i++) { + if (sc->sc_portconfig[i].mode == OMAP3_EHCI_PORT_MODE_PHY) { + omap3_ehci_phy_reset(sc, i); + } + } -#ifdef OMAP_4430 - if (obio->obio_addr != EHCI1_BASE_4430) - return 0; -#endif + delay(10); - obioehci_clkinit(obio); + for (i = 0; sc->sc_phy_reset && i < 3; i++) { + if (sc->sc_portconfig[i].gpio != -1) { + if (!omap2_gpio_has_pin(sc->sc_portconfig[i].gpio)) + continue; + omap2_gpio_ctl(sc->sc_portconfig[i].gpio, GPIO_PIN_OUTPUT); + omap2_gpio_write(sc->sc_portconfig[i].gpio, 1); + delay(10); + } + } + + omap3_ehci_find_companions(sc); + + err = ehci_init(&sc->sc); + if (err != USBD_NORMAL_COMPLETION) { + aprint_error_dev(self, "init failed, error = %d\n", err); + return; + } - return 1; + sc->sc.sc_child = config_found(self, &sc->sc.sc_bus, usbctlprint); } -static void -obioehci_attach(device_t parent, device_t self, void *aux) +static int +omap3_ehci_match(device_t parent, cfdata_t match, void *opaque) { - struct obio_softc * const psc = device_private(parent); - struct obioehci_softc * const sc = device_private(self); - struct obio_attach_args * const obio = aux; - usbd_status r; + struct obio_attach_args *obio = opaque; - /* Map I/O space */ - if (bus_space_map(obio->obio_iot, obio->obio_addr, obio->obio_size, 0, - &sc->sc.ioh)) { - aprint_error(": couldn't map memory space\n"); - return; + if (obio->obio_addr == EHCI1_BASE_3530) + return 1; + + return 0; +} + +static enum omap3_ehci_port_mode +omap3_ehci_get_port_mode(prop_dictionary_t prop, const char *key) +{ + const char *s = NULL; + enum omap3_ehci_port_mode mode = OMAP3_EHCI_PORT_MODE_NONE; + + if (prop_dictionary_get_cstring_nocopy(prop, key, &s) && s != NULL) { + if (strcmp(s, "phy") == 0) { + mode = OMAP3_EHCI_PORT_MODE_PHY; + } else if (strcmp(s, "tll") == 0) { + mode = OMAP3_EHCI_PORT_MODE_TLL; + } } - sc->sc.iot = obio->obio_iot; - sc->sc_addr = obio->obio_addr; + return mode; +} + +static int +omap3_ehci_get_port_gpio(prop_dictionary_t prop, const char *key) +{ + int16_t gpio; - aprint_naive(": USB Controller\n"); - aprint_normal(": USB Controller\n"); + if (prop_dictionary_get_int16(prop, key, &gpio) == false) + gpio = -1; + + return gpio; +} + +static void +omap3_ehci_parse_properties(struct omap3_ehci_softc *sc, prop_dictionary_t prop) +{ + prop_dictionary_get_bool(prop, "phy-reset", &sc->sc_phy_reset); + sc->sc_portconfig[0].mode = omap3_ehci_get_port_mode(prop, "port0-mode"); + sc->sc_portconfig[0].gpio = omap3_ehci_get_port_gpio(prop, "port0-gpio"); + sc->sc_portconfig[1].mode = omap3_ehci_get_port_mode(prop, "port1-mode"); + sc->sc_portconfig[1].gpio = omap3_ehci_get_port_gpio(prop, "port1-gpio"); + sc->sc_portconfig[2].mode = omap3_ehci_get_port_mode(prop, "port2-mode"); + sc->sc_portconfig[2].gpio = omap3_ehci_get_port_gpio(prop, "port2-gpio"); + + prop_dictionary_get_uint16(prop, "dpll5-m", &sc->sc_dpll5.m); + prop_dictionary_get_uint16(prop, "dpll5-n", &sc->sc_dpll5.n); + prop_dictionary_get_uint16(prop, "dpll5-m2", &sc->sc_dpll5.m2); + +#ifdef OMAP3_EHCI_DEBUG + printf(" GPIO PHY reset: %d\n", sc->sc_phy_reset); + printf(" Port #0: mode %d, gpio %d\n", sc->sc_portconfig[0].mode, sc->sc_portconfig[0].gpio); + printf(" Port #1: mode %d, gpio %d\n", sc->sc_portconfig[1].mode, sc->sc_portconfig[1].gpio); + printf(" Port #2: mode %d, gpio %d\n", sc->sc_portconfig[2].mode, sc->sc_portconfig[2].gpio); + printf(" DPLL5: m=%d n=%d m2=%d\n", sc->sc_dpll5.m, sc->sc_dpll5.n, sc->sc_dpll5.m2); +#endif +} + +static void +omap3_ehci_attach(device_t parent, device_t self, void *opaque) +{ + struct omap3_ehci_softc *sc = device_private(self); + struct obio_attach_args *obio = opaque; + int rv; sc->sc.sc_dev = self; + sc->sc.sc_bus.hci_private = sc; + + aprint_naive("\n"); + aprint_normal(": OMAP USB controller\n"); + + omap3_ehci_parse_properties(sc, device_properties(self)); + + sc->sc.iot = obio->obio_iot; + rv = bus_space_map(obio->obio_iot, obio->obio_addr, obio->obio_size, 0, &sc->sc.ioh); + if (rv) { + aprint_error_dev(self, "couldn't map memory space\n"); + return; + } sc->sc.sc_size = obio->obio_size; + rv = bus_space_map(obio->obio_iot, USBTLL_BASE, USBTLL_SIZE, 0, &sc->sc_ioh_usbtll); + if (rv) { + aprint_error_dev(self, "couldn't map usbtll memory space\n"); + return; + } + sc->sc_usbtll_size = USBTLL_SIZE; + rv = bus_space_map(obio->obio_iot, UHH_BASE, UHH_SIZE, 0, &sc->sc_ioh_uhh); + if (rv) { + aprint_error_dev(self, "couldn't map uhh memory space\n"); + return; + } + sc->sc_uhh_size = UHH_SIZE; sc->sc.sc_bus.dmatag = obio->obio_dmat; sc->sc.sc_bus.usbrev = USBREV_2_0; - sc->sc.sc_bus.hci_private = &sc->sc; - if (psc->sc_obio_dev) - sc->sc.sc_comps[sc->sc.sc_ncomp++] = psc->sc_obio_dev; - - /* XXX copied from ehci_pci.c. needed? */ - bus_space_barrier(sc->sc.iot, sc->sc.ioh, 0, sc->sc.sc_size, - BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE); - - /* start the usb clock */ -#ifdef NOTYET - pxa2x0_clkman_config(CKEN_USBHC, 1); -#endif - obioehci_enable(sc); + sc->sc.sc_id_vendor = PCI_VENDOR_TI; + strlcpy(sc->sc.sc_vendor, "OMAP3", sizeof(sc->sc.sc_vendor)); - /* offs is needed for EOWRITEx */ - sc->sc.sc_offs = EREAD1(&sc->sc, EHCI_CAPLENGTH); + dpll5_init(sc); - /* Disable interrupts, so we don't get any spurious ones. */ - EOWRITE4(&sc->sc, EHCI_USBINTR, 0); + usbhost_init(sc, 1); - sc->sc_ih = intr_establish(obio->obio_intr, IPL_USB, IST_LEVEL, - ehci_intr, &sc->sc); - if (sc->sc_ih == NULL) { - aprint_error(": unable to establish interrupt\n"); - goto free_map; - } + sc->sc.sc_offs = EREAD1(&sc->sc, EHCI_CAPLENGTH); - r = ehci_init(&sc->sc); - if (r != USBD_NORMAL_COMPLETION) { - aprint_error_dev(self, "init failed, error=%d\n", r); - goto free_intr; - } + //EOWRITE4(&sc->sc, EHCI_INSNREG04, 1 << 5); - sc->sc.sc_child = config_found(self, &sc->sc.sc_bus, usbctlprint); - return; + sc->sc_ih = intr_establish(obio->obio_intr, IPL_USB, IST_LEVEL, ehci_intr, &sc->sc); -free_intr: - sc->sc_ih = NULL; -free_map: - obioehci_disable(sc); -#ifdef NOTYET - pxa2x0_clkman_config(CKEN_USBHC, 0); -#endif - bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size); - sc->sc.sc_size = 0; + //config_interrupts(self, omap3_ehci_attach1); + omap3_ehci_attach1(self); } static int -obioehci_detach(device_t self, int flags) +omap3_ehci_detach(device_t self, int flags) { - struct obioehci_softc *sc = device_private(self); - int error; + struct omap3_ehci_softc *sc = device_private(self); + int rv; + + rv = ehci_detach(&sc->sc, flags); + if (rv) + return rv; - error = ehci_detach(&sc->sc, flags); - if (error) - return error; + EOWRITE2(&sc->sc, EHCI_USBINTR, 0); + EOREAD2(&sc->sc, EHCI_USBINTR); if (sc->sc_ih) { -#ifdef NOTYET - obio_gpio_intr_disestablish(sc->sc_ih); -#endif + intr_disestablish(sc->sc_ih); sc->sc_ih = NULL; } - obioehci_disable(sc); + usbtll_power(sc, false); -#ifdef NOTYET - /* stop clock */ -#ifdef DEBUG - pxa2x0_clkman_config(CKEN_USBHC, 0); -#endif -#endif + if (sc->sc_usbtll_size) { + bus_space_unmap(sc->sc.iot, sc->sc_ioh_usbtll, sc->sc_usbtll_size); + sc->sc_usbtll_size = 0; + } + + if (sc->sc_uhh_size) { + bus_space_unmap(sc->sc.iot, sc->sc_ioh_uhh, sc->sc_uhh_size); + sc->sc_uhh_size = 0; + } if (sc->sc.sc_size) { bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size); @@ -202,53 +425,260 @@ obioehci_detach(device_t self, int flags } static void -obioehci_enable(struct obioehci_softc *sc) +dpll5_init(struct omap3_ehci_softc *sc) { -#if 0 - printf("%s: TBD\n", __func__); + bus_space_tag_t iot = sc->sc.iot; + bus_space_handle_t ioh; + uint32_t m, n, m2, v; + int retry = 1000, err; + + if (sc->sc_dpll5.m == 0 || sc->sc_dpll5.n == 0 || sc->sc_dpll5.m2 == 0) + return; + + err = bus_space_map(iot, CCR_CM_BASE, CCR_CM_SIZE, 0, &ioh); + if (err) + panic("%s: cannot map CCR_CM_BASE at %#x, error %d\n", + __func__, CCR_CM_BASE, err); + +#if OMAP_MPU_TIMER_CLOCK_FREQ != 12000000 +#error FIXME #endif + + /* set the multiplier and divider values for the desired CLKOUT freq */ + m = sc->sc_dpll5.m; + n = sc->sc_dpll5.n; + /* set the corresponding output dividers */ + m2 = sc->sc_dpll5.m2; + + /* 4.7.6.2 In the DPLL programming sequence, the DPLL_FREQSEL must be programmed + * before the new Multiplier factor M and the Divider factor N are programmed so + * that the new value is taken into account during current DPLL relock. + */ + bus_space_write_4(iot, ioh, CM_CLKEN2_PLL, (0x4 << 4) | 0x7); + + bus_space_write_4(iot, ioh, CM_CLKSEL4_PLL, (m << 8) | n); + bus_space_write_4(iot, ioh, CM_CLKSEL5_PLL, m2); + + /* Put DPLL5 into low power stop mode when the 120MHz clock is not required (restarted automatically) */ + bus_space_write_4(iot, ioh, CM_AUTOIDLE2_PLL, AUTO_PERIPH2_DPLL); + + /* Wait for DPLL5 lock */ + while (((v = bus_space_read_4(iot, ioh, CM_IDLEST2_CKGEN)) & ST_PERIPH2_CLK) == 0 && --retry > 0) { + delay(100); + } + if (retry == 0) + printf("%s: timeout\n", __func__); + + bus_space_unmap(iot, ioh, CCR_CM_SIZE); +} + +static void +usbhost_init(struct omap3_ehci_softc *sc, int enable) +{ + bus_space_tag_t iot = sc->sc.iot; + bus_space_handle_t ioh; + uint32_t r; + int err; + + /* + * USBHOST + */ + err = bus_space_map(iot, USBHOST_CM_BASE, USBHOST_CM_SIZE, 0, &ioh); + if (err) + panic("%s: cannot map USBHOST_CM_BASE at %#x, error %d\n", + __func__, USBHOST_CM_BASE, err); + + r = bus_space_read_4(iot, ioh, CM_FCLKEN_USBHOST); + if (enable) + r |= EN_USBHOST1; + else + r &= ~EN_USBHOST1; + bus_space_write_4(iot, ioh, CM_FCLKEN_USBHOST, r); + + r = bus_space_read_4(iot, ioh, CM_ICLKEN_USBHOST); + if (enable) + r |= EN_USBHOST; + else + r &= ~EN_USBHOST; + bus_space_write_4(iot, ioh, CM_ICLKEN_USBHOST, r); + + bus_space_unmap(iot, ioh, USBHOST_CM_SIZE); + + delay(10000); + + /* + * USBTLL + */ + err = bus_space_map(iot, CORE_CM_BASE, CORE_CM_SIZE, 0, &ioh); + if (err) + panic("%s: cannot map CORE_CM_BASE a5 %#x, error %d\n", + __func__, CORE_CM_BASE, err); + + r = bus_space_read_4(iot, ioh, CM_FCLKEN3_CORE); + if (enable) + r |= EN_USBTLL; + else + r &= ~EN_USBTLL; + bus_space_write_4(iot, ioh, CM_FCLKEN3_CORE, r); + + r = bus_space_read_4(iot, ioh, CM_ICLKEN3_CORE); + if (enable) + r |= EN_USBTLL; + else + r &= ~EN_USBTLL; + bus_space_write_4(iot, ioh, CM_ICLKEN3_CORE, r); + + r = bus_space_read_4(iot, ioh, CM_AUTOIDLE3_CORE); + if (enable) + r &= ~AUTO_USBTLL; + else + r |= AUTO_USBTLL; + bus_space_write_4(iot, ioh, CM_AUTOIDLE3_CORE, r); + + bus_space_unmap(iot, ioh, CORE_CM_SIZE); + + delay(10000); + +#undef USBHOST_CM_SIZE +#undef USBHOST_CM_BASE +#undef CORE_CM_SIZE +#undef CORE_CM_BASE } static void -obioehci_disable(struct obioehci_softc *sc) +usbtll_reset(struct omap3_ehci_softc *sc) { -#ifdef NOTYET - uint32_t hr; + uint32_t v; + int retry = 5000; + + USBTLL_WRITE4(sc, USBTLL_SYSCONFIG, USBTLL_SYSCONFIG_SOFTRESET); + do { + v = USBTLL_READ4(sc, USBTLL_SYSSTATUS); + if (v & USBTLL_SYSSTATUS_RESETDONE) + break; + delay(10); + } while (retry-- > 0); + if (retry == 0) + aprint_error_dev(sc->sc.sc_dev, + "reset timeout, status = 0x%08x\n", v); +} - /* Full host reset */ - hr = HREAD4(sc, USBHC_HR); - HWRITE4(sc, USBHC_HR, (hr & USBHC_HR_MASK) | USBHC_HR_FHR); +static void +usbtll_power(struct omap3_ehci_softc *sc, bool on) +{ + uint32_t v; - DELAY(USBHC_RST_WAIT); + usbtll_reset(sc); - hr = HREAD4(sc, USBHC_HR); - HWRITE4(sc, USBHC_HR, (hr & USBHC_HR_MASK) & ~(USBHC_HR_FHR)); -#endif + if (on) { + v = USBTLL_SYSCONFIG_ENAWAKEUP | + USBTLL_SYSCONFIG_AUTOIDLE | + USBTLL_SYSCONFIG_SIDLEMODE | + USBTLL_SYSCONFIG_CLOCKACTIVITY; + USBTLL_WRITE4(sc, USBTLL_SYSCONFIG, v); + } } static void -obioehci_clkinit(struct obio_attach_args *obio) +usbtll_init(struct omap3_ehci_softc *sc, int chmask) { -#ifdef OMAP2 - bus_space_handle_t ioh; - uint32_t r; - int err; + int i; + uint32_t v; - err = bus_space_map(obio->obio_iot, OMAP2_CM_BASE, - OMAP2_CM_SIZE, 0, &ioh); - if (err != 0) - panic("%s: cannot map OMAP2_CM_BASE at %#x, error %d\n", - __func__, OMAP2_CM_BASE, err); - - r = bus_space_read_4(obio->obio_iot, ioh, OMAP2_CM_FCLKEN2_CORE); - r |= OMAP2_CM_FCLKEN2_CORE_EN_USB; - bus_space_write_4(obio->obio_iot, ioh, OMAP2_CM_FCLKEN2_CORE, r); - - r = bus_space_read_4(obio->obio_iot, ioh, OMAP2_CM_ICLKEN2_CORE); - r |= OMAP2_CM_ICLKEN2_CORE_EN_USB; - r &= ~OMAP2_CM_ICLKEN2_CORE_EN_USBHS; /* force FS for ehci */ - bus_space_write_4(obio->obio_iot, ioh, OMAP2_CM_ICLKEN2_CORE, r); + v = USBTLL_READ4(sc, USBTLL_SHARED_CONF); + v |= (USBTLL_SHARED_CONF_FCLK_IS_ON | (1 << 2)/*divration*/); + v &= ~USBTLL_SHARED_CONF_USB_90D_DDR_EN; + v &= ~USBTLL_SHARED_CONF_USB_180D_SDR_EN; + USBTLL_WRITE4(sc, USBTLL_SHARED_CONF, v); + + for (i = 0; i < 3; i++) { + if (sc->sc_portconfig[i].mode == OMAP3_EHCI_PORT_MODE_NONE) + continue; + v = USBTLL_READ4(sc, USBTLL_CHANNEL_CONF(i)); + v &= ~(USBTLL_CHANNEL_CONF_ULPINOBITSTUFF| + USBTLL_CHANNEL_CONF_ULPIAUTOIDLE| + USBTLL_CHANNEL_CONF_ULPIDDRMODE); + //v |= USBTLL_CHANNEL_CONF_FSLSMODE; + v |= USBTLL_CHANNEL_CONF_CHANEN; + USBTLL_WRITE4(sc, USBTLL_CHANNEL_CONF(i), v); + } +} - bus_space_unmap(obio->obio_iot, ioh, OMAP2_CM_SIZE); -#endif +static void +uhh_power(struct omap3_ehci_softc *sc, bool on) +{ + uint32_t v; + int retry = 5000; + + if (on) { + v = UHH_READ4(sc, UHH_SYSCONFIG); + v &= ~(UHH_SYSCONFIG_SIDLEMODE_MASK|UHH_SYSCONFIG_MIDLEMODE_MASK); + v |= UHH_SYSCONFIG_MIDLEMODE_SMARTSTANDBY; + v |= UHH_SYSCONFIG_CLOCKACTIVITY; + v |= UHH_SYSCONFIG_SIDLEMODE_SMARTIDLE; + v |= UHH_SYSCONFIG_ENAWAKEUP; + v &= ~UHH_SYSCONFIG_AUTOIDLE; + UHH_WRITE4(sc, UHH_SYSCONFIG, v); + + v = UHH_READ4(sc, UHH_SYSCONFIG); + } else { + v = UHH_READ4(sc, UHH_SYSCONFIG); + v |= UHH_SYSCONFIG_SOFTRESET; + UHH_WRITE4(sc, UHH_SYSCONFIG, v); + do { + v = UHH_READ4(sc, UHH_SYSSTATUS); + if (v & UHH_SYSSTATUS_RESETDONE_ALL) + break; + delay(10); + } while (retry-- > 0); + if (retry == 0) + aprint_error_dev(sc->sc.sc_dev, + "reset timeout, status = 0x%08x\n", v); + } } + +static void +uhh_portconfig(struct omap3_ehci_softc *sc) +{ + uint32_t v; + + v = UHH_READ4(sc, UHH_HOSTCONFIG); + v |= UHH_HOSTCONFIG_ENA_INCR16; + v |= UHH_HOSTCONFIG_ENA_INCR8; + v |= UHH_HOSTCONFIG_ENA_INCR4; + v |= UHH_HOSTCONFIG_APP_START_CLK; + v &= ~UHH_HOSTCONFIG_ENA_INCR_ALIGN; + + if (sc->sc_portconfig[0].mode == OMAP3_EHCI_PORT_MODE_NONE) + v &= ~UHH_HOSTCONFIG_P1_CONNECT_STATUS; + if (sc->sc_portconfig[1].mode == OMAP3_EHCI_PORT_MODE_NONE) + v &= ~UHH_HOSTCONFIG_P2_CONNECT_STATUS; + if (sc->sc_portconfig[2].mode == OMAP3_EHCI_PORT_MODE_NONE) + v &= ~UHH_HOSTCONFIG_P3_CONNECT_STATUS; + + if (sc->sc_portconfig[0].mode == OMAP3_EHCI_PORT_MODE_PHY) + v &= ~UHH_HOSTCONFIG_P1_ULPI_BYPASS; + else + v |= UHH_HOSTCONFIG_P1_ULPI_BYPASS; + + if (sc->sc_portconfig[1].mode == OMAP3_EHCI_PORT_MODE_PHY) + v &= ~UHH_HOSTCONFIG_P2_ULPI_BYPASS; + else + v |= UHH_HOSTCONFIG_P2_ULPI_BYPASS; + + if (sc->sc_portconfig[2].mode == OMAP3_EHCI_PORT_MODE_PHY) + v &= ~UHH_HOSTCONFIG_P3_ULPI_BYPASS; + else + v |= UHH_HOSTCONFIG_P3_ULPI_BYPASS; + + UHH_WRITE4(sc, UHH_HOSTCONFIG, v); +} + +CFATTACH_DECL2_NEW(omap3_ehci, sizeof(struct omap3_ehci_softc), + omap3_ehci_match, + omap3_ehci_attach, + omap3_ehci_detach, + ehci_activate, + NULL, + ehci_childdet +); Index: src/sys/arch/evbarm/beagle/beagle_machdep.c diff -u src/sys/arch/evbarm/beagle/beagle_machdep.c:1.24 src/sys/arch/evbarm/beagle/beagle_machdep.c:1.25 --- src/sys/arch/evbarm/beagle/beagle_machdep.c:1.24 Tue Dec 11 19:24:38 2012 +++ src/sys/arch/evbarm/beagle/beagle_machdep.c Wed Dec 12 00:33:45 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: beagle_machdep.c,v 1.24 2012/12/11 19:24:38 riastradh Exp $ */ +/* $NetBSD: beagle_machdep.c,v 1.25 2012/12/12 00:33:45 matt Exp $ */ /* * Machine dependent functions for kernel setup for TI OSK5912 board. @@ -125,7 +125,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: beagle_machdep.c,v 1.24 2012/12/11 19:24:38 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: beagle_machdep.c,v 1.25 2012/12/12 00:33:45 matt Exp $"); #include "opt_machdep.h" #include "opt_ddb.h" @@ -173,6 +173,7 @@ __KERNEL_RCSID(0, "$NetBSD: beagle_machd #include <arm/omap/omap_var.h> #include <arm/omap/omap_wdtvar.h> #include <arm/omap/omap2_prcm.h> +#include <arm/omap/omap2_gpio.h> #ifdef TI_AM335X # include <arm/omap/am335x_prcm.h> #endif @@ -649,4 +650,21 @@ beagle_device_register(device_t self, vo curcpu()->ci_data.cpu_cc_freq / 2); return; } + + if (device_is_a(self, "ehci")) { +#if defined(OMAP_3530) + /* XXX Beagleboard specific port configuration */ + prop_dictionary_set_cstring(dict, "port0-mode", "none"); + prop_dictionary_set_cstring(dict, "port1-mode", "phy"); + prop_dictionary_set_cstring(dict, "port2-mode", "none"); + prop_dictionary_set_bool(dict, "phy-reset", true); + prop_dictionary_set_int16(dict, "port0-gpio", -1); + prop_dictionary_set_int16(dict, "port1-gpio", 147); + prop_dictionary_set_int16(dict, "port2-gpio", -1); + prop_dictionary_set_uint16(dict, "dpll5-m", 443); + prop_dictionary_set_uint16(dict, "dpll5-n", 11); + prop_dictionary_set_uint16(dict, "dpll5-m2", 4); +#endif + return; + } } Added files: Index: src/sys/arch/arm/omap/omap2_gpio.h diff -u /dev/null src/sys/arch/arm/omap/omap2_gpio.h:1.1 --- /dev/null Wed Dec 12 00:33:45 2012 +++ src/sys/arch/arm/omap/omap2_gpio.h Wed Dec 12 00:33:45 2012 @@ -0,0 +1,44 @@ +/* + * Copyright 2003 Wasabi Systems, Inc. + * All rights reserved. + * + * Written by Steve C. Woodford for Wasabi Systems, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed for the NetBSD Project by + * Wasabi Systems, Inc. + * 4. The name of Wasabi Systems, Inc. may not be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _ARM_OMAP_OMAP2_GPIO_H_ +#define _ARM_OMAP_OMAP2_GPIO_H_ + +extern bool omap2_gpio_has_pin(u_int); +extern u_int omap2_gpio_read(u_int); +extern void omap2_gpio_write(u_int, u_int); +extern void omap2_gpio_ctl(u_int, int); + +#endif /* _ARM_OMAP_OMAP2_GPIO_H_ */ Index: src/sys/arch/arm/omap/omap3_uhhreg.h diff -u /dev/null src/sys/arch/arm/omap/omap3_uhhreg.h:1.1 --- /dev/null Wed Dec 12 00:33:45 2012 +++ src/sys/arch/arm/omap/omap3_uhhreg.h Wed Dec 12 00:33:45 2012 @@ -0,0 +1,78 @@ +/* $NetBSD: omap3_uhhreg.h,v 1.1 2012/12/12 00:33:45 matt Exp $ */ + +/*- + * Copyright (c) 2010 Jared D. McNeill <jmcne...@invisible.ca> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _OMAP3_UHHREG_H +#define _OMAP3_UHHREG_H + +/* 32-bit */ +#define UHH_REVISION 0x00 +#define UHH_REVISION_MAJOR(x) (((x) >> 4) & 0xf) +#define UHH_REVISION_MINOR(x) ((x) & 0xf) + +#define UHH_SYSCONFIG 0x10 +#define UHH_SYSCONFIG_MIDLEMODE_MASK 0x00003000 +#define UHH_SYSCONFIG_MIDLEMODE_SMARTSTANDBY 0x00002000 +#define UHH_SYSCONFIG_CLOCKACTIVITY 0x00000100 +#define UHH_SYSCONFIG_SIDLEMODE_MASK 0x00000018 +#define UHH_SYSCONFIG_SIDLEMODE_SMARTIDLE 0x00000008 +#define UHH_SYSCONFIG_ENAWAKEUP 0x00000004 +#define UHH_SYSCONFIG_SOFTRESET 0x00000002 +#define UHH_SYSCONFIG_AUTOIDLE 0x00000001 + +#define UHH_SYSSTATUS 0x14 +#define UHH_SYSSTATUS_EHCI_RESETDONE 0x00000004 +#define UHH_SYSSTATUS_OHCI_RESETDONE 0x00000002 +#define UHH_SYSSTATUS_RESETDONE 0x00000001 +#define UHH_SYSSTATUS_RESETDONE_ALL \ + (UHH_SYSSTATUS_EHCI_RESETDONE | \ + UHH_SYSSTATUS_OHCI_RESETDONE | \ + UHH_SYSSTATUS_RESETDONE) + +#define UHH_HOSTCONFIG 0x40 +#define UHH_HOSTCONFIG_APP_START_CLK 0x80000000 +#define UHH_HOSTCONFIG_P3_ULPI_BYPASS 0x00001000 +#define UHH_HOSTCONFIG_P2_ULPI_BYPASS 0x00000800 +#define UHH_HOSTCONFIG_P3_CONNECT_STATUS 0x00000400 +#define UHH_HOSTCONFIG_P2_CONNECT_STATUS 0x00000200 +#define UHH_HOSTCONFIG_P1_CONNECT_STATUS 0x00000100 +#define UHH_HOSTCONFIG_ENA_INCR_ALIGN 0x00000020 +#define UHH_HOSTCONFIG_ENA_INCR16 0x00000010 +#define UHH_HOSTCONFIG_ENA_INCR8 0x00000008 +#define UHH_HOSTCONFIG_ENA_INCR4 0x00000004 +#define UHH_HOSTCONFIG_AUTOPPD_ON_OVERCUR_EN 0x00000002 +#define UHH_HOSTCONFIG_P1_ULPI_BYPASS 0x00000001 + +#define UHH_DEBUG_CSR 0x44 +#define UHH_DEBUG_CSR_OHCI_CCS_3 0x00080000 +#define UHH_DEBUG_CSR_OHCI_CCS_2 0x00040000 +#define UHH_DEBUG_CSR_OHCI_CCS_1 0x00020000 +#define UHH_DEBUG_CSR_OHCI_GLOBALSUSPEND 0x00010000 +#define UHH_DEBUG_CSR_OHCI_CNTSEL 0x00000080 +#define UHH_DEBUG_CSR_EHCI_SIMULATION_MODE 0x00000040 +#define UHH_DEBUG_CSR_EHCI_FLADJ 0x0000003f + +#endif /* !_OMAP3_UHHREG_H */ Index: src/sys/arch/arm/omap/omap3_usbtllreg.h diff -u /dev/null src/sys/arch/arm/omap/omap3_usbtllreg.h:1.1 --- /dev/null Wed Dec 12 00:33:45 2012 +++ src/sys/arch/arm/omap/omap3_usbtllreg.h Wed Dec 12 00:33:45 2012 @@ -0,0 +1,166 @@ +/* $NetBSD: omap3_usbtllreg.h,v 1.1 2012/12/12 00:33:45 matt Exp $ */ + +/*- + * Copyright (c) 2010 Jared D. McNeill <jmcne...@invisible.ca> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _OMAP3_USBTLLREG_H +#define _OMAP3_USBTLLREG_H + +/* 32-bit */ +#define USBTLL_REVISION 0x00 +#define USBTLL_REVISION_MAJOR(x) (((x) >> 4) & 0xf) +#define USBTLL_REVISION_MINOR(x) ((x) & 0xf) + +#define USBTLL_SYSCONFIG 0x10 +#define USBTLL_SYSCONFIG_CLOCKACTIVITY 0x00000100 +#define USBTLL_SYSCONFIG_SIDLEMODE 0x00000018 +#define USBTLL_SYSCONFIG_ENAWAKEUP 0x00000004 +#define USBTLL_SYSCONFIG_SOFTRESET 0x00000002 +#define USBTLL_SYSCONFIG_AUTOIDLE 0x00000001 + +#define USBTLL_SYSSTATUS 0x14 +#define USBTLL_SYSSTATUS_RESETDONE 0x00000001 + +#define USBTLL_IRQSTATUS 0x18 +#define USBTLL_IRQSTATUS_ACCESS_ERROR 0x00000004 +#define USBTLL_IRQSTATUS_FCLK_END 0x00000002 +#define USBTLL_IRQSTATUS_FCLK_START 0x00000001 + +#define USBTLL_IRQENABLE 0x1c +#define USBTLL_IRQENABLE_ACCESS_ERROR_EN 0x00000004 +#define USBTLL_IRQENABLE_FCLK_END_EN 0x00000002 +#define USBTLL_IRQENABLE_FCLK_START_EN 0x00000001 + +#define USBTLL_SHARED_CONF 0x30 +#define USBTLL_SHARED_CONF_USB_90D_DDR_EN 0x00000040 +#define USBTLL_SHARED_CONF_USB_180D_SDR_EN 0x00000020 +#define USBTLL_SHARED_CONF_USB_DIVRATIO 0x0000001c +#define USBTLL_SHARED_CONF_FCLK_REQ 0x00000002 +#define USBTLL_SHARED_CONF_FCLK_IS_ON 0x00000001 + +#define USBTLL_CHANNEL_CONF(i) (0x40 + (0x04 * (i))) +#define USBTLL_CHANNEL_CONF_FSLSLINESTATE 0x30000000 +#define USBTLL_CHANNEL_CONF_FSLSMODE 0x0f000000 +#define USBTLL_CHANNEL_CONF_TESTTXSE0 0x00100000 +#define USBTLL_CHANNEL_CONF_TESTTXDAT 0x00080000 +#define USBTLL_CHANNEL_CONF_TESTTXEN 0x00040000 +#define USBTLL_CHANNEL_CONF_TESTEN 0x00020000 +#define USBTLL_CHANNEL_CONF_DRVVBUS 0x00010000 +#define USBTLL_CHANNEL_CONF_CHRGVBUS 0x00008000 +#define USBTLL_CHANNEL_CONF_ULPINOBITSTUFF 0x00000800 +#define USBTLL_CHANNEL_CONF_ULPIAUTOIDLE 0x00000400 +#define USBTLL_CHANNEL_CONF_UTMIAUTOIDLE 0x00000200 +#define USBTLL_CHANNEL_CONF_ULPIDDRMODE 0x00000100 +#define USBTLL_CHANNEL_CONF_ULPIOUTCLKMODE 0x00000080 +#define USBTLL_CHANNEL_CONF_TLLFULLSPEED 0x00000040 +#define USBTLL_CHANNEL_CONF_TLLCONNECT 0x00000020 +#define USBTLL_CHANNEL_CONF_TLLATTACH 0x00000010 +#define USBTLL_CHANNEL_CONF_UTMIISADEV 0x00000008 +#define USBTLL_CHANNEL_CONF_CHANMODE 0x00000006 +#define USBTLL_CHANNEL_CONF_CHANEN 0x00000001 + +/* 8-bit */ +#define ULPI_VENDOR_ID_LO(i) (0x100 * (i) + 0) +#define ULPI_VENDOR_ID_HI(i) (0x100 * (i) + 1) +#define ULPI_PRODUCT_ID_LO(i) (0x100 * (i) + 2) +#define ULPI_PRODUCT_ID_HI(i) (0x100 * (i) + 3) + +#define ULPI_FUNCTION_CTRL(i) (0x100 * (i) + 4) +#define ULPI_FUNCTION_CTRL_SET(i) (0x100 * (i) + 5) +#define ULPI_FUNCTION_CTRL_CLR(i) (0x100 * (i) + 6) +#define ULPI_FUNCTION_CTRL_SUSPENDM 0x40 +#define ULPI_FUNCTION_CTRL_RESET 0x20 +#define ULPI_FUNCTION_CTRL_OPMODE 0x18 +#define ULPI_FUNCTION_CTRL_TERMSELECT 0x04 +#define ULPI_FUNCTION_CTRL_XCVRSELECT 0x03 + +#define ULPI_INTERFACE_CTRL(i) (0x100 * (i) + 7) +#define ULPI_INTERFACE_CTRL_SET(i) (0x100 * (i) + 8) +#define ULPI_INTERFACE_CTRL_CLR(i) (0x100 * (i) + 9) +#define ULPI_INTERFACE_CTRL_INTERFACE_PROTECT_DISABLE 0x80 +#define ULPI_INTERFACE_CTRL_AUTORESUME 0x10 +#define ULPI_INTERFACE_CTRL_CLOCKSUSPENDM 0x08 +#define ULPI_INTERFACE_CTRL_FSLSSERIALMODE_3PIN 0x02 +#define ULPI_INTERFACE_CTRL_FSLSSERIALMODE_6PIN 0x01 + +#define ULPI_OTG_CTRL(i) (0x100 * (i) + 10) +#define ULPI_OTG_CTRL_SET(i) (0x100 * (i) + 11) +#define ULPI_OTG_CTRL_CLR(i) (0x100 * (i) + 12) +#define ULPI_OTG_CTRL_DRVVBUS 0x20 +#define ULPI_OTG_CTRL_CHRGVBUS 0x10 +#define ULPI_OTG_CTRL_DISCHRGVBUS 0x08 +#define ULPI_OTG_CTRL_DMPULLDOWN 0x04 +#define ULPI_OTG_CTRL_DPPULLDOWN 0x02 +#define ULPI_OTG_CTRL_IDPULLUP 0x01 + +#define ULPI_USB_INT_EN_RISE(i) (0x100 * (i) + 13) +#define ULPI_USB_INT_EN_RISE_SET(i) (0x100 * (i) + 14) +#define ULPI_USB_INT_EN_RISE_CLR(i) (0x100 * (i) + 15) +#define ULPI_USB_INT_EN_FALL(i) (0x100 * (i) + 16) +#define ULPI_USB_INT_EN_FALL_SET(i) (0x100 * (i) + 17) +#define ULPI_USB_INT_EN_FALL_CLR(i) (0x100 * (i) + 18) +#define ULPI_USB_INT_STATUS(i) (0x100 * (i) + 19) +#define ULPI_USB_INT_LATCH(i) (0x100 * (i) + 20) +#define ULPI_USB_INT_IDGND 0x10 +#define ULPI_USB_INT_SESSEND 0x08 +#define ULPI_USB_INT_SESSVALID 0x04 +#define ULPI_USB_INT_VBUSVALID 0x02 +#define ULPI_USB_INT_HOSTDISCONNECT 0x01 + +#define ULPI_DEBUG(i) (0x100 * (i) + 21) +#define ULPI_DEBUG_LINESTATE 0x03 + +#define ULPI_SCRATCH_REGISTER(i) (0x100 * (i) + 22) +#define ULPI_SCRATCH_REGISTER_SET(i) (0x100 * (i) + 23) +#define ULPI_SCRATCH_REGISTER_CLR(i) (0x100 * (i) + 24) + +#define ULPI_EXTENDED_SET_ACCESS(i) (0x100 * (i) + 47) + +#define ULPI_UTMI_VCONTROL_EN(i) (0x100 * (i) + 48) +#define ULPI_UTMI_VCONTROL_EN_SET(i) (0x100 * (i) + 49) +#define ULPI_UTMI_VCONTROL_EN_CLR(i) (0x100 * (i) + 50) +#define ULPI_UTMI_VCONTROL_STATUS(i) (0x100 * (i) + 51) +#define ULPI_UTMI_VCONTROL_LATCH(i) (0x100 * (i) + 52) +#define ULPI_UTMI_VC(n) (1 << (n)) + +#define ULPI_UTMI_VSTATUS(i) (0x100 * (i) + 53) +#define ULPI_UTMI_VSTATUS_SET(i) (0x100 * (i) + 54) +#define ULPI_UTMI_VSTATUS_CLR(i) (0x100 * (i) + 55) + +#define ULPI_USB_INT_LATCH_NOCLR(i) (0x100 * (i) + 56) + /* use ULPI_USB_INT_* */ + +#define ULPI_VENDOR_INT_EN(i) (0x100 * (i) + 59) +#define ULPI_VENDOR_INT_EN_SET(i) (0x100 * (i) + 60) +#define ULPI_VENDOR_INT_EN_CLR(i) (0x100 * (i) + 61) +#define ULPI_VENDOR_INT_EN_P2P_EN 0x01 + +#define ULPI_VENDOR_INT_STATUS(i) (0x100 * (i) + 62) +#define ULPI_VENDOR_INT_STATUS_UTMI_SUSPENDM 0x01 + +#define ULPI_VENDOR_INT_LATCH(i) (0x100 * (i) + 62) +#define ULPI_VENDOR_INT_STATUS_P2P_LATCH 0x01 + +#endif /* !_OMAP3_USBTLLREG_H */