Index: sys/arm/ti/clk/clock_common.h =================================================================== --- sys/arm/ti/clk/clock_common.h +++ sys/arm/ti/clk/clock_common.h @@ -30,14 +30,20 @@ #include __FBSDID("$FreeBSD$"); -struct clock_cell_info { - cell_t *clock_cells; - uint8_t *clock_cells_ncells; - uint32_t num_clock_cells; - uint8_t num_real_clocks; +struct parent_lookup_table { + const char *node_name; + int parent_cnt; + const char **parent_names; }; -void read_clock_cells(device_t dev, struct clock_cell_info *clk); -int find_parent_clock_names(device_t dev, struct clock_cell_info *clk, struct clknode_init_def *def); -void create_clkdef(device_t dev, struct clock_cell_info *clk, struct clknode_init_def *def); -void free_clkdef(struct clknode_init_def *def); +/* From rk3399_cru.c & rk_cru.c */ +#define PLIST(x) static const char *x[] + +#define LINK(_name) \ +{ \ + .clkdef.id = 0, \ + .clkdef.name = _name, \ + .clkdef.parent_names = NULL, \ + .clkdef.parent_cnt = 0, \ + .clkdef.flags = CLK_NODE_STATIC_STRINGS, \ +} Index: sys/arm/ti/clk/clock_common.c =================================================================== --- sys/arm/ti/clk/clock_common.c +++ sys/arm/ti/clk/clock_common.c @@ -1,152 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2020 Oskar Holmlund - * - * 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. - * - * $FreeBSD$ - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include "clock_common.h" - -#if 0 -#define DPRINTF(dev, msg...) device_printf(dev, msg) -#else -#define DPRINTF(dev, msg...) -#endif - -void -read_clock_cells(device_t dev, struct clock_cell_info *clk) { - ssize_t numbytes_clocks; - phandle_t node, parent, *cells; - int index, ncells, rv; - - node = ofw_bus_get_node(dev); - - /* Get names of parent clocks */ - numbytes_clocks = OF_getproplen(node, "clocks"); - clk->num_clock_cells = numbytes_clocks / sizeof(cell_t); - - /* Allocate space and get clock cells content */ - /* clock_cells / clock_cells_ncells will be freed in - * find_parent_clock_names() - */ - clk->clock_cells = malloc(numbytes_clocks, M_DEVBUF, M_WAITOK|M_ZERO); - clk->clock_cells_ncells = malloc(clk->num_clock_cells*sizeof(uint8_t), - M_DEVBUF, M_WAITOK|M_ZERO); - OF_getencprop(node, "clocks", clk->clock_cells, numbytes_clocks); - - /* Count number of clocks */ - clk->num_real_clocks = 0; - for (index = 0; index < clk->num_clock_cells; index++) { - rv = ofw_bus_parse_xref_list_alloc(node, "clocks", "#clock-cells", - clk->num_real_clocks, &parent, &ncells, &cells); - if (rv != 0) - continue; - - if (cells != NULL) - OF_prop_free(cells); - - clk->clock_cells_ncells[index] = ncells; - index += ncells; - clk->num_real_clocks++; - } -} - -int -find_parent_clock_names(device_t dev, struct clock_cell_info *clk, struct clknode_init_def *def) { - int index, clock_index, err; - bool found_all = true; - clk_t parent; - - /* Figure out names */ - for (index = 0, clock_index = 0; index < clk->num_clock_cells; index++) { - /* Get name of parent clock */ - err = clk_get_by_ofw_index(dev, 0, clock_index, &parent); - if (err != 0) { - clock_index++; - found_all = false; - DPRINTF(dev, "Failed to find clock_cells[%d]=0x%x\n", - index, clk->clock_cells[index]); - - index += clk->clock_cells_ncells[index]; - continue; - } - - def->parent_names[clock_index] = clk_get_name(parent); - clk_release(parent); - - DPRINTF(dev, "Found parent clock[%d/%d]: %s\n", - clock_index, clk->num_real_clocks, - def->parent_names[clock_index]); - - clock_index++; - index += clk->clock_cells_ncells[index]; - } - - if (!found_all) { - return 1; - } - - free(clk->clock_cells, M_DEVBUF); - free(clk->clock_cells_ncells, M_DEVBUF); - return 0; -} - -void -create_clkdef(device_t dev, struct clock_cell_info *clk, struct clknode_init_def *def) { - def->id = 1; - - clk_parse_ofw_clk_name(dev, ofw_bus_get_node(dev), &def->name); - - DPRINTF(dev, "node name: %s\n", def->name); - - def->parent_cnt = clk->num_real_clocks; - def->parent_names = malloc(clk->num_real_clocks*sizeof(char *), - M_OFWPROP, M_WAITOK); -} -void -free_clkdef(struct clknode_init_def *def) { - OF_prop_free(__DECONST(char *, def->name)); - OF_prop_free(def->parent_names); -} Index: sys/arm/ti/clk/ti_clk_clkctrl.c =================================================================== --- sys/arm/ti/clk/ti_clk_clkctrl.c +++ sys/arm/ti/clk/ti_clk_clkctrl.c @@ -41,7 +41,7 @@ #include "clkdev_if.h" -#if 0 +#if 1 #define DPRINTF(dev, msg...) device_printf(dev, msg) #else #define DPRINTF(dev, msg...) @@ -102,6 +102,7 @@ sc = clknode_get_softc(clk); + DEVICE_LOCK(clk); READ4(clk, sc->register_offset, &val); DPRINTF(sc->dev, "val(%x) & (%x | %x = %x)\n", val, GPIO_X_GDBCLK_MASK, MODULEMODE_MASK, @@ -129,6 +130,8 @@ DELAY(10); timeout--; } + DEVICE_UNLOCK(clk); + if (timeout == 0) { device_printf(sc->dev, "ti_clkctrl_set_gdbclk_gate: Timeout\n"); return (1); @@ -151,7 +154,7 @@ err = ti_clkctrl_set_gdbclk_gate(clk, enable); return (err); } - + DEVICE_LOCK(clk); READ4(clk, sc->register_offset, &val); if (enable) @@ -175,6 +178,7 @@ timeout--; } + DEVICE_UNLOCK(clk); if (timeout == 0) { device_printf(sc->dev, "ti_clkctrl_set_gate: Timeout\n"); return (1); Index: sys/arm/ti/clk/ti_divider_clock.c =================================================================== --- sys/arm/ti/clk/ti_divider_clock.c +++ sys/arm/ti/clk/ti_divider_clock.c @@ -42,12 +42,16 @@ #include #include +#include #include #include #include "clock_common.h" -#if 0 +#include "clkdev_if.h" +#include "syscon_if.h" + +#if 1 #define DPRINTF(dev, msg...) device_printf(dev, msg) #else #define DPRINTF(dev, msg...) @@ -60,11 +64,10 @@ struct ti_divider_softc { device_t sc_dev; - bool attach_done; struct clk_div_def div_def; - struct clock_cell_info clock_cell; struct clkdom *clkdom; + struct syscon *syscon; }; static int ti_divider_probe(device_t dev); @@ -81,7 +84,87 @@ { NULL, TI_DIVIDER_END } }; +PLIST(dpll_core_m4_ck_parent) = { "dpll_core_x2_ck" }; +PLIST(dpll_core_m5_ck_parent) = { "dpll_core_x2_ck" }; +PLIST(dpll_core_m6_ck_parent) = { "dpll_core_x2_ck" }; +PLIST(dpll_mpu_m2_ck_parent) = { "dpll_mpu_ck@488" }; +PLIST(dpll_ddr_m2_ck_parent) = { "dpll_ddr_ck@494" }; +PLIST(dpll_disp_m2_ck_parent) = { "dpll_disp_ck@498" }; +PLIST(dpll_per_m2_ck_parent) = { "dpll_per_ck@48c" }; +PLIST(gfx_fck_div_ck_parent) = { "gfx_fclk_clksel_ck@52c" }; +PLIST(clkout2_div_ck_parent) = { "sysclkout_pre_ck@700" }; + + +static struct parent_lookup_table div_parent_table[] = { + { "dpll_core_m4_ck@480", nitems(dpll_core_m4_ck_parent), dpll_core_m4_ck_parent }, + { "dpll_core_m5_ck@484", nitems(dpll_core_m5_ck_parent), dpll_core_m5_ck_parent }, + { "dpll_core_m6_ck@4d8", nitems(dpll_core_m6_ck_parent), dpll_core_m6_ck_parent }, + { "dpll_mpu_m2_ck@4a8", nitems(dpll_mpu_m2_ck_parent), dpll_mpu_m2_ck_parent }, + { "dpll_ddr_m2_ck@4a0", nitems(dpll_ddr_m2_ck_parent), dpll_ddr_m2_ck_parent }, + { "dpll_disp_m2_ck@4a4", nitems(dpll_disp_m2_ck_parent), dpll_disp_m2_ck_parent }, + { "dpll_per_m2_ck@4ac", nitems(dpll_per_m2_ck_parent), dpll_per_m2_ck_parent }, + { "gfx_fck_div_ck@52c", nitems(gfx_fck_div_ck_parent), gfx_fck_div_ck_parent }, + { "clkout2_div_ck@700", nitems(clkout2_div_ck_parent), clkout2_div_ck_parent }, +}; + + static int +ti_divider_clkdev_write_4(device_t dev, bus_addr_t addr, uint32_t val) +{ + struct ti_divider_softc *sc; + + sc = device_get_softc(dev); +DPRINTF(sc->sc_dev, "ti_divider_clkdev_write_4: addr %x val %x\n", addr, val); + return (SYSCON_UNLOCKED_WRITE_4(sc->syscon, addr, val)); +} + +static int +ti_divider_clkdev_read_4(device_t dev, bus_addr_t addr, uint32_t *val) +{ + struct ti_divider_softc *sc; + uint32_t rdval; + + sc = device_get_softc(dev); + + rdval = SYSCON_UNLOCKED_READ_4(sc->syscon, addr); + *val = rdval; +DPRINTF(sc->sc_dev, "ti_divider_clkdev_read_4: addr %x val %x\n", addr, *val); + return (0); +} + +static int +ti_divider_clkdev_modify_4(device_t dev, bus_addr_t addr, + uint32_t clear_mask, uint32_t set_mask) +{ + struct ti_divider_softc *sc; + + sc = device_get_softc(dev); +DPRINTF(sc->sc_dev, "ti_divider_clkdev_modify_4: addr %x clear %x set %x\n", addr, clear_mask, set_mask); + return (SYSCON_UNLOCKED_MODIFY_4(sc->syscon, addr, clear_mask, + set_mask)); +} + +static void +ti_divider_clkdev_device_lock(device_t dev) +{ + struct ti_divider_softc *sc; + + sc = device_get_softc(dev); +DPRINTF(sc->sc_dev, "ti_divider_clkdev_device_lock\n"); + SYSCON_DEVICE_LOCK(sc->syscon->pdev); +} + +static void +ti_divider_clkdev_device_unlock(device_t dev) +{ + struct ti_divider_softc *sc; + + sc = device_get_softc(dev); +DPRINTF(sc->sc_dev, "ti_divider_clkdev_device_unlock\n"); + SYSCON_DEVICE_UNLOCK(sc->syscon->pdev); +} + +static int register_clk(struct ti_divider_softc *sc) { int err; @@ -125,14 +208,25 @@ { struct ti_divider_softc *sc; phandle_t node; - int err; + int err, index; cell_t value; uint32_t ti_max_div; + const char *node_name; sc = device_get_softc(dev); sc->sc_dev = dev; node = ofw_bus_get_node(dev); + err = SYSCON_GET_HANDLE(dev, &sc->syscon); + if (err != 0) { + panic("Cannot get syscon handle.\n"); + } + + node_name = ofw_bus_get_name(dev); + if (node_name == NULL) { + panic("Cannot get name of the clock node"); + } + /* Grab the content of reg properties */ OF_getencprop(node, "reg", &value, sizeof(value)); sc->div_def.offset = value; @@ -178,30 +272,33 @@ DPRINTF(sc->sc_dev, "div_def.i_width %x\n", sc->div_def.i_width); - read_clock_cells(sc->sc_dev, &sc->clock_cell); + /* Fill clknode_init_def */ + ((struct clknode_init_def *)&sc->div_def.clkdef)->id = 1; + ((struct clknode_init_def *)&sc->div_def.clkdef)->flags = CLK_NODE_STATIC_STRINGS; - create_clkdef(sc->sc_dev, &sc->clock_cell, &sc->div_def.clkdef); + /* Find parent in lookup table */ + for (index = 0; index < nitems(div_parent_table); index++) { + if (strcmp(node_name, div_parent_table[index].node_name) == 0) { + device_printf(dev, "!!! Found %s in lookup table index %d\n", + node_name, index); - err = find_parent_clock_names(sc->sc_dev, &sc->clock_cell, &sc->div_def.clkdef); - - if (err) { - /* free_clkdef will be called in ti_divider_new_pass */ - DPRINTF(sc->sc_dev, "find_parent_clock_names failed\n"); - return (bus_generic_attach(sc->sc_dev)); + ((struct clknode_init_def *)&sc->div_def.clkdef)->name = div_parent_table[index].node_name; + ((struct clknode_init_def *)&sc->div_def.clkdef)->parent_cnt = div_parent_table[index].parent_cnt; + ((struct clknode_init_def *)&sc->div_def.clkdef)->parent_names = div_parent_table[index].parent_names; + break; + } } + if (index == nitems(div_parent_table)) + panic("Cant find clock %s\n", sc->div_def.clkdef.name); + err = register_clk(sc); - if (err) { - /* free_clkdef will be called in ti_divider_new_pass */ - DPRINTF(sc->sc_dev, "register_clk failed\n"); - return (bus_generic_attach(sc->sc_dev)); + if (err != 0) { + DPRINTF(sc->sc_dev, "Cannot register clock\n"); + return (ENXIO); } - sc->attach_done = true; - - free_clkdef(&sc->div_def.clkdef); - return (bus_generic_attach(sc->sc_dev)); } @@ -211,45 +308,18 @@ return (EBUSY); } -static void -ti_divider_new_pass(device_t dev) -{ - struct ti_divider_softc *sc; - int err; - - sc = device_get_softc(dev); - - if (sc->attach_done) { - return; - } - - err = find_parent_clock_names(sc->sc_dev, &sc->clock_cell, &sc->div_def.clkdef); - if (err) { - /* free_clkdef will be called in a later call to ti_divider_new_pass */ - DPRINTF(sc->sc_dev, "new_pass find_parent_clock_names failed\n"); - return; - } - - err = register_clk(sc); - if (err) { - /* free_clkdef will be called in a later call to ti_divider_new_pass */ - DPRINTF(sc->sc_dev, "new_pass register_clk failed\n"); - return; - } - - sc->attach_done = true; - - free_clkdef(&sc->div_def.clkdef); -} - static device_method_t ti_divider_methods[] = { /* Device interface */ DEVMETHOD(device_probe, ti_divider_probe), DEVMETHOD(device_attach, ti_divider_attach), DEVMETHOD(device_detach, ti_divider_detach), - /* Bus interface */ - DEVMETHOD(bus_new_pass, ti_divider_new_pass), + /* Clock device interface */ + DEVMETHOD(clkdev_device_lock, ti_divider_clkdev_device_lock), + DEVMETHOD(clkdev_device_unlock, ti_divider_clkdev_device_unlock), + DEVMETHOD(clkdev_read_4, ti_divider_clkdev_read_4), + DEVMETHOD(clkdev_write_4, ti_divider_clkdev_write_4), + DEVMETHOD(clkdev_modify_4, ti_divider_clkdev_modify_4), DEVMETHOD_END }; Index: sys/arm/ti/clk/ti_dpll_clock.c =================================================================== --- sys/arm/ti/clk/ti_dpll_clock.c +++ sys/arm/ti/clk/ti_dpll_clock.c @@ -48,7 +48,7 @@ #include #include "clock_common.h" -#if 0 +#if 1 #define DPRINTF(dev, msg...) device_printf(dev, msg) #else #define DPRINTF(dev, msg...) @@ -63,10 +63,8 @@ device_t dev; uint8_t dpll_type; - bool attach_done; struct ti_clk_dpll_def dpll_def; - struct clock_cell_info clock_cell; struct clkdom *clkdom; }; @@ -114,6 +112,39 @@ { NULL, TI_DPLL_END } }; + +PLIST(dpll_core_ck_parent) = { "sys_clkin_ck@40", "sys_clkin_ck@40" }; +PLIST(dpll_core_x2_parent) = { "dpll_core_ck@490" }; + +PLIST(dpll_mpu_ck_parent) = { "sys_clkin_ck@40", "sys_clkin_ck@40" }; + +PLIST(dpll_ddr_ck_parent) = { "sys_clkin_ck@40", "sys_clkin_ck@40" }; +PLIST(dpll_ddr_m2_div2_ck_parent) = { "dpll_ddr_m2_ck@4a0" }; + +PLIST(dpll_disp_ck_parent) = { "sys_clkin_ck@40", "sys_clkin_ck@40" }; + +PLIST(dpll_per_ck_parent) = { "sys_clkin_ck@40", "sys_clkin_ck@40" }; + +PLIST(dpll_per_m2_div4_wkupdm_ck_parent) = { "dpll_per_m2_ck@4ac" }; +PLIST(dpll_per_m2_div4_ck_parent) = { "dpll_per_m2_ck@4ac" }; + +static struct parent_lookup_table dpll_parent_table[] = { + { "dpll_core_ck@490", nitems(dpll_core_ck_parent), dpll_core_ck_parent }, + { "dpll_core_x2_ck", nitems(dpll_core_x2_parent), dpll_core_x2_parent }, + + + { "dpll_mpu_ck@488", nitems(dpll_mpu_ck_parent), dpll_mpu_ck_parent }, + + { "dpll_ddr_ck@494", nitems(dpll_ddr_ck_parent), dpll_ddr_ck_parent }, + { "dpll_ddr_m2_div2_ck", nitems(dpll_ddr_m2_div2_ck_parent), dpll_ddr_m2_div2_ck_parent }, + + { "dpll_disp_ck@498", nitems(dpll_disp_ck_parent), dpll_disp_ck_parent }, + + { "dpll_per_ck@48c", nitems(dpll_per_ck_parent), dpll_per_ck_parent }, + { "dpll_per_m2_div4_wkupdm_ck", nitems(dpll_per_m2_div4_wkupdm_ck_parent), dpll_per_m2_div4_wkupdm_ck_parent }, + { "dpll_per_m2_div4_ck", nitems(dpll_per_m2_div4_ck_parent), dpll_per_m2_div4_ck_parent }, +}; + static int register_clk(struct ti_dpll_softc *sc) { int err; @@ -261,9 +292,10 @@ static int ti_dpll_attach(device_t dev) { - struct ti_dpll_softc *sc; - phandle_t node; - int err; + struct ti_dpll_softc *sc; + phandle_t node; + int err, index; + const char *node_name; sc = device_get_softc(dev); sc->dev = dev; @@ -271,6 +303,11 @@ sc->dpll_type = ofw_bus_search_compatible(dev, compat_data)->ocd_data; node = ofw_bus_get_node(dev); + node_name = ofw_bus_get_name(dev); + if (node_name == NULL) { + panic("Cannot get name of the clock node"); + } + /* Grab the content of reg properties */ parse_dpll_reg(sc); @@ -287,31 +324,33 @@ sc->dpll_def.ti_clkmode_flags |= LOCK_MODE_FLAG; } - read_clock_cells(sc->dev, &sc->clock_cell); + /* Fill clknode_init_def */ + ((struct clknode_init_def *)&sc->dpll_def.clkdef)->id = 1; - create_clkdef(sc->dev, &sc->clock_cell, &sc->dpll_def.clkdef); + /* Find parent in lookup table */ + for (index = 0; index < nitems(dpll_parent_table); index++) { + if (strcmp(node_name, dpll_parent_table[index].node_name) == 0) { + device_printf(dev, "!!! Found %s in lookup table index %d\n", + node_name, index); - err = find_parent_clock_names(sc->dev, &sc->clock_cell, - &sc->dpll_def.clkdef); - - if (err) { - /* free_clkdef will be called in ti_dpll_new_pass */ - DPRINTF(sc->dev, "find_parent_clock_names failed\n"); - return (bus_generic_attach(sc->dev)); + ((struct clknode_init_def *)&sc->dpll_def.clkdef)->name = dpll_parent_table[index].node_name; + ((struct clknode_init_def *)&sc->dpll_def.clkdef)->parent_cnt = dpll_parent_table[index].parent_cnt; + ((struct clknode_init_def *)&sc->dpll_def.clkdef)->parent_names = dpll_parent_table[index].parent_names; + ((struct clknode_init_def *)&sc->dpll_def.clkdef)->flags = CLK_NODE_STATIC_STRINGS; + break; + } } + if (index == nitems(dpll_parent_table)) + panic("Cant find clock %s\n", sc->dpll_def.clkdef.name); + err = register_clk(sc); if (err) { - /* free_clkdef will be called in ti_dpll_new_pass */ DPRINTF(sc->dev, "register_clk failed\n"); return (bus_generic_attach(sc->dev)); } - sc->attach_done = true; - - free_clkdef(&sc->dpll_def.clkdef); - return (bus_generic_attach(sc->dev)); } @@ -321,46 +360,11 @@ return (EBUSY); } -static void -ti_dpll_new_pass(device_t dev) -{ - struct ti_dpll_softc *sc; - int err; - - sc = device_get_softc(dev); - - if (sc->attach_done) { - return; - } - - err = find_parent_clock_names(sc->dev, &sc->clock_cell, - &sc->dpll_def.clkdef); - if (err) { - /* free_clkdef will be called in a later call to ti_dpll_new_pass */ - DPRINTF(sc->dev, - "new_pass find_parent_clock_names failed\n"); - return; - } - - err = register_clk(sc); - if (err) { - /* free_clkdef will be called in a later call to ti_dpll_new_pass */ - DPRINTF(sc->dev, "new_pass register_clk failed\n"); - return; - } - - sc->attach_done = true; - free_clkdef(&sc->dpll_def.clkdef); -} - static device_method_t ti_dpll_methods[] = { /* Device interface */ DEVMETHOD(device_probe, ti_dpll_probe), DEVMETHOD(device_attach, ti_dpll_attach), DEVMETHOD(device_detach, ti_dpll_detach), - - /* Bus interface */ - DEVMETHOD(bus_new_pass, ti_dpll_new_pass), DEVMETHOD_END }; Index: sys/arm/ti/clk/ti_gate_clock.c =================================================================== --- sys/arm/ti/clk/ti_gate_clock.c +++ sys/arm/ti/clk/ti_gate_clock.c @@ -41,13 +41,16 @@ #include #include -#include #include #include +#include +#include #include "clock_common.h" +#include "clkdev_if.h" +#include "syscon_if.h" -#define DEBUG_GATE 0 +#define DEBUG_GATE 1 #if DEBUG_GATE #define DPRINTF(dev, msg...) device_printf(dev, msg) @@ -62,12 +65,11 @@ struct ti_gate_softc { device_t sc_dev; - bool attach_done; uint8_t sc_type; struct clk_gate_def gate_def; - struct clock_cell_info clock_cell; struct clkdom *clkdom; + struct syscon *syscon; }; static int ti_gate_probe(device_t dev); @@ -94,7 +96,81 @@ { NULL, TI_GATE_END } }; +PLIST(ehrpwm0_tbclk_parent) = { "l4ls_gclk" }; +PLIST(ehrpwm1_tbclk_parent) = { "l4ls_gclk" }; +PLIST(ehrpwm2_tbclk_parent) = { "l4ls_gclk" }; +PLIST(mmu_fck_parent) = { "dpll_core_m4_ck@480" }; +PLIST(usbotg_fck_parent) = { "dpll_per_ck@48c" }; +PLIST(ieee5000_fck_parent) = { "dpll_core_m4_div2_ck" }; +PLIST(clkout2_ck_parent) = { "clkout2_div_ck@700" }; + + +static struct parent_lookup_table gate_parent_table[] = { + { "ehrpwm0_tbclk@44e10664", nitems(ehrpwm0_tbclk_parent), ehrpwm0_tbclk_parent }, + { "ehrpwm1_tbclk@44e10664", nitems(ehrpwm1_tbclk_parent), ehrpwm1_tbclk_parent }, + { "ehrpwm2_tbclk@44e10664", nitems(ehrpwm2_tbclk_parent), ehrpwm2_tbclk_parent }, + { "mmu_fck@914", nitems(mmu_fck_parent), mmu_fck_parent }, + { "usbotg_fck@47c", nitems(usbotg_fck_parent), usbotg_fck_parent }, + { "ieee5000_fck@e4", nitems(ieee5000_fck_parent), ieee5000_fck_parent }, + { "clkout2_ck@700", nitems(clkout2_ck_parent), clkout2_ck_parent }, +}; + + static int +ti_gate_clkdev_write_4(device_t dev, bus_addr_t addr, uint32_t val) +{ + struct ti_gate_softc *sc; + + sc = device_get_softc(dev); +DPRINTF(sc->sc_dev, "gate_clkdev_write_4: addr %x val %x\n", addr, val); + return (SYSCON_UNLOCKED_WRITE_4(sc->syscon, addr, val)); +} + +static int +ti_gate_clkdev_read_4(device_t dev, bus_addr_t addr, uint32_t *val) +{ + struct ti_gate_softc *sc; + + sc = device_get_softc(dev); + + *val = SYSCON_UNLOCKED_READ_4(sc->syscon, addr); +DPRINTF(sc->sc_dev, "gate_clkdev_write_4: addr %x val %x\n", addr, *val); + return (0); +} + +static int +ti_gate_clkdev_modify_4(device_t dev, bus_addr_t addr, + uint32_t clear_mask, uint32_t set_mask) +{ + struct ti_gate_softc *sc; + + sc = device_get_softc(dev); +DPRINTF(sc->sc_dev, "clkdev_modify_4: addr %x clear_mask %x set_mask %x\n", addr, clear_mask, set_mask); + return (SYSCON_UNLOCKED_MODIFY_4(sc->syscon, addr, clear_mask, + set_mask)); +} + +static void +ti_gate_clkdev_device_lock(device_t dev) +{ + struct ti_gate_softc *sc; + + sc = device_get_softc(dev); +DPRINTF(sc->sc_dev, "ti_gate_clkdev_device_lock\n"); + SYSCON_DEVICE_LOCK(sc->syscon->pdev); +} + +static void +ti_gate_clkdev_device_unlock(device_t dev) +{ + struct ti_gate_softc *sc; + + sc = device_get_softc(dev); +DPRINTF(sc->sc_dev, "ti_gate_clkdev_device_unlock\n"); + SYSCON_DEVICE_UNLOCK(sc->syscon->pdev); +} + +static int ti_gate_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) @@ -111,6 +187,7 @@ static int register_clk(struct ti_gate_softc *sc) { int err; + sc->clkdom = clkdom_create(sc->sc_dev); if (sc->clkdom == NULL) { DPRINTF(sc->sc_dev, "Failed to create clkdom\n"); @@ -136,14 +213,26 @@ ti_gate_attach(device_t dev) { struct ti_gate_softc *sc; - phandle_t node; - int err; - cell_t value; + phandle_t node; + int err, index; + cell_t value; + const char *node_name; sc = device_get_softc(dev); sc->sc_dev = dev; node = ofw_bus_get_node(dev); + /* Get syscon */ + err = SYSCON_GET_HANDLE(dev, &sc->syscon); + if (err != 0) { + panic("Cannot get syscon handle.\n"); + } + + node_name = ofw_bus_get_name(dev); + if (node_name == NULL) { + panic("Cannot get name of the clock node"); + } + /* Get the compatible type */ sc->sc_type = ofw_bus_search_compatible(dev, compat_data)->ocd_data; @@ -153,6 +242,7 @@ sc->gate_def.offset = value; } #if DEBUG_GATE + /* MMEL this looks wrong - sc->gate_def.offset shoul be initialized */ else { DPRINTF(sc->sc_dev, "no reg (TI_CLKDM_GATE_CLOCK)\n"); } @@ -176,35 +266,40 @@ sc->gate_def.gate_flags = 0x0; - read_clock_cells(sc->sc_dev, &sc->clock_cell); + /* Fill clknode_init_def */ + ((struct clknode_init_def *)&sc->gate_def.clkdef)->id = 1; + ((struct clknode_init_def *)&sc->gate_def.clkdef)->flags = CLK_NODE_STATIC_STRINGS; - create_clkdef(sc->sc_dev, &sc->clock_cell, &sc->gate_def.clkdef); + /* Find parent in lookup table */ + for (index = 0; index < nitems(gate_parent_table); index++) { + if (strcmp(node_name, gate_parent_table[index].node_name) == 0) { + device_printf(dev, "!!! Found %s in lookup table index %d\n", + node_name, index); - /* Calculate mask */ - sc->gate_def.mask = (1 << fls(sc->clock_cell.num_real_clocks)) - 1; - DPRINTF(sc->sc_dev, "num_real_clocks %x gate_def.mask %x\n", - sc->clock_cell.num_real_clocks, sc->gate_def.mask); + ((struct clknode_init_def *)&sc->gate_def.clkdef)->name = gate_parent_table[index].node_name; + ((struct clknode_init_def *)&sc->gate_def.clkdef)->parent_cnt = gate_parent_table[index].parent_cnt; + ((struct clknode_init_def *)&sc->gate_def.clkdef)->parent_names = gate_parent_table[index].parent_names; + break; + } + } - err = find_parent_clock_names(sc->sc_dev, &sc->clock_cell, &sc->gate_def.clkdef); + if (index == nitems(gate_parent_table)) + panic("Cant find clock %s\n", sc->gate_def.clkdef.name); - if (err) { - /* free_clkdef will be called in ti_gate_new_pass */ - DPRINTF(sc->sc_dev, "find_parent_clock_names failed\n"); - return (bus_generic_attach(sc->sc_dev)); - } + /* Calculate mask */ + sc->gate_def.mask = (1 << fls(((struct clknode_init_def *)&sc->gate_def.clkdef)->parent_cnt)) - 1; + DPRINTF(sc->sc_dev, "num_real_clocks %x gate_def.mask %x\n", + ((struct clknode_init_def *)&sc->gate_def.clkdef)->parent_cnt, + sc->gate_def.mask); + err = register_clk(sc); - if (err) { - /* free_clkdef will be called in ti_gate_new_pass */ - DPRINTF(sc->sc_dev, "register_clk failed\n"); - return (bus_generic_attach(sc->sc_dev)); + if (err != 0) { + device_printf(sc->sc_dev, "Cannt register clock\n"); + return (ENXIO); } - sc->attach_done = true; - - free_clkdef(&sc->gate_def.clkdef); - return (bus_generic_attach(sc->sc_dev)); } @@ -214,44 +309,18 @@ return (EBUSY); } -static void -ti_gate_new_pass(device_t dev) { - struct ti_gate_softc *sc; - int err; - - sc = device_get_softc(dev); - - if (sc->attach_done) { - return; - } - - err = find_parent_clock_names(sc->sc_dev, &sc->clock_cell, &sc->gate_def.clkdef); - if (err) { - /* free_clkdef will be called in later call to ti_gate_new_pass */ - DPRINTF(sc->sc_dev, "new_pass find_parent_clock_names failed\n"); - return; - } - - err = register_clk(sc); - if (err) { - /* free_clkdef will be called in later call to ti_gate_new_pass */ - DPRINTF(sc->sc_dev, "new_pass register_clk failed\n"); - return; - } - - sc->attach_done = true; - - free_clkdef(&sc->gate_def.clkdef); -} - static device_method_t ti_gate_methods[] = { /* Device interface */ DEVMETHOD(device_probe, ti_gate_probe), DEVMETHOD(device_attach, ti_gate_attach), DEVMETHOD(device_detach, ti_gate_detach), - /* Bus interface */ - DEVMETHOD(bus_new_pass, ti_gate_new_pass), + /* Clock device interface */ + DEVMETHOD(clkdev_device_lock, ti_gate_clkdev_device_lock), + DEVMETHOD(clkdev_device_unlock, ti_gate_clkdev_device_unlock), + DEVMETHOD(clkdev_read_4, ti_gate_clkdev_read_4), + DEVMETHOD(clkdev_write_4, ti_gate_clkdev_write_4), + DEVMETHOD(clkdev_modify_4, ti_gate_clkdev_modify_4), DEVMETHOD_END }; Index: sys/arm/ti/clk/ti_mux_clock.c =================================================================== --- sys/arm/ti/clk/ti_mux_clock.c +++ sys/arm/ti/clk/ti_mux_clock.c @@ -44,17 +44,56 @@ #include #include +#include + #include #include #include "clock_common.h" +#include "clkdev_if.h" +#include "syscon_if.h" -#if 0 +#if 1 #define DPRINTF(dev, msg...) device_printf(dev, msg) #else #define DPRINTF(dev, msg...) #endif + +PLIST(sys_clkin_ck_parent) = { "virt_19200000_ck", "virt_24000000_ck", "virt_25000000_ck", "virt_26000000_ck" }; +PLIST(pruss_ocp_gclk_parent) = { "l3_gclk", "dpll_disp_m2_ck@4a4" }; +PLIST(timer1_fck_parent) = { "sys_clkin_ck@40", "clk-24mhz-clkctrl@14c_0", "tclkin_ck", "clk_rc32k_ck", "clk_32768_ck" }; +PLIST(timer2_fck_parent) = { "tclkin_ck", "sys_clkin_ck@40", "clk-24mhz-clkctrl@14c_0" }; +PLIST(timer3_fck_parent) = { "tclkin_ck", "sys_clkin_ck@40", "clk-24mhz-clkctrl@14c_0" }; +PLIST(timer4_fck_parent) = { "tclkin_ck", "sys_clkin_ck@40", "clk-24mhz-clkctrl@14c_0" }; +PLIST(timer5_fck_parent) = { "tclkin_ck", "sys_clkin_ck@40", "clk-24mhz-clkctrl@14c_0" }; +PLIST(timer6_fck_parent) = { "tclkin_ck", "sys_clkin_ck@40", "clk-24mhz-clkctrl@14c_0" }; +PLIST(timer7_fck_parent) = { "tclkin_ck", "sys_clkin_ck@40", "clk-24mhz-clkctrl@14c_0" }; +PLIST(wdt1_fck_parent) = { "clk_rc32k_ck", "clk-24mhz-clkctrl@14c_0" }; +PLIST(cpsw_cpts_tft_clk_parent) = { "dpll_core_m5_ck@484", "dpll_core_m4_ck@480" }; +PLIST(gpio0_dbclk_mux_ck_parent) = { "clk_rc32k_ck", "clk_32768_ck", "clk-24mhz-clkctrl@14c_0" }; +PLIST(lcd_gclk_parent) = { "dpll_disp_m2_ck@4a4", "dpll_core_m5_ck@484", "dpll_per_m2_ck@4ac" }; +PLIST(gfx_fclk_clksel_ck_parent) = { "dpll_core_m4_ck@480", "dpll_per_m2_ck@4ac" }; +PLIST(sysclkout_pre_ck_parent) = { "clk_32768_ck", "l3_gclk", "dpll_ddr_m2_ck@4a0", "dpll_per_m2_ck@4ac", "lcd_gclk@534" }; + +static struct parent_lookup_table mux_parent_table[] = { + { "sys_clkin_ck@40", nitems(sys_clkin_ck_parent), sys_clkin_ck_parent }, + { "pruss_ocp_gclk@530", nitems(pruss_ocp_gclk_parent), pruss_ocp_gclk_parent }, + { "timer1_fck@528", nitems(timer1_fck_parent), timer1_fck_parent }, + { "timer2_fck@508", nitems(timer2_fck_parent), timer2_fck_parent }, + { "timer3_fck@50c", nitems(timer3_fck_parent), timer3_fck_parent }, + { "timer4_fck@510", nitems(timer4_fck_parent), timer4_fck_parent }, + { "timer5_fck@518", nitems(timer5_fck_parent), timer5_fck_parent }, + { "timer6_fck@51c", nitems(timer6_fck_parent), timer6_fck_parent }, + { "timer7_fck@504", nitems(timer7_fck_parent), timer7_fck_parent }, + { "wdt1_fck@538", nitems(wdt1_fck_parent), wdt1_fck_parent }, + { "cpsw_cpts_rft_clk@520", nitems(cpsw_cpts_tft_clk_parent), cpsw_cpts_tft_clk_parent }, + { "gpio0_dbclk_mux_ck@53c", nitems(gpio0_dbclk_mux_ck_parent), gpio0_dbclk_mux_ck_parent }, + { "lcd_gclk@534", nitems(lcd_gclk_parent), lcd_gclk_parent }, + { "gfx_fclk_clksel_ck@52c", nitems(gfx_fclk_clksel_ck_parent), gfx_fclk_clksel_ck_parent }, + { "sysclkout_pre_ck@700", nitems(sysclkout_pre_ck_parent), sysclkout_pre_ck_parent }, +}; + /* * Devicetree description * Documentation/devicetree/bindings/clock/ti/mux.txt @@ -62,11 +101,10 @@ struct ti_mux_softc { device_t sc_dev; - bool attach_done; struct clk_mux_def mux_def; - struct clock_cell_info clock_cell; struct clkdom *clkdom; + struct syscon *syscon; }; static int ti_mux_probe(device_t dev); @@ -84,6 +122,63 @@ }; static int +ti_mux_clkdev_write_4(device_t dev, bus_addr_t addr, uint32_t val) +{ + struct ti_mux_softc *sc; + + sc = device_get_softc(dev); +DPRINTF(sc->sc_dev, "mux_clkdev_write_4: addr %x val %x\n", addr, val); + return (SYSCON_UNLOCKED_WRITE_4(sc->syscon, addr, val)); +} + +static int +ti_mux_clkdev_read_4(device_t dev, bus_addr_t addr, uint32_t *val) +{ + struct ti_mux_softc *sc; + uint32_t rdval; + + sc = device_get_softc(dev); + + rdval = SYSCON_UNLOCKED_READ_4(sc->syscon, addr); + *val = rdval; +DPRINTF(sc->sc_dev, "clkdev_read_4: addr %x val %x\n", addr, *val); + return (0); +} + +static int +ti_mux_clkdev_modify_4(device_t dev, bus_addr_t addr, + uint32_t clear_mask, uint32_t set_mask) +{ + struct ti_mux_softc *sc; + + sc = device_get_softc(dev); +DPRINTF(sc->sc_dev, "clkdev_modify_4: addr %x clear %x mask %x\n", addr, clear_mask, set_mask); + return (SYSCON_UNLOCKED_MODIFY_4(sc->syscon, addr, clear_mask, + set_mask)); +} + +static void +ti_mux_clkdev_device_lock(device_t dev) +{ + struct ti_mux_softc *sc; + + sc = device_get_softc(dev); +DPRINTF(sc->sc_dev, "ti_mux_clkdev_device_lock\n"); + SYSCON_DEVICE_LOCK(sc->syscon->pdev); +} + +static void +ti_mux_clkdev_device_unlock(device_t dev) +{ + struct ti_mux_softc *sc; + + sc = device_get_softc(dev); +DPRINTF(sc->sc_dev, "ti_mux_clkdev_device_unlock\n"); + SYSCON_DEVICE_UNLOCK(sc->syscon->pdev); +} + + +static int ti_mux_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) @@ -126,14 +221,25 @@ ti_mux_attach(device_t dev) { struct ti_mux_softc *sc; - phandle_t node; - int err; - cell_t value; + phandle_t node; + int err, index; + cell_t value; + const char *node_name; sc = device_get_softc(dev); sc->sc_dev = dev; node = ofw_bus_get_node(dev); + err = SYSCON_GET_HANDLE(device_get_parent(dev), &sc->syscon); + if (err != 0) { + panic("Cannot get syscon handle.\n"); + } + + node_name = ofw_bus_get_name(dev); + if (node_name == NULL) { + panic("Cannot get name of the clock node"); + } + /* Grab the content of reg properties */ OF_getencprop(node, "reg", &value, sizeof(value)); sc->mux_def.offset = value; @@ -154,73 +260,45 @@ if (OF_hasprop(node, "ti,latch-bit")) device_printf(sc->sc_dev, "ti,latch-bit - Not implemented\n"); - read_clock_cells(sc->sc_dev, &sc->clock_cell); + /* Fill clknode_init_def */ + ((struct clknode_init_def *)&sc->mux_def.clkdef)->id = 1; + ((struct clknode_init_def *)&sc->mux_def.clkdef)->flags = CLK_NODE_STATIC_STRINGS; - create_clkdef(sc->sc_dev, &sc->clock_cell, &sc->mux_def.clkdef); + /* Find parent in lookup table */ + for (index = 0; index < nitems(mux_parent_table); index++) { + if (strcmp(node_name, mux_parent_table[index].node_name) == 0) { + device_printf(dev, "!!! Found %s in lookup table index %d\n", + node_name, index); + + ((struct clknode_init_def *)&sc->mux_def.clkdef)->name = mux_parent_table[index].node_name; + ((struct clknode_init_def *)&sc->mux_def.clkdef)->parent_cnt = mux_parent_table[index].parent_cnt; + ((struct clknode_init_def *)&sc->mux_def.clkdef)->parent_names = mux_parent_table[index].parent_names; + break; + } + } + if (index == nitems(mux_parent_table)) + panic("Cant find clock %s\n", sc->mux_def.clkdef.name); + /* Figure out the width from ti_max_div */ if (sc->mux_def.mux_flags) - sc->mux_def.width = fls(sc->clock_cell.num_real_clocks-1); + sc->mux_def.width = fls(((struct clknode_init_def *)&sc->mux_def.clkdef)->parent_cnt-1); else - sc->mux_def.width = fls(sc->clock_cell.num_real_clocks); + sc->mux_def.width = fls(((struct clknode_init_def *)&sc->mux_def.clkdef)->parent_cnt); - DPRINTF(sc->sc_dev, "sc->clock_cell.num_real_clocks %x def.width %x\n", - sc->clock_cell.num_real_clocks, sc->mux_def.width); + DPRINTF(sc->sc_dev, "parents %x def.width %x\n", + ((struct clknode_init_def *)&sc->mux_def.clkdef)->parent_cnt, sc->mux_def.width); - err = find_parent_clock_names(sc->sc_dev, &sc->clock_cell, &sc->mux_def.clkdef); - - if (err) { - /* free_clkdef will be called in ti_mux_new_pass */ - DPRINTF(sc->sc_dev, "find_parent_clock_names failed\n"); - return (bus_generic_attach(sc->sc_dev)); - } - err = register_clk(sc); - if (err) { - /* free_clkdef will be called in ti_mux_new_pass */ - DPRINTF(sc->sc_dev, "register_clk failed\n"); - return (bus_generic_attach(sc->sc_dev)); + if (err != 0) { + DPRINTF(sc->sc_dev, "Cannot register clock\n"); + return (ENXIO); } - sc->attach_done = true; - - free_clkdef(&sc->mux_def.clkdef); - return (bus_generic_attach(sc->sc_dev)); } -static void -ti_mux_new_pass(device_t dev) -{ - struct ti_mux_softc *sc; - int err; - - sc = device_get_softc(dev); - - if (sc->attach_done) { - return; - } - - err = find_parent_clock_names(sc->sc_dev, &sc->clock_cell, &sc->mux_def.clkdef); - if (err) { - /* free_clkdef will be called in later call to ti_mux_new_pass */ - DPRINTF(sc->sc_dev, "ti_mux_new_pass find_parent_clock_names failed\n"); - return; - } - - err = register_clk(sc); - if (err) { - /* free_clkdef will be called in later call to ti_mux_new_pass */ - DPRINTF(sc->sc_dev, "ti_mux_new_pass register_clk failed\n"); - return; - } - - sc->attach_done = true; - - free_clkdef(&sc->mux_def.clkdef); -} - static int ti_mux_detach(device_t dev) { @@ -233,8 +311,12 @@ DEVMETHOD(device_attach, ti_mux_attach), DEVMETHOD(device_detach, ti_mux_detach), - /* Bus interface */ - DEVMETHOD(bus_new_pass, ti_mux_new_pass), + /* Clock device interface */ + DEVMETHOD(clkdev_device_lock, ti_mux_clkdev_device_lock), + DEVMETHOD(clkdev_device_unlock, ti_mux_clkdev_device_unlock), + DEVMETHOD(clkdev_read_4, ti_mux_clkdev_read_4), + DEVMETHOD(clkdev_write_4, ti_mux_clkdev_write_4), + DEVMETHOD(clkdev_modify_4, ti_mux_clkdev_modify_4), DEVMETHOD_END }; Index: sys/arm/ti/files.ti =================================================================== --- sys/arm/ti/files.ti +++ sys/arm/ti/files.ti @@ -5,7 +5,6 @@ arm/ti/ti_prcm.c standard arm/ti/ti_omap4_cm.c standard arm/ti/ti_scm.c standard -arm/ti/ti_scm_syscon.c standard arm/ti/ti_pinmux.c standard dev/mbox/mbox_if.m optional ti_mbox arm/ti/ti_mbox.c optional ti_mbox @@ -20,7 +19,6 @@ arm/ti/ti_spi.c optional ti_spi arm/ti/ti_sysc.c standard -arm/ti/clk/clock_common.c standard arm/ti/clk/ti_clk_clkctrl.c standard arm/ti/clk/ti_clkctrl.c standard arm/ti/clk/ti_clk_dpll.c standard Index: sys/arm/ti/ti_prcm.c =================================================================== --- sys/arm/ti/ti_prcm.c +++ sys/arm/ti/ti_prcm.c @@ -40,18 +40,14 @@ #include #include #include -#include +#include #include -#include -#include -#include #include -#include -#include #include #include #include +#include #include @@ -59,25 +55,26 @@ #include #include +#include +#include +#include +#include + +#include "syscon_if.h" #include "clkdev_if.h" -#if 0 +#if 1 #define DPRINTF(dev, msg...) device_printf(dev, msg) #else #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; + struct syscon_generic_softc *syscon_generic; + struct clkdom *clkdom; }; -static struct ti_prcm_softc *ti_prcm_sc = NULL; +//static struct ti_prcm_softc *ti_prcm_sc = NULL; static void omap4_prcm_reset(void); static void am335x_prcm_reset(void); @@ -123,63 +120,144 @@ { NULL, TI_PRCM_END} }; -static int -ti_prcm_probe(device_t dev) -{ - if (!ofw_bus_status_okay(dev)) - return (ENXIO); +static struct clk_link_def scm_clocks[] = { + LINK("sys_clkin_ck@40"), + LINK("adc_tsc_fck"), + LINK("dcan0_fck"), + LINK("dcan1_fck"), + LINK("mcasp0_fck"), + LINK("mcasp1_fck"), + LINK("smartreflex0_fck"), + LINK("smartreflex1_fck"), + LINK("sha0_fck"), + LINK("aes0_fck"), + LINK("rng_fck"), + LINK("ehrpwm0_tbclk@44e10664"), + LINK("ehrpwm1_tbclk@44e10664"), + LINK("ehrpwm2_tbclk@44e10664"), +}; - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) { - return (ENXIO); - } +static struct clk_link_def per_cm_0[] = { + LINK("l4ls-clkctrl@38_0"), + LINK("l4ls-clkctrl@38_4"), + LINK("l4ls-clkctrl@38_8"), + LINK("l4ls-clkctrl@38_c"), + LINK("l4ls-clkctrl@38_10"), + LINK("l4ls-clkctrl@38_14"), + LINK("l4ls-clkctrl@38_18"), + LINK("l4ls-clkctrl@38_1c"), + LINK("l4ls-clkctrl@38_20"), + LINK("l4ls-clkctrl@38_24"), + LINK("l4ls-clkctrl@38_28"), + LINK("l4ls-clkctrl@38_34"), + LINK("l4ls-clkctrl@38_38"), + LINK("l4ls-clkctrl@38_3c"), + LINK("l4ls-clkctrl@38_40"), + LINK("l4ls-clkctrl@38_44"), + LINK("l4ls-clkctrl@38_48"), + LINK("l4ls-clkctrl@38_4c"), + LINK("l4ls-clkctrl@38_50"), + LINK("l4ls-clkctrl@38_54"), + LINK("l4ls-clkctrl@38_58"), + LINK("l4ls-clkctrl@38_74"), + LINK("l4ls-clkctrl@38_75"), + LINK("l4ls-clkctrl@38_78"), + LINK("l4ls-clkctrl@38_79"), + LINK("l4ls-clkctrl@38_7c"), + LINK("l4ls-clkctrl@38_7d"), + LINK("l4ls-clkctrl@38_88"), + LINK("l4ls-clkctrl@38_8c"), + LINK("l4ls-clkctrl@38_90"), + LINK("l4ls-clkctrl@38_94"), + LINK("l4ls-clkctrl@38_98"), + LINK("l4ls-clkctrl@38_9c"), + LINK("l4ls-clkctrl@38_a0"), + LINK("l4ls-clkctrl@38_b4"), + LINK("l4ls-clkctrl@38_b8"), + LINK("l4ls-clkctrl@38_bc"), + LINK("l4ls-clkctrl@38_d4"), + LINK("l4ls-clkctrl@38_d8"), + LINK("l4ls-clkctrl@38_f8"), - device_set_desc(dev, "TI Power and Clock Management"); - return(BUS_PROBE_DEFAULT); -} + LINK("l3s-clkctrl@1c_0"), + LINK("l3s-clkctrl@1c_14"), + LINK("l3s-clkctrl@1c_18"), + LINK("l3s-clkctrl@1c_4c"), + LINK("l3s-clkctrl@1c_dc"), -static int -ti_prcm_attach(device_t dev) -{ - struct ti_prcm_softc *sc; - phandle_t node, child; - int rid; + LINK("l3-clkctrl@24_0"), + LINK("l3-clkctrl@24_4"), + LINK("l3-clkctrl@24_8"), + LINK("l3-clkctrl@24_70"), + LINK("l3-clkctrl@24_74"), + LINK("l3-clkctrl@24_78"), + LINK("l3-clkctrl@24_7c"), + LINK("l3-clkctrl@24_98"), + LINK("l3-clkctrl@24_bc"), + LINK("l3-clkctrl@24_d8"), + LINK("l3-clkctrl@24_dc"), - sc = device_get_softc(dev); - sc->dev = dev; + LINK("l4hs-clkctrl@120_0"), - node = ofw_bus_get_node(sc->dev); - simplebus_init(sc->dev, node); + LINK("pruss-ocp-clkctrl@e8_0"), - 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); - } + LINK("cpsw-125mhz-clkctrl@0_0"), + LINK("cpsw-125mhz-clkctrl@0_4"), + LINK("cpsw-125mhz-clkctrl@0_8"), + LINK("cpsw-125mhz-clkctrl@0_c"), + LINK("cpsw-125mhz-clkctrl@0_10"), + LINK("cpsw-125mhz-clkctrl@0_14"), - 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); + LINK("lcdc-clkctrl@18_0"), - if (sc->mem_res == NULL) { - return (ENXIO); - } + LINK("clk-24mhz-clkctrl@14c_0"), - sc->bst = rman_get_bustag(sc->mem_res); - sc->bsh = rman_get_bushandle(sc->mem_res); + LINK("l4-wkup-clkctrl@0_0"), + LINK("l4-wkup-clkctrl@0_4"), + LINK("l4-wkup-clkctrl@0_8"), + LINK("l4-wkup-clkctrl@0_9"), + LINK("l4-wkup-clkctrl@0_c"), + LINK("l4-wkup-clkctrl@0_b4"), + LINK("l4-wkup-clkctrl@0_b8"), + LINK("l4-wkup-clkctrl@0_bc"), + LINK("l4-wkup-clkctrl@0_c0"), + LINK("l4-wkup-clkctrl@0_c4"), + LINK("l4-wkup-clkctrl@0_c8"), + LINK("l4-wkup-clkctrl@0_cc"), + LINK("l4-wkup-clkctrl@0_d0"), + LINK("l4-wkup-clkctrl@0_d4"), - mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF); + LINK("l3-aon-clkctrl@14_0"), + LINK("l4-wkup-aon-clkctrl@b0_0"), - /* Fixme: for xxx_prcm_reset functions. - * Get rid of global variables? - */ - ti_prcm_sc = sc; + LINK("mpu-clkctrl@0_0"), + LINK("mpu-clkctrl@0_4"), + LINK("l4-rtc-clkctrl@0_0"), + + LINK("gfx-l3-clkctrl@0_0"), + LINK("gfx-l3-clkctrl@0_4"), + + LINK("l4-cefuse-clkctrl@0_0"), + LINK("l4-cefuse-clkctrl@0_4"), + LINK("l4-cefuse-clkctrl@0_8"), + LINK("l4-cefuse-clkctrl@0_c"), + LINK("l4-cefuse-clkctrl@0_10"), + LINK("l4-cefuse-clkctrl@0_14"), + LINK("l4-cefuse-clkctrl@0_18"), + LINK("l4-cefuse-clkctrl@0_1c"), + LINK("l4-cefuse-clkctrl@0_20"), +}; + +static int +ti_prcm_probe(device_t dev) +{ + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) + return (ENXIO); + switch(ti_chip()) { #ifdef SOC_OMAP4 case CHIP_OMAP_4: @@ -193,32 +271,65 @@ #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); + device_set_desc(dev, "TI Power and Clock Management"); + return (BUS_PROBE_DEFAULT); +} + +static int +ti_prcm_attach(device_t dev) { + int i, err, ret; + struct ti_prcm_softc *prcm_sc; + + + device_printf(dev, "ti_prcm_attach\n"); + prcm_sc = device_get_softc(dev); + + prcm_sc->clkdom = clkdom_create(dev); + if (prcm_sc->clkdom == NULL) + panic("Cannot create clkdom\n"); + + for (i = 0; i < nitems(scm_clocks); i++) { + err = clknode_link_register(prcm_sc->clkdom, + &scm_clocks[i]); + if (err != 0) + device_printf(dev, "Cant create clock link %s\n", + scm_clocks[i].clkdef.name); + } + for (i = 0; i < nitems(per_cm_0); i++) { + err = clknode_link_register(prcm_sc->clkdom, + &per_cm_0[i]); + if (err != 0) + device_printf(dev, "Cant create clock link %s\n", + per_cm_0[i].clkdef.name); + } - return (bus_generic_attach(sc->dev)); + if (clkdom_finit(prcm_sc->clkdom) != 0) + panic("cannot finalize clkdom initialization\n"); + + ret = syscon_generic_attach(dev); + return (ret); } 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); +DPRINTF(sc->dev, "ti_prcm_read_4: addr %x\n", addr); + + *val = SYSCON_UNLOCKED_READ_4(sc->syscon, addr); DPRINTF(sc->dev, "offset=%lx Read %x\n", addr, *val); return (0); } @@ -226,39 +337,40 @@ 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; +DPRINTF(dev, "ti_prcm_device_lock\n"); sc = device_get_softc(dev); - mtx_lock(&sc->mtx); + SYSCON_DEVICE_LOCK(sc->syscon->pdev); } void ti_prcm_device_unlock(device_t dev) { - struct ti_prcm_softc *sc; + struct syscon_generic_softc *sc; +DPRINTF(dev, "ti_prcm_device_unlock\n"); sc = device_get_softc(dev); - mtx_unlock(&sc->mtx); + + SYSCON_DEVICE_UNLOCK(sc->syscon->pdev); } static device_method_t ti_prcm_methods[] = { + /* syscon interface */ + //DEVMETHOD(syscon_get_handle, ti_prcm_syscon_get_handle), + + /* Device interface */ DEVMETHOD(device_probe, ti_prcm_probe), DEVMETHOD(device_attach, ti_prcm_attach), @@ -273,16 +385,18 @@ }; DEFINE_CLASS_1(ti_prcm, ti_prcm_driver, ti_prcm_methods, - sizeof(struct ti_prcm_softc), simplebus_driver); + sizeof(struct ti_prcm_softc), syscon_generic_driver); + //sizeof(struct syscon_generic_softc), syscon_generic_driver); static devclass_t ti_prcm_devclass; -EARLY_DRIVER_MODULE(ti_prcm, ofwbus, ti_prcm_driver, +EARLY_DRIVER_MODULE(ti_prcm, syscon_generic_dev, ti_prcm_driver, ti_prcm_devclass, 0, 0, BUS_PASS_BUS); EARLY_DRIVER_MODULE(ti_prcm, simplebus, ti_prcm_driver, ti_prcm_devclass, 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 @@ -293,7 +407,9 @@ static void am335x_prcm_reset(void) { +#if 0 ti_prcm_write_4(ti_prcm_sc->dev, AM335x_PRM_RSTCTRL, (1<<1)); +#endif } /* FIXME: Is this correct - or should the license part be ontop? */ @@ -335,10 +451,12 @@ static void omap4_prcm_reset(void) { +#if 0 uint32_t reg; ti_prcm_read_4(ti_prcm_sc->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, ®); +#endif } Index: sys/arm/ti/ti_prm.c =================================================================== --- sys/arm/ti/ti_prm.c +++ sys/arm/ti/ti_prm.c @@ -42,10 +42,13 @@ #include +#include #include #include -#if 0 +#include "syscon_if.h" + +#if 1 #define DPRINTF(dev, msg...) device_printf(dev, msg) #else #define DPRINTF(dev, msg...) @@ -58,6 +61,7 @@ device_t dev; uint8_t type; bool has_reset; + struct syscon *syscon; }; /* Device */ @@ -106,6 +110,7 @@ { struct ti_prm_softc *sc; phandle_t node; + int err; sc = device_get_softc(dev); sc->dev = dev; @@ -113,6 +118,12 @@ node = ofw_bus_get_node(sc->dev); + err = SYSCON_GET_HANDLE(dev, &sc->syscon); + if (err != 0) { + panic("Cannot get syscon handle.\n"); + return (ENXIO); + } + if (OF_hasprop(node, "#reset-cells")) { sc->has_reset = true; } else @@ -139,56 +150,9 @@ if (sc->has_reset == false) return 1; - err = ti_prm_modify_4(dev, TI_PRM_PER_RSTCTRL, 0x2, 0x00); - return (err); -} + err = SYSCON_MODIFY_4(sc->syscon, TI_PRM_PER_RSTCTRL, 0x2, 0x00); -int -ti_prm_write_4(device_t dev, bus_addr_t addr, uint32_t val) -{ - struct ti_prm_softc *sc; - device_t parent; - - parent = device_get_parent(dev); - sc = device_get_softc(dev); - DPRINTF(sc->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) -{ - struct ti_prm_softc *sc; - device_t parent; - - parent = device_get_parent(dev); - sc = device_get_softc(dev); - - ti_prcm_device_lock(parent); - ti_prcm_read_4(parent, addr, val); - ti_prcm_device_unlock(parent); - DPRINTF(sc->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) -{ - struct ti_prm_softc *sc; - device_t parent; - - parent = device_get_parent(dev); - sc = device_get_softc(dev); - - ti_prcm_device_lock(parent); - ti_prcm_modify_4(parent, addr, clr, set); - ti_prcm_device_unlock(parent); - DPRINTF(sc->dev, "offset=%lx (clr %x set %x)\n", addr, clr, set); - - return (0); + return (err); } static device_method_t ti_prm_methods[] = { Index: sys/arm/ti/ti_scm_syscon.c =================================================================== --- sys/arm/ti/ti_scm_syscon.c +++ sys/arm/ti/ti_scm_syscon.c @@ -1,298 +0,0 @@ -/*- - * Copyright (c) 2019 Emmanuel Vadot - * - * Copyright (c) 2020 Oskar Holmlund - * - * 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. - * - * $FreeBSD$ - */ -/* Based on sys/arm/ti/ti_sysc.c */ - -#include -__FBSDID("$FreeBSD$"); - -#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 - -#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) -{ - 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; - int err; - - 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"); - 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"); - return (ENXIO); - } - - simplebus_init(sc->dev, node); - - err = 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); - } - - return (bus_generic_attach(sc->dev)); -} - -/* syscon interface */ -static int -ti_scm_syscon_get_handle(device_t dev, struct syscon **syscon) -{ - struct ti_scm_syscon_softc *sc; - - sc = device_get_softc(dev); - *syscon = sc->syscon; - if (*syscon == NULL) - return (ENODEV); - 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); - -static devclass_t ti_scm_syscon_devclass; - -EARLY_DRIVER_MODULE(ti_scm_syscon, simplebus, ti_scm_syscon_driver, - ti_scm_syscon_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE); -MODULE_VERSION(ti_scm_syscon, 1); -MODULE_DEPEND(ti_scm_syscon, ti_scm, 1, 1, 1); Index: sys/arm/ti/ti_sysc.c =================================================================== --- sys/arm/ti/ti_sysc.c +++ sys/arm/ti/ti_sysc.c @@ -55,7 +55,7 @@ #include #include -#define DEBUG_SYSC 0 +#define DEBUG_SYSC 1 #if DEBUG_SYSC #define DPRINTF(dev, msg...) device_printf(dev, msg) @@ -112,6 +112,128 @@ { NULL, TI_SYSC_END } }; +PLIST(target_module_7000) = { "l4-wkup-clkctrl@0_8", "l4-wkup-clkctrl@0_9" }; /* gpio0 */ +PLIST(target_module_9000) = { "l4-wkup-clkctrl@0_b4" }; /* uart0 */ +PLIST(target_module_b000) = { "l4-wkup-clkctrl@0_b8" }; /* i2c1 */ +PLIST(target_module_d000) = { "l4-wkup-clkctrl@0_bc" }; /* adc_tsc */ +PLIST(target_module_31000) = { "l4-wkup-clkctrl@0_c4" }; /* timer1 */ +PLIST(target_module_35000) = { "l4-wkup-clkctrl@0_d4" }; /* timer2 */ + +PLIST(target_module_3e000) = { "l4-rtc-clkctrl@0_0" }; /* rtc */ + +PLIST(target_module_100000) = { "cpsw-125mhz-clkctrl@0_14" }; /* cpsw (ethernet) */ + +PLIST(target_module_300000) = { "pruss-ocp-clkctrl@e8_0" }; /* pru */ + +PLIST(target_module_22000) = { "l4ls-clkctrl@38_34" }; /* uart2 */ +PLIST(target_module_24000) = { "l4ls-clkctrl@38_38" }; /* uart3 */ +PLIST(target_module_2a000) = { "l4ls-clkctrl@38_10" }; /* i2c2 */ +PLIST(target_module_30000) = { "l4ls-clkctrl@38_14" }; /* spi0 */ + +PLIST(target_module_38000) = { "l3s-clkctrl@1c_18" }; /* mcasp0 */ +PLIST(target_module_3c000) = { "l3s-clkctrl@1c_4c" }; /* mcasp1 */ + +PLIST(target_module_40000) = { "l4ls-clkctrl@38_48" }; /* timer2 */ +PLIST(target_module_42000) = { "l4ls-clkctrl@38_4c" }; /* timer3 */ +PLIST(target_module_44000) = { "l4ls-clkctrl@38_50" }; /* timer4 */ +PLIST(target_module_46000) = { "l4ls-clkctrl@38_b4" }; /* timer5 */ +PLIST(target_module_48000) = { "l4ls-clkctrl@38_b8" }; /* timer6 */ +PLIST(target_module_4a000) = { "l4ls-clkctrl@38_44" }; /* timer7 */ +PLIST(target_module_4c000) = { "l4ls-clkctrl@38_74", "l4ls-clkctrl@38_75" }; /* gpio2 */ +PLIST(target_module_60000) = { "l4ls-clkctrl@38_4" }; /* mmc1 */ +PLIST(target_module_80000) = { "l4ls-clkctrl@38_8" }; /* elm */ +PLIST(target_module_c8000) = { "l4ls-clkctrl@38_d8" }; /* mailbox */ +PLIST(target_module_ca000) = { "l4ls-clkctrl@38_d4" }; /* spinlock */ +PLIST(target_module_9c000) = { "l4ls-clkctrl@38_c" }; /* i2c3 */ +PLIST(target_module_a0000) = { "l4ls-clkctrl@38_18" }; /* spi1 */ +PLIST(target_module_a6000) = { "l4ls-clkctrl@38_3c" }; /* uart4 */ +PLIST(target_module_a8000) = { "l4ls-clkctrl@38_40" }; /* uart5 */ +PLIST(target_module_aa000) = { "l4ls-clkctrl@38_0" }; /* uart6 */ +PLIST(target_module_ac000) = { "l4ls-clkctrl@38_78", "l4ls-clkctrl@38_79" }; /* gpio3 */ +PLIST(target_module_ae000) = { "l4ls-clkctrl@38_7c", "l4ls-clkctrl@38_7d" }; /* gpio4 */ +PLIST(target_module_cc000) = { "l4ls-clkctrl@38_88" }; /* dcan0 */ +PLIST(target_module_d0000) = { "l4ls-clkctrl@38_8c" }; /* dcan1 */ +PLIST(target_module_d8000) = { "l4ls-clkctrl@38_bc" }; /* mmc2 */ +PLIST(target_module_0) = { "l4ls-clkctrl@38_9c" }; /* epwmss0 */ +PLIST(target_module_2000) = { "l4ls-clkctrl@38_94" }; /* epwmss1 */ +PLIST(target_module_4000) = { "l4ls-clkctrl@38_a0" }; /* epwmss2 */ + +PLIST(target_module_e000) = { "lcdc-clkctrl@18_0" }; /* lcdc */ + +PLIST(target_module_10000) = { "l4ls-clkctrl@38_58" }; /* rng */ + +PLIST(target_module_49000000) = { "l3-clkctrl@24_98" }; /* tpcc */ +PLIST(target_module_49800000) = { "l3-clkctrl@24_0" }; /* tptco */ +PLIST(target_module_49900000) = { "l3-clkctrl@24_d8" }; /* tptc1 */ +PLIST(target_module_49a00000) = { "l3-clkctrl@24_dc" }; /* tptc2 */ +PLIST(target_module_47810000) = { "l3s-clkctrl@1c_dc" }; /* mmc3 */ +PLIST(target_module_47400000) = { "l3s-clkctrl@1c_0" }; /* usb otg hs */ +PLIST(target_module_53100000) = { "l3-clkctrl@24_7c" }; /* sham */ +PLIST(target_module_53500000) = { "l3-clkctrl@24_70" }; /* aes */ +PLIST(target_module_56000000) = { "gfx-l3-clkctrl@0_4" }; /* gfx */ + + +static struct parent_lookup_table sysc_clock_table[] = { + { "target-module@7000", nitems(target_module_7000), target_module_7000 }, + { "target-module@9000", nitems(target_module_9000), target_module_9000 }, + { "target-module@b000", nitems(target_module_b000), target_module_b000 }, + { "target-module@d000", nitems(target_module_d000), target_module_d000 }, + { "target-module@31000", nitems(target_module_31000), target_module_31000 }, + { "target-module@35000", nitems(target_module_35000), target_module_35000 }, + + { "target-module@3e000", nitems(target_module_3e000), target_module_3e000 }, + + { "target-module@100000", nitems(target_module_100000), target_module_100000 }, + { "target-module@300000", nitems(target_module_300000), target_module_300000 }, + + { "target-module@22000", nitems(target_module_22000), target_module_22000 }, + { "target-module@24000", nitems(target_module_24000), target_module_24000 }, + { "target-module@2a000", nitems(target_module_2a000), target_module_2a000 }, + { "target-module@30000", nitems(target_module_30000), target_module_30000 }, + + { "target-module@38000", nitems(target_module_38000), target_module_38000 }, + { "target-module@3c000", nitems(target_module_3c000), target_module_3c000 }, + + { "target-module@40000", nitems(target_module_40000), target_module_40000 }, + { "target-module@42000", nitems(target_module_42000), target_module_42000 }, + { "target-module@44000", nitems(target_module_44000), target_module_44000 }, + { "target-module@46000", nitems(target_module_46000), target_module_46000 }, + { "target-module@48000", nitems(target_module_48000), target_module_48000 }, + { "target-module@4a000", nitems(target_module_4a000), target_module_4a000 }, + { "target-module@4c000", nitems(target_module_4c000), target_module_4c000 }, + { "target-module@60000", nitems(target_module_60000), target_module_60000 }, + { "target-module@80000", nitems(target_module_80000), target_module_80000 }, + { "target-module@c8000", nitems(target_module_c8000), target_module_c8000 }, + { "target-module@ca000", nitems(target_module_ca000), target_module_ca000 }, + { "target-module@9c000", nitems(target_module_9c000), target_module_9c000 }, + { "target-module@a0000", nitems(target_module_a0000), target_module_a0000 }, + { "target-module@a6000", nitems(target_module_a6000), target_module_a6000 }, + { "target-module@a8000", nitems(target_module_a8000), target_module_a8000 }, + { "target-module@aa000", nitems(target_module_aa000), target_module_aa000 }, + { "target-module@ac000", nitems(target_module_ac000), target_module_ac000 }, + { "target-module@ae000", nitems(target_module_ae000), target_module_ae000 }, + { "target-module@cc000", nitems(target_module_cc000), target_module_cc000 }, + { "target-module@d0000", nitems(target_module_d0000), target_module_d0000 }, + { "target-module@d8000", nitems(target_module_d8000), target_module_d8000 }, + { "target-module@0", nitems(target_module_0), target_module_0 }, + { "target-module@2000", nitems(target_module_2000), target_module_2000 }, + { "target-module@4000", nitems(target_module_4000), target_module_4000 }, + + { "target-module@e000", nitems(target_module_e000), target_module_e000 }, + { "target-module@10000", nitems(target_module_10000), target_module_10000 }, + + { "target-module@49000000", nitems(target_module_49000000), target_module_49000000 }, + { "target-module@49800000", nitems(target_module_49800000), target_module_49800000 }, + { "target-module@49900000", nitems(target_module_49900000), target_module_49900000 }, + { "target-module@49a00000", nitems(target_module_49a00000), target_module_49a00000 }, + { "target-module@47810000", nitems(target_module_47810000), target_module_47810000 }, + { "target-module@47400000", nitems(target_module_47400000), target_module_47400000 }, + { "target-module@53100000", nitems(target_module_53100000), target_module_53100000 }, + { "target-module@53500000", nitems(target_module_53500000), target_module_53500000 }, + { "target-module@56000000", nitems(target_module_56000000), target_module_56000000 }, +}; + + /* reg-names can be "rev", "sysc" and "syss" */ static const char * reg_names[] = { "rev", "sysc", "syss" }; #define REG_REV 0 @@ -135,7 +257,6 @@ struct ti_sysc_softc { struct simplebus_softc sc; - bool attach_done; device_t dev; int device_type; @@ -243,6 +364,9 @@ int err; TAILQ_FOREACH_SAFE(clkp, &sc->clk_list, next, clkp_tmp) { +DPRINTF(sc->dev, "clk_enable %s\n", + clk_get_name(clkp->clk)); + err = clk_enable(clkp->clk); if (err) { @@ -395,6 +519,7 @@ idle[i] = -1; } +#if 0 static int ti_sysc_attach_clocks(struct ti_sysc_softc *sc) { clk_t *clk; @@ -418,6 +543,7 @@ /* All clocks are found, add to list */ for (index = 0; index < sc->num_clocks; index++) { + struct clk_list *clkp; clkp = malloc(sizeof(*clkp), M_DEVBUF, M_WAITOK | M_ZERO); clkp->clk = clk[index]; TAILQ_INSERT_TAIL(&sc->clk_list, clkp, next); @@ -427,6 +553,7 @@ free(clk, M_DEVBUF); return (0); } +#endif static int ti_sysc_simplebus_attach_child(device_t dev) { @@ -533,20 +660,49 @@ sc->ti_no_idle); if (OF_hasprop(node, "clocks")) { - struct clock_cell_info cell_info; - read_clock_cells(sc->dev, &cell_info); - free(cell_info.clock_cells, M_DEVBUF); - free(cell_info.clock_cells_ncells, M_DEVBUF); + int index; + const char *name = ofw_bus_get_name(dev); +device_printf(dev, "%s has clock\n", name); - sc->num_clocks = cell_info.num_real_clocks; - TAILQ_INIT(&sc->clk_list); + for (index = 0; index < nitems(sysc_clock_table); index++) { + if (strcmp(sysc_clock_table[index].node_name, name) == 0) { + device_printf(dev, "!!! Found %s in lookup table index %d\n", name, index); + break; + } + } - err = ti_sysc_attach_clocks(sc); - if (err) { - DPRINTF(sc->dev, "Failed to attach clocks\n"); - return (bus_generic_attach(sc->dev)); + if (index < nitems(sysc_clock_table)) { + /* + * Found the correct place in the lookup table. + * Loop through and get the clocks + */ + int clk_index; + + TAILQ_INIT(&sc->clk_list); + sc->num_clocks = sysc_clock_table[index].parent_cnt; + for (clk_index = 0 ; clk_index < sysc_clock_table[index].parent_cnt; clk_index++) { + struct clk_list *clkp; + clkp = malloc(sizeof(*clkp), M_DEVBUF, M_WAITOK | M_ZERO); + //clkp->clk = clk[index]; +#if 0 + err = clk_get_by_ofw_name(dev, node, + sysc_clock_table[index].parent_names[clk_index], + &clkp->clk); +#endif + err = clk_get_by_name(dev, + sysc_clock_table[index].parent_names[clk_index], + &clkp->clk); + if (err != 0) + panic("Cant get clock %s err %d", + sysc_clock_table[index].parent_names[clk_index], + err); + + TAILQ_INSERT_TAIL(&sc->clk_list, clkp, next); + } + } else { + panic("Cant find clocks for node %s\n", name); } - } + } err = ti_sysc_simplebus_attach_child(sc->dev); if (err) { @@ -555,8 +711,6 @@ return (err); } - sc->attach_done = true; - return (bus_generic_attach(sc->dev)); } @@ -566,49 +720,11 @@ return (EBUSY); } -/* Bus interface */ -static void -ti_sysc_new_pass(device_t dev) -{ - struct ti_sysc_softc *sc; - int err; - phandle_t node; - - sc = device_get_softc(dev); - - if (sc->attach_done) { - bus_generic_new_pass(sc->dev); - return; - } - - node = ofw_bus_get_node(sc->dev); - if (OF_hasprop(node, "clocks")) { - err = ti_sysc_attach_clocks(sc); - if (err) { - DPRINTF(sc->dev, "Failed to attach clocks\n"); - return; - } - } - - err = ti_sysc_simplebus_attach_child(sc->dev); - if (err) { - DPRINTF(sc->dev, - "ti_sysc_simplebus_attach_child failed %d\n", err); - return; - } - sc->attach_done = true; - - bus_generic_attach(sc->dev); -} - static device_method_t ti_sysc_methods[] = { /* Device interface */ DEVMETHOD(device_probe, ti_sysc_probe), DEVMETHOD(device_attach, ti_sysc_attach), DEVMETHOD(device_detach, ti_sysc_detach), - - /* Bus interface */ - DEVMETHOD(bus_new_pass, ti_sysc_new_pass), DEVMETHOD_END }; Index: sys/dev/extres/syscon/syscon_generic.h =================================================================== --- sys/dev/extres/syscon/syscon_generic.h +++ sys/dev/extres/syscon/syscon_generic.h @@ -40,6 +40,8 @@ bool simplebus_attached; }; +int syscon_generic_attach(device_t dev); + DECLARE_CLASS(syscon_generic_driver); #endif /* DEV_SYSCON_GENERIC_H */ Index: sys/dev/extres/syscon/syscon_generic.c =================================================================== --- sys/dev/extres/syscon/syscon_generic.c +++ sys/dev/extres/syscon/syscon_generic.c @@ -161,7 +161,7 @@ return (BUS_PROBE_GENERIC); } -static int +int syscon_generic_attach(device_t dev) { struct syscon_generic_softc *sc; @@ -218,12 +218,27 @@ return (0); } +static int +syscon_generic_get_handle(device_t dev, struct syscon **syscon) +{ + struct syscon_generic_softc *sc; + + sc = device_get_softc(dev); + *syscon = sc->syscon; + if (*syscon == NULL) + return (ENODEV); + return (0); +} + static device_method_t syscon_generic_dmethods[] = { /* Device interface */ DEVMETHOD(device_probe, syscon_generic_probe), DEVMETHOD(device_attach, syscon_generic_attach), DEVMETHOD(device_detach, syscon_generic_detach), + /* syscon interface */ + DEVMETHOD(syscon_get_handle, syscon_generic_get_handle), + DEVMETHOD(syscon_device_lock, syscon_generic_lock), DEVMETHOD(syscon_device_unlock, syscon_generic_unlock),