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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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 <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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 <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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);
+}