Module Name:    src
Committed By:   jmcneill
Date:           Tue Oct 29 22:19:13 UTC 2019

Modified Files:
        src/sys/arch/arm/ti: files.ti ti_com.c ti_dpll_clock.c ti_gpio.c
            ti_iic.c ti_omapintc.c ti_omaptimer.c ti_prcm.c ti_prcm.h ti_rng.c
            ti_sdhc.c
Added Files:
        src/sys/arch/arm/ti: omap3_cm.c omap3_platform.c omap3_prm.c

Log Message:
Add support for TI OMAP3.


To generate a diff of this commit:
cvs rdiff -u -r1.15 -r1.16 src/sys/arch/arm/ti/files.ti
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/ti/omap3_cm.c \
    src/sys/arch/arm/ti/omap3_platform.c src/sys/arch/arm/ti/omap3_prm.c
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/arm/ti/ti_com.c
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/ti/ti_dpll_clock.c \
    src/sys/arch/arm/ti/ti_gpio.c src/sys/arch/arm/ti/ti_iic.c \
    src/sys/arch/arm/ti/ti_omapintc.c src/sys/arch/arm/ti/ti_rng.c
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/ti/ti_omaptimer.c \
    src/sys/arch/arm/ti/ti_prcm.c src/sys/arch/arm/ti/ti_prcm.h \
    src/sys/arch/arm/ti/ti_sdhc.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/ti/files.ti
diff -u src/sys/arch/arm/ti/files.ti:1.15 src/sys/arch/arm/ti/files.ti:1.16
--- src/sys/arch/arm/ti/files.ti:1.15	Tue Oct 29 10:54:10 2019
+++ src/sys/arch/arm/ti/files.ti	Tue Oct 29 22:19:13 2019
@@ -1,8 +1,9 @@
-#	$NetBSD: files.ti,v 1.15 2019/10/29 10:54:10 jmcneill Exp $
+#	$NetBSD: files.ti,v 1.16 2019/10/29 22:19:13 jmcneill Exp $
 #
 
 file	arch/arm/ti/ti_cpufreq.c	soc_ti
 file	arch/arm/ti/am3_platform.c	soc_am33xx
+file	arch/arm/ti/omap3_platform.c	soc_omap3
 
 # Interrupt controller
 device	omapintc: pic, pic_splfuncs
@@ -23,6 +24,16 @@ device	am3prcm { } : fdt, ti_prcm
 attach	am3prcm at fdt with am3_prcm
 file	arch/arm/ti/am3_prcm.c		am3_prcm
 
+# CM (OMAP3)
+device	omap3cm { } : fdt, ti_prcm
+attach	omap3cm at fdt with omap3_cm
+file	arch/arm/ti/omap3_cm.c		omap3_cm
+
+# PRM (OMAP3)
+device	omap3prm { } : fdt
+attach	omap3prm at fdt with omap3_prm
+file	arch/arm/ti/omap3_prm.c		omap3_prm
+
 # Clocks
 device	timuxclk
 attach	timuxclk at fdt with ti_mux_clock
@@ -88,3 +99,4 @@ file	arch/arm/ti/ti_rng.c		ti_rng
 # SOC parameters
 defflag	opt_soc.h			SOC_TI
 defflag	opt_soc.h			SOC_AM33XX: SOC_TI
+defflag	opt_soc.h			SOC_OMAP3: SOC_TI

Index: src/sys/arch/arm/ti/ti_com.c
diff -u src/sys/arch/arm/ti/ti_com.c:1.7 src/sys/arch/arm/ti/ti_com.c:1.8
--- src/sys/arch/arm/ti/ti_com.c:1.7	Sun Oct 27 12:14:51 2019
+++ src/sys/arch/arm/ti/ti_com.c	Tue Oct 29 22:19:13 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: ti_com.c,v 1.7 2019/10/27 12:14:51 jmcneill Exp $ */
+/* $NetBSD: ti_com.c,v 1.8 2019/10/29 22:19:13 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca>
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: ti_com.c,v 1.7 2019/10/27 12:14:51 jmcneill Exp $");
+__KERNEL_RCSID(1, "$NetBSD: ti_com.c,v 1.8 2019/10/29 22:19:13 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -105,7 +105,7 @@ ti_com_attach(device_t parent, device_t 
 		return;
 	}
 
-	if (ti_prcm_enable_hwmod(OF_parent(phandle), 0) != 0) {
+	if (ti_prcm_enable_hwmod(phandle, 0) != 0) {
 		aprint_error(": couldn't enable module\n");
 		return;
 	}

Index: src/sys/arch/arm/ti/ti_dpll_clock.c
diff -u src/sys/arch/arm/ti/ti_dpll_clock.c:1.1 src/sys/arch/arm/ti/ti_dpll_clock.c:1.2
--- src/sys/arch/arm/ti/ti_dpll_clock.c:1.1	Mon Oct 28 21:16:47 2019
+++ src/sys/arch/arm/ti/ti_dpll_clock.c	Tue Oct 29 22:19:13 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: ti_dpll_clock.c,v 1.1 2019/10/28 21:16:47 jmcneill Exp $ */
+/* $NetBSD: ti_dpll_clock.c,v 1.2 2019/10/29 22:19:13 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2019 Jared McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ti_dpll_clock.c,v 1.1 2019/10/28 21:16:47 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ti_dpll_clock.c,v 1.2 2019/10/29 22:19:13 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -39,24 +39,25 @@ __KERNEL_RCSID(0, "$NetBSD: ti_dpll_cloc
 
 #include <dev/fdt/fdtvar.h>
 
-/* CM_IDLEST_DPLL_MPU */
-#define	ST_MN_BYPASS		__BIT(8)
-#define	ST_DPLL_CLK		__BIT(0)
-
-/* CM_CLKSEL_DPLL_MPU */
-#define	DPLL_BYP_CLKSEL		__BIT(23)
 #define	DPLL_MULT		__BITS(18,8)
 #define	DPLL_DIV		__BITS(6,0)
 
-/* CM_CLKMODE_DPLL_MPU */
-#define	DPLL_EN			__BITS(2,0)
-#define	 DPLL_EN_NM_BYPASS	4
-#define	 DPLL_EN_LOCK		7
-
-static const char * const compatible[] = {
-	"ti,am3-dpll-clock",
-	NULL
-};
+#define	AM3_ST_MN_BYPASS	__BIT(8)
+#define	AM3_ST_DPLL_CLK		__BIT(0)
+
+#define	AM3_DPLL_EN		__BITS(2,0)
+#define	 AM3_DPLL_EN_NM_BYPASS	4
+#define	 AM3_DPLL_EN_LOCK	7
+
+#define	OMAP3_ST_MPU_CLK	__BIT(0)
+
+#define	OMAP3_EN_MPU_DPLL	__BITS(2,0)
+#define	 OMAP3_EN_MPU_DPLL_BYPASS	5
+#define	 OMAP3_EN_MPU_DPLL_LOCK		7
+
+#define	OMAP3_CORE_DPLL_CLKOUT_DIV __BITS(31,27)
+#define	OMAP3_CORE_DPLL_MULT	__BITS(26,16)
+#define	OMAP3_CORE_DPLL_DIV	__BITS(14,8)
 
 static int	ti_dpll_clock_match(device_t, cfdata_t, void *);
 static void	ti_dpll_clock_attach(device_t, device_t, void *);
@@ -69,18 +70,45 @@ static const struct fdtbus_clock_control
 
 static struct clk *ti_dpll_clock_get(void *, const char *);
 static void	ti_dpll_clock_put(void *, struct clk *);
-static int	ti_dpll_clock_set_rate(void *, struct clk *, u_int);
 static u_int	ti_dpll_clock_get_rate(void *, struct clk *);
 static struct clk *ti_dpll_clock_get_parent(void *, struct clk *);
 
-static const struct clk_funcs ti_dpll_clock_clk_funcs = {
+static int	am3_dpll_clock_set_rate(void *, struct clk *, u_int);
+
+static const struct clk_funcs am3_dpll_clock_clk_funcs = {
 	.get = ti_dpll_clock_get,
 	.put = ti_dpll_clock_put,
-	.set_rate = ti_dpll_clock_set_rate,
+	.set_rate = am3_dpll_clock_set_rate,
 	.get_rate = ti_dpll_clock_get_rate,
 	.get_parent = ti_dpll_clock_get_parent,
 };
 
+static int	omap3_dpll_clock_set_rate(void *, struct clk *, u_int);
+
+static const struct clk_funcs omap3_dpll_clock_clk_funcs = {
+	.get = ti_dpll_clock_get,
+	.put = ti_dpll_clock_put,
+	.set_rate = omap3_dpll_clock_set_rate,
+	.get_rate = ti_dpll_clock_get_rate,
+	.get_parent = ti_dpll_clock_get_parent,
+};
+
+static u_int	omap3_dpll_core_clock_get_rate(void *, struct clk *);
+
+static const struct clk_funcs omap3_dpll_core_clock_clk_funcs = {
+	.get = ti_dpll_clock_get,
+	.put = ti_dpll_clock_put,
+	.get_rate = omap3_dpll_core_clock_get_rate,
+	.get_parent = ti_dpll_clock_get_parent,
+};
+
+static const struct of_compat_data compat_data[] = {
+	{ "ti,am3-dpll-clock",		(uintptr_t)&am3_dpll_clock_clk_funcs },
+	{ "ti,omap3-dpll-clock",	(uintptr_t)&omap3_dpll_clock_clk_funcs },
+	{ "ti,omap3-dpll-core-clock",	(uintptr_t)&omap3_dpll_core_clock_clk_funcs },
+	{ NULL }
+};
+
 enum {
 	REG_CONTROL,
 	REG_IDLEST,
@@ -111,7 +139,7 @@ ti_dpll_clock_match(device_t parent, cfd
 {
 	const struct fdt_attach_args *faa = aux;
 
-	return of_match_compatible(faa->faa_phandle, compatible);
+	return of_match_compat_data(faa->faa_phandle, compat_data);
 }
 
 static void
@@ -120,6 +148,7 @@ ti_dpll_clock_attach(device_t parent, de
 	struct ti_dpll_clock_softc * const sc = device_private(self);
 	const struct fdt_attach_args *faa = aux;
 	const int phandle = faa->faa_phandle;
+	const struct clk_funcs *clkfuncs;
 	bus_addr_t addr[NREG], base_addr;
 	u_int n;
 
@@ -146,8 +175,10 @@ ti_dpll_clock_attach(device_t parent, de
 		}
 	}
 
+	clkfuncs = (const void *)of_search_compatible(phandle, compat_data)->data;
+
 	sc->sc_clkdom.name = device_xname(self);
-	sc->sc_clkdom.funcs = &ti_dpll_clock_clk_funcs;
+	sc->sc_clkdom.funcs = clkfuncs;
 	sc->sc_clkdom.priv = sc;
 
 	sc->sc_clk.domain = &sc->sc_clkdom;
@@ -202,8 +233,17 @@ ti_dpll_clock_get_rate(void *priv, struc
 	return (u_int)((mult * parent_rate) / div);
 }
 
+static struct clk *
+ti_dpll_clock_get_parent(void *priv, struct clk *clk)
+{
+	struct ti_dpll_clock_softc * const sc = priv;
+
+	/* XXX assume ref clk */
+	return fdtbus_clock_get_index(sc->sc_phandle, 0);
+}
+
 static int
-ti_dpll_clock_set_rate(void *priv, struct clk *clk, u_int rate)
+am3_dpll_clock_set_rate(void *priv, struct clk *clk, u_int rate)
 {
 	struct ti_dpll_clock_softc * const sc = priv;
 	struct clk *clk_parent = clk_get_parent(clk);
@@ -214,6 +254,8 @@ ti_dpll_clock_set_rate(void *priv, struc
 		return ENXIO;
 
 	parent_rate = clk_get_rate(clk_parent);
+	if (parent_rate == 0)
+		return EIO;
 
 	const u_int div = (parent_rate / 1000000) - 1;
 	const u_int mult = rate / (parent_rate / (div + 1));
@@ -221,32 +263,83 @@ ti_dpll_clock_set_rate(void *priv, struc
 		return EINVAL;
 
 	control = RD4(sc, REG_CONTROL);
-	control &= ~DPLL_EN;
-	control |= __SHIFTIN(DPLL_EN_LOCK, DPLL_EN);
+	control &= ~AM3_DPLL_EN;
+	control |= __SHIFTIN(AM3_DPLL_EN_NM_BYPASS, AM3_DPLL_EN);
 	WR4(sc, REG_CONTROL, control);
 
-	while ((RD4(sc, REG_IDLEST) & DPLL_EN_NM_BYPASS) != 0)
+	while ((RD4(sc, REG_IDLEST) & AM3_ST_MN_BYPASS) != 0)
 		;
 
 	mult_div1 = __SHIFTIN(mult, DPLL_MULT);
 	mult_div1 |= __SHIFTIN(div, DPLL_DIV);
 	WR4(sc, REG_MULT_DIV1, mult_div1);
 
-	control &= ~DPLL_EN;
-	control |= __SHIFTIN(DPLL_EN_LOCK, DPLL_EN);
+	control &= ~AM3_DPLL_EN;
+	control |= __SHIFTIN(AM3_DPLL_EN_LOCK, AM3_DPLL_EN);
 	WR4(sc, REG_CONTROL, control);
 
-	while ((RD4(sc, REG_IDLEST) & ST_DPLL_CLK) != 0)
+	while ((RD4(sc, REG_IDLEST) & AM3_ST_DPLL_CLK) != 0)
 		;    
 
 	return 0;
 }
 
-static struct clk *
-ti_dpll_clock_get_parent(void *priv, struct clk *clk)
+static int
+omap3_dpll_clock_set_rate(void *priv, struct clk *clk, u_int rate)
 {
 	struct ti_dpll_clock_softc * const sc = priv;
+	struct clk *clk_parent = clk_get_parent(clk);
+	uint64_t parent_rate;
+	uint32_t control, mult_div1;
 
-	/* XXX assume ref clk */
-	return fdtbus_clock_get_index(sc->sc_phandle, 0);
+	if (clk_parent == NULL)
+		return ENXIO;
+
+	parent_rate = clk_get_rate(clk_parent);
+
+	const u_int div = (parent_rate / 1000000) - 1;
+	const u_int mult = rate / (parent_rate / (div + 1));
+	if (mult < 2 || mult > 2047)
+		return EINVAL;
+
+	control = RD4(sc, REG_CONTROL);
+	control &= ~OMAP3_EN_MPU_DPLL;
+	control |= __SHIFTIN(OMAP3_EN_MPU_DPLL_BYPASS, OMAP3_EN_MPU_DPLL);
+	WR4(sc, REG_CONTROL, control);
+
+	delay(10);
+
+	mult_div1 = __SHIFTIN(mult, DPLL_MULT);
+	mult_div1 |= __SHIFTIN(div, DPLL_DIV);
+	WR4(sc, REG_MULT_DIV1, mult_div1);
+
+	control &= ~OMAP3_EN_MPU_DPLL;
+	control |= __SHIFTIN(OMAP3_EN_MPU_DPLL_LOCK, OMAP3_EN_MPU_DPLL);
+	WR4(sc, REG_CONTROL, control);
+
+	while ((RD4(sc, REG_IDLEST) & OMAP3_ST_MPU_CLK) != 0)
+		;    
+
+	return 0;
+}
+
+static u_int
+omap3_dpll_core_clock_get_rate(void *priv, struct clk *clk)
+{
+	struct ti_dpll_clock_softc * const sc = priv;
+	struct clk *clk_parent = clk_get_parent(clk);
+	uint32_t val;
+	uint64_t parent_rate;
+
+	if (clk_parent == NULL)
+		return 0;
+
+	val = RD4(sc, REG_MULT_DIV1);
+	const u_int mult = __SHIFTOUT(val, OMAP3_CORE_DPLL_MULT);
+	const u_int div = __SHIFTOUT(val, OMAP3_CORE_DPLL_DIV) + 1;
+	const u_int postdiv = __SHIFTOUT(val, OMAP3_CORE_DPLL_CLKOUT_DIV);
+
+	parent_rate = clk_get_rate(clk_parent);
+
+	return (u_int)((mult * parent_rate) / div) / postdiv;
 }
Index: src/sys/arch/arm/ti/ti_gpio.c
diff -u src/sys/arch/arm/ti/ti_gpio.c:1.1 src/sys/arch/arm/ti/ti_gpio.c:1.2
--- src/sys/arch/arm/ti/ti_gpio.c:1.1	Mon Oct 28 22:21:35 2019
+++ src/sys/arch/arm/ti/ti_gpio.c	Tue Oct 29 22:19:13 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: ti_gpio.c,v 1.1 2019/10/28 22:21:35 jmcneill Exp $ */
+/* $NetBSD: ti_gpio.c,v 1.2 2019/10/29 22:19:13 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2019 Jared McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ti_gpio.c,v 1.1 2019/10/28 22:21:35 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ti_gpio.c,v 1.2 2019/10/29 22:19:13 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -44,14 +44,16 @@ __KERNEL_RCSID(0, "$NetBSD: ti_gpio.c,v 
 
 #include <arm/ti/ti_prcm.h>
 
-#define	GPIO_OE				0x134
-#define	GPIO_DATAIN			0x138
-#define	GPIO_CLEARDATAOUT		0x190
-#define	GPIO_SETDATAOUT			0x194
-
-static const char * const compatible[] = {
-	"ti,omap4-gpio",
-	NULL
+#define	GPIO_OE				0x34
+#define	GPIO_DATAIN			0x38
+#define	GPIO_CLEARDATAOUT		0x90
+#define	GPIO_SETDATAOUT			0x94
+
+static const struct of_compat_data compat_data[] = {
+	/* compatible			reg offset */
+	{ "ti,omap3-gpio",		0x0 },
+	{ "ti,omap4-gpio",		0x100 },
+	{ NULL }
 };
 
 struct ti_gpio_softc {
@@ -59,6 +61,7 @@ struct ti_gpio_softc {
 	bus_space_tag_t sc_bst;
 	bus_space_handle_t sc_bsh;
 	kmutex_t sc_lock;
+	bus_size_t sc_regoff;
 
 	struct gpio_chipset_tag sc_gp;
 	gpio_pin_t sc_pins[32];
@@ -73,9 +76,9 @@ struct ti_gpio_pin {
 };
 
 #define RD4(sc, reg) 		\
-    bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
+    bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg) + (sc)->sc_regoff)
 #define WR4(sc, reg, val) 	\
-    bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
+    bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg) + (sc)->sc_regoff, (val))
 
 static int	ti_gpio_match(device_t, cfdata_t, void *);
 static void	ti_gpio_attach(device_t, device_t, void *);
@@ -264,7 +267,7 @@ ti_gpio_match(device_t parent, cfdata_t 
 {
 	struct fdt_attach_args * const faa = aux;
 
-	return of_match_compatible(faa->faa_phandle, compatible);
+	return of_match_compat_data(faa->faa_phandle, compat_data);
 }
 
 static void
@@ -273,6 +276,7 @@ ti_gpio_attach(device_t parent, device_t
 	struct ti_gpio_softc * const sc = device_private(self);
 	struct fdt_attach_args * const faa = aux;
 	const int phandle = faa->faa_phandle;
+	const char *modname;
 	bus_addr_t addr;
 	bus_size_t size;
 
@@ -280,7 +284,7 @@ ti_gpio_attach(device_t parent, device_t
 		aprint_error(": couldn't get registers\n");
 		return;
 	}
-	if (ti_prcm_enable_hwmod(OF_parent(phandle), 0) != 0) {
+	if (ti_prcm_enable_hwmod(phandle, 0) != 0) {
 		aprint_error(": couldn't enable module\n");
 		return;
 	}
@@ -291,10 +295,15 @@ ti_gpio_attach(device_t parent, device_t
 		aprint_error(": couldn't map registers\n");
 		return;
 	}
+	sc->sc_regoff = of_search_compatible(phandle, compat_data)->data;
 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);
 
+	modname = fdtbus_get_string(phandle, "ti,hwmods");
+	if (modname == NULL)
+		modname = fdtbus_get_string(OF_parent(phandle), "ti,hwmods");
+
 	aprint_naive("\n");
-	aprint_normal(": GPIO (%s)\n", fdtbus_get_string(OF_parent(phandle), "ti,hwmods"));
+	aprint_normal(": GPIO (%s)\n", modname);
 
 	fdtbus_register_gpio_controller(self, phandle, &ti_gpio_funcs);
 
Index: src/sys/arch/arm/ti/ti_iic.c
diff -u src/sys/arch/arm/ti/ti_iic.c:1.1 src/sys/arch/arm/ti/ti_iic.c:1.2
--- src/sys/arch/arm/ti/ti_iic.c:1.1	Sun Oct 27 19:11:07 2019
+++ src/sys/arch/arm/ti/ti_iic.c	Tue Oct 29 22:19:13 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: ti_iic.c,v 1.1 2019/10/27 19:11:07 jmcneill Exp $ */
+/* $NetBSD: ti_iic.c,v 1.2 2019/10/29 22:19:13 jmcneill Exp $ */
 
 /*
  * Copyright (c) 2013 Manuel Bouyer.  All rights reserved.
@@ -50,7 +50,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ti_iic.c,v 1.1 2019/10/27 19:11:07 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ti_iic.c,v 1.2 2019/10/29 22:19:13 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -81,9 +81,11 @@ __KERNEL_RCSID(0, "$NetBSD: ti_iic.c,v 1
 #define DPRINTF(args)
 #endif
 
-static const char * compatible [] = {
-	"ti,omap4-i2c",
-	NULL
+static const struct of_compat_data compat_data[] = {
+	/* compatible		reg shift */
+	{ "ti,omap3-i2c",	2 },
+	{ "ti,omap4-i2c",	0 },
+	{ NULL }
 };
 
 /* operation in progress */
@@ -103,6 +105,8 @@ struct ti_iic_softc {
 	bus_space_tag_t		sc_iot;
 	bus_space_handle_t	sc_ioh;
 
+	u_int			sc_reg_shift;
+
 	void			*sc_ih;
 	kmutex_t		sc_mtx;
 	kcondvar_t		sc_cv;
@@ -118,13 +122,13 @@ struct ti_iic_softc {
 };
 
 #define I2C_READ_REG(sc, reg)		\
-	bus_space_read_2((sc)->sc_iot, (sc)->sc_ioh, (reg))
+	bus_space_read_2((sc)->sc_iot, (sc)->sc_ioh, (reg) << (sc)->sc_reg_shift)
 #define I2C_READ_DATA(sc)		\
-	bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, OMAP2_I2C_DATA);
+	bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, OMAP2_I2C_DATA << (sc)->sc_reg_shift);
 #define I2C_WRITE_REG(sc, reg, val)	\
-	bus_space_write_2((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
+	bus_space_write_2((sc)->sc_iot, (sc)->sc_ioh, (reg) << (sc)->sc_reg_shift, (val))
 #define I2C_WRITE_DATA(sc, val)		\
-	bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, OMAP2_I2C_DATA, (val))
+	bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, OMAP2_I2C_DATA << (sc)->sc_reg_shift, (val))
 
 static int	ti_iic_match(device_t, cfdata_t, void *);
 static void	ti_iic_attach(device_t, device_t, void *);
@@ -161,7 +165,7 @@ ti_iic_match(device_t parent, cfdata_t m
 {
 	struct fdt_attach_args * const faa = opaque;
 
-	return of_match_compatible(faa->faa_phandle, compatible);
+	return of_match_compat_data(faa->faa_phandle, compat_data);
 }
 
 static void
@@ -185,7 +189,7 @@ ti_iic_attach(device_t parent, device_t 
 		return;
 	}
 
-	if (ti_prcm_enable_hwmod(OF_parent(phandle), 0) != 0) {
+	if (ti_prcm_enable_hwmod(phandle, 0) != 0) {
 		aprint_error(": couldn't enable module\n");
 		return;
 	}
@@ -204,6 +208,7 @@ ti_iic_attach(device_t parent, device_t 
 		aprint_error(": couldn't map registers\n");
 		return;
 	}
+	sc->sc_reg_shift = of_search_compatible(phandle, compat_data)->data;
 
 	sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_NET, 0,
 	    ti_iic_intr, sc);
Index: src/sys/arch/arm/ti/ti_omapintc.c
diff -u src/sys/arch/arm/ti/ti_omapintc.c:1.1 src/sys/arch/arm/ti/ti_omapintc.c:1.2
--- src/sys/arch/arm/ti/ti_omapintc.c:1.1	Thu Oct 26 01:16:32 2017
+++ src/sys/arch/arm/ti/ti_omapintc.c	Tue Oct 29 22:19:13 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: ti_omapintc.c,v 1.1 2017/10/26 01:16:32 jakllsch Exp $	*/
+/*	$NetBSD: ti_omapintc.c,v 1.2 2019/10/29 22:19:13 jmcneill Exp $	*/
 /*
  * Define the SDP2430 specific information and then include the generic OMAP
  * interrupt header.
@@ -29,11 +29,12 @@
 #define _INTR_PRIVATE
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ti_omapintc.c,v 1.1 2017/10/26 01:16:32 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ti_omapintc.c,v 1.2 2019/10/29 22:19:13 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/evcnt.h>
 #include <sys/device.h>
+#include <sys/kmem.h>
 
 #include <uvm/uvm_extern.h>
 
@@ -57,6 +58,12 @@ __KERNEL_RCSID(0, "$NetBSD: ti_omapintc.
 
 #define INTC_MAX_SOURCES	128
 
+static const struct of_compat_data compat_data[] = {
+	/* compatible			number of banks */
+	{ "ti,omap3-intc",		3 },
+	{ "ti,am33xx-intc",		4 },
+	{ NULL }
+};
 
 #define	INTC_READ(sc, g, o)		\
 	bus_space_read_4((sc)->sc_memt, (sc)->sc_memh, (g) * 0x20 + (o))
@@ -92,7 +99,8 @@ struct omap2icu_softc {
 	bus_space_tag_t sc_memt;
 	bus_space_handle_t sc_memh;
 	struct pic_softc sc_pic;
-	uint32_t sc_enabled_irqs[howmany(INTC_MAX_SOURCES, 32)];
+	uint32_t *sc_enabled_irqs;
+	u_int sc_nbank;
 };
 
 static struct omap2icu_softc *intc_softc;
@@ -143,20 +151,16 @@ omap_irq_handler(void *frame)
 	struct omap2icu_softc * const sc = intc_softc;
 	const int oldipl = ci->ci_cpl;
 	const uint32_t oldipl_mask = __BIT(oldipl);
-	int ipl_mask = 0;
+	int ipl_mask = 0, n;
 
 	ci->ci_data.cpu_nintr++;
 
-	if (sc->sc_enabled_irqs[0])
-		ipl_mask |= find_pending_irqs(sc, 0);
-	if (sc->sc_enabled_irqs[1])
-		ipl_mask |= find_pending_irqs(sc, 1);
-	if (sc->sc_enabled_irqs[2])
-		ipl_mask |= find_pending_irqs(sc, 2);
-	if (sc->sc_enabled_irqs[3])
-		ipl_mask |= find_pending_irqs(sc, 3);
+	for (n = 0; n < sc->sc_nbank; n++) {
+		if (sc->sc_enabled_irqs[n])
+			ipl_mask |= find_pending_irqs(sc, n);
+	}
 
-	/* force INTC to recomputq IRQ */
+	/* force INTC to recompute IRQ */
 	INTC_WRITE(sc, 0, INTC_CONTROL, INTC_CONTROL_NEWIRQAGR);
 
 	/*
@@ -221,12 +225,7 @@ omap2icu_match(device_t parent, cfdata_t
 {
 	struct fdt_attach_args * const faa = aux;
 
-	static const char * const compatible[] = {
-		"ti,am33xx-intc",
-		NULL
-	};
-
-	return of_match_compatible(faa->faa_phandle, compatible);
+	return of_match_compat_data(faa->faa_phandle, compat_data);
 }
 
 void
@@ -237,7 +236,7 @@ omap2icu_attach(device_t parent, device_
 	const int phandle = faa->faa_phandle;
 	bus_addr_t addr;
 	bus_size_t size;
-	int error;
+	int error, n;
 
 	if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
 		aprint_error(": couldn't get registers\n");
@@ -250,19 +249,21 @@ omap2icu_attach(device_t parent, device_
 		aprint_error(": couldn't map registers\n");
 		return;
 	}
+	sc->sc_nbank = of_search_compatible(phandle, compat_data)->data;
+	sc->sc_enabled_irqs =
+	    kmem_zalloc(sizeof(*sc->sc_enabled_irqs) * sc->sc_nbank, KM_SLEEP);
 
 	aprint_naive("\n");
 	aprint_normal("\n");
 
-	INTC_WRITE(sc, 0, INTC_MIR_SET, 0xffffffff);
-	INTC_WRITE(sc, 1, INTC_MIR_SET, 0xffffffff);
-	INTC_WRITE(sc, 2, INTC_MIR_SET, 0xffffffff);
+	for (n = 0; n < sc->sc_nbank; n++)
+		INTC_WRITE(sc, n, INTC_MIR_SET, 0xffffffff);
 
 	sc->sc_dev = self;
 	self->dv_private = sc;
 
 	sc->sc_pic.pic_ops = &omap2icu_picops;
-	sc->sc_pic.pic_maxsources = INTC_MAX_SOURCES;
+	sc->sc_pic.pic_maxsources = sc->sc_nbank * 32;
 	snprintf(sc->sc_pic.pic_name, sizeof(sc->sc_pic.pic_name), "intc");
 	pic_add(&sc->sc_pic, 0);
 	error = fdtbus_register_interrupt_controller(self, phandle,
Index: src/sys/arch/arm/ti/ti_rng.c
diff -u src/sys/arch/arm/ti/ti_rng.c:1.1 src/sys/arch/arm/ti/ti_rng.c:1.2
--- src/sys/arch/arm/ti/ti_rng.c:1.1	Mon Oct 28 23:57:59 2019
+++ src/sys/arch/arm/ti/ti_rng.c	Tue Oct 29 22:19:13 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: ti_rng.c,v 1.1 2019/10/28 23:57:59 jmcneill Exp $ */
+/* $NetBSD: ti_rng.c,v 1.2 2019/10/29 22:19:13 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ti_rng.c,v 1.1 2019/10/28 23:57:59 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ti_rng.c,v 1.2 2019/10/29 22:19:13 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -90,7 +90,7 @@ ti_rng_attach(device_t parent, device_t 
 		return;
 	}
 
-	if (ti_prcm_enable_hwmod(OF_parent(phandle), 0) != 0) {
+	if (ti_prcm_enable_hwmod(phandle, 0) != 0) {
 		aprint_error(": couldn't enable module\n");
 		return;
 	}

Index: src/sys/arch/arm/ti/ti_omaptimer.c
diff -u src/sys/arch/arm/ti/ti_omaptimer.c:1.2 src/sys/arch/arm/ti/ti_omaptimer.c:1.3
--- src/sys/arch/arm/ti/ti_omaptimer.c:1.2	Sun Oct 27 17:59:21 2019
+++ src/sys/arch/arm/ti/ti_omaptimer.c	Tue Oct 29 22:19:13 2019
@@ -1,7 +1,7 @@
-/*	$NetBSD: ti_omaptimer.c,v 1.2 2019/10/27 17:59:21 jmcneill Exp $	*/
+/*	$NetBSD: ti_omaptimer.c,v 1.3 2019/10/29 22:19:13 jmcneill Exp $	*/
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ti_omaptimer.c,v 1.2 2019/10/27 17:59:21 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ti_omaptimer.c,v 1.3 2019/10/29 22:19:13 jmcneill Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -17,25 +17,55 @@ __KERNEL_RCSID(0, "$NetBSD: ti_omaptimer
 
 #include <arm/ti/ti_prcm.h>
 
-#define	TIMER_IRQENABLE_SET	0x2c
-#define	TIMER_IRQENABLE_CLR	0x30
+enum omaptimer_type {
+	DM_TIMER_AM335X,
+	DM_TIMER_OMAP3430,
+	_DM_NTIMER
+};
+
+enum {
+	TIMER_TISR,
+	TIMER_TIER,
+	TIMER_TCLR,
+	TIMER_TCRR,
+	TIMER_TLDR,
+	_TIMER_NREG
+};
+
+/* TISR bits */
+#define	 OVF_IT_FLAG		__BIT(1)
+
+/* TIER bits */
 #define	 MAT_EN_FLAG		__BIT(0)
 #define	 OVF_EN_FLAG		__BIT(1)
 #define	 TCAR_EN_FLAG		__BIT(2)
-#define	TIMER_TCLR		0x38
+
+/* TCLR bits */
 #define	 TCLR_ST		__BIT(0)
 #define	 TCLR_AR		__BIT(1)
-#define	TIMER_TCRR		0x3c
-#define	TIMER_TLDR		0x40
 
-/* XXX */
-#define	IS_TIMER2(addr)	((addr) == 0x48040000)
-#define	IS_TIMER3(addr)	((addr) == 0x48042000)
-
-static const char * const compatible[] = {
-	"ti,am335x-timer-1ms",
-	"ti,am335x-timer",
-	NULL
+static uint8_t omaptimer_regmap[_DM_NTIMER][_TIMER_NREG] = {
+	[DM_TIMER_AM335X] = {
+		[TIMER_TISR]	= 0x28,
+		[TIMER_TIER]	= 0x2c,
+		[TIMER_TCLR] 	= 0x38,
+		[TIMER_TCRR]	= 0x3c,
+		[TIMER_TLDR]	= 0x40,
+	},
+	[DM_TIMER_OMAP3430] = {
+		[TIMER_TISR]	= 0x18,
+		[TIMER_TIER]	= 0x1c,
+		[TIMER_TCLR] 	= 0x24,
+		[TIMER_TCRR]	= 0x28,
+		[TIMER_TLDR]	= 0x2c,
+	},
+};
+
+static const struct of_compat_data compat_data[] = {
+	{ "ti,am335x-timer-1ms",	DM_TIMER_AM335X },
+	{ "ti,am335x-timer",		DM_TIMER_AM335X },
+	{ "ti,omap3430-timer",		DM_TIMER_OMAP3430 },
+	{ NULL }
 };
 
 struct omaptimer_softc {
@@ -43,10 +73,15 @@ struct omaptimer_softc {
 	bus_space_tag_t sc_bst;
 	bus_space_handle_t sc_bsh;
 	int sc_phandle;
-	struct clk *sc_clk;
+	enum omaptimer_type sc_type;
 	struct timecounter sc_tc;
 };
 
+#define	RD4(sc, reg)			\
+	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, omaptimer_regmap[(sc)->sc_type][(reg)])
+#define	WR4(sc, reg, val)		\
+	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, omaptimer_regmap[(sc)->sc_type][(reg)], val)
+
 static struct omaptimer_softc *timer_softc;
 
 static int
@@ -55,7 +90,7 @@ omaptimer_intr(void *arg)
 	struct omaptimer_softc * const sc = timer_softc;
 	struct clockframe * const frame = arg;
 
-	bus_space_write_4(sc->sc_bst, sc->sc_bsh, 0x28, 2);
+	WR4(sc, TIMER_TISR, OVF_IT_FLAG);
 	hardclock(frame);
 
 	return 1;
@@ -79,7 +114,7 @@ omaptimer_cpu_initclocks(void)
 	aprint_normal_dev(sc->sc_dev, "interrupting on %s\n", intrstr);
 
 	/* Enable interrupts */
-	bus_space_write_4(sc->sc_bst, sc->sc_bsh, TIMER_IRQENABLE_SET, OVF_EN_FLAG);
+	WR4(sc, TIMER_TIER, OVF_EN_FLAG);
 }
 
 static u_int
@@ -87,7 +122,7 @@ omaptimer_get_timecount(struct timecount
 {
 	struct omaptimer_softc * const sc = tc->tc_priv;
 
-	return bus_space_read_4(sc->sc_bst, sc->sc_bsh, TIMER_TCRR);
+	return RD4(sc, TIMER_TCRR);
 }
 
 static int
@@ -95,7 +130,7 @@ omaptimer_match(device_t parent, cfdata_
 {
 	struct fdt_attach_args * const faa = aux;
 
-	return of_match_compatible(faa->faa_phandle, compatible);
+	return of_match_compat_data(faa->faa_phandle, compat_data);
 }
 
 static void
@@ -105,6 +140,7 @@ omaptimer_attach(device_t parent, device
 	struct fdt_attach_args * const faa = aux;
 	const int phandle = faa->faa_phandle;
 	struct timecounter *tc = &sc->sc_tc;
+	const char *modname;
 	bus_addr_t addr;
 	bus_size_t size;
 
@@ -113,47 +149,44 @@ omaptimer_attach(device_t parent, device
 		return;
 	}
 
-#if 0
-	if ((sc->sc_clk = fdtbus_clock_get_index(phandle, 0)) == NULL) {
-		aprint_error(": couldn't get clock\n");
-		return;
-	}
-#endif
-
 	sc->sc_dev = self;
 	sc->sc_phandle = phandle;
 	sc->sc_bst = faa->faa_bst;
+	sc->sc_type = of_search_compatible(phandle, compat_data)->data;
 
 	if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
 		device_printf(self, "unable to map bus space");
 		return;
 	}
 
-	if (ti_prcm_enable_hwmod(OF_parent(phandle), 0) != 0) {
+	if (ti_prcm_enable_hwmod(phandle, 0) != 0) {
 		aprint_error(": couldn't enable module\n");
 		return;
 	}
 
+	modname = fdtbus_get_string(phandle, "ti,hwmods");
+	if (modname == NULL)
+		modname = fdtbus_get_string(OF_parent(phandle), "ti,hwmods");
+
 	aprint_naive("\n");
-	aprint_normal(": Timer\n");
+	aprint_normal(": Timer (%s)\n", modname);
 
-	if (IS_TIMER2(addr)) {
+	if (strcmp(modname, "timer2") == 0) {
 		/* Install timecounter */
 		tc->tc_get_timecount = omaptimer_get_timecount;
 		tc->tc_counter_mask = ~0u;
 		tc->tc_frequency = 24000000;
-		tc->tc_name = "Timer2";
+		tc->tc_name = modname;
 		tc->tc_quality = 200;
 		tc->tc_priv = sc;
 		tc_init(tc);
-	} else if (IS_TIMER3(addr)) {
+	} else if (strcmp(modname, "timer3") == 0) {
 		/* Configure the timer */
 		const uint32_t value = (0xffffffff - ((24000000UL / hz) - 1));
-		bus_space_write_4(sc->sc_bst, sc->sc_bsh, TIMER_TLDR, value);
-		bus_space_write_4(sc->sc_bst, sc->sc_bsh, TIMER_TCRR, value);
-		bus_space_write_4(sc->sc_bst, sc->sc_bsh, TIMER_IRQENABLE_CLR, 
-		    MAT_EN_FLAG | OVF_EN_FLAG | TCAR_EN_FLAG);
-		bus_space_write_4(sc->sc_bst, sc->sc_bsh, TIMER_TCLR, TCLR_ST | TCLR_AR);
+		WR4(sc, TIMER_TLDR, value);
+		WR4(sc, TIMER_TCRR, value);
+		WR4(sc, TIMER_TIER, 0);
+		WR4(sc, TIMER_TCLR, TCLR_ST | TCLR_AR);
 
 		/* Use this as the OS timer in UP configurations */
 		if (!arm_has_mpext_p) {
Index: src/sys/arch/arm/ti/ti_prcm.c
diff -u src/sys/arch/arm/ti/ti_prcm.c:1.2 src/sys/arch/arm/ti/ti_prcm.c:1.3
--- src/sys/arch/arm/ti/ti_prcm.c:1.2	Sun Oct 27 12:14:51 2019
+++ src/sys/arch/arm/ti/ti_prcm.c	Tue Oct 29 22:19:13 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: ti_prcm.c,v 1.2 2019/10/27 12:14:51 jmcneill Exp $ */
+/* $NetBSD: ti_prcm.c,v 1.3 2019/10/29 22:19:13 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ti_prcm.c,v 1.2 2019/10/27 12:14:51 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ti_prcm.c,v 1.3 2019/10/29 22:19:13 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -228,12 +228,15 @@ ti_prcm_get_hwmod(const int phandle, u_i
 {
 	struct ti_prcm_clk *tc;
 	const char *hwmods, *p;
-	int len, resid;
+	int len, resid, hwmod_phandle;
 	u_int n;
 
 	KASSERTMSG(prcm_softc != NULL, "prcm driver not attached");
 
-	hwmods = fdtbus_get_prop(phandle, "ti,hwmods", &len);
+	/* If this node does not have a ti,hwmods property, try the parent */
+	hwmod_phandle = of_hasprop(phandle, "ti,hwmods") ? phandle : OF_parent(phandle);
+
+	hwmods = fdtbus_get_prop(hwmod_phandle, "ti,hwmods", &len);
 	if (len <= 0)
 		return NULL;
 
Index: src/sys/arch/arm/ti/ti_prcm.h
diff -u src/sys/arch/arm/ti/ti_prcm.h:1.2 src/sys/arch/arm/ti/ti_prcm.h:1.3
--- src/sys/arch/arm/ti/ti_prcm.h:1.2	Sun Oct 27 12:14:51 2019
+++ src/sys/arch/arm/ti/ti_prcm.h	Tue Oct 29 22:19:13 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: ti_prcm.h,v 1.2 2019/10/27 12:14:51 jmcneill Exp $ */
+/* $NetBSD: ti_prcm.h,v 1.3 2019/10/29 22:19:13 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca>
@@ -55,6 +55,7 @@ struct ti_prcm_fixed_factor {
 
 struct ti_prcm_hwmod {
 	bus_size_t		reg;
+	uint32_t		mask;
 	const char		*parent;
 };
 
@@ -137,9 +138,13 @@ 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)
+
+#define	TI_PRCM_HWMOD_MASK(_name, _reg, _mask, _parent, _enable)	\
 	{								\
 		.type = TI_PRCM_HWMOD, .base.name = (_name),		\
 		.u.hwmod.reg = (_reg),					\
+		.u.hwmod.mask = (_mask),				\
 		.u.hwmod.parent = (_parent),				\
 		.enable = (_enable),					\
 		.get_parent = ti_prcm_hwmod_get_parent,			\
Index: src/sys/arch/arm/ti/ti_sdhc.c
diff -u src/sys/arch/arm/ti/ti_sdhc.c:1.2 src/sys/arch/arm/ti/ti_sdhc.c:1.3
--- src/sys/arch/arm/ti/ti_sdhc.c:1.2	Sun Oct 27 17:21:23 2019
+++ src/sys/arch/arm/ti/ti_sdhc.c	Tue Oct 29 22:19:13 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: ti_sdhc.c,v 1.2 2019/10/27 17:21:23 jmcneill Exp $	*/
+/*	$NetBSD: ti_sdhc.c,v 1.3 2019/10/29 22:19:13 jmcneill Exp $	*/
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ti_sdhc.c,v 1.2 2019/10/27 17:21:23 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ti_sdhc.c,v 1.3 2019/10/29 22:19:13 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -162,7 +162,7 @@ ti_sdhc_attach(device_t parent, device_t
 
 	conf = (const void *)of_search_compatible(phandle, compat_data)->data;
 
-	if (ti_prcm_enable_hwmod(OF_parent(phandle), 0) != 0) {
+	if (ti_prcm_enable_hwmod(phandle, 0) != 0) {
 		aprint_error(": couldn't enable module\n");
 		return;
 	}

Added files:

Index: src/sys/arch/arm/ti/omap3_cm.c
diff -u /dev/null src/sys/arch/arm/ti/omap3_cm.c:1.1
--- /dev/null	Tue Oct 29 22:19:13 2019
+++ src/sys/arch/arm/ti/omap3_cm.c	Tue Oct 29 22:19:13 2019
@@ -0,0 +1,183 @@
+/* $NetBSD: omap3_cm.c,v 1.1 2019/10/29 22:19:13 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2017 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(1, "$NetBSD: omap3_cm.c,v 1.1 2019/10/29 22:19:13 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+
+#include <dev/fdt/fdtvar.h>
+
+#define	TI_PRCM_PRIVATE
+#include <arm/ti/ti_prcm.h>
+
+#define	CM_CORE1_BASE		0x0a00
+#define	CM_CORE3_BASE		0x0a08
+#define	CM_WKUP_BASE		0x0c00
+#define	CM_PER_BASE		0x1000
+#define	CM_USBHOST_BASE		0x1400
+
+#define	CM_FCLKEN		0x00
+#define	CM_ICLKEN		0x10
+
+static int omap3_cm_match(device_t, cfdata_t, void *);
+static void omap3_cm_attach(device_t, device_t, void *);
+
+static int
+omap3_cm_hwmod_enable(struct ti_prcm_softc *sc, struct ti_prcm_clk *tc, int enable)
+{
+	uint32_t val;
+
+	val = PRCM_READ(sc, tc->u.hwmod.reg + CM_FCLKEN);
+	if (enable)
+		val |= tc->u.hwmod.mask;
+	else
+		val &= ~tc->u.hwmod.mask;
+	PRCM_WRITE(sc, tc->u.hwmod.reg + CM_FCLKEN, val);
+
+	val = PRCM_READ(sc, tc->u.hwmod.reg + CM_ICLKEN);
+	if (enable)
+		val |= tc->u.hwmod.mask;
+	else
+		val &= ~tc->u.hwmod.mask;
+	PRCM_WRITE(sc, tc->u.hwmod.reg + CM_ICLKEN, 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)
+
+static const char * const compatible[] = {
+	"ti,omap3-cm",
+	NULL
+};
+
+CFATTACH_DECL_NEW(omap3_cm, sizeof(struct ti_prcm_softc),
+	omap3_cm_match, omap3_cm_attach, NULL, NULL);
+
+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"),
+
+	OMAP3_CM_HWMOD_USBHOST("usb_host_hs", __BITS(1,0), "PERIPH_CLK"),
+};
+
+static int
+omap3_cm_match(device_t parent, cfdata_t cf, void *aux)
+{
+	struct fdt_attach_args * const faa = aux;
+
+	return of_match_compatible(faa->faa_phandle, compatible);
+}
+
+static void
+omap3_cm_attach(device_t parent, device_t self, void *aux)
+{
+	struct ti_prcm_softc * const sc = device_private(self);
+	struct fdt_attach_args * const faa = aux;
+	int clocks;
+
+	sc->sc_dev = self;
+	sc->sc_phandle = faa->faa_phandle;
+	sc->sc_bst = faa->faa_bst;
+
+	sc->sc_clks = omap3_cm_clks;
+	sc->sc_nclks = __arraycount(omap3_cm_clks);
+
+	if (ti_prcm_attach(sc) != 0)
+		return;
+
+	aprint_naive("\n");
+	aprint_normal(": OMAP3xxx CM\n");
+
+	clocks = of_find_firstchild_byname(sc->sc_phandle, "clocks");
+	if (clocks > 0)
+		fdt_add_bus(self, clocks, faa);
+}
Index: src/sys/arch/arm/ti/omap3_platform.c
diff -u /dev/null src/sys/arch/arm/ti/omap3_platform.c:1.1
--- /dev/null	Tue Oct 29 22:19:13 2019
+++ src/sys/arch/arm/ti/omap3_platform.c	Tue Oct 29 22:19:13 2019
@@ -0,0 +1,200 @@
+/* $NetBSD: omap3_platform.c,v 1.1 2019/10/29 22:19:13 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. 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 "opt_soc.h"
+#include "opt_console.h"
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: omap3_platform.c,v 1.1 2019/10/29 22:19:13 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/cpu.h>
+#include <sys/device.h>
+#include <sys/termios.h>
+
+#include <dev/fdt/fdtvar.h>
+#include <arm/fdt/arm_fdtvar.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <machine/bootconfig.h>
+#include <arm/cpufunc.h>
+
+#include <dev/ic/ns16550reg.h>
+#include <dev/ic/comreg.h>
+
+#include <evbarm/fdt/platform.h>
+#include <evbarm/fdt/machdep.h>
+
+#include <net/if_ether.h>
+
+#include <libfdt.h>
+
+#define	OMAP3_L4_CORE_VBASE	KERNEL_IO_VBASE
+#define	OMAP3_L4_CORE_PBASE	0x48000000
+#define	OMAP3_L4_CORE_SIZE	0x00100000
+
+#define	OMAP3_L4_WKUP_VBASE	(OMAP3_L4_CORE_VBASE + OMAP3_L4_CORE_SIZE)
+#define	OMAP3_L4_WKUP_PBASE	0x48300000
+#define	OMAP3_L4_WKUP_SIZE	0x00100000
+
+#define	OMAP3_L4_PER_VBASE	(OMAP3_L4_WKUP_VBASE + OMAP3_L4_WKUP_SIZE)
+#define	OMAP3_L4_PER_PBASE	0x49000000
+#define	OMAP3_L4_PER_SIZE	0x00100000
+
+#define	OMAP3_PRCM_BASE		0x48306000
+#define	OMAP3_PRCM_GR_BASE	(OMAP3_PRCM_BASE + 0x1200)
+#define	 PRM_RSTCTRL		(OMAP3_PRCM_GR_BASE + 0x50)
+#define	  PRM_RSTCTRL_RST_DPLL3	__BIT(1)
+
+#define	OMAP3_32KTIMER_BASE	0x48320000
+#define	 REG_32KSYNCNT_CR	(OMAP3_32KTIMER_BASE + 0x10)
+
+static inline vaddr_t
+omap3_phystovirt(paddr_t pa)
+{
+	if (pa >= OMAP3_L4_CORE_PBASE &&
+	    pa < OMAP3_L4_CORE_PBASE + OMAP3_L4_CORE_SIZE)
+		return (pa - OMAP3_L4_CORE_PBASE) + OMAP3_L4_CORE_VBASE;
+
+	if (pa >= OMAP3_L4_WKUP_PBASE &&
+	    pa < OMAP3_L4_WKUP_PBASE + OMAP3_L4_WKUP_SIZE)
+		return (pa - OMAP3_L4_WKUP_PBASE) + OMAP3_L4_WKUP_VBASE;
+
+	if (pa >= OMAP3_L4_PER_PBASE &&
+	    pa < OMAP3_L4_PER_PBASE + OMAP3_L4_PER_SIZE)
+		return (pa - OMAP3_L4_PER_PBASE) + OMAP3_L4_PER_VBASE;
+
+	panic("%s: pa %#x not in devmap", __func__, (uint32_t)pa);
+}
+
+#define	OMAP3_PHYSTOVIRT(pa)	\
+	(((pa) - OMAP3_L4_CORE_VBASE) + OMAP3_L4_CORE_PBASE)
+
+extern struct arm32_bus_dma_tag arm_generic_dma_tag;
+extern struct bus_space arm_generic_bs_tag;
+extern struct bus_space arm_generic_a4x_bs_tag;
+
+static const struct pmap_devmap *
+omap3_platform_devmap(void)
+{
+	static const struct pmap_devmap devmap[] = {
+		DEVMAP_ENTRY(OMAP3_L4_CORE_VBASE,
+			     OMAP3_L4_CORE_PBASE,
+			     OMAP3_L4_CORE_SIZE),
+		DEVMAP_ENTRY(OMAP3_L4_WKUP_VBASE,
+			     OMAP3_L4_WKUP_PBASE,
+			     OMAP3_L4_WKUP_SIZE),
+		DEVMAP_ENTRY(OMAP3_L4_PER_VBASE,
+			     OMAP3_L4_PER_PBASE,
+			     OMAP3_L4_PER_SIZE),
+		DEVMAP_ENTRY_END
+	};
+
+	return devmap;
+}
+
+static void
+omap3_platform_init_attach_args(struct fdt_attach_args *faa)
+{
+	faa->faa_bst = &arm_generic_bs_tag;
+	faa->faa_a4x_bst = &arm_generic_a4x_bs_tag;
+	faa->faa_dmat = &arm_generic_dma_tag;
+}
+
+void omap3_platform_early_putchar(char);
+
+void
+omap3_platform_early_putchar(char c)
+{
+#ifdef CONSADDR
+	volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ?
+	    (volatile uint32_t *)omap3_phystovirt(CONSADDR):
+	    (volatile uint32_t *)CONSADDR;
+
+	while ((le32toh(uartaddr[com_lsr]) & LSR_TXRDY) == 0)
+		;
+
+	uartaddr[com_data] = htole32(c);
+#endif
+}
+
+static void
+omap3_platform_device_register(device_t self, void *aux)
+{
+}
+
+static u_int
+omap3_platform_uart_freq(void)
+{
+	return 48000000U;
+}
+
+static void
+omap3_platform_reset(void)
+{
+	volatile uint32_t *rstctrl =
+	    (volatile uint32_t *)omap3_phystovirt(PRM_RSTCTRL);
+
+	*rstctrl |= PRM_RSTCTRL_RST_DPLL3;
+
+	for (;;)
+		__asm("wfi");
+}
+
+static void
+omap3_platform_delay(u_int n)
+{
+	volatile uint32_t *cr =
+	    (volatile uint32_t *)omap3_phystovirt(REG_32KSYNCNT_CR);
+	uint32_t cur, prev;
+
+	long ticks = howmany(n * 32768, 1000000);
+	prev = *cr;
+	while (ticks > 0) {
+		cur = *cr;
+		if (cur >= prev)
+			ticks -= (cur - prev);
+		else
+			ticks -= (UINT32_MAX - cur + prev);
+		prev = cur;
+	}
+}
+
+static const struct arm_platform omap3_platform = {
+	.ap_devmap = omap3_platform_devmap,
+	.ap_bootstrap = arm_fdt_cpu_bootstrap,
+	.ap_init_attach_args = omap3_platform_init_attach_args,
+	.ap_device_register = omap3_platform_device_register,
+	.ap_reset = omap3_platform_reset,
+	.ap_delay = omap3_platform_delay,
+	.ap_uart_freq = omap3_platform_uart_freq,
+};
+
+ARM_PLATFORM(omap3, "ti,omap3", &omap3_platform);
Index: src/sys/arch/arm/ti/omap3_prm.c
diff -u /dev/null src/sys/arch/arm/ti/omap3_prm.c:1.1
--- /dev/null	Tue Oct 29 22:19:13 2019
+++ src/sys/arch/arm/ti/omap3_prm.c	Tue Oct 29 22:19:13 2019
@@ -0,0 +1,77 @@
+/* $NetBSD: omap3_prm.c,v 1.1 2019/10/29 22:19:13 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. 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: omap3_prm.c,v 1.1 2019/10/29 22:19:13 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 <sys/kmem.h>
+
+#include <dev/fdt/fdtvar.h>
+
+#include <arm/ti/ti_prcm.h>
+
+static int	omap3_prm_match(device_t, cfdata_t, void *);
+static void	omap3_prm_attach(device_t, device_t, void *);
+
+CFATTACH_DECL_NEW(omap3_prm, 0, omap3_prm_match, omap3_prm_attach, NULL, NULL);
+
+static const char * compatible[] = {
+	"ti,omap3-prm",
+	NULL
+};
+
+static int
+omap3_prm_match(device_t parent, cfdata_t cf, void *aux)
+{
+	struct fdt_attach_args * const faa = aux;
+
+	return of_match_compatible(faa->faa_phandle, compatible);
+}
+
+static void
+omap3_prm_attach(device_t parent, device_t self, void *aux)
+{
+	struct fdt_attach_args * const faa = aux;
+	const int phandle = faa->faa_phandle;
+	int clocks;
+
+	aprint_naive("\n");
+	aprint_normal("\n");
+
+	fdt_add_bus(self, phandle, faa);
+
+	clocks = of_find_firstchild_byname(phandle, "clocks");
+	if (clocks > 0)
+		fdt_add_bus(self, clocks, faa);
+}

Reply via email to