summaryrefslogtreecommitdiff
path: root/drivers/clk/meson/meson8b-clkc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/meson/meson8b-clkc.c')
-rw-r--r--drivers/clk/meson/meson8b-clkc.c93
1 files changed, 65 insertions, 28 deletions
diff --git a/drivers/clk/meson/meson8b-clkc.c b/drivers/clk/meson/meson8b-clkc.c
index dcd8f030782d..57dea03e64b2 100644
--- a/drivers/clk/meson/meson8b-clkc.c
+++ b/drivers/clk/meson/meson8b-clkc.c
@@ -41,6 +41,8 @@
#define MESON8B_REG_PLL_SYS 0x0300
#define MESON8B_REG_PLL_VID 0x0320
+static DEFINE_SPINLOCK(clk_lock);
+
static const struct pll_rate_table sys_pll_rate_table[] = {
PLL_RATE(312000000, 52, 1, 2),
PLL_RATE(336000000, 56, 1, 2),
@@ -111,18 +113,6 @@ static const struct clk_div_table cpu_div_table[] = {
{ /* sentinel */ },
};
-PNAME(p_clk81) = { "fclk_div3", "fclk_div4", "fclk_div5" };
-
-static u32 mux_table_clk81[] = { 6, 5, 7 };
-
-static const struct composite_conf clk81_conf __initconst = {
- .mux_table = mux_table_clk81,
- .mux_flags = CLK_MUX_READ_ONLY,
- .mux_parm = PARM(0x00, 12, 3),
- .div_parm = PARM(0x00, 0, 7),
- .gate_parm = PARM(0x00, 7, 1),
-};
-
static struct clk_fixed_rate meson8b_xtal = {
.fixed_rate = 24000000,
.hw.init = &(struct clk_init_data){
@@ -267,6 +257,11 @@ static struct clk_fixed_factor meson8b_fclk_div7 = {
},
};
+/*
+ * FIXME cpu clocks and the legacy composite clocks (e.g. clk81) are both PLL
+ * post-dividers and should be modeled with their respective PLLs via the
+ * forthcoming coordinated clock rates feature
+ */
static struct meson_clk_cpu meson8b_cpu_clk = {
.reg_off = MESON8B_REG_SYS_CPU_CNTL1,
.div_table = cpu_div_table,
@@ -279,18 +274,57 @@ static struct meson_clk_cpu meson8b_cpu_clk = {
},
};
-static const struct clk_conf meson8b_clk_confs[] __initconst = {
- COMPOSITE(MESON8B_REG_HHI_MPEG, CLKID_CLK81, "clk81", p_clk81,
- CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED, &clk81_conf),
+static u32 mux_table_clk81[] = { 6, 5, 7 };
+
+struct clk_mux meson8b_mpeg_clk_sel = {
+ .reg = (void *)MESON8B_REG_HHI_MPEG,
+ .mask = 0x7,
+ .shift = 12,
+ .flags = CLK_MUX_READ_ONLY,
+ .table = mux_table_clk81,
+ .lock = &clk_lock,
+ .hw.init = &(struct clk_init_data){
+ .name = "mpeg_clk_sel",
+ .ops = &clk_mux_ro_ops,
+ /*
+ * FIXME bits 14:12 selects from 8 possible parents:
+ * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2,
+ * fclk_div4, fclk_div3, fclk_div5
+ */
+ .parent_names = (const char *[]){ "fclk_div3", "fclk_div4",
+ "fclk_div5" },
+ .num_parents = 3,
+ .flags = (CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED),
+ },
+};
+
+struct clk_divider meson8b_mpeg_clk_div = {
+ .reg = (void *)MESON8B_REG_HHI_MPEG,
+ .shift = 0,
+ .width = 7,
+ .lock = &clk_lock,
+ .hw.init = &(struct clk_init_data){
+ .name = "mpeg_clk_div",
+ .ops = &clk_divider_ops,
+ .parent_names = (const char *[]){ "mpeg_clk_sel" },
+ .num_parents = 1,
+ .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),
+ },
+};
+
+struct clk_gate meson8b_clk81 = {
+ .reg = (void *)MESON8B_REG_HHI_MPEG,
+ .bit_idx = 7,
+ .lock = &clk_lock,
+ .hw.init = &(struct clk_init_data){
+ .name = "clk81",
+ .ops = &clk_gate_ops,
+ .parent_names = (const char *[]){ "mpeg_clk_div" },
+ .num_parents = 1,
+ .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),
+ },
};
-/*
- * FIXME we cannot register two providers w/o breaking things. Luckily only
- * clk81 is actually used by any drivers. Convert clk81 to use
- * clk_hw_onecell_data last and flip the switch to call of_clk_add_hw_provider
- * instead of of_clk_add_provider in the clk81 conversion patch to keep from
- * breaking bisect. Then delete this comment ;-)
- */
static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
.hws = {
[CLKID_XTAL] = &meson8b_xtal.hw,
@@ -303,6 +337,9 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
[CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw,
[CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw,
[CLKID_CPUCLK] = &meson8b_cpu_clk.hw,
+ [CLKID_MPEG_SEL] = &meson8b_mpeg_clk_sel.hw,
+ [CLKID_MPEG_DIV] = &meson8b_mpeg_clk_div.hw,
+ [CLKID_CLK81] = &meson8b_clk81.hw,
},
.num = CLK_NR_CLKS,
};
@@ -320,9 +357,6 @@ static void __init meson8b_clkc_init(struct device_node *np)
struct clk_hw *parent_hw;
struct clk *parent_clk;
- if (!meson_clk_init(np, CLK_NR_CLKS))
- return;
-
/* Generic clocks and PLLs */
clk_base = of_iomap(np, 1);
if (!clk_base) {
@@ -337,6 +371,11 @@ static void __init meson8b_clkc_init(struct device_node *np)
/* Populate the base address for CPU clk */
meson8b_cpu_clk.base = clk_base;
+ /* Populate the base address for the MPEG clks */
+ meson8b_mpeg_clk_sel.reg = clk_base + (u32)meson8b_mpeg_clk_sel.reg;
+ meson8b_mpeg_clk_div.reg = clk_base + (u32)meson8b_mpeg_clk_div.reg;
+ meson8b_clk81.reg = clk_base + (u32)meson8b_clk81.reg;
+
/*
* register all clks
* CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
@@ -375,9 +414,7 @@ static void __init meson8b_clkc_init(struct device_node *np)
goto unregister_clk_nb;
}
- meson_clk_register_clks(meson8b_clk_confs,
- ARRAY_SIZE(meson8b_clk_confs),
- clk_base);
+ of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &meson8b_hw_onecell_data);
return;
/* FIXME remove after converting to platform_driver/devm_clk_register */