diff --git a/sys/arm/ti/ti_prcm.c b/sys/arm/ti/ti_prcm.c --- a/sys/arm/ti/ti_prcm.c +++ b/sys/arm/ti/ti_prcm.c @@ -35,14 +35,9 @@ #include #include #include -#include +#include #include -#include -#include -#include #include -#include -#include #include #include @@ -54,6 +49,11 @@ #include #include +#include +#include +#include + +#include "syscon_if.h" #include "clkdev_if.h" #if 0 @@ -62,17 +62,7 @@ #define DPRINTF(dev, msg...) #endif -struct ti_prcm_softc { - struct simplebus_softc sc_simplebus; - device_t dev; - struct resource * mem_res; - bus_space_tag_t bst; - bus_space_handle_t bsh; - int attach_done; - struct mtx mtx; -}; - -static struct ti_prcm_softc *ti_prcm_sc = NULL; +static device_t ti_prcm_dev; static void omap4_prcm_reset(void); static void am335x_prcm_reset(void); @@ -97,25 +87,25 @@ #define TI_PRCM_END 0 static struct ofw_compat_data compat_data[] = { - { "ti,am3-prcm", TI_AM3_PRCM }, - { "ti,am4-prcm", TI_AM4_PRCM }, - { "ti,omap2-prcm", TI_OMAP2_PRCM }, - { "ti,omap3-prm", TI_OMAP3_PRM }, - { "ti,omap3-cm", TI_OMAP3_CM }, - { "ti,omap4-cm1", TI_OMAP4_CM1 }, - { "ti,omap4-prm", TI_OMAP4_PRM }, - { "ti,omap4-cm2", TI_OMAP4_CM2 }, - { "ti,omap4-scrm", TI_OMAP4_SCRM }, - { "ti,omap5-prm", TI_OMAP5_PRM }, - { "ti,omap5-cm-core-aon", TI_OMAP5_CM_CORE_AON }, - { "ti,omap5-scrm", TI_OMAP5_SCRM }, - { "ti,omap5-cm-core", TI_OMAP5_CM_CORE }, - { "ti,dra7-prm", TI_DRA7_PRM }, - { "ti,dra7-cm-core-aon", TI_DRA7_CM_CORE_AON }, - { "ti,dra7-cm-core", TI_DRA7_CM_CORE }, - { "ti,dm814-prcm", TI_DM814_PRCM }, - { "ti,dm816-prcm", TI_DM816_PRCM }, - { NULL, TI_PRCM_END} + { "ti,am3-prcm", TI_AM3_PRCM }, + { "ti,am4-prcm", TI_AM4_PRCM }, + { "ti,omap2-prcm", TI_OMAP2_PRCM }, + { "ti,omap3-prm", TI_OMAP3_PRM }, + { "ti,omap3-cm", TI_OMAP3_CM }, + { "ti,omap4-cm1", TI_OMAP4_CM1 }, + { "ti,omap4-prm", TI_OMAP4_PRM }, + { "ti,omap4-cm2", TI_OMAP4_CM2 }, + { "ti,omap4-scrm", TI_OMAP4_SCRM }, + { "ti,omap5-prm", TI_OMAP5_PRM }, + { "ti,omap5-cm-core-aon", TI_OMAP5_CM_CORE_AON }, + { "ti,omap5-scrm", TI_OMAP5_SCRM }, + { "ti,omap5-cm-core", TI_OMAP5_CM_CORE }, + { "ti,dra7-prm", TI_DRA7_PRM }, + { "ti,dra7-cm-core-aon", TI_DRA7_CM_CORE_AON }, + { "ti,dra7-cm-core", TI_DRA7_CM_CORE }, + { "ti,dm814-prcm", TI_DM814_PRCM }, + { "ti,dm816-prcm", TI_DM816_PRCM }, + { NULL, TI_PRCM_END} }; static int @@ -124,56 +114,15 @@ if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) { + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); - } device_set_desc(dev, "TI Power and Clock Management"); - return(BUS_PROBE_DEFAULT); -} - -static int -ti_prcm_attach(device_t dev) -{ - struct ti_prcm_softc *sc; - phandle_t node, child; - int rid; - - sc = device_get_softc(dev); - sc->dev = dev; - - node = ofw_bus_get_node(sc->dev); - simplebus_init(sc->dev, node); - - if (simplebus_fill_ranges(node, &sc->sc_simplebus) < 0) { - device_printf(sc->dev, "could not get ranges\n"); - return (ENXIO); - } - if (sc->sc_simplebus.nranges == 0) { - device_printf(sc->dev, "nranges == 0\n"); - return (ENXIO); - } - - sc->mem_res = bus_alloc_resource(sc->dev, SYS_RES_MEMORY, &rid, - sc->sc_simplebus.ranges[0].host, - (sc->sc_simplebus.ranges[0].host + - sc->sc_simplebus.ranges[0].size - 1), - sc->sc_simplebus.ranges[0].size, - RF_ACTIVE | RF_SHAREABLE); - - if (sc->mem_res == NULL) { - return (ENXIO); - } + if (bootverbose == 0) + device_quiet(dev); - sc->bst = rman_get_bustag(sc->mem_res); - sc->bsh = rman_get_bushandle(sc->mem_res); - - mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF); - - /* Fixme: for xxx_prcm_reset functions. - * Get rid of global variables? - */ - ti_prcm_sc = sc; + /* Setup reset handler */ + ti_prcm_dev = dev; switch(ti_chip()) { #ifdef SOC_OMAP4 @@ -188,32 +137,26 @@ #endif } - bus_generic_probe(sc->dev); - for (child = OF_child(node); child != 0; child = OF_peer(child)) { - simplebus_add_device(dev, child, 0, NULL, -1, NULL); - } - - return (bus_generic_attach(sc->dev)); + return (BUS_PROBE_DEFAULT); } int ti_prcm_write_4(device_t dev, bus_addr_t addr, uint32_t val) { - struct ti_prcm_softc *sc; + struct syscon_generic_softc *sc; sc = device_get_softc(dev); - DPRINTF(sc->dev, "offset=%lx write %x\n", addr, val); - bus_space_write_4(sc->bst, sc->bsh, addr, val); - return (0); + DPRINTF(sc->dev, "ti_prcm_write_4: offset=%lx write %x\n", addr, val); + return (SYSCON_UNLOCKED_WRITE_4(sc->syscon, addr, val)); } + int ti_prcm_read_4(device_t dev, bus_addr_t addr, uint32_t *val) { - struct ti_prcm_softc *sc; + struct syscon_generic_softc *sc; sc = device_get_softc(dev); - - *val = bus_space_read_4(sc->bst, sc->bsh, addr); + *val = SYSCON_UNLOCKED_READ_4(sc->syscon, addr); DPRINTF(sc->dev, "offset=%lx Read %x\n", addr, *val); return (0); } @@ -221,41 +164,53 @@ int ti_prcm_modify_4(device_t dev, bus_addr_t addr, uint32_t clr, uint32_t set) { - struct ti_prcm_softc *sc; - uint32_t reg; + struct syscon_generic_softc *sc; sc = device_get_softc(dev); - - reg = bus_space_read_4(sc->bst, sc->bsh, addr); - reg &= ~clr; - reg |= set; - bus_space_write_4(sc->bst, sc->bsh, addr, reg); - DPRINTF(sc->dev, "offset=%lx reg: %x (clr %x set %x)\n", addr, reg, clr, set); - - return (0); + DPRINTF(sc->dev, "ti_prcm_modify_4: addr %x clear_mask %x set_mask %x\n", + addr, clr, set); + return (SYSCON_UNLOCKED_MODIFY_4(sc->syscon, addr, clr, + set)); } void ti_prcm_device_lock(device_t dev) { - struct ti_prcm_softc *sc; + struct syscon_generic_softc *sc; sc = device_get_softc(dev); - mtx_lock(&sc->mtx); + DPRINTF(sc->dev, "ti_prcm_device_lock\n"); + SYSCON_DEVICE_LOCK(sc->syscon->pdev); } void ti_prcm_device_unlock(device_t dev) { - struct ti_prcm_softc *sc; + struct syscon_generic_softc *sc; + + sc = device_get_softc(dev); + DPRINTF(sc->dev, "ti_prcm_device_unlock\n"); + SYSCON_DEVICE_UNLOCK(sc->syscon->pdev); +} + +static int +ti_prcm_get_handle(device_t dev, struct syscon **syscon) +{ + struct syscon_generic_softc *sc; sc = device_get_softc(dev); - mtx_unlock(&sc->mtx); + *syscon = sc->syscon; + if (*syscon == NULL) + return (ENODEV); + return (0); } static device_method_t ti_prcm_methods[] = { + /* Device interface */ DEVMETHOD(device_probe, ti_prcm_probe), - DEVMETHOD(device_attach, ti_prcm_attach), + + /* Syscon */ + DEVMETHOD(syscon_get_handle, ti_prcm_get_handle), /* clkdev interface */ DEVMETHOD(clkdev_write_4, ti_prcm_write_4), @@ -268,13 +223,13 @@ }; DEFINE_CLASS_1(ti_prcm, ti_prcm_driver, ti_prcm_methods, - sizeof(struct ti_prcm_softc), simplebus_driver); + sizeof(struct syscon_generic_softc), syscon_generic_driver); -EARLY_DRIVER_MODULE(ti_prcm, ofwbus, ti_prcm_driver, 0, 0, BUS_PASS_BUS); EARLY_DRIVER_MODULE(ti_prcm, simplebus, ti_prcm_driver, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE); + MODULE_VERSION(ti_prcm, 1); -MODULE_DEPEND(ti_prcm, ti_scm, 1, 1, 1); +MODULE_DEPEND(ti_prcm, syscon_generic_dev, 1, 1, 1); /* From sys/arm/ti/am335x/am335x_prcm.c * Copyright (c) 2012 Damjan Marion @@ -285,7 +240,9 @@ static void am335x_prcm_reset(void) { - ti_prcm_write_4(ti_prcm_sc->dev, AM335x_PRM_RSTCTRL, (1<<1)); + ti_prcm_device_lock(ti_prcm_dev); + ti_prcm_write_4(ti_prcm_dev, AM335x_PRM_RSTCTRL, (1<<1)); + ti_prcm_device_unlock(ti_prcm_dev); } /* FIXME: Is this correct - or should the license part be ontop? */ @@ -329,8 +286,10 @@ { uint32_t reg; - ti_prcm_read_4(ti_prcm_sc->dev, PRM_RSTCTRL, ®); + ti_prcm_device_lock(ti_prcm_dev); + ti_prcm_read_4(ti_prcm_dev, PRM_RSTCTRL, ®); reg = reg | PRM_RSTCTRL_RESET; - ti_prcm_write_4(ti_prcm_sc->dev, PRM_RSTCTRL, reg); - ti_prcm_read_4(ti_prcm_sc->dev, PRM_RSTCTRL, ®); + ti_prcm_write_4(ti_prcm_dev, PRM_RSTCTRL, reg); + ti_prcm_read_4(ti_prcm_dev, PRM_RSTCTRL, ®); + ti_prcm_device_unlock(ti_prcm_dev); } diff --git a/sys/arm/ti/ti_prm.c b/sys/arm/ti/ti_prm.c --- a/sys/arm/ti/ti_prm.c +++ b/sys/arm/ti/ti_prm.c @@ -37,9 +37,12 @@ #include +#include #include #include +#include "syscon_if.h" + #if 0 #define DPRINTF(dev, msg...) device_printf(dev, msg) #else @@ -53,6 +56,7 @@ device_t dev; uint8_t type; bool has_reset; + struct syscon *syscon; }; /* Device */ @@ -93,6 +97,10 @@ return (ENXIO); device_set_desc(dev, "TI OMAP Power Management"); + + if (bootverbose == 0) + device_quiet(dev); + return(BUS_PROBE_DEFAULT); } @@ -101,6 +109,7 @@ { struct ti_prm_softc *sc; phandle_t node; + int err; sc = device_get_softc(dev); sc->dev = dev; @@ -108,9 +117,13 @@ node = ofw_bus_get_node(sc->dev); - if (OF_hasprop(node, "#reset-cells")) { + err = SYSCON_GET_HANDLE(dev, &sc->syscon); + if (err != 0) + panic("Cannot get syscon handle.\n"); + + if (OF_hasprop(node, "#reset-cells") == 1) sc->has_reset = true; - } else + else sc->has_reset = false; /* Make device visible for other drivers */ @@ -134,50 +147,9 @@ if (sc->has_reset == false) return 1; - err = ti_prm_modify_4(dev, TI_PRM_PER_RSTCTRL, 0x2, 0x00); - return (err); -} - -int -ti_prm_write_4(device_t dev, bus_addr_t addr, uint32_t val) -{ - device_t parent; + err = SYSCON_MODIFY_4(sc->syscon, TI_PRM_PER_RSTCTRL, 0x2, 0x00); - parent = device_get_parent(dev); - DPRINTF(dev, "offset=%lx write %x\n", addr, val); - ti_prcm_device_lock(parent); - ti_prcm_write_4(parent, addr, val); - ti_prcm_device_unlock(parent); - return (0); -} - -int -ti_prm_read_4(device_t dev, bus_addr_t addr, uint32_t *val) -{ - device_t parent; - - parent = device_get_parent(dev); - - ti_prcm_device_lock(parent); - ti_prcm_read_4(parent, addr, val); - ti_prcm_device_unlock(parent); - DPRINTF(dev, "offset=%lx Read %x\n", addr, *val); - return (0); -} - -int -ti_prm_modify_4(device_t dev, bus_addr_t addr, uint32_t clr, uint32_t set) -{ - device_t parent; - - parent = device_get_parent(dev); - - ti_prcm_device_lock(parent); - ti_prcm_modify_4(parent, addr, clr, set); - ti_prcm_device_unlock(parent); - DPRINTF(dev, "offset=%lx (clr %x set %x)\n", addr, clr, set); - - return (0); + return (err); } static device_method_t ti_prm_methods[] = { diff --git a/sys/arm/ti/ti_scm_syscon.c b/sys/arm/ti/ti_scm_syscon.c --- a/sys/arm/ti/ti_scm_syscon.c +++ b/sys/arm/ti/ti_scm_syscon.c @@ -27,177 +27,61 @@ /* Based on sys/arm/ti/ti_sysc.c */ #include -#include +#include #include #include -#include -#include -#include -#include #include - -#include -#include - -#include +#include #include #include #include -#include "syscon_if.h" #include -#include "clkdev_if.h" - +#include #include +#include "syscon_if.h" + #if 0 #define DPRINTF(dev, msg...) device_printf(dev, msg) #else #define DPRINTF(dev, msg...) #endif -MALLOC_DECLARE(M_SYSCON); - -struct ti_scm_syscon_softc { - struct simplebus_softc sc_simplebus; - device_t dev; - struct syscon * syscon; - struct resource * res[1]; - bus_space_tag_t bst; - bus_space_handle_t bsh; - struct mtx mtx; -}; - -static struct resource_spec ti_scm_syscon_res_spec[] = { - { SYS_RES_MEMORY, 0, RF_ACTIVE | RF_SHAREABLE }, - { -1, 0 } -}; - -/* Device */ -static struct ofw_compat_data compat_data[] = { - { "syscon", 1 }, - { NULL, 0 } -}; - -/* --- dev/extres/syscon syscon_method_t interface --- */ -static int -ti_scm_syscon_write_4(struct syscon *syscon, bus_size_t offset, uint32_t val) -{ - struct ti_scm_syscon_softc *sc; - - sc = device_get_softc(syscon->pdev); - DPRINTF(sc->dev, "offset=%lx write %x\n", offset, val); - mtx_lock(&sc->mtx); - bus_space_write_4(sc->bst, sc->bsh, offset, val); - mtx_unlock(&sc->mtx); - return (0); -} - -static uint32_t -ti_scm_syscon_read_4(struct syscon *syscon, bus_size_t offset) -{ - struct ti_scm_syscon_softc *sc; - uint32_t val; - - sc = device_get_softc(syscon->pdev); - - mtx_lock(&sc->mtx); - val = bus_space_read_4(sc->bst, sc->bsh, offset); - mtx_unlock(&sc->mtx); - DPRINTF(sc->dev, "offset=%lx Read %x\n", offset, val); - return (val); -} -static int -ti_scm_syscon_modify_4(struct syscon *syscon, bus_size_t offset, uint32_t clr, uint32_t set) -{ - struct ti_scm_syscon_softc *sc; - uint32_t reg; - - sc = device_get_softc(syscon->pdev); - - mtx_lock(&sc->mtx); - reg = bus_space_read_4(sc->bst, sc->bsh, offset); - reg &= ~clr; - reg |= set; - bus_space_write_4(sc->bst, sc->bsh, offset, reg); - mtx_unlock(&sc->mtx); - DPRINTF(sc->dev, "offset=%lx reg: %x (clr %x set %x)\n", offset, reg, clr, set); - - return (0); -} - -static syscon_method_t ti_scm_syscon_reg_methods[] = { - SYSCONMETHOD(syscon_read_4, ti_scm_syscon_read_4), - SYSCONMETHOD(syscon_write_4, ti_scm_syscon_write_4), - SYSCONMETHOD(syscon_modify_4, ti_scm_syscon_modify_4), - - SYSCONMETHOD_END -}; - -DEFINE_CLASS_1(ti_scm_syscon_reg, ti_scm_syscon_reg_class, ti_scm_syscon_reg_methods, - 0, syscon_class); - /* device interface */ static int ti_scm_syscon_probe(device_t dev) { + const char *name; if (!ofw_bus_status_okay(dev)) return (ENXIO); if (!ti_soc_is_supported()) return (ENXIO); - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) - return (ENXIO); - - device_set_desc(dev, "TI OMAP Control Module Syscon"); - return(BUS_PROBE_DEFAULT); -} - -static int -ti_scm_syscon_attach(device_t dev) -{ - struct ti_scm_syscon_softc *sc; - phandle_t node, child; - - sc = device_get_softc(dev); - sc->dev = dev; - - if (bus_alloc_resources(dev, ti_scm_syscon_res_spec, sc->res)) { - device_printf(sc->dev, "Cant allocate resources\n"); + /* Need to be both "syscon" and "simple-bus" */ + if (ofw_bus_is_compatible(dev, "syscon") == 0 || + ofw_bus_is_compatible(dev, "simple-bus") == 0) return (ENXIO); - } - - sc->dev = dev; - sc->bst = rman_get_bustag(sc->res[0]); - sc->bsh = rman_get_bushandle(sc->res[0]); - mtx_init(&sc->mtx, device_get_nameunit(sc->dev), NULL, MTX_DEF); - node = ofw_bus_get_node(sc->dev); - - /* dev/extres/syscon interface */ - sc->syscon = syscon_create_ofw_node(dev, &ti_scm_syscon_reg_class, node); - if (sc->syscon == NULL) { - device_printf(dev, "Failed to create/register syscon\n"); + /* Require the node are named scm_conf@0 */ + name = ofw_bus_get_name(dev); + if (name == NULL || strcmp(name, "scm_conf@0") != 0) return (ENXIO); - } - simplebus_init(sc->dev, node); + device_set_desc(dev, "TI OMAP Control Module Syscon"); - bus_generic_probe(sc->dev); - for (child = OF_child(node); child != 0; child = OF_peer(child)) { - simplebus_add_device(sc->dev, child, 0, NULL, -1, NULL); - } + if (bootverbose == 0) + device_quiet(dev); - return (bus_generic_attach(sc->dev)); + return(BUS_PROBE_DEFAULT); } -/* syscon interface */ static int ti_scm_syscon_get_handle(device_t dev, struct syscon **syscon) { - struct ti_scm_syscon_softc *sc; + struct syscon_generic_softc *sc; sc = device_get_softc(dev); *syscon = sc->syscon; @@ -206,84 +90,17 @@ return (0); } -/* clkdev interface */ -static int -ti_scm_syscon_clk_write_4(device_t dev, bus_addr_t addr, uint32_t val) -{ - struct ti_scm_syscon_softc *sc; - - sc = device_get_softc(dev); - DPRINTF(sc->dev, "offset=%lx write %x\n", addr, val); - bus_space_write_4(sc->bst, sc->bsh, addr, val); - return (0); -} - -static int -ti_scm_syscon_clk_read_4(device_t dev, bus_addr_t addr, uint32_t *val) -{ - struct ti_scm_syscon_softc *sc; - - sc = device_get_softc(dev); - - *val = bus_space_read_4(sc->bst, sc->bsh, addr); - DPRINTF(sc->dev, "offset=%lx Read %x\n", addr, *val); - return (0); -} - -static int -ti_scm_syscon_clk_modify_4(device_t dev, bus_addr_t addr, uint32_t clr, uint32_t set) -{ - struct ti_scm_syscon_softc *sc; - uint32_t reg; - - sc = device_get_softc(dev); - - reg = bus_space_read_4(sc->bst, sc->bsh, addr); - reg &= ~clr; - reg |= set; - bus_space_write_4(sc->bst, sc->bsh, addr, reg); - DPRINTF(sc->dev, "offset=%lx reg: %x (clr %x set %x)\n", addr, reg, clr, set); - - return (0); -} - -static void -ti_scm_syscon_clk_device_lock(device_t dev) -{ - struct ti_scm_syscon_softc *sc; - - sc = device_get_softc(dev); - mtx_lock(&sc->mtx); -} - -static void -ti_scm_syscon_clk_device_unlock(device_t dev) -{ - struct ti_scm_syscon_softc *sc; - sc = device_get_softc(dev); - mtx_unlock(&sc->mtx); -} - static device_method_t ti_scm_syscon_methods[] = { DEVMETHOD(device_probe, ti_scm_syscon_probe), - DEVMETHOD(device_attach, ti_scm_syscon_attach), - - /* syscon interface */ DEVMETHOD(syscon_get_handle, ti_scm_syscon_get_handle), - /* clkdev interface */ - DEVMETHOD(clkdev_write_4, ti_scm_syscon_clk_write_4), - DEVMETHOD(clkdev_read_4, ti_scm_syscon_clk_read_4), - DEVMETHOD(clkdev_modify_4, ti_scm_syscon_clk_modify_4), - DEVMETHOD(clkdev_device_lock, ti_scm_syscon_clk_device_lock), - DEVMETHOD(clkdev_device_unlock, ti_scm_syscon_clk_device_unlock), - DEVMETHOD_END }; DEFINE_CLASS_1(ti_scm_syscon, ti_scm_syscon_driver, ti_scm_syscon_methods, - sizeof(struct ti_scm_syscon_softc), simplebus_driver); + sizeof(struct syscon_generic_softc), syscon_generic_driver); +/* ti_scm_syscon needs to attach "as soon as posible" due to it has clocks */ EARLY_DRIVER_MODULE(ti_scm_syscon, simplebus, ti_scm_syscon_driver, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE); MODULE_VERSION(ti_scm_syscon, 1);