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); +}