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 <[email protected]>
+/*-
+ * Copyright (c) 2010-2012 Jared D. McNeill <[email protected]>
+ * 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 <[email protected]>
+ * 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 <[email protected]>
+ * 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 */