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 */

Reply via email to