Module Name:    src
Committed By:   jmcneill
Date:           Wed Oct 30 21:41:40 UTC 2019

Modified Files:
        src/sys/arch/arm/ti: files.ti omap3_cm.c ti_prcm.h
Added Files:
        src/sys/arch/arm/ti: ti_ehci.c ti_usb.c ti_usbtll.c

Log Message:
Add OMAP3 USB support.


To generate a diff of this commit:
cvs rdiff -u -r1.16 -r1.17 src/sys/arch/arm/ti/files.ti
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/ti/omap3_cm.c
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/ti/ti_ehci.c \
    src/sys/arch/arm/ti/ti_usb.c src/sys/arch/arm/ti/ti_usbtll.c
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/ti/ti_prcm.h

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/ti/files.ti
diff -u src/sys/arch/arm/ti/files.ti:1.16 src/sys/arch/arm/ti/files.ti:1.17
--- src/sys/arch/arm/ti/files.ti:1.16	Tue Oct 29 22:19:13 2019
+++ src/sys/arch/arm/ti/files.ti	Wed Oct 30 21:41:40 2019
@@ -1,4 +1,4 @@
-#	$NetBSD: files.ti,v 1.16 2019/10/29 22:19:13 jmcneill Exp $
+#	$NetBSD: files.ti,v 1.17 2019/10/30 21:41:40 jmcneill Exp $
 #
 
 file	arch/arm/ti/ti_cpufreq.c	soc_ti
@@ -88,6 +88,17 @@ device	tiotg { } : fdt
 attach	tiotg at fdt with ti_otg
 file	arch/arm/ti/ti_otg.c		ti_otg
 
+device	tiusb { } : fdt
+attach	tiusb at fdt with ti_usb
+file	arch/arm/ti/ti_usb.c		ti_usb
+
+device	tiusbtll
+attach	tiusbtll at fdt with ti_usbtll
+file	arch/arm/ti/ti_usbtll.c		ti_usbtll
+
+attach	ehci at fdt with ti_ehci
+file	arch/arm/ti/ti_ehci.c		ti_ehci
+
 attach	motg at fdt with ti_motg
 file	arch/arm/ti/ti_motg.c		ti_motg
 

Index: src/sys/arch/arm/ti/omap3_cm.c
diff -u src/sys/arch/arm/ti/omap3_cm.c:1.1 src/sys/arch/arm/ti/omap3_cm.c:1.2
--- src/sys/arch/arm/ti/omap3_cm.c:1.1	Tue Oct 29 22:19:13 2019
+++ src/sys/arch/arm/ti/omap3_cm.c	Wed Oct 30 21:41:40 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: omap3_cm.c,v 1.1 2019/10/29 22:19:13 jmcneill Exp $ */
+/* $NetBSD: omap3_cm.c,v 1.2 2019/10/30 21:41:40 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca>
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: omap3_cm.c,v 1.1 2019/10/29 22:19:13 jmcneill Exp $");
+__KERNEL_RCSID(1, "$NetBSD: omap3_cm.c,v 1.2 2019/10/30 21:41:40 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -43,11 +43,20 @@ __KERNEL_RCSID(1, "$NetBSD: omap3_cm.c,v
 #define	CM_CORE1_BASE		0x0a00
 #define	CM_CORE3_BASE		0x0a08
 #define	CM_WKUP_BASE		0x0c00
+#define	CM_CLK_CTRL_REG_BASE	0x0d00
 #define	CM_PER_BASE		0x1000
 #define	CM_USBHOST_BASE		0x1400
 
 #define	CM_FCLKEN		0x00
 #define	CM_ICLKEN		0x10
+#define	CM_AUTOIDLE		0x30
+#define	CM_CLKSEL		0x40
+
+#define	CM_CLKEN2_PLL		0x04
+#define	CM_IDLEST2_CKGEN	0x24
+#define	CM_AUTOIDLE2_PLL	0x34
+#define	CM_CLKSEL4_PLL		0x4c
+#define	CM_CLKSEL5_PLL		0x50
 
 static int omap3_cm_match(device_t, cfdata_t, void *);
 static void omap3_cm_attach(device_t, device_t, void *);
@@ -71,19 +80,25 @@ omap3_cm_hwmod_enable(struct ti_prcm_sof
 		val &= ~tc->u.hwmod.mask;
 	PRCM_WRITE(sc, tc->u.hwmod.reg + CM_ICLKEN, val);
 
+	if (tc->u.hwmod.flags & TI_HWMOD_DISABLE_AUTOIDLE) {
+		val = PRCM_READ(sc, tc->u.hwmod.reg + CM_AUTOIDLE);
+		val &= ~tc->u.hwmod.mask;
+		PRCM_WRITE(sc, tc->u.hwmod.reg + CM_AUTOIDLE, val);
+	}
+
 	return 0;
 }
 
-#define	OMAP3_CM_HWMOD_CORE1(_name, _bit, _parent)	\
-	TI_PRCM_HWMOD_MASK((_name), CM_CORE1_BASE, __BIT(_bit), (_parent), omap3_cm_hwmod_enable)
-#define	OMAP3_CM_HWMOD_CORE3(_name, _bit, _parent)	\
-	TI_PRCM_HWMOD_MASK((_name), CM_CORE3_BASE, __BIT(_bit), (_parent), omap3_cm_hwmod_enable)
-#define	OMAP3_CM_HWMOD_WKUP(_name, _bit, _parent)	\
-	TI_PRCM_HWMOD_MASK((_name), CM_WKUP_BASE, __BIT(_bit), (_parent), omap3_cm_hwmod_enable)
-#define	OMAP3_CM_HWMOD_PER(_name, _bit, _parent)	\
-	TI_PRCM_HWMOD_MASK((_name), CM_PER_BASE, __BIT(_bit), (_parent), omap3_cm_hwmod_enable)
-#define	OMAP3_CM_HWMOD_USBHOST(_name, _mask, _parent)	\
-	TI_PRCM_HWMOD_MASK((_name), CM_USBHOST_BASE, (_mask), (_parent), omap3_cm_hwmod_enable)
+#define	OMAP3_CM_HWMOD_CORE1(_name, _bit, _parent, _flags)	\
+	TI_PRCM_HWMOD_MASK((_name), CM_CORE1_BASE, __BIT(_bit), (_parent), omap3_cm_hwmod_enable, (_flags))
+#define	OMAP3_CM_HWMOD_CORE3(_name, _bit, _parent, _flags)	\
+	TI_PRCM_HWMOD_MASK((_name), CM_CORE3_BASE, __BIT(_bit), (_parent), omap3_cm_hwmod_enable, (_flags))
+#define	OMAP3_CM_HWMOD_WKUP(_name, _bit, _parent, _flags)	\
+	TI_PRCM_HWMOD_MASK((_name), CM_WKUP_BASE, __BIT(_bit), (_parent), omap3_cm_hwmod_enable, (_flags))
+#define	OMAP3_CM_HWMOD_PER(_name, _bit, _parent, _flags)	\
+	TI_PRCM_HWMOD_MASK((_name), CM_PER_BASE, __BIT(_bit), (_parent), omap3_cm_hwmod_enable, (_flags))
+#define	OMAP3_CM_HWMOD_USBHOST(_name, _bit, _parent, _flags)	\
+	TI_PRCM_HWMOD_MASK((_name), CM_USBHOST_BASE, __BIT(_bit), (_parent), omap3_cm_hwmod_enable, (_flags))
 
 static const char * const compatible[] = {
 	"ti,omap3-cm",
@@ -96,59 +111,79 @@ CFATTACH_DECL_NEW(omap3_cm, sizeof(struc
 static struct ti_prcm_clk omap3_cm_clks[] = {
 	/* XXX until we get a proper clock tree */
 	TI_PRCM_FIXED("FIXED_32K", 32768),
-	TI_PRCM_FIXED("FIXED_48MHZ", 48000000),
-	TI_PRCM_FIXED("FIXED_96MHZ", 96000000),
-	TI_PRCM_FIXED_FACTOR("PERIPH_CLK", 1, 1, "FIXED_48MHZ"),
-	TI_PRCM_FIXED_FACTOR("MMC_CLK", 1, 1, "FIXED_96MHZ"),
-
-	OMAP3_CM_HWMOD_CORE1("usb_otg_hs", 4, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_CORE1("mcbsp1", 9, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_CORE1("mcbsp5", 10, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_CORE1("timer10", 11, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_CORE1("timer11", 12, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_CORE1("uart1", 13, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_CORE1("uart2", 14, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_CORE1("i2c1", 15, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_CORE1("i2c2", 16, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_CORE1("i2c3", 17, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_CORE1("mcspi1", 18, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_CORE1("mcspi2", 19, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_CORE1("mcspi3", 20, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_CORE1("mcspi4", 21, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_CORE1("hdq1w", 22, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_CORE1("mmc1", 24, "MMC_CLK"),
-	OMAP3_CM_HWMOD_CORE1("mmc2", 25, "MMC_CLK"),
-	OMAP3_CM_HWMOD_CORE1("mmc3", 30, "MMC_CLK"),
-
-	OMAP3_CM_HWMOD_CORE3("usb_tll_hs", 2, "PERIPH_CLK"),
-
-	OMAP3_CM_HWMOD_WKUP("timer1", 0, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_WKUP("counter_32k", 2, "FIXED_32K"),
-	OMAP3_CM_HWMOD_WKUP("gpio1", 3, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_WKUP("wd_timer2", 5, "FIXED_32K"),
-
-	OMAP3_CM_HWMOD_PER("mcbsp2", 0, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_PER("mcbsp3", 1, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_PER("mcbsp4", 2, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_PER("timer2", 3, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_PER("timer3", 4, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_PER("timer4", 5, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_PER("timer5", 6, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_PER("timer6", 7, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_PER("timer7", 8, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_PER("timer8", 9, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_PER("timer9", 10, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_PER("uart3", 11, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_PER("wd_timer3", 12, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_PER("gpio2", 13, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_PER("gpio3", 14, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_PER("gpio4", 15, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_PER("gpio5", 16, "PERIPH_CLK"),
-	OMAP3_CM_HWMOD_PER("gpio6", 17, "PERIPH_CLK"),
+	TI_PRCM_FIXED("SYS_CLK", 13000000),
+	TI_PRCM_FIXED("MMC_CLK", 96000000),
+	TI_PRCM_FIXED_FACTOR("PERIPH_CLK", 1, 1, "SYS_CLK"),
+
+	OMAP3_CM_HWMOD_CORE1("usb_otg_hs", 4, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_CORE1("mcbsp1", 9, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_CORE1("mcbsp5", 10, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_CORE1("timer10", 11, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_CORE1("timer11", 12, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_CORE1("uart1", 13, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_CORE1("uart2", 14, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_CORE1("i2c1", 15, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_CORE1("i2c2", 16, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_CORE1("i2c3", 17, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_CORE1("mcspi1", 18, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_CORE1("mcspi2", 19, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_CORE1("mcspi3", 20, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_CORE1("mcspi4", 21, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_CORE1("hdq1w", 22, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_CORE1("mmc1", 24, "MMC_CLK", 0),
+	OMAP3_CM_HWMOD_CORE1("mmc2", 25, "MMC_CLK", 0),
+	OMAP3_CM_HWMOD_CORE1("mmc3", 30, "MMC_CLK", 0),
+
+	OMAP3_CM_HWMOD_CORE3("usb_tll_hs", 2, "PERIPH_CLK", TI_HWMOD_DISABLE_AUTOIDLE),
+
+	OMAP3_CM_HWMOD_WKUP("timer1", 0, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_WKUP("counter_32k", 2, "FIXED_32K", 0),
+	OMAP3_CM_HWMOD_WKUP("gpio1", 3, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_WKUP("wd_timer2", 5, "FIXED_32K", 0),
+
+	OMAP3_CM_HWMOD_PER("mcbsp2", 0, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_PER("mcbsp3", 1, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_PER("mcbsp4", 2, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_PER("timer2", 3, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_PER("timer3", 4, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_PER("timer4", 5, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_PER("timer5", 6, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_PER("timer6", 7, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_PER("timer7", 8, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_PER("timer8", 9, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_PER("timer9", 10, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_PER("uart3", 11, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_PER("wd_timer3", 12, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_PER("gpio2", 13, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_PER("gpio3", 14, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_PER("gpio4", 15, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_PER("gpio5", 16, "PERIPH_CLK", 0),
+	OMAP3_CM_HWMOD_PER("gpio6", 17, "PERIPH_CLK", 0),
 
-	OMAP3_CM_HWMOD_USBHOST("usb_host_hs", __BITS(1,0), "PERIPH_CLK"),
+	OMAP3_CM_HWMOD_USBHOST("usb_host_hs", 0, "PERIPH_CLK", 0),
 };
 
+static void
+omap3_cm_initclocks(struct ti_prcm_softc *sc)
+{
+	uint32_t val;
+
+	/* Select SYS_CLK for GPTIMER 2 and 3 */
+	val = PRCM_READ(sc, CM_PER_BASE + CM_CLKSEL);
+	val |= __BIT(0);	/* CLKSEL_GPT2  0x1: source is SYS_CLK */
+	val |= __BIT(1);	/* CLKSEL_GPT3  0x1: source is SYS_CLK */
+	PRCM_WRITE(sc, CM_PER_BASE + CM_CLKSEL, val);
+
+	/* Enable DPLL5  */
+	const u_int m = 443, n = 11, m2 = 4;
+	PRCM_WRITE(sc, CM_CLK_CTRL_REG_BASE + CM_CLKEN2_PLL, (0x4 << 4) | 0x7);
+	PRCM_WRITE(sc, CM_CLK_CTRL_REG_BASE + CM_CLKSEL4_PLL, (m << 8) | n);
+	PRCM_WRITE(sc, CM_CLK_CTRL_REG_BASE + CM_CLKSEL5_PLL, m2);
+	PRCM_WRITE(sc, CM_CLK_CTRL_REG_BASE + CM_AUTOIDLE2_PLL, 1);
+	while ((PRCM_READ(sc, CM_CLK_CTRL_REG_BASE + CM_IDLEST2_CKGEN) & 1) == 0)
+		delay(100);
+}
+
 static int
 omap3_cm_match(device_t parent, cfdata_t cf, void *aux)
 {
@@ -177,6 +212,8 @@ omap3_cm_attach(device_t parent, device_
 	aprint_naive("\n");
 	aprint_normal(": OMAP3xxx CM\n");
 
+	omap3_cm_initclocks(sc);
+
 	clocks = of_find_firstchild_byname(sc->sc_phandle, "clocks");
 	if (clocks > 0)
 		fdt_add_bus(self, clocks, faa);

Index: src/sys/arch/arm/ti/ti_prcm.h
diff -u src/sys/arch/arm/ti/ti_prcm.h:1.3 src/sys/arch/arm/ti/ti_prcm.h:1.4
--- src/sys/arch/arm/ti/ti_prcm.h:1.3	Tue Oct 29 22:19:13 2019
+++ src/sys/arch/arm/ti/ti_prcm.h	Wed Oct 30 21:41:40 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: ti_prcm.h,v 1.3 2019/10/29 22:19:13 jmcneill Exp $ */
+/* $NetBSD: ti_prcm.h,v 1.4 2019/10/30 21:41:40 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca>
@@ -57,8 +57,11 @@ struct ti_prcm_hwmod {
 	bus_size_t		reg;
 	uint32_t		mask;
 	const char		*parent;
+	u_int			flags;
 };
 
+#define	TI_HWMOD_DISABLE_AUTOIDLE	0x01
+
 struct ti_prcm_clk {
 	struct clk		base;
 	enum ti_prcm_clktype	type;
@@ -138,13 +141,14 @@ ti_prcm_hwmod_get_parent(struct ti_prcm_
 }
 
 #define	TI_PRCM_HWMOD(_name, _reg, _parent, _enable)			\
-	TI_PRCM_HWMOD_MASK(_name, _reg, 0, _parent, _enable)
+	TI_PRCM_HWMOD_MASK(_name, _reg, 0, _parent, _enable, 0)
 
-#define	TI_PRCM_HWMOD_MASK(_name, _reg, _mask, _parent, _enable)	\
+#define	TI_PRCM_HWMOD_MASK(_name, _reg, _mask, _parent, _enable, _flags) \
 	{								\
 		.type = TI_PRCM_HWMOD, .base.name = (_name),		\
 		.u.hwmod.reg = (_reg),					\
 		.u.hwmod.mask = (_mask),				\
+		.u.hwmod.flags = (_flags),				\
 		.u.hwmod.parent = (_parent),				\
 		.enable = (_enable),					\
 		.get_parent = ti_prcm_hwmod_get_parent,			\

Added files:

Index: src/sys/arch/arm/ti/ti_ehci.c
diff -u /dev/null src/sys/arch/arm/ti/ti_ehci.c:1.1
--- /dev/null	Wed Oct 30 21:41:40 2019
+++ src/sys/arch/arm/ti/ti_ehci.c	Wed Oct 30 21:41:40 2019
@@ -0,0 +1,157 @@
+/* $NetBSD: ti_ehci.c,v 1.1 2019/10/30 21:41:40 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2015-2019 Jared 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. 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.
+ *
+ * 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 <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: ti_ehci.c,v 1.1 2019/10/30 21:41:40 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/intr.h>
+#include <sys/systm.h>
+#include <sys/kernel.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 <dev/fdt/fdtvar.h>
+
+#define	TI_EHCI_NPORTS	3
+
+static int	ti_ehci_match(device_t, cfdata_t, void *);
+static void	ti_ehci_attach(device_t, device_t, void *);
+
+CFATTACH_DECL2_NEW(ti_ehci, sizeof(struct ehci_softc),
+	ti_ehci_match, ti_ehci_attach, NULL,
+	ehci_activate, NULL, ehci_childdet);
+
+static int
+ti_ehci_match(device_t parent, cfdata_t cf, void *aux)
+{
+	const char * const compatible[] = {
+		"ti,ehci-omap",
+		NULL
+	};
+	struct fdt_attach_args * const faa = aux;
+
+	return of_match_compatible(faa->faa_phandle, compatible);
+}
+
+static void
+ti_ehci_attach(device_t parent, device_t self, void *aux)
+{
+	struct ehci_softc * const sc = device_private(self);
+	struct fdt_attach_args * const faa = aux;
+	const int phandle = faa->faa_phandle;
+	struct fdtbus_reset *rst;
+	struct fdtbus_phy *phy;
+	struct clk *clk;
+	char intrstr[128];
+	bus_addr_t addr;
+	bus_size_t size;
+	int error;
+	void *ih;
+	u_int n;
+
+	if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return;
+	}
+
+	/* Enable clocks */
+	for (n = 0; (clk = fdtbus_clock_get_index(phandle, n)) != NULL; n++)
+		if (clk_enable(clk) != 0) {
+			aprint_error(": couldn't enable clock #%d\n", n);
+			return;
+		}
+	/* De-assert resets */
+	for (n = 0; (rst = fdtbus_reset_get_index(phandle, n)) != NULL; n++)
+		if (fdtbus_reset_deassert(rst) != 0) {
+			aprint_error(": couldn't de-assert reset #%d\n", n);
+			return;
+		}
+
+	sc->sc_dev = self;
+	sc->sc_bus.ub_hcpriv = sc;
+	sc->sc_bus.ub_dmatag = faa->faa_dmat;
+	sc->sc_bus.ub_revision = USBREV_2_0;
+	if (of_hasprop(phandle, "has-transaction-translator"))
+		sc->sc_flags |= EHCIF_ETTF;
+	else
+		sc->sc_ncomp = 1;
+	sc->sc_size = size;
+	sc->iot = faa->faa_bst;
+	if (bus_space_map(sc->iot, addr, size, 0, &sc->ioh) != 0) {
+		aprint_error(": couldn't map registers\n");
+		return;
+	}
+
+	aprint_naive("\n");
+	aprint_normal(": EHCI\n");
+
+	/* Enable PHYs */
+	for (n = 0; n < TI_EHCI_NPORTS; n++) {
+		phy = fdtbus_phy_get_index(phandle, n);
+		if (phy && fdtbus_phy_enable(phy, true) != 0) {
+			aprint_error(": couldn't enable phy\n");
+			return;
+		}
+	}
+
+	/* Disable interrupts */
+	sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH);
+	EOWRITE4(sc, EHCI_USBINTR, 0);
+
+	if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
+		aprint_error_dev(self, "failed to decode interrupt\n");
+		return;
+	}
+
+	ih = fdtbus_intr_establish(phandle, 0, IPL_USB, FDT_INTR_MPSAFE,
+	    ehci_intr, sc);
+	if (ih == NULL) {
+		aprint_error_dev(self, "couldn't establish interrupt on %s\n",
+		    intrstr);
+		return;
+	}
+	aprint_normal_dev(self, "interrupting on %s\n", intrstr);
+
+	error = ehci_init(sc);
+	if (error) {
+		aprint_error_dev(self, "init failed, error = %d\n", error);
+		return;
+	}
+
+	pmf_device_register1(self, NULL, NULL, ehci_shutdown);
+
+	sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint);
+}
Index: src/sys/arch/arm/ti/ti_usb.c
diff -u /dev/null src/sys/arch/arm/ti/ti_usb.c:1.1
--- /dev/null	Wed Oct 30 21:41:40 2019
+++ src/sys/arch/arm/ti/ti_usb.c	Wed Oct 30 21:41:40 2019
@@ -0,0 +1,221 @@
+/* $NetBSD: ti_usb.c,v 1.1 2019/10/30 21:41:40 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2019 Jared 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.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: ti_usb.c,v 1.1 2019/10/30 21:41:40 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/conf.h>
+#include <sys/mutex.h>
+#include <sys/bus.h>
+
+#include <dev/fdt/fdtvar.h>
+
+#include <arm/ti/ti_prcm.h>
+
+#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_HOSTCONFIG				0x40
+#define  UHH_HOSTCONFIG_APP_START_CLK		__BIT(31)
+#define	 UHH_HOSTCONFIG_P3_MODE			__BITS(21,20)
+#define	 UHH_HOSTCONFIG_P2_MODE			__BITS(19,18)
+#define	 UHH_HOSTCONFIG_P1_MODE			__BITS(17,16)
+#define   UHH_HOSTCONFIG_PMODE_ULPI_PHY		0
+#define   UHH_HOSTCONFIG_PMODE_UTMI		1
+#define   UHH_HOSTCONFIG_PMODE_HSIC		3
+#define	 UHH_HOSTCONFIG_P3_ULPI_BYPASS		__BIT(12)
+#define	 UHH_HOSTCONFIG_P2_ULPI_BYPASS		__BIT(11)
+#define	 UHH_HOSTCONFIG_P3_CONNECT_STATUS	__BIT(10)
+#define	 UHH_HOSTCONFIG_P2_CONNECT_STATUS	__BIT(9)
+#define	 UHH_HOSTCONFIG_P1_CONNECT_STATUS	__BIT(8)
+#define	 UHH_HOSTCONFIG_ENA_INCR_ALIGN		__BIT(5)
+#define	 UHH_HOSTCONFIG_ENA_INCR16		__BIT(4)
+#define	 UHH_HOSTCONFIG_ENA_INCR8		__BIT(3)
+#define	 UHH_HOSTCONFIG_ENA_INCR4		__BIT(2)
+#define	 UHH_HOSTCONFIG_AUTOPPD_ON_OVERCUR_EN	__BIT(1)
+#define	 UHH_HOSTCONFIG_P1_ULPI_BYPASS		__BIT(0)
+
+extern void tl_usbtll_enable_port(u_int);
+
+static const char * const compatible[] = {
+	"ti,usbhs-host",
+	NULL
+};
+
+#define	TI_USB_NPORTS	3
+
+enum {
+	CONNECT_STATUS,
+	ULPI_BYPASS,
+	TI_USB_NBITS
+};
+
+static const uint32_t ti_usb_portbits[TI_USB_NPORTS][TI_USB_NBITS] = {
+	[0] = {
+		[CONNECT_STATUS] = UHH_HOSTCONFIG_P1_CONNECT_STATUS,
+		[ULPI_BYPASS] = UHH_HOSTCONFIG_P1_ULPI_BYPASS,
+	},
+	[1] = {
+		[CONNECT_STATUS] = UHH_HOSTCONFIG_P2_CONNECT_STATUS,
+		[ULPI_BYPASS] = UHH_HOSTCONFIG_P2_ULPI_BYPASS,
+	},
+	[2] = {
+		[CONNECT_STATUS] = UHH_HOSTCONFIG_P3_CONNECT_STATUS,
+		[ULPI_BYPASS] = UHH_HOSTCONFIG_P3_ULPI_BYPASS,
+	},
+};
+
+enum {
+	PORT_UNUSED,
+	PORT_EHCI_PHY,
+	PORT_EHCI_TLL,
+	PORT_EHCI_HSIC,
+};
+
+struct ti_usb_softc {
+	device_t sc_dev;
+	bus_space_tag_t sc_bst;
+	bus_space_handle_t sc_bsh;
+
+	u_int sc_portmode[TI_USB_NPORTS];
+};
+
+static int	ti_usb_match(device_t, cfdata_t, void *);
+static void	ti_usb_attach(device_t, device_t, void *);
+
+CFATTACH_DECL_NEW(ti_usb, sizeof(struct ti_usb_softc),
+    ti_usb_match, ti_usb_attach, NULL, NULL);
+
+#define RD4(sc, reg) \
+	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
+#define WR4(sc, reg, val) \
+	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
+
+static void
+ti_usb_init(struct ti_usb_softc *sc)
+{
+	uint32_t val;
+	int port;
+
+	val = RD4(sc, UHH_SYSCONFIG);
+	val &= ~(UHH_SYSCONFIG_SIDLEMODE_MASK|UHH_SYSCONFIG_MIDLEMODE_MASK);
+	val |= UHH_SYSCONFIG_MIDLEMODE_SMARTSTANDBY;
+	val |= UHH_SYSCONFIG_CLOCKACTIVITY;
+	val |= UHH_SYSCONFIG_SIDLEMODE_SMARTIDLE;
+	val |= UHH_SYSCONFIG_ENAWAKEUP;
+	val &= ~UHH_SYSCONFIG_AUTOIDLE;
+	WR4(sc, UHH_SYSCONFIG, val);
+
+	val = RD4(sc, UHH_SYSCONFIG);
+
+	val = RD4(sc, UHH_HOSTCONFIG);
+	val |= UHH_HOSTCONFIG_ENA_INCR16;
+	val |= UHH_HOSTCONFIG_ENA_INCR8;
+	val |= UHH_HOSTCONFIG_ENA_INCR4;
+	val |= UHH_HOSTCONFIG_APP_START_CLK;
+	val &= ~UHH_HOSTCONFIG_ENA_INCR_ALIGN;
+	for (port = 0; port < TI_USB_NPORTS; port++) {
+		if (sc->sc_portmode[port] == PORT_UNUSED)
+			val &= ~ti_usb_portbits[port][CONNECT_STATUS];
+		if (sc->sc_portmode[port] == PORT_EHCI_PHY)
+			val &= ~ti_usb_portbits[port][ULPI_BYPASS];
+		else
+			val |= ti_usb_portbits[port][ULPI_BYPASS];
+	}
+	WR4(sc, UHH_HOSTCONFIG, val);
+}
+
+static int
+ti_usb_match(device_t parent, cfdata_t match, void *aux)
+{
+	struct fdt_attach_args * const faa = aux;
+
+	return of_match_compatible(faa->faa_phandle, compatible);
+}
+
+static void
+ti_usb_attach(device_t parent, device_t self, void *aux)
+{
+	struct ti_usb_softc *sc = device_private(self);
+	struct fdt_attach_args * const faa = aux;
+	const int phandle = faa->faa_phandle;
+	bus_addr_t addr;
+	bus_size_t size;
+	char propname[16];
+	const char *portmode;
+	int port;
+
+	if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return;
+	}
+
+	if (ti_prcm_enable_hwmod(phandle, 0) != 0) {
+		aprint_error(": couldn't enable module\n");
+		return;
+	}
+
+	sc->sc_dev = self;
+	sc->sc_bst = faa->faa_bst;
+	if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
+		aprint_error(": couldn't map registers\n");
+		return;
+	}
+
+	for (port = 0; port < TI_USB_NPORTS; port++) {
+		snprintf(propname, sizeof(propname), "port%d-mode", port + 1);
+		portmode = fdtbus_get_string(phandle, propname);
+		if (portmode == NULL)
+			continue;
+		if (strcmp(portmode, "ehci-phy") == 0)
+			sc->sc_portmode[port] = PORT_EHCI_PHY;
+		else if (strcmp(portmode, "ehci-tll") == 0)
+			sc->sc_portmode[port] = PORT_EHCI_TLL;
+		else if (strcmp(portmode, "ehci-hsic") == 0)
+			sc->sc_portmode[port] = PORT_EHCI_HSIC;
+
+		if (sc->sc_portmode[port] != PORT_UNUSED)
+			tl_usbtll_enable_port(port);
+	}
+
+	aprint_naive("\n");
+	aprint_normal(": OMAP HS USB Host\n");
+
+	ti_usb_init(sc);
+
+	fdt_add_bus(self, phandle, faa);
+}
Index: src/sys/arch/arm/ti/ti_usbtll.c
diff -u /dev/null src/sys/arch/arm/ti/ti_usbtll.c:1.1
--- /dev/null	Wed Oct 30 21:41:40 2019
+++ src/sys/arch/arm/ti/ti_usbtll.c	Wed Oct 30 21:41:40 2019
@@ -0,0 +1,203 @@
+/* $NetBSD: ti_usbtll.c,v 1.1 2019/10/30 21:41:40 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2019 Jared 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.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: ti_usbtll.c,v 1.1 2019/10/30 21:41:40 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/conf.h>
+#include <sys/mutex.h>
+#include <sys/bus.h>
+
+#include <dev/fdt/fdtvar.h>
+
+#include <arm/ti/ti_prcm.h>
+
+#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_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
+
+static const char * const compatible[] = {
+	"ti,usbhs-tll",
+	NULL
+};
+
+struct ti_usbtll_softc {
+	device_t sc_dev;
+	bus_space_tag_t sc_bst;
+	bus_space_handle_t sc_bsh;
+};
+
+static int	ti_usbtll_match(device_t, cfdata_t, void *);
+static void	ti_usbtll_attach(device_t, device_t, void *);
+
+CFATTACH_DECL_NEW(ti_usbtll, sizeof(struct ti_usbtll_softc),
+    ti_usbtll_match, ti_usbtll_attach, NULL, NULL);
+
+#define RD4(sc, reg) \
+	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
+#define WR4(sc, reg, val) \
+	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
+
+static struct ti_usbtll_softc *ti_usbtll_sc = NULL;
+
+void	tl_usbtll_enable_port(u_int);
+
+void
+tl_usbtll_enable_port(u_int port)
+{
+	struct ti_usbtll_softc *sc = ti_usbtll_sc;
+	uint32_t val;
+
+	if (sc == NULL) {
+		printf("%s: driver not loaded\n", __func__);
+		return;
+	}
+
+	val = RD4(sc, USBTLL_CHANNEL_CONF(port));
+	val &= ~(USBTLL_CHANNEL_CONF_ULPINOBITSTUFF|
+		 USBTLL_CHANNEL_CONF_ULPIAUTOIDLE|
+		 USBTLL_CHANNEL_CONF_ULPIDDRMODE);
+	val |= USBTLL_CHANNEL_CONF_CHANEN;
+	WR4(sc, USBTLL_CHANNEL_CONF(port), val);
+}
+
+static void
+ti_usbtll_reset(struct ti_usbtll_softc *sc)
+{
+	uint32_t val;
+	int retry = 5000;
+
+	WR4(sc, USBTLL_SYSCONFIG, USBTLL_SYSCONFIG_SOFTRESET);
+	do {
+		val = RD4(sc, USBTLL_SYSSTATUS);
+		if (val & USBTLL_SYSSTATUS_RESETDONE)
+			break;
+		delay(10);
+	} while (--retry > 0);
+	if (retry == 0)
+		aprint_error_dev(sc->sc_dev, "reset timeout\n");
+}
+
+static void
+ti_usbtll_init(struct ti_usbtll_softc *sc)
+{
+	uint32_t val;
+
+	ti_usbtll_reset(sc);
+
+	val = USBTLL_SYSCONFIG_ENAWAKEUP |
+	      USBTLL_SYSCONFIG_AUTOIDLE |
+	      USBTLL_SYSCONFIG_SIDLEMODE |
+	      USBTLL_SYSCONFIG_CLOCKACTIVITY;
+	WR4(sc, USBTLL_SYSCONFIG, val);
+
+	val = RD4(sc, USBTLL_SHARED_CONF);
+	val |= (USBTLL_SHARED_CONF_FCLK_IS_ON | (1 << 2));
+	val &= ~USBTLL_SHARED_CONF_USB_90D_DDR_EN;
+	val &= ~USBTLL_SHARED_CONF_USB_180D_SDR_EN;
+	WR4(sc, USBTLL_SHARED_CONF, val);
+}
+
+static int
+ti_usbtll_match(device_t parent, cfdata_t match, void *aux)
+{
+	struct fdt_attach_args * const faa = aux;
+
+	return of_match_compatible(faa->faa_phandle, compatible);
+}
+
+static void
+ti_usbtll_attach(device_t parent, device_t self, void *aux)
+{
+	struct ti_usbtll_softc *sc = device_private(self);
+	struct fdt_attach_args * const faa = aux;
+	const int phandle = faa->faa_phandle;
+	bus_addr_t addr;
+	bus_size_t size;
+
+	if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return;
+	}
+
+	if (ti_prcm_enable_hwmod(phandle, 0) != 0) {
+		aprint_error(": couldn't enable module\n");
+		return;
+	}
+
+	sc->sc_dev = self;
+	sc->sc_bst = faa->faa_bst;
+	if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
+		aprint_error(": couldn't map registers\n");
+		return;
+	}
+
+	aprint_naive("\n");
+	aprint_normal(": OMAP HS USB Host TLL\n");
+
+	ti_usbtll_init(sc);
+
+	if (ti_usbtll_sc == NULL)
+		ti_usbtll_sc = sc;
+}

Reply via email to