Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F115786546
D27889.id82297.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
102 KB
Referenced Files
None
Subscribers
None
D27889.id82297.diff
View Options
diff --git a/sys/arm/ti/clk/clock_common.h b/sys/arm/ti/clk/clock_common.h
--- a/sys/arm/ti/clk/clock_common.h
+++ b/sys/arm/ti/clk/clock_common.h
@@ -30,14 +30,20 @@
#include <sys/cdefs.h>
__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, \
+}
diff --git a/sys/arm/ti/clk/clock_common.c b/sys/arm/ti/clk/clock_common.c
--- a/sys/arm/ti/clk/clock_common.c
+++ b/sys/arm/ti/clk/clock_common.c
@@ -1,152 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2020 Oskar Holmlund <oskar.holmlund@ohdata.se>
- *
- * 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 <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/conf.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/systm.h>
-#include <sys/libkern.h>
-#include <sys/types.h>
-#include <sys/malloc.h>
-
-#include <machine/bus.h>
-#include <dev/fdt/simplebus.h>
-
-#include <dev/extres/clk/clk_mux.h>
-#include <dev/ofw/ofw_bus.h>
-#include <dev/ofw/ofw_bus_subr.h>
-
-#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);
-}
diff --git a/sys/arm/ti/clk/ti_clk_clkctrl.c b/sys/arm/ti/clk/ti_clk_clkctrl.c
--- a/sys/arm/ti/clk/ti_clk_clkctrl.c
+++ b/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);
diff --git a/sys/arm/ti/clk/ti_clkctrl.c b/sys/arm/ti/clk/ti_clkctrl.c
--- a/sys/arm/ti/clk/ti_clkctrl.c
+++ b/sys/arm/ti/clk/ti_clkctrl.c
@@ -51,11 +51,12 @@
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
+#include <arm/ti/clk/clock_common.h>
#include <arm/ti/clk/ti_clk_clkctrl.h>
#include <arm/ti/ti_omap4_cm.h>
#include <arm/ti/ti_cpuid.h>
-#if 0
+#if 1
#define DPRINTF(dev, msg...) device_printf(dev, msg)
#else
#define DPRINTF(dev, msg...)
@@ -89,14 +90,317 @@
struct clkdom *clkdom;
};
+/* reg = <0x38 0x2c>, <0x6c 0x28>, <0xac 0xc>, <0xc0 0x1c>, <0xec 0xc>, <0x10c 0x8>, <0x130 0x4>; */
+/* <0x38 0x2c> */
+PLIST(l4ls_clkctrl_38_0) = { "dpll_per_m2_div4_ck" }; /* am3.h UART6 clkctrl, TRM 19.2.2 */
+PLIST(l4ls_clkctrl_38_4) = { "mmc_clk" }; /* am3.h MMC1 clkctrl, TRM 18.2.2 */
+PLIST(l4ls_clkctrl_38_8) = { "l4ls_gclk" }; /* am3.h ELM clkctrl, TRM 7.4.2.2 */
+PLIST(l4ls_clkctrl_38_c) = { "dpll_per_m2_div4_ck" }; /* am3.h I2C3 clkctrl, TRM 21.2.2 */
+PLIST(l4ls_clkctrl_38_10) = { "dpll_per_m2_div4_ck" }; /* am3.h I2C2 clkctrl, TRM 21.2.2 */
+PLIST(l4ls_clkctrl_38_14) = { "dpll_per_m2_div4_ck" }; /* am3.h SPI0 clkctrl, TRM 24.2.2 */
+PLIST(l4ls_clkctrl_38_18) = { "dpll_per_m2_div4_ck" }; /* am3.h SPI1 clkctrl, TRM 24.2.2 */
+/* 1c, 20, 24 are not described in the TRM */
+//PLIST(l4ls_clkctrl_38_1c) = { NULL }; /* am3.h TRM ? */
+//PLIST(l4ls_clkctrl_38_20) = { NULL }; /* am3.h TRM ? */
+//PLIST(l4ls_clkctrl_38_24) = { NULL }; /* am3.h TRM ? */
+PLIST(l4ls_clkctrl_38_28) = { "l4ls_gclk" }; /* am3.h L4_LS clkctrl, TRM 8.1.12.1.19 */
+/* <0x6c 0x28> */
+PLIST(l4ls_clkctrl_38_34) = { "dpll_per_m2_div4_ck" }; /* am3.h UART2 clkctrl, TRM 19.2.2 */
+PLIST(l4ls_clkctrl_38_38) = { "dpll_per_m2_div4_ck" }; /* am3.h UART3 clkctrl, TRM 19.2.2 */
+PLIST(l4ls_clkctrl_38_3c) = { "dpll_per_m2_div4_ck" }; /* am3.h UART4 clkctrl, TRM 19.2.2 */
+PLIST(l4ls_clkctrl_38_40) = { "dpll_per_m2_div4_ck" }; /* am3.h UART4 clkctrl, TRM 19.2.2 */
+PLIST(l4ls_clkctrl_38_44) = { "dpll_per_m2_div4_ck" }; /* am3.h UART5 clkctrl, TRM 19.2.2 */
+PLIST(l4ls_clkctrl_38_48) = { "timer7_fck@504" }; /* am3.h TIMER7 clkctrl, TRM 20.1.2.3 */
+PLIST(l4ls_clkctrl_38_4c) = { "timer2_fck@508" }; /* am3.h TIMER2 clkctrl, TRM 20.1.2.3 */
+PLIST(l4ls_clkctrl_38_50) = { "timer3_fck@50c" }; /* am3.h TIMER3 clkctrl, TRM 20.1.2.3 */
+PLIST(l4ls_clkctrl_38_54) = { "timer4_fck@510" }; /* am3.h TIMER4 clkctrl, TRM 20.1.2.3 */
+PLIST(l4ls_clkctrl_38_58) = { "rng_fck" }; /* am3.h RNG clkctrl, TRM doesnt describe the rng, rng_fck only from the am33xx-clocks.dtsi */
+/* <0xac 0xc> */
+PLIST(l4ls_clkctrl_38_74) = { "l4ls_gclk" }; /* am3.h GPIO2 clkctrl, TRM 25.2.2 */
+PLIST(l4ls_clkctrl_38_75) = { "clk_32768_ck" }; /* am3.h GPIO2 clkctrl, TRM 25.2.2 */
+PLIST(l4ls_clkctrl_38_78) = { "l4ls_gclk" }; /* am3.h GPIO3 clkctrl, TRM 25.2.2 */
+PLIST(l4ls_clkctrl_38_79) = { "clk_32768_ck" }; /* am3.h GPIO3 clkctrl, TRM 25.2.2 */
+PLIST(l4ls_clkctrl_38_7c) = { "l4ls_gclk" }; /* am3.h GPIO4 clkctrl, TRM 25.2.2 */
+PLIST(l4ls_clkctrl_38_7d) = { "clk_32768_ck" }; /* am3.h GPIO4 clkctrl, TRM 25.2.2 */
+/* <0xc0 0x1c> */
+PLIST(l4ls_clkctrl_38_88) = { "dcan0_fck" }; /* am3.h D_CAN0 clkctrl, TRM 23.2.2 */
+PLIST(l4ls_clkctrl_38_8c) = { "dcan1_fck" }; /* am3.h D_CAN1 clkctrl, TRM 23.2.2 */
+/* 90 not described in am3.h */
+//PLIST(l4ls_clkctrl_38_90) = { NULL }; /* am3.h */
+PLIST(l4ls_clkctrl_38_94) = { "l4ls_gclk" }; /* am3.h EPWMMS1 clkctrl, TRM 15.1.2.3 */
+/* 98 not described in am3.h */
+//PLIST(l4ls_clkctrl_38_98) = { NULL }; /* am3.h */
+PLIST(l4ls_clkctrl_38_9c) = { "l4ls_gclk" }; /* am3.h EPWMMS0 clkctrl, TRM 15.1.2.3 */
+PLIST(l4ls_clkctrl_38_a0) = { "l4ls_gclk" }; /* am3.h EPWMMS2 clkctrl, TRM 15.1.2.3 */
+/* <0xec 0xc> */
+PLIST(l4ls_clkctrl_38_b4) = { "timer5_fck@518" }; /* am3.h TIMER5 clkctrl, TRM 20.1.2.3 */
+PLIST(l4ls_clkctrl_38_b8) = { "timer6_fck@51c" }; /* am3.h TIMER6 clkctrl, TRM 20.1.2.3 */
+PLIST(l4ls_clkctrl_38_bc) = { "mmc_clk" }; /* am3.h MMC2 clkctrl, TRM 18.2.2 */
+/* <0xd4 0x8> */
+PLIST(l4ls_clkctrl_38_d4) = { "l4ls_gclk" }; /* am3.h SPINLOCK clkctrl, TRM 8.1.12.1.48 "SPINLOCK clocks" */
+PLIST(l4ls_clkctrl_38_d8) = { "l4ls_gclk" }; /* am3.h MAILBOX clkctrl, TRM 17.1.1.2 */
+/* <0x130 0x4> */
+PLIST(l4ls_clkctrl_38_f8) = { "l4ls_gclk" }; /* am3.h OCPWP clkctrl, TRM 8.1.12.1.53 "OCPWP clocks" */
+
+/* reg = <0x1c 0x4>, <0x30 0x8>, <0x68 0x4>, <0xf8 0x4> */
+/* <0x1c 0x4> */
+PLIST(l3s_clkctrl_1c_0) = { "usbotg_fck@47c" }; /* am3.h USB_OTG_HS clkctrl, TRM 16.1.2 fig 16-1 */
+/* <0x30 0x8> */
+PLIST(l3s_clkctrl_1c_14) = { "l3s_gclk" }; /* am3.h GPMC clkctrl, TRM 7.1.2.2 */
+PLIST(l3s_clkctrl_1c_18) = { "mcasp0_fck" }; /* am3.h MCASP0 clkctrl, TRM 22.2.2 */
+/* <0x68 0x4> */
+PLIST(l3s_clkctrl_1c_4c) = { "mcasp1_fck" }; /* am3.h MCASP1 clkctrl, TRM 22.2.2 */
+/* <0xf8 0x4> */
+PLIST(l3s_clkctrl_1c_dc) = { "mmc_clk" }; /* am3.h MMC3 clkctrl, TRM 18.2.2 */
+
+/* reg = <0x24 0xc>, <0x94 0x10>, <0xbc 0x4>, <0xdc 0x8>, <0xfc 0x8>; */
+/* <0x24 0xc> */
+PLIST(l3_clkctrl_24_0) = { "l3_gclk" }; /* am3.h TPTC0 clkctrl, TRM 11.2.2.2 */
+PLIST(l3_clkctrl_24_4) = { "dpll_ddr_m2_div2_ck" }; /* am3.h EMIF clkctrl, TRM 7.3.2.2 */
+PLIST(l3_clkctrl_24_8) = { "l3_gclk" }; /* am3.h OCMCRAM clkctrl, TRM 7.2.2.2 */
+/* <0x94 0x10> */
+PLIST(l3_clkctrl_24_70) = { "aes0_fck" }; /* am3.h AES clkctrl, not in TRM, derived from am33xx-clocks.dtsi */
+//PLIST(l3_clkctrl_24_74) = { NULL }; /* am3.h ?? clkctrl, TRM ??? */
+//PLIST(l3_clkctrl_24_78) = { NULL }; /* am3.h ?? clkctrl, TRM ???? */
+PLIST(l3_clkctrl_24_7c) = { "l3_gclk" }; /* am3.h SHAM clkctrl, not in TRM, assume l3_gclk */
+/* <0xbc 0x4> */
+PLIST(l3_clkctrl_24_98) = { "l3_gclk" }; /* am3.h TPCC clkctrl, TRM 11.2.1.2 */
+/* <0xdc 0x8> */
+PLIST(l3_clkctrl_24_b8) = { "l3_gclk" }; /* am3.h L3 INSTR clkctrl, TRM 8.1.12.1.38 "L3 INSTR clocks" */
+PLIST(l3_clkctrl_24_bc) = { "l3_gclk" }; /* am3.h L3 Main clkctrl, TRM 18.1.12.1.39 "L3 interconnect clocks" */
+/* <0xfc 0x8> */
+PLIST(l3_clkctrl_24_d8) = { "l3_gclk" }; /* am3.h TPTC1 clkctrl, TRM 11.2.2.2 */
+PLIST(l3_clkctrl_24_dc) = { "l3_gclk" }; /* am3.h TPTC2 clkctrl, TRM 11.2.2.2 */
+
+/* reg = <0x120 0x4>; */
+PLIST(l4hs_clkctrl_120_0) = { "l4hs_gclk" }; /* am3.h L4HS clkctrl, TRM 8.1.12.1.50 */
+
+/* reg = <0xe8 0x4>; */
+PLIST(pruss_ocp_clkctrl_e8_0) = { "pruss_ocp_gclk@530" }; /* am3.h ocp pruss clkctrl, TRM 4.2.2 */
+
+/* reg = <0x0 0x18>; */
+#if 0
+PLIST(cpsw_125mhz_clkctrl_0_0) = { NULL }; /* am3.h Not mentioned in TRM, TRM 14.2.2 */
+PLIST(cpsw_125mhz_clkctrl_0_4) = { NULL }; /* am3.h Not mentioned in TRM, TRM 14.2.2 */
+PLIST(cpsw_125mhz_clkctrl_0_8) = { NULL }; /* am3.h Not mentioned in TRM, TRM 14.2.2 */
+PLIST(cpsw_125mhz_clkctrl_0_c) = { NULL }; /* am3.h Not mentioned in TRM, TRM 14.2.2 */
+PLIST(cpsw_125mhz_clkctrl_0_10) = { NULL }; /* am3.h Not mentioned in TRM, TRM 14.2.2 */
+#endif
+PLIST(cpsw_125mhz_clkctrl_0_14) = { "cpsw_125mhz_gclk" }; /* am3.h cpsw 125 mhz cpgmaco clkctrl, TRM 14.2.2 */
+
+/* reg = <0x18 0x4>; */
+PLIST(lcdc_clkctrl_18_0) = { "lcd_gclk@534" }; /* am3.h lcdc clkctrl, TRM 13.2.2 */
+
+/* reg = <0x14c 0x4>; */
+PLIST(clk_24mhz_clkctrl_14c_0) = { "clkdiv32k_ck" }; /* am3.h clkdiv32k clkctrl, TRM 8.1.12.1.57 */
+
+/* reg = <0x0 0x10>, <0xb4 0x24>; */
+/* <0x0 0x10> */
+//PLIST(l4_wkup_clkctrl_0_0) = { NULL }; /* am3.h clkstctrl, TRM 8.1.12.2.1 */
+PLIST(l4_wkup_clkctrl_0_4) = { "mmc_clk" }; /* am3.h control clkctrl, TRM 18.2.2 */
+PLIST(l4_wkup_clkctrl_0_8) = { "dpll_core_m4_div2_ck" }; /* am3.h gpio1 clkctrl, TRM 25.2.2 */
+PLIST(l4_wkup_clkctrl_0_9) = { "gpio0_dbclk_mux_ck@53c" }; /* am3.h gpio1 clkctrl, TRM 25.2.2 */
+PLIST(l4_wkup_clkctrl_0_c) = { "mmc_clk" }; /* am3.h L4 wkup clkctrl, TRM 18.2.2 */
+/* <0xb4 0x24> */
+PLIST(l4_wkup_clkctrl_0_b4) = { "dpll_per_m2_div4_wkupdm_ck" }; /* am3.h uart1 clkctrl, TRM 19.2.2 */
+PLIST(l4_wkup_clkctrl_0_b8) = { "dpll_per_m2_div4_wkupdm_ck" }; /* am3.h i2c1 wkup clkctrl, TRM 21.2.2 */
+PLIST(l4_wkup_clkctrl_0_bc) = { "adc_tsc_fck" }; /* am3.h adc tsc clkctrl, TRM 12.2.2 */
+PLIST(l4_wkup_clkctrl_0_c0) = { "smartreflex0_fck" }; /* am3.h smartreflex0 clkctrl, TRM 8.1.12.2.49 */
+PLIST(l4_wkup_clkctrl_0_c4) = { "timer1_fck@528" }; /* am3.h timer1 clkctrl, TRM 20.1.2.3 */
+PLIST(l4_wkup_clkctrl_0_c8) = { "smartreflex1_fck" }; /* am3.h smartreflex1 clkctrl, TRM 8.1.12.2.51 */
+//PLIST(l4_wkup_clkctrl_0_cc) = { NULL }; /* am3.h l4_wkup_aon_clkstctrl, TRM 8.1.12.2.52 */
+//PLIST(l4_wkup_clkctrl_0_d0) = { NULL }; /* am3.h ??? clkctrl, not in TRM */
+PLIST(l4_wkup_clkctrl_0_d4) = { "wdt1_fck@538" }; /* am3.h wd timer2 clkctrl, TRM 20.4.2.2 */
+
+/* reg = <0x14 0x4>; */
+//PLIST(l3_aon_clkctrl_14_0) = { NULL }; /* am3.h debugss clkctrl, TRM 8.1.12.2.6 multiple sub clocks - todo */
+
+/* reg = <0xb0 0x4>; */
+//PLIST(l4_wkup_aon_wkup_m3_clkctrl_b0_0) = { NULL }; /* am3.h l4 wkup aon wkup m3 clkctrl, TRM 8.1.12.2.45 */
+
+/* reg = <0x0 0x8>; */
+//PLIST(mpu_clkctrl_0_0) = { NULL }; /* am3.h mpu clkstctrl, TRM 8.1.12.4.1 */
+PLIST(mpu_clkctrl_0_4) = { "dpll_mpu_ck@488" }; /* am3.h mpu clkctrl, TRM 8.1.12.4.2 / 3.1.3 */
+
+/* reg = <0x0 0x4>; */
+PLIST(l4_rtc_clkctrl_0_0) = { "clk_32768_ck" }; /* am3.h RTC clkctrl, TRM 20.3.2.2 */
+
+/* reg = <0x0 0x8>; */
+//PLIST(gfx_l3_clkctrl_0_0) = { NULL }; /* am3.h L3 GFX clkctrl, TRM 5.1.2 */
+PLIST(gfx_l3_clkctrl_0_4) = { "gfx_fck_div_ck@52c" }; /* am3.h L3 GFX clkctrl, TRM 5.1.2 */
+
+/* reg = <0x0 0x24>; */
+#if 0
+PLIST(l4_cefuse_clkctrl_0_0) = { NULL }; /* am3.h cefuse clkctrl, TRM 8.1.12.8.2 */
+PLIST(l4_cefuse_clkctrl_0_4) = { NULL }; /* am3.h cefuse clkctrl, TRM 8.1.12.8.2 */
+PLIST(l4_cefuse_clkctrl_0_8) = { NULL }; /* am3.h cefuse clkctrl, TRM 8.1.12.8.2 */
+PLIST(l4_cefuse_clkctrl_0_c) = { NULL }; /* am3.h cefuse clkctrl, TRM 8.1.12.8.2 */
+PLIST(l4_cefuse_clkctrl_0_10) = { NULL }; /* am3.h cefuse clkctrl, TRM 8.1.12.8.2 */
+PLIST(l4_cefuse_clkctrl_0_14) = { NULL }; /* am3.h cefuse clkctrl, TRM 8.1.12.8.2 */
+PLIST(l4_cefuse_clkctrl_0_18) = { NULL }; /* am3.h cefuse clkctrl, TRM 8.1.12.8.2 */
+PLIST(l4_cefuse_clkctrl_0_1c) = { NULL }; /* am3.h cefuse clkctrl, TRM 8.1.12.8.2 */
+PLIST(l4_cefuse_clkctrl_0_20) = { NULL }; /* am3.h cefuse clkctrl, TRM 8.1.12.8.2 */
+#endif
+
+
+static struct parent_lookup_table clkctrl_parent_table[] = {
+
+/* reg = <0x38 0x2c>, <0x6c 0x28>, <0xac 0xc>, <0xc0 0x1c>, <0xec 0xc>, <0x10c 0x8>, <0x130 0x4>;
+ */
+/* <0x38 0x2c> */
+ { "l4ls-clkctrl@38_0", nitems(l4ls_clkctrl_38_0), l4ls_clkctrl_38_0 },
+ { "l4ls-clkctrl@38_4", nitems(l4ls_clkctrl_38_4), l4ls_clkctrl_38_4 },
+ { "l4ls-clkctrl@38_8", nitems(l4ls_clkctrl_38_8), l4ls_clkctrl_38_8 },
+ { "l4ls-clkctrl@38_c", nitems(l4ls_clkctrl_38_c), l4ls_clkctrl_38_c },
+ { "l4ls-clkctrl@38_10", nitems(l4ls_clkctrl_38_10), l4ls_clkctrl_38_10 },
+ { "l4ls-clkctrl@38_14", nitems(l4ls_clkctrl_38_14), l4ls_clkctrl_38_14 },
+ { "l4ls-clkctrl@38_18", nitems(l4ls_clkctrl_38_18), l4ls_clkctrl_38_18 },
+ { "l4ls-clkctrl@38_1c", 0, NULL },
+ { "l4ls-clkctrl@38_20", 0, NULL },
+ { "l4ls-clkctrl@38_24", 0, NULL },
+ { "l4ls-clkctrl@38_28", nitems(l4ls_clkctrl_38_28), l4ls_clkctrl_38_28 },
+/* <0x6c 0x28> */
+ { "l4ls-clkctrl@38_34", nitems(l4ls_clkctrl_38_34), l4ls_clkctrl_38_34 },
+ { "l4ls-clkctrl@38_38", nitems(l4ls_clkctrl_38_38), l4ls_clkctrl_38_38 },
+ { "l4ls-clkctrl@38_3c", nitems(l4ls_clkctrl_38_3c), l4ls_clkctrl_38_3c },
+ { "l4ls-clkctrl@38_40", nitems(l4ls_clkctrl_38_40), l4ls_clkctrl_38_40 },
+ { "l4ls-clkctrl@38_44", nitems(l4ls_clkctrl_38_44), l4ls_clkctrl_38_44 },
+ { "l4ls-clkctrl@38_48", nitems(l4ls_clkctrl_38_48), l4ls_clkctrl_38_48 },
+ { "l4ls-clkctrl@38_4c", nitems(l4ls_clkctrl_38_4c), l4ls_clkctrl_38_4c },
+ { "l4ls-clkctrl@38_50", nitems(l4ls_clkctrl_38_50), l4ls_clkctrl_38_50 },
+ { "l4ls-clkctrl@38_54", nitems(l4ls_clkctrl_38_54), l4ls_clkctrl_38_54 },
+ { "l4ls-clkctrl@38_58", nitems(l4ls_clkctrl_38_58), l4ls_clkctrl_38_58 },
+/* <0xac 0xc> */
+ { "l4ls-clkctrl@38_74", nitems(l4ls_clkctrl_38_74), l4ls_clkctrl_38_74 },
+ { "l4ls-clkctrl@38_75", nitems(l4ls_clkctrl_38_75), l4ls_clkctrl_38_75 },
+ { "l4ls-clkctrl@38_78", nitems(l4ls_clkctrl_38_78), l4ls_clkctrl_38_78 },
+ { "l4ls-clkctrl@38_79", nitems(l4ls_clkctrl_38_79), l4ls_clkctrl_38_79 },
+ { "l4ls-clkctrl@38_7c", nitems(l4ls_clkctrl_38_7c), l4ls_clkctrl_38_7c },
+ { "l4ls-clkctrl@38_7d", nitems(l4ls_clkctrl_38_7d), l4ls_clkctrl_38_7d },
+/* <0xc0 0x1c> */
+ { "l4ls-clkctrl@38_88", nitems(l4ls_clkctrl_38_88), l4ls_clkctrl_38_88 },
+ { "l4ls-clkctrl@38_8c", nitems(l4ls_clkctrl_38_8c), l4ls_clkctrl_38_8c },
+ { "l4ls-clkctrl@38_90", 0, NULL },
+ { "l4ls-clkctrl@38_94", nitems(l4ls_clkctrl_38_94), l4ls_clkctrl_38_94 },
+ { "l4ls-clkctrl@38_98", 0, NULL },
+ { "l4ls-clkctrl@38_9c", nitems(l4ls_clkctrl_38_9c), l4ls_clkctrl_38_9c },
+ { "l4ls-clkctrl@38_a0", nitems(l4ls_clkctrl_38_a0), l4ls_clkctrl_38_a0 },
+/* <0xec 0xc> */
+ { "l4ls-clkctrl@38_b4", nitems(l4ls_clkctrl_38_b4), l4ls_clkctrl_38_b4 },
+ { "l4ls-clkctrl@38_b8", nitems(l4ls_clkctrl_38_b8), l4ls_clkctrl_38_b8 },
+ { "l4ls-clkctrl@38_bc", nitems(l4ls_clkctrl_38_bc), l4ls_clkctrl_38_bc },
+/* <0xd4 0x8> */
+ { "l4ls-clkctrl@38_d4", nitems(l4ls_clkctrl_38_d4), l4ls_clkctrl_38_d4 },
+ { "l4ls-clkctrl@38_d8", nitems(l4ls_clkctrl_38_d8), l4ls_clkctrl_38_d8 },
+/* <0x130 0x4> */
+ { "l4ls-clkctrl@38_f8", nitems(l4ls_clkctrl_38_f8), l4ls_clkctrl_38_f8 },
+
+/* reg = <0x1c 0x4>, <0x30 0x8>, <0x68 0x4>, <0xf8 0x4> */
+/* <0x1c 0x4> */
+ { "l3s-clkctrl@1c_0", nitems(l3s_clkctrl_1c_0), l3s_clkctrl_1c_0 },
+/* <0x30 0x8> */
+ { "l3s-clkctrl@1c_14", nitems(l3s_clkctrl_1c_14), l3s_clkctrl_1c_14 },
+ { "l3s-clkctrl@1c_18", nitems(l3s_clkctrl_1c_18), l3s_clkctrl_1c_18 },
+/* <0x68 0x4> */
+ { "l3s-clkctrl@1c_4c", nitems(l3s_clkctrl_1c_4c), l3s_clkctrl_1c_4c },
+/* <0xf8 0x4> */
+ { "l3s-clkctrl@1c_dc", nitems(l3s_clkctrl_1c_dc), l3s_clkctrl_1c_dc },
+
+/* reg = <0x24 0xc>, <0x94 0x10>, <0xbc 0x4>, <0xdc 0x8>, <0xfc 0x8>; */
+/* <0x24 0xc> */
+ { "l3-clkctrl@24_0", nitems(l3_clkctrl_24_0), l3_clkctrl_24_0 },
+ { "l3-clkctrl@24_4", nitems(l3_clkctrl_24_4), l3_clkctrl_24_4 },
+ { "l3-clkctrl@24_8", nitems(l3_clkctrl_24_8), l3_clkctrl_24_8 },
+/* <0x94 0x10> */
+ { "l3-clkctrl@24_70", nitems(l3_clkctrl_24_70), l3_clkctrl_24_70 },
+ { "l3-clkctrl@24_74", 0, NULL },
+ { "l3-clkctrl@24_78", 0, NULL },
+ { "l3-clkctrl@24_7c", nitems(l3_clkctrl_24_7c), l3_clkctrl_24_7c },
+/* <0xbc 0x4> */
+ { "l3-clkctrl@24_98", nitems(l3_clkctrl_24_98), l3_clkctrl_24_98 },
+/* <0xdc 0x8> */
+ { "l3-clkctrl@24_b8", nitems(l3_clkctrl_24_b8), l3_clkctrl_24_b8 },
+ { "l3-clkctrl@24_bc", nitems(l3_clkctrl_24_bc), l3_clkctrl_24_bc },
+/* <0xfc 0x8> */
+ { "l3-clkctrl@24_d8", nitems(l3_clkctrl_24_d8), l3_clkctrl_24_d8 },
+ { "l3-clkctrl@24_dc", nitems(l3_clkctrl_24_dc), l3_clkctrl_24_dc },
+
+/* reg = <0x120 0x4>; */
+ { "l4hs-clkctrl@120_0", nitems(l4hs_clkctrl_120_0), l4hs_clkctrl_120_0 },
+
+/* reg = <0xe8 0x4>; */
+ { "pruss-ocp-clkctrl@e8_0", nitems(pruss_ocp_clkctrl_e8_0), pruss_ocp_clkctrl_e8_0 },
+
+/* reg = <0x0 0x18>; */
+ { "cpsw-125mhz-clkctrl@0_0", 0, NULL },
+ { "cpsw-125mhz-clkctrl@0_4", 0, NULL },
+ { "cpsw-125mhz-clkctrl@0_8", 0, NULL },
+ { "cpsw-125mhz-clkctrl@0_c", 0, NULL },
+ { "cpsw-125mhz-clkctrl@0_10", 0, NULL },
+ { "cpsw-125mhz-clkctrl@0_14", nitems(cpsw_125mhz_clkctrl_0_14), cpsw_125mhz_clkctrl_0_14 },
+
+/* reg = <0x18 0x4>; */
+ { "lcdc-clkctrl@18_0", nitems(lcdc_clkctrl_18_0), lcdc_clkctrl_18_0 },
+
+/* reg = <0x14c 0x4>; */
+ { "clk-24mhz-clkctrl@14c_0", nitems(clk_24mhz_clkctrl_14c_0), clk_24mhz_clkctrl_14c_0 },
+
+/* reg = <0x0 0x10>, <0xb4 0x24>; */
+/* <0x0 0x10> */
+ { "l4-wkup-clkctrl@0_0", 0, NULL },
+ { "l4-wkup-clkctrl@0_4", nitems(l4_wkup_clkctrl_0_4), l4_wkup_clkctrl_0_4 },
+ { "l4-wkup-clkctrl@0_8", nitems(l4_wkup_clkctrl_0_8), l4_wkup_clkctrl_0_8 },
+ { "l4-wkup-clkctrl@0_9", nitems(l4_wkup_clkctrl_0_9), l4_wkup_clkctrl_0_9 },
+ { "l4-wkup-clkctrl@0_c", nitems(l4_wkup_clkctrl_0_c), l4_wkup_clkctrl_0_c },
+/* <0xb4 0x24> */
+ { "l4-wkup-clkctrl@0_b4", nitems(l4_wkup_clkctrl_0_b4), l4_wkup_clkctrl_0_b4 },
+ { "l4-wkup-clkctrl@0_b8", nitems(l4_wkup_clkctrl_0_b8), l4_wkup_clkctrl_0_b8 },
+ { "l4-wkup-clkctrl@0_bc", nitems(l4_wkup_clkctrl_0_bc), l4_wkup_clkctrl_0_bc },
+ { "l4-wkup-clkctrl@0_c0", nitems(l4_wkup_clkctrl_0_c0), l4_wkup_clkctrl_0_c0 },
+ { "l4-wkup-clkctrl@0_c4", nitems(l4_wkup_clkctrl_0_c4), l4_wkup_clkctrl_0_c4 },
+ { "l4-wkup-clkctrl@0_c8", nitems(l4_wkup_clkctrl_0_c8), l4_wkup_clkctrl_0_c8 },
+ { "l4-wkup-clkctrl@0_cc", 0, NULL },
+ { "l4-wkup-clkctrl@0_d0", 0, NULL },
+ { "l4-wkup-clkctrl@0_d4", nitems(l4_wkup_clkctrl_0_d4), l4_wkup_clkctrl_0_d4 },
+
+/* reg = <0x14 0x4>; */
+ { "l3-aon-clkctrl@14_0", 0, NULL },
+
+/* reg = <0xb0 0x4>; */
+ { "l4-wkup-aon-clkctrl@b0_0", 0, NULL },
+
+/* reg = <0x0 0x8>; */
+ { "mpu-clkctrl@0_0", 0, NULL },
+ { "mpu-clkctrl@0_4", nitems(mpu_clkctrl_0_4), mpu_clkctrl_0_4 },
+
+/* reg = <0x0 0x4>; */
+ { "l4-rtc-clkctrl@0_0", nitems(l4_rtc_clkctrl_0_0), l4_rtc_clkctrl_0_0 },
+
+/* reg = <0x0 0x8>; */
+ { "gfx-l3-clkctrl@0_0", 0, NULL },
+ { "gfx-l3-clkctrl@0_4", nitems(gfx_l3_clkctrl_0_4), gfx_l3_clkctrl_0_4 },
+
+/* reg = <0x0 0x24>; */
+ { "l4-cefuse-clkctrl@0_0", 0, NULL },
+ { "l4-cefuse-clkctrl@0_4", 0, NULL },
+ { "l4-cefuse-clkctrl@0_8", 0, NULL },
+ { "l4-cefuse-clkctrl@0_c", 0, NULL },
+ { "l4-cefuse-clkctrl@0_10", 0, NULL },
+ { "l4-cefuse-clkctrl@0_14", 0, NULL },
+ { "l4-cefuse-clkctrl@0_18", 0, NULL },
+ { "l4-cefuse-clkctrl@0_1c", 0, NULL },
+ { "l4-cefuse-clkctrl@0_20", 0, NULL },
+};
+
+
static int ti_clkctrl_probe(device_t dev);
static int ti_clkctrl_attach(device_t dev);
static int ti_clkctrl_detach(device_t dev);
int clkctrl_ofw_map(struct clkdom *clkdom, uint32_t ncells,
- phandle_t *cells, struct clknode **clk);
+ phandle_t *cells, struct clknode **clk);
static int
create_clkctrl(struct ti_clkctrl_softc *sc, cell_t *reg, uint32_t index, uint32_t reg_offset,
- uint64_t parent_offset, const char *org_name, bool special_gdbclk_reg);
+ uint64_t parent_offset, const char *org_name, bool special_gdbclk_reg);
static int
ti_clkctrl_probe(device_t dev)
@@ -198,7 +502,7 @@
for (reg_offset = 0; reg_offset < reg[index+1]; reg_offset += sizeof(cell_t)) {
err = create_clkctrl(sc, reg, index, reg_offset, parent_offset,
org_name, false);
- if (err)
+ if (err != 0)
goto cleanup;
/* Create special clkctrl for GDBCLK in GPIO registers */
@@ -213,7 +517,7 @@
{
err = create_clkctrl(sc, reg, index, reg_offset,
parent_offset, org_name, true);
- if (err)
+ if (err != 0)
goto cleanup;
}
break;
@@ -223,7 +527,7 @@
{
err = create_clkctrl(sc, reg, index, reg_offset,
parent_offset, org_name, true);
- if (err)
+ if (err != 0)
goto cleanup;
}
break;
@@ -232,7 +536,7 @@
} /* for */
err = clkdom_finit(sc->clkdom);
- if (err) {
+ if (err != 0) {
DPRINTF(sc->dev, "Clk domain finit fails %x.\n", err);
err = ENXIO;
goto cleanup;
@@ -243,7 +547,7 @@
free(reg, M_DEVBUF);
- if (err)
+ if (err != 0)
return (err);
return (bus_generic_attach(dev));
@@ -285,12 +589,12 @@
create_clkctrl(struct ti_clkctrl_softc *sc, cell_t *reg, uint32_t index, uint32_t reg_offset,
uint64_t parent_offset, const char *org_name, bool special_gdbclk_reg) {
struct ti_clk_clkctrl_def def;
- char *name;
+ char *node_name;
size_t name_len;
- int err;
+ int err, p_index=0;
name_len = strlen(org_name) + 1 + 5; /* 5 = _xxxx */
- name = malloc(name_len, M_OFWPROP, M_WAITOK);
+ node_name = malloc(name_len, M_OFWPROP, M_WAITOK);
/*
* Check out XX_CLKCTRL-INDEX(offset)-macro dance in
@@ -307,28 +611,40 @@
def.gdbclk = special_gdbclk_reg;
/* Make up an uniq name in the namespace for each clkctrl */
- snprintf(name, name_len, "%s_%x",
+ snprintf(node_name, name_len, "%s_%x",
org_name, def.clkdef.id);
- def.clkdef.name = (const char *) name;
DPRINTF(sc->dev, "ti_clkctrl_attach: reg[%d]: %s %x\n",
- index, def.clkdef.name, def.clkdef.id);
+ index, node_name, def.clkdef.id);
- /* No parent name */
- def.clkdef.parent_cnt = 0;
+ /* Find parent in lookup table */
+ for (p_index = 0; p_index < nitems(clkctrl_parent_table); p_index++) {
+ if (strcmp(node_name, clkctrl_parent_table[p_index].node_name) == 0)
+ break;
+ }
- /* set flags */
- def.clkdef.flags = 0x0;
+ if (p_index == nitems(clkctrl_parent_table))
+ panic("Cant find clock %s\n", node_name);
+ DPRINTF(sc->dev, "%s at clkctrl_parent_table[%d] parent_cnt %d \n",
+ node_name, p_index, clkctrl_parent_table[p_index].parent_cnt);
+ /* set flags and name */
+ def.clkdef.flags = CLK_NODE_STATIC_STRINGS;
+ def.clkdef.name = clkctrl_parent_table[p_index].node_name;
+
+ /* Handle parents */
+ def.clkdef.parent_cnt = clkctrl_parent_table[p_index].parent_cnt;
+ def.clkdef.parent_names = clkctrl_parent_table[p_index].parent_names;
+
/* Register the clkctrl */
err = ti_clknode_clkctrl_register(sc->clkdom, &def);
- if (err) {
+ if (err != 0) {
DPRINTF(sc->dev,
"ti_clknode_clkctrl_register[%d:%d] failed %x\n",
index, reg_offset, err);
err = ENXIO;
}
- OF_prop_free(name);
+ OF_prop_free(node_name);
return (err);
}
diff --git a/sys/arm/ti/clk/ti_divider_clock.c b/sys/arm/ti/clk/ti_divider_clock.c
--- a/sys/arm/ti/clk/ti_divider_clock.c
+++ b/sys/arm/ti/clk/ti_divider_clock.c
@@ -42,12 +42,16 @@
#include <dev/fdt/simplebus.h>
#include <dev/extres/clk/clk_div.h>
+#include <dev/extres/syscon/syscon.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#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...)
@@ -59,12 +63,11 @@
*/
struct ti_divider_softc {
- device_t sc_dev;
- bool attach_done;
+ device_t dev;
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,31 +84,125 @@
{ 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
-register_clk(struct ti_divider_softc *sc) {
- int err;
+ti_divider_clkdev_write_4(device_t dev, bus_addr_t addr, uint32_t val)
+{
+ struct ti_divider_softc *sc;
- sc->clkdom = clkdom_create(sc->sc_dev);
- if (sc->clkdom == NULL) {
- DPRINTF(sc->sc_dev, "Failed to create clkdom\n");
- return (ENXIO);
- }
+ sc = device_get_softc(dev);
+ DPRINTF(sc->dev, "ti_divider_clkdev_write_4: addr %x val %x\n",
+ addr, val);
+ return (SYSCON_UNLOCKED_WRITE_4(sc->syscon, addr, val));
+}
- err = clknode_div_register(sc->clkdom, &sc->div_def);
- if (err) {
- DPRINTF(sc->sc_dev, "clknode_div_register failed %x\n", err);
- return (ENXIO);
- }
+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;
- err = clkdom_finit(sc->clkdom);
- if (err) {
- DPRINTF(sc->sc_dev, "Clk domain finit fails %x.\n", err);
- return (ENXIO);
- }
+ sc = device_get_softc(dev);
+ rdval = SYSCON_UNLOCKED_READ_4(sc->syscon, addr);
+ *val = rdval;
+ DPRINTF(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->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->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->dev, "ti_divider_clkdev_device_unlock\n");
+ SYSCON_DEVICE_UNLOCK(sc->syscon->pdev);
+}
+
static int
ti_divider_probe(device_t dev)
{
@@ -125,14 +222,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;
+ 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;
@@ -148,7 +256,8 @@
if (OF_hasprop(node, "ti,index-power-of-two")) {
/* FIXME: later */
- device_printf(sc->sc_dev, "ti,index-power-of-two - Not implemented\n");
+ device_printf(sc->dev,
+ "ti,index-power-of-two - Not implemented\n");
/* remember to update i_width a few lines below */
}
if (OF_hasprop(node, "ti,max-div")) {
@@ -157,18 +266,21 @@
}
if (OF_hasprop(node, "clock-output-names"))
- device_printf(sc->sc_dev, "clock-output-names\n");
+ device_printf(sc->dev, "clock-output-names\n");
if (OF_hasprop(node, "ti,dividers"))
- device_printf(sc->sc_dev, "ti,dividers\n");
+ device_printf(sc->dev, "ti,dividers\n");
if (OF_hasprop(node, "ti,min-div"))
- device_printf(sc->sc_dev, "ti,min-div - Not implemented\n");
+ device_printf(sc->dev, "ti,min-div - Not implemented\n");
if (OF_hasprop(node, "ti,autoidle-shift"))
- device_printf(sc->sc_dev, "ti,autoidle-shift - Not implemented\n");
+ device_printf(sc->dev,
+ "ti,autoidle-shift - Not implemented\n");
if (OF_hasprop(node, "ti,set-rate-parent"))
- device_printf(sc->sc_dev, "ti,set-rate-parent - Not implemented\n");
+ device_printf(sc->dev,
+ "ti,set-rate-parent - Not implemented\n");
if (OF_hasprop(node, "ti,latch-bit"))
- device_printf(sc->sc_dev, "ti,latch-bit - Not implemented\n");
+ device_printf(sc->dev,
+ "ti,latch-bit - Not implemented\n");
/* Figure out the width from ti_max_div */
if (sc->div_def.div_flags)
@@ -176,33 +288,46 @@
else
sc->div_def.i_width = fls(ti_max_div);
- DPRINTF(sc->sc_dev, "div_def.i_width %x\n", sc->div_def.i_width);
+ DPRINTF(sc->dev, "div_def.i_width %x\n", sc->div_def.i_width);
- read_clock_cells(sc->sc_dev, &sc->clock_cell);
+ /* 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)
+ break;
+ }
- create_clkdef(sc->sc_dev, &sc->clock_cell, &sc->div_def.clkdef);
+ if (index == nitems(div_parent_table))
+ panic("Cant find clock %s\n", node_name);
- err = find_parent_clock_names(sc->sc_dev, &sc->clock_cell, &sc->div_def.clkdef);
+ DPRINTF(sc->dev, "%s at div_parent_table[%d]\n", node_name, index);
- 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));
+ /* Fill clknode_init_def */
+ sc->div_def.clkdef.id = 1;
+ sc->div_def.clkdef.flags = CLK_NODE_STATIC_STRINGS;
+ sc->div_def.clkdef.name = div_parent_table[index].node_name;
+ sc->div_def.clkdef.parent_cnt = div_parent_table[index].parent_cnt;
+ sc->div_def.clkdef.parent_names =
+ div_parent_table[index].parent_names;
+
+ sc->clkdom = clkdom_create(sc->dev);
+ if (sc->clkdom == NULL) {
+ DPRINTF(sc->dev, "Failed to create clkdom\n");
+ return (ENXIO);
}
- err = register_clk(sc);
+ err = clknode_div_register(sc->clkdom, &sc->div_def);
+ if (err != 0) {
+ DPRINTF(sc->dev, "clknode_div_register failed %x\n", err);
+ return (ENXIO);
+ }
- 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));
+ err = clkdom_finit(sc->clkdom);
+ if (err != 0) {
+ DPRINTF(sc->dev, "Clk domain finit fails %x.\n", err);
+ return (ENXIO);
}
- sc->attach_done = true;
-
- free_clkdef(&sc->div_def.clkdef);
-
- return (bus_generic_attach(sc->sc_dev));
+ return (bus_generic_attach(sc->dev));
}
static int
@@ -211,45 +336,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
};
diff --git a/sys/arm/ti/clk/ti_dpll_clock.c b/sys/arm/ti/clk/ti_dpll_clock.c
--- a/sys/arm/ti/clk/ti_dpll_clock.c
+++ b/sys/arm/ti/clk/ti_dpll_clock.c
@@ -48,7 +48,7 @@
#include <arm/ti/clk/ti_clk_dpll.h>
#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,32 +112,74 @@
{ NULL, TI_DPLL_END }
};
-static int
-register_clk(struct ti_dpll_softc *sc) {
- int err;
- sc->clkdom = clkdom_create(sc->dev);
- if (sc->clkdom == NULL) {
- DPRINTF(sc->dev, "Failed to create clkdom\n");
- return (ENXIO);
- }
+PLIST(dpll_core_ck_parent) = { "sys_clkin_ck@40", "sys_clkin_ck@40" };
+PLIST(dpll_core_x2_parent) = { "dpll_core_ck@490" };
- err = ti_clknode_dpll_register(sc->clkdom, &sc->dpll_def);
- if (err) {
- DPRINTF(sc->dev,
- "ti_clknode_dpll_register failed %x\n", err);
- return (ENXIO);
- }
+PLIST(dpll_mpu_ck_parent) = { "sys_clkin_ck@40", "sys_clkin_ck@40" };
- err = clkdom_finit(sc->clkdom);
- if (err) {
- DPRINTF(sc->dev, "Clk domain finit fails %x.\n", err);
- return (ENXIO);
- }
+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" };
- return (0);
-}
+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
ti_dpll_probe(device_t dev)
{
@@ -261,9 +301,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 +312,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 +333,44 @@
sc->dpll_def.ti_clkmode_flags |= LOCK_MODE_FLAG;
}
- read_clock_cells(sc->dev, &sc->clock_cell);
+ /* 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)
+ break;
+ }
- create_clkdef(sc->dev, &sc->clock_cell, &sc->dpll_def.clkdef);
+ if (index == nitems(dpll_parent_table))
+ panic("Cant find clock %s\n", node_name);
- err = find_parent_clock_names(sc->dev, &sc->clock_cell,
- &sc->dpll_def.clkdef);
+ DPRINTF(sc->dev, "%s at dpll_parent_table[%d]\n", node_name, index);
- 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));
+ /* Fill clknode_init_def */
+ sc->dpll_def.clkdef.id = 1;
+ sc->dpll_def.clkdef.name = dpll_parent_table[index].node_name;
+ sc->dpll_def.clkdef.parent_cnt = dpll_parent_table[index].parent_cnt;
+ sc->dpll_def.clkdef.parent_names =
+ dpll_parent_table[index].parent_names;
+ sc->dpll_def.clkdef.flags = CLK_NODE_STATIC_STRINGS;
+
+ sc->clkdom = clkdom_create(sc->dev);
+ if (sc->clkdom == NULL) {
+ DPRINTF(sc->dev, "Failed to create clkdom\n");
+ return (ENXIO);
}
- err = register_clk(sc);
+ err = ti_clknode_dpll_register(sc->clkdom, &sc->dpll_def);
+ if (err != 0) {
+ DPRINTF(sc->dev,
+ "ti_clknode_dpll_register failed %x\n", err);
+ return (ENXIO);
+ }
- 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));
+ err = clkdom_finit(sc->clkdom);
+ if (err != 0) {
+ DPRINTF(sc->dev, "Clk domain finit fails %x.\n", err);
+ return (ENXIO);
}
- sc->attach_done = true;
-
- free_clkdef(&sc->dpll_def.clkdef);
-
return (bus_generic_attach(sc->dev));
}
@@ -321,46 +380,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
};
diff --git a/sys/arm/ti/clk/ti_gate_clock.c b/sys/arm/ti/clk/ti_gate_clock.c
--- a/sys/arm/ti/clk/ti_gate_clock.c
+++ b/sys/arm/ti/clk/ti_gate_clock.c
@@ -41,13 +41,16 @@
#include <machine/bus.h>
#include <dev/fdt/simplebus.h>
-#include <dev/extres/clk/clk_gate.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/extres/clk/clk_gate.h>
+#include <dev/extres/syscon/syscon.h>
#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)
@@ -61,13 +64,12 @@
*/
struct ti_gate_softc {
- device_t sc_dev;
- bool attach_done;
+ device_t dev;
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);
@@ -88,13 +90,119 @@
{ "ti,wait-gate-clock", TI_WAIT_GATE_CLOCK },
{ "ti,dss-gate-clock", TI_DSS_GATE_CLOCK },
{ "ti,am35xx-gate-clock", TI_AM35XX_GATE_CLOCK },
- { "ti,clkdm-gate-clock", TI_CLKDM_GATE_CLOCK },
+ /* For now, dont support clkdm-gate-clock */
+ /* { "ti,clkdm-gate-clock", TI_CLKDM_GATE_CLOCK }, */
{ "ti,hsdiv-gate-cloc", TI_HSDIV_GATE_CLOCK },
- { "ti,composite-no-wait-gate-clock", TI_COMPOSITE_NO_WAIT_GATE_CLOCK },
+ { "ti,composite-no-wait-gate-clock", TI_COMPOSITE_NO_WAIT_GATE_CLOCK },
{ 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->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->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->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->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->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))
@@ -109,103 +217,104 @@
}
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");
- return ENXIO;
- }
-
- err = clknode_gate_register(sc->clkdom, &sc->gate_def);
- if (err) {
- DPRINTF(sc->sc_dev, "clknode_gate_register failed %x\n", err);
- return ENXIO;
- }
-
- err = clkdom_finit(sc->clkdom);
- if (err) {
- DPRINTF(sc->sc_dev, "Clk domain finit fails %x.\n", err);
- return ENXIO;
- }
-
- return (0);
-}
-
-static int
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;
+ 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;
/* Get the content of reg properties */
- if (sc->sc_type != TI_CLKDM_GATE_CLOCK) {
- OF_getencprop(node, "reg", &value, sizeof(value));
- sc->gate_def.offset = value;
+ if (!OF_hasprop(node, "reg")) {
+ device_printf(sc->dev, "missing reg property\n");
+ return (ENXIO);
}
-#if DEBUG_GATE
- else {
- DPRINTF(sc->sc_dev, "no reg (TI_CLKDM_GATE_CLOCK)\n");
- }
-#endif
+ OF_getencprop(node, "reg", &value, sizeof(value));
+ sc->gate_def.offset = value;
if (OF_hasprop(node, "ti,bit-shift")) {
OF_getencprop(node, "ti,bit-shift", &value, sizeof(value));
sc->gate_def.shift = value;
- DPRINTF(sc->sc_dev, "ti,bit-shift => shift %x\n", sc->gate_def.shift);
+ DPRINTF(sc->dev, "ti,bit-shift => shift %x\n",
+ sc->gate_def.shift);
}
if (OF_hasprop(node, "ti,set-bit-to-disable")) {
sc->gate_def.on_value = 0;
sc->gate_def.off_value = 1;
- DPRINTF(sc->sc_dev,
+ DPRINTF(sc->dev,
"on_value = 0, off_value = 1 (ti,set-bit-to-disable)\n");
} else {
sc->gate_def.on_value = 1;
sc->gate_def.off_value = 0;
- DPRINTF(sc->sc_dev, "on_value = 1, off_value = 0\n");
+ DPRINTF(sc->dev, "on_value = 1, off_value = 0\n");
}
sc->gate_def.gate_flags = 0x0;
- read_clock_cells(sc->sc_dev, &sc->clock_cell);
- 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)
+ break;
+ }
- /* 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);
+ if (index == nitems(gate_parent_table))
+ panic("Cant find clock %s\n", node_name);
- err = find_parent_clock_names(sc->sc_dev, &sc->clock_cell, &sc->gate_def.clkdef);
+ DPRINTF(dev, "%s at gate_parent_table[%d]\n",
+ node_name, index);
- 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));
- }
+ /* Fill clknode_init_def */
+ sc->gate_def.clkdef.id = 1;
+ sc->gate_def.clkdef.flags = CLK_NODE_STATIC_STRINGS;
+ sc->gate_def.clkdef.name = gate_parent_table[index].node_name;
+ sc->gate_def.clkdef.parent_cnt = gate_parent_table[index].parent_cnt;
+ sc->gate_def.clkdef.parent_names = gate_parent_table[index].parent_names;
- err = register_clk(sc);
+ /* Calculate mask */
+ sc->gate_def.mask = (1 << fls(sc->gate_def.clkdef.parent_cnt)) - 1;
+ DPRINTF(sc->dev, "num_real_clocks %x gate_def.mask %x\n",
+ sc->gate_def.clkdef.parent_cnt,
+ sc->gate_def.mask);
- 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));
+ sc->clkdom = clkdom_create(sc->dev);
+ if (sc->clkdom == NULL) {
+ DPRINTF(sc->dev, "Failed to create clkdom\n");
+ return ENXIO;
}
- sc->attach_done = true;
+ err = clknode_gate_register(sc->clkdom, &sc->gate_def);
+ if (err != 0) {
+ DPRINTF(sc->dev, "clknode_gate_register failed %x\n", err);
+ return ENXIO;
+ }
- free_clkdef(&sc->gate_def.clkdef);
+ err = clkdom_finit(sc->clkdom);
+ if (err != 0) {
+ DPRINTF(sc->dev, "Clk domain finit fails %x.\n", err);
+ return ENXIO;
+ }
- return (bus_generic_attach(sc->sc_dev));
+ return (bus_generic_attach(sc->dev));
}
static int
@@ -214,44 +323,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
};
diff --git a/sys/arm/ti/clk/ti_mux_clock.c b/sys/arm/ti/clk/ti_mux_clock.c
--- a/sys/arm/ti/clk/ti_mux_clock.c
+++ b/sys/arm/ti/clk/ti_mux_clock.c
@@ -44,29 +44,199 @@
#include <dev/fdt/simplebus.h>
#include <dev/extres/clk/clk_mux.h>
+#include <dev/extres/syscon/syscon.h>
+
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#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
*/
struct ti_mux_softc {
- device_t sc_dev;
- bool attach_done;
+ device_t dev;
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,56 +254,102 @@
};
static int
-ti_mux_probe(device_t dev)
+ti_mux_clkdev_write_4(device_t dev, bus_addr_t addr, uint32_t val)
{
- if (!ofw_bus_status_okay(dev))
- return (ENXIO);
+ struct ti_mux_softc *sc;
- if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
- return (ENXIO);
+ sc = device_get_softc(dev);
+ DPRINTF(sc->dev, "mux_clkdev_write_4: addr %x val %x\n",
+ addr, val);
+ return (SYSCON_UNLOCKED_WRITE_4(sc->syscon, addr, val));
+}
- device_set_desc(dev, "TI Mux Clock");
+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;
- return (BUS_PROBE_DEFAULT);
+ sc = device_get_softc(dev);
+
+ rdval = SYSCON_UNLOCKED_READ_4(sc->syscon, addr);
+ *val = rdval;
+ DPRINTF(sc->dev, "clkdev_read_4: addr %x val %x\n",
+ addr, *val);
+ return (0);
}
static int
-register_clk(struct ti_mux_softc *sc) {
- int err;
+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->clkdom = clkdom_create(sc->sc_dev);
- if (sc->clkdom == NULL) {
- DPRINTF(sc->sc_dev, "Failed to create clkdom\n");
- return ENXIO;
- }
+ sc = device_get_softc(dev);
+ DPRINTF(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));
+}
- err = clknode_mux_register(sc->clkdom, &sc->mux_def);
- if (err) {
- DPRINTF(sc->sc_dev, "clknode_mux_register failed %x\n", err);
- return ENXIO;
- }
+static void
+ti_mux_clkdev_device_lock(device_t dev)
+{
+ struct ti_mux_softc *sc;
- err = clkdom_finit(sc->clkdom);
- if (err) {
- DPRINTF(sc->sc_dev, "Clk domain finit fails %x.\n", err);
- return ENXIO;
- }
+ sc = device_get_softc(dev);
+ DPRINTF(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;
- return 0;
+ sc = device_get_softc(dev);
+ DPRINTF(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))
+ return (ENXIO);
+
+ if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+ return (ENXIO);
+
+ device_set_desc(dev, "TI Mux Clock");
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
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;
+ 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;
@@ -141,84 +357,70 @@
if (OF_hasprop(node, "ti,bit-shift")) {
OF_getencprop(node, "ti,bit-shift", &value, sizeof(value));
sc->mux_def.shift = value;
- DPRINTF(sc->sc_dev, "ti,bit-shift => shift %x\n", sc->mux_def.shift);
+ DPRINTF(sc->dev, "ti,bit-shift => shift %x\n",
+ sc->mux_def.shift);
}
if (OF_hasprop(node, "ti,index-starts-at-one")) {
/* FIXME: Add support in dev/extres/clk */
/*sc->mux_def.mux_flags = ... */
- device_printf(sc->sc_dev, "ti,index-starts-at-one - Not implemented\n");
+ device_printf(sc->dev,
+ "ti,index-starts-at-one - Not implemented\n");
}
if (OF_hasprop(node, "ti,set-rate-parent"))
- device_printf(sc->sc_dev, "ti,set-rate-parent - Not implemented\n");
+ device_printf(sc->dev,
+ "ti,set-rate-parent - Not implemented\n");
if (OF_hasprop(node, "ti,latch-bit"))
- device_printf(sc->sc_dev, "ti,latch-bit - Not implemented\n");
+ device_printf(sc->dev,
+ "ti,latch-bit - Not implemented\n");
- read_clock_cells(sc->sc_dev, &sc->clock_cell);
- 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)
+ break;
+ }
+ if (index == nitems(mux_parent_table))
+ panic("Cant find clock %s\n", node_name);
+ DPRINTF(sc->dev, "%s at mux_parent_table[%d]\n",
+ node_name, index);
+ /* Fill clknode_init_def */
+ sc->mux_def.clkdef.id = 1;
+ sc->mux_def.clkdef.flags = CLK_NODE_STATIC_STRINGS;
+
+ sc->mux_def.clkdef.name = mux_parent_table[index].node_name;
+ sc->mux_def.clkdef.parent_cnt = mux_parent_table[index].parent_cnt;
+ sc->mux_def.clkdef.parent_names = mux_parent_table[index].parent_names;
+
/* 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(sc->mux_def.clkdef.parent_cnt-1);
else
- sc->mux_def.width = fls(sc->clock_cell.num_real_clocks);
+ sc->mux_def.width = fls(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->dev, "parents %x def.width %x\n",
+ 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));
+ sc->clkdom = clkdom_create(sc->dev);
+ if (sc->clkdom == NULL) {
+ DPRINTF(sc->dev, "Failed to create clkdom\n");
+ return ENXIO;
}
- 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));
+ err = clknode_mux_register(sc->clkdom, &sc->mux_def);
+ if (err != 0) {
+ DPRINTF(sc->dev, "clknode_mux_register failed %x\n", err);
+ 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 = clkdom_finit(sc->clkdom);
+ if (err != 0) {
+ DPRINTF(sc->dev, "Clk domain finit fails %x.\n", err);
+ return ENXIO;
}
- 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);
+ return (bus_generic_attach(sc->dev));
}
static int
@@ -233,8 +435,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
};
diff --git a/sys/arm/ti/files.ti b/sys/arm/ti/files.ti
--- a/sys/arm/ti/files.ti
+++ b/sys/arm/ti/files.ti
@@ -5,7 +5,7 @@
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_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 +20,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
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
@@ -40,18 +40,14 @@
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
-#include <sys/malloc.h>
+#include <sys/mutex.h>
#include <sys/rman.h>
-#include <sys/timeet.h>
-#include <sys/timetc.h>
-#include <sys/watchdog.h>
#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/intr.h>
#include <arm/ti/ti_cpuid.h>
#include <arm/ti/ti_prcm.h>
#include <arm/ti/tivar.h>
+#include <arm/ti/clk/clock_common.h>
#include <dev/fdt/simplebus.h>
@@ -59,22 +55,23 @@
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/extres/clk/clk.h>
+#include <dev/extres/clk/clk_link.h>
+#include <dev/extres/syscon/syscon.h>
+#include <dev/extres/syscon/syscon_generic.h>
+
+#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;
@@ -102,84 +99,241 @@
#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 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"),
+};
+
+static struct clk_link_def per_cm_0[] = {
+ /* reg = <0x38 0x2c>, <0x6c 0x28>, <0xac 0xc>,
+ <0xc0 0x1c>, <0xec 0xc>, <0x10c 0x8>, <0x130 0x4>; */
+ /* <0x38 0x2c> */
+ 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"),
+ /* <0x6c 0x28> */
+ 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"),
+ /* <0xac 0xc> */
+ 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"),
+ /* <0xc0 0x1c> */
+ 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"),
+ /* <0xec 0xc> */
+ LINK("l4ls-clkctrl@38_b4"),
+ LINK("l4ls-clkctrl@38_b8"),
+ LINK("l4ls-clkctrl@38_bc"),
+ /* <0xd4 0x8> */
+ LINK("l4ls-clkctrl@38_d4"),
+ LINK("l4ls-clkctrl@38_d8"),
+ /* <0x130 0x4> */
+ LINK("l4ls-clkctrl@38_f8"),
+
+
+ /* reg = <0x1c 0x4>, <0x30 0x8>, <0x68 0x4>, <0xf8 0x4> */
+ /* <0x1c 0x4> */
+ LINK("l3s-clkctrl@1c_0"),
+ /* <0x30 0x8> */
+ LINK("l3s-clkctrl@1c_14"),
+ LINK("l3s-clkctrl@1c_18"),
+ /* <0x68 0x4> */
+ LINK("l3s-clkctrl@1c_4c"),
+ /* <0xf8 0x4> */
+ LINK("l3s-clkctrl@1c_dc"),
+
+ /* reg = <0x24 0xc>, <0x94 0x10>, <0xbc 0x4>, <0xdc 0x8>, <0xfc 0x8>; */
+ /* <0x24 0xc> */
+ LINK("l3-clkctrl@24_0"),
+ LINK("l3-clkctrl@24_4"),
+ LINK("l3-clkctrl@24_8"),
+ /* <0x94 0x10> */
+ LINK("l3-clkctrl@24_70"),
+ LINK("l3-clkctrl@24_74"),
+ LINK("l3-clkctrl@24_78"),
+ LINK("l3-clkctrl@24_7c"),
+ /* <0xbc 0x4> */
+ LINK("l3-clkctrl@24_98"),
+ /* <0xdc 0x8> */
+ LINK("l3-clkctrl@24_b8"),
+ LINK("l3-clkctrl@24_bc"),
+ /* <0xfc 0x8> */
+ LINK("l3-clkctrl@24_d8"),
+ LINK("l3-clkctrl@24_dc"),
+
+ /* reg = <0x120 0x4>; */
+ LINK("l4hs-clkctrl@120_0"),
+
+ /* reg = <0xe8 0x4>; */
+ LINK("pruss-ocp-clkctrl@e8_0"),
+
+ /* reg = <0x0 0x18>; */
+ 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"),
+
+ /* reg = <0x18 0x4>; */
+ LINK("lcdc-clkctrl@18_0"),
+
+ /* reg = <0x14c 0x4>; */
+ LINK("clk-24mhz-clkctrl@14c_0"),
+
+ /* reg = <0x0 0x10>, <0xb4 0x24>; */
+ /* <0x0 0x10> */
+ 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"),
+ /* <0xb4 0x24> */
+ 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"),
+
+ /* reg = <0x14 0x4>; */
+ LINK("l3-aon-clkctrl@14_0"),
+
+ /* reg = <0xb0 0x4>; */
+ LINK("l4-wkup-aon-clkctrl@b0_0"),
+
+ /* reg = <0x0 0x8>; */
+ LINK("mpu-clkctrl@0_0"),
+ LINK("mpu-clkctrl@0_4"),
+
+ /* reg = <0x0 0x4>; */
+ LINK("l4-rtc-clkctrl@0_0"),
+
+ /* reg = <0x0 0x8>; */
+ LINK("gfx-l3-clkctrl@0_0"),
+ LINK("gfx-l3-clkctrl@0_4"),
+
+ /* reg = <0x0 0x24>; */
+ 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) {
+ 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);
+ return (BUS_PROBE_DEFAULT);
}
static int
-ti_prcm_attach(device_t dev)
-{
- struct ti_prcm_softc *sc;
- phandle_t node, child;
- int rid;
+ti_prcm_attach(device_t dev) {
+ int i, err, ret;
+ struct ti_prcm_softc *prcm_sc;
- sc = device_get_softc(dev);
- sc->dev = dev;
- node = ofw_bus_get_node(sc->dev);
- simplebus_init(sc->dev, node);
+ device_printf(dev, "ti_prcm_attach\n");
+ prcm_sc = device_get_softc(dev);
- 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);
- }
+ prcm_sc->clkdom = clkdom_create(dev);
+ if (prcm_sc->clkdom == NULL)
+ panic("Cannot create clkdom\n");
- 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);
+ 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);
- if (sc->mem_res == NULL) {
- return (ENXIO);
}
+ 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);
+ }
- sc->bst = rman_get_bustag(sc->mem_res);
- sc->bsh = rman_get_bushandle(sc->mem_res);
+ if (clkdom_finit(prcm_sc->clkdom) != 0)
+ panic("cannot finalize clkdom initialization\n");
- mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF);
+ /* Setup reset handler */
+ ti_prcm_sc = prcm_sc;
- /* Fixme: for xxx_prcm_reset functions.
- * Get rid of global variables?
- */
- ti_prcm_sc = sc;
-
switch(ti_chip()) {
#ifdef SOC_OMAP4
case CHIP_OMAP_4:
@@ -193,32 +347,30 @@
#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));
+ 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,42 +378,56 @@
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 int
+ti_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 ti_prcm_methods[] = {
+ /* Device interface */
DEVMETHOD(device_probe, ti_prcm_probe),
DEVMETHOD(device_attach, ti_prcm_attach),
+ /* syscon interface */
+ DEVMETHOD(syscon_get_handle, ti_syscon_generic_get_handle),
+
/* clkdev interface */
DEVMETHOD(clkdev_write_4, ti_prcm_write_4),
DEVMETHOD(clkdev_read_4, ti_prcm_read_4),
@@ -273,16 +439,15 @@
};
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);
static devclass_t ti_prcm_devclass;
-EARLY_DRIVER_MODULE(ti_prcm, ofwbus, 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 <dmarion@Freebsd.org>
@@ -293,7 +458,11 @@
static void
am335x_prcm_reset(void)
{
- ti_prcm_write_4(ti_prcm_sc->dev, AM335x_PRM_RSTCTRL, (1<<1));
+ device_t dev = ((struct syscon_generic_softc *)ti_prcm_sc)->dev;
+
+ ti_prcm_device_lock(dev);
+ ti_prcm_write_4(dev, AM335x_PRM_RSTCTRL, (1<<1));
+ ti_prcm_device_unlock(dev);
}
/* FIXME: Is this correct - or should the license part be ontop? */
@@ -336,9 +505,12 @@
omap4_prcm_reset(void)
{
uint32_t reg;
+ device_t dev = ((struct syscon_generic_softc *)ti_prcm_sc)->dev;
- ti_prcm_read_4(ti_prcm_sc->dev, PRM_RSTCTRL, ®);
+ ti_prcm_device_lock(dev);
+ ti_prcm_read_4(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(dev, PRM_RSTCTRL, reg);
+ ti_prcm_read_4(dev, PRM_RSTCTRL, ®);
+ ti_prcm_device_unlock(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
@@ -42,10 +42,13 @@
#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/extres/syscon/syscon.h>
#include <arm/ti/ti_prcm.h>
#include <arm/ti/ti_prm.h>
-#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[] = {
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
@@ -32,266 +32,78 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
-#include <sys/systm.h>
+#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/resource.h>
-#include <sys/rman.h>
-#include <sys/lock.h>
#include <sys/mutex.h>
+#include <sys/rman.h>
-#include <machine/bus.h>
-#include <machine/resource.h>
-
-#include <dev/fdt/simplebus.h>
-
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
-#include "syscon_if.h"
#include <dev/extres/syscon/syscon.h>
-#include "clkdev_if.h"
-
+#include <dev/extres/syscon/syscon_generic.h>
#include <arm/ti/ti_cpuid.h>
+#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)
+ /* 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);
+ /* 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);
+
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;
+ struct syscon_generic_softc *sc;
- sc = device_get_softc(dev);
- *syscon = sc->syscon;
- if (*syscon == NULL)
- return (ENODEV);
- return (0);
+ 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);
+ sizeof(struct syscon_generic_softc), syscon_generic_driver);
static devclass_t ti_scm_syscon_devclass;
+/* 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,
ti_scm_syscon_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);
MODULE_VERSION(ti_scm_syscon, 1);
diff --git a/sys/arm/ti/ti_sysc.c b/sys/arm/ti/ti_sysc.c
--- a/sys/arm/ti/ti_sysc.c
+++ b/sys/arm/ti/ti_sysc.c
@@ -55,7 +55,7 @@
#include <arm/ti/ti_sysc.h>
#include <arm/ti/clk/clock_common.h>
-#define DEBUG_SYSC 0
+#define DEBUG_SYSC 1
#if DEBUG_SYSC
#define DPRINTF(dev, msg...) device_printf(dev, msg)
@@ -112,6 +112,342 @@
{ 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 +471,6 @@
struct ti_sysc_softc {
struct simplebus_softc sc;
- bool attach_done;
device_t dev;
int device_type;
@@ -245,7 +580,7 @@
TAILQ_FOREACH_SAFE(clkp, &sc->clk_list, next, clkp_tmp) {
err = clk_enable(clkp->clk);
- if (err) {
+ if (err != 0) {
DPRINTF(sc->dev, "clk_enable %s failed %d\n",
clk_get_name(clkp->clk), err);
break;
@@ -263,7 +598,7 @@
TAILQ_FOREACH_SAFE(clkp, &sc->clk_list, next, clkp_tmp) {
err = clk_disable(clkp->clk);
- if (err) {
+ if (err != 0) {
DPRINTF(sc->dev, "clk_enable %s failed %d\n",
clk_get_name(clkp->clk), err);
break;
@@ -346,6 +681,7 @@
sc->reg[prop_idx].size);
}
free(reg, M_DEVBUF);
+
return (0);
}
@@ -396,39 +732,6 @@
}
static int
-ti_sysc_attach_clocks(struct ti_sysc_softc *sc) {
- clk_t *clk;
- struct clk_list *clkp;
- int index, err;
- phandle_t cnode;
-
- clk = malloc(sc->num_clocks*sizeof(clk_t), M_DEVBUF, M_WAITOK | M_ZERO);
-
- cnode = ofw_bus_get_node(sc->dev);
-
- /* Check if all clocks can be found */
- for (index = 0; index < sc->num_clocks; index++) {
- err = clk_get_by_ofw_index(sc->dev, 0, index, &clk[index]);
-
- if (err != 0) {
- free(clk, M_DEVBUF);
- return (1);
- }
- }
-
- /* All clocks are found, add to list */
- for (index = 0; index < sc->num_clocks; index++) {
- clkp = malloc(sizeof(*clkp), M_DEVBUF, M_WAITOK | M_ZERO);
- clkp->clk = clk[index];
- TAILQ_INSERT_TAIL(&sc->clk_list, clkp, next);
- }
-
- /* Release the clk array */
- free(clk, M_DEVBUF);
- return (0);
-}
-
-static int
ti_sysc_simplebus_attach_child(device_t dev) {
device_t cdev;
phandle_t node, child;
@@ -486,7 +789,7 @@
/* Required field reg & reg-names - assume at least "rev" exists */
err = parse_regfields(sc);
- if (err) {
+ if (err != 0) {
DPRINTF(sc->dev, "parse_regfields failed %d\n", err);
return (ENXIO);
}
@@ -533,30 +836,51 @@
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 idx, clk_idx;
+ const char *name = ofw_bus_get_name(dev);
+ DPRINTF(dev, "%s has clock\n", name);
- sc->num_clocks = cell_info.num_real_clocks;
+ for (idx = 0; idx < nitems(sysc_clock_table); idx++) {
+ if (strcmp(sysc_clock_table[idx].node_name, name)==0)
+ break;
+ }
+
+ if (idx == nitems(sysc_clock_table))
+ panic("Cant find clocks for node %s\n", name);
+
+ DPRINTF(dev, "%s at sysc_clock_table[%d]\n", name, idx);
+ /*
+ * Found the correct place in the lookup table.
+ * Loop through and get the clocks
+ */
+
TAILQ_INIT(&sc->clk_list);
+ sc->num_clocks = sysc_clock_table[idx].parent_cnt;
+ clk_idx = 0;
+ for (; clk_idx < sysc_clock_table[idx].parent_cnt; clk_idx++) {
+ struct clk_list *clkp;
+ clkp = malloc(sizeof(*clkp), M_DEVBUF,
+ M_WAITOK | M_ZERO);
- err = ti_sysc_attach_clocks(sc);
- if (err) {
- DPRINTF(sc->dev, "Failed to attach clocks\n");
- return (bus_generic_attach(sc->dev));
+ err = clk_get_by_name(dev,
+ sysc_clock_table[idx].parent_names[clk_idx],
+ &clkp->clk);
+ if (err != 0)
+ panic("Cant get clock %s err %d",
+ sysc_clock_table[idx].parent_names[clk_idx],
+ err);
+
+ TAILQ_INSERT_TAIL(&sc->clk_list, clkp, next);
}
- }
+ }
err = ti_sysc_simplebus_attach_child(sc->dev);
- if (err) {
+ if (err != 0) {
DPRINTF(sc->dev, "ti_sysc_simplebus_attach_child %d\n",
err);
return (err);
}
- sc->attach_done = true;
-
return (bus_generic_attach(sc->dev));
}
@@ -566,50 +890,12 @@
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
};
@@ -619,4 +905,4 @@
static devclass_t ti_sysc_devclass;
EARLY_DRIVER_MODULE(ti_sysc, simplebus, ti_sysc_driver,
- ti_sysc_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_FIRST);
+ ti_sysc_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_LATE);
diff --git a/sys/dev/extres/syscon/syscon_generic.h b/sys/dev/extres/syscon/syscon_generic.h
--- a/sys/dev/extres/syscon/syscon_generic.h
+++ b/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 */
diff --git a/sys/dev/extres/syscon/syscon_generic.c b/sys/dev/extres/syscon/syscon_generic.c
--- a/sys/dev/extres/syscon/syscon_generic.c
+++ b/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;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Apr 29, 4:00 PM (16 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17842519
Default Alt Text
D27889.id82297.diff (102 KB)
Attached To
Mode
D27889: TI SoC rework clk support
Attached
Detach File
Event Timeline
Log In to Comment