From 6c937ab67318a128b0b50f1396f92fcda7c8711a Mon Sep 17 00:00:00 2001 From: Qiufang Dai Date: Sat, 26 May 2018 11:31:36 +0800 Subject: [PATCH] clk: add sys1_pll/sys_pll for g12b PD#165090: Add sys1_pll/sys_pll for g12b These patch is compatible with g12a. clk structur: G12A: sys_pll(0xbd) ----> cpu_mux(0x67) ---> A53 G12B: sys1_pll(0xe0) ----> cpu_mux(0x67) ---> A53 sys_pll(0xbd) ----> cpu_mux1(0x82) ---> A73 Change-Id: I67b508f216db6124885154ea09ccb4868834e772 Signed-off-by: Qiufang Dai --- drivers/amlogic/clk/g12a/g12a.c | 93 ++++++++++++++++++++++++--- drivers/amlogic/clk/g12b/g12b.c | 23 ++++--- drivers/amlogic/cpu_version/meson64_cpu.c | 6 ++ include/dt-bindings/clock/amlogic,g12a-clkc.h | 10 +-- 4 files changed, 111 insertions(+), 21 deletions(-) diff --git a/drivers/amlogic/clk/g12a/g12a.c b/drivers/amlogic/clk/g12a/g12a.c index ebf7c4a..a155c5b 100644 --- a/drivers/amlogic/clk/g12a/g12a.c +++ b/drivers/amlogic/clk/g12a/g12a.c @@ -23,13 +23,13 @@ #include #include +#include #include "../clkc.h" #include "g12a.h" static struct clk_onecell_data clk_data; /* #undef pr_debug */ /* #define pr_debug pr_info */ - static const struct clk_div_table cpu_div_table[] = { { .val = 1, .div = 1 }, { .val = 2, .div = 2 }, @@ -103,6 +103,34 @@ static struct meson_clk_pll g12a_sys_pll = { }, }; +static struct meson_clk_pll g12b_sys1_pll = { + .m = { + .reg_off = HHI_SYS1_PLL_CNTL0, + .shift = 0, + .width = 9, + }, + .n = { + .reg_off = HHI_SYS1_PLL_CNTL0, + .shift = 10, + .width = 5, + }, + .od = { + .reg_off = HHI_SYS1_PLL_CNTL0, + .shift = 16, + .width = 3, + }, + .rate_table = g12a_pll_rate_table, + .rate_count = ARRAY_SIZE(g12a_pll_rate_table), + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "sys1_pll", + .ops = &meson_g12a_pll_ops, + .parent_names = (const char *[]){ "xtal" }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + static struct meson_clk_pll g12a_gp0_pll = { .m = { .reg_off = HHI_GP0_PLL_CNTL0, @@ -503,6 +531,24 @@ static struct meson_clk_cpu g12a_cpu_clk = { }, }; +static struct meson_clk_cpu g12b_cpu_clk1 = { + .reg_off = HHI_SYS_CPU_CLK_CNTL0, + .clk_nb.notifier_call = meson_clk_cpu_notifier_cb, + .mux.reg = (void *)HHI_SYS_CPU_CLK_CNTL0, + .mux.shift = 11, + .mux.mask = 0x1, + .mux.lock = &clk_lock, + .mux.table = mux_table_cpu_px, + .mux.hw.init = &(struct clk_init_data){ + .name = "cpu_clk", + .ops = &meson_clk_cpu_ops, + .parent_names = (const char *[]){ "cpu_fixedpll_p", "sys1_pll"}, + .num_parents = 2, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + + static u32 mux_table_clk81[] = { 6, 5, 7 }; @@ -636,7 +682,7 @@ static MESON_GATE(g12a_ao_i2c, HHI_GCLK_AO, 4); /* Array of all clocks provided by this provider */ static struct clk_hw *g12a_clk_hws[] = { - [CLKID_SYS_PLL] = &g12a_sys_pll.hw, + //[CLKID_SYS_PLL] = &g12a_sys_pll.hw, [CLKID_FIXED_PLL] = &g12a_fixed_pll.hw, [CLKID_GP0_PLL] = &g12a_gp0_pll.hw, [CLKID_HIFI_PLL] = &g12a_hifi_pll.hw, @@ -745,7 +791,7 @@ static struct clk_hw *g12a_clk_hws[] = { static struct meson_clk_pll *const g12a_clk_plls[] = { &g12a_fixed_pll, - &g12a_sys_pll, + //&g12a_sys_pll, &g12a_gp0_pll, &g12a_hifi_pll, &g12a_pcie_pll, @@ -841,6 +887,8 @@ static void __init g12a_clkc_init(struct device_node *np) struct clk_hw *parent_hw; struct clk *parent_clk; + meson_cpu_version_init(); + /* Generic clocks and PLLs */ if (!clk_base) clk_base = of_iomap(np, 0); @@ -854,13 +902,25 @@ static void __init g12a_clkc_init(struct device_node *np) for (i = 0; i < ARRAY_SIZE(g12a_clk_plls); i++) g12a_clk_plls[i]->base = clk_base; + if (is_meson_g12b_cpu()) + g12b_sys1_pll.base = clk_base; + else + g12a_sys_pll.base = clk_base; + /* Populate base address for MPLLs */ for (i = 0; i < ARRAY_SIZE(g12a_clk_mplls); i++) g12a_clk_mplls[i]->base = clk_base; /* Populate the base address for CPU clk */ - g12a_cpu_clk.base = clk_base; - g12a_cpu_clk.mux.reg = clk_base + (u64)g12a_cpu_clk.mux.reg; + if (is_meson_g12b_cpu()) { + g12a_clk_hws[CLKID_CPU_CLK] = &g12b_cpu_clk1.mux.hw; + g12b_cpu_clk1.base = clk_base; + g12b_cpu_clk1.mux.reg = clk_base + (u64)g12b_cpu_clk1.mux.reg; + } else { + g12a_cpu_clk.base = clk_base; + g12a_cpu_clk.mux.reg = clk_base + (u64)g12a_cpu_clk.mux.reg; + } + #if 0 g12a_cpu_fixedpll_p00.reg = clk_base + (u64)g12a_cpu_fixedpll_p00.reg; g12a_cpu_fixedpll_p01.reg = clk_base + (u64)g12a_cpu_fixedpll_p01.reg; @@ -895,6 +955,16 @@ static void __init g12a_clkc_init(struct device_node *np) * register all clks */ + if (is_meson_g12b_cpu()) { + clks[CLKID_SYS1_PLL] = clk_register(NULL, &g12b_sys1_pll.hw); + if (IS_ERR(clks[CLKID_SYS1_PLL])) { + pr_err("%s: failed to register %s\n", __func__, + clk_hw_get_name(&g12b_sys1_pll.hw)); + goto iounmap; + } + } else + g12a_clk_hws[CLKID_SYS_PLL] = &g12a_sys_pll.hw; + for (clkid = 0; clkid < ARRAY_SIZE(g12a_clk_hws); clkid++) { if (g12a_clk_hws[clkid]) { clks[clkid] = clk_register(NULL, g12a_clk_hws[clkid]); @@ -926,9 +996,16 @@ static void __init g12a_clkc_init(struct device_node *np) * a new clk_hw, and this hack will no longer work. Releasing the ccr * feature before that time solves the problem :-) */ - parent_hw = clk_hw_get_parent(&g12a_cpu_clk.mux.hw); - parent_clk = parent_hw->clk; - ret = clk_notifier_register(parent_clk, &g12a_cpu_clk.clk_nb); + if (is_meson_g12b_cpu()) { + parent_hw = clk_hw_get_parent(&g12b_cpu_clk1.mux.hw); + parent_clk = parent_hw->clk; + ret = clk_notifier_register(parent_clk, &g12b_cpu_clk1.clk_nb); + } else { + parent_hw = clk_hw_get_parent(&g12a_cpu_clk.mux.hw); + parent_clk = parent_hw->clk; + ret = clk_notifier_register(parent_clk, &g12a_cpu_clk.clk_nb); + } + if (ret) { pr_err("%s: failed to register clock notifier for cpu_clk\n", __func__); diff --git a/drivers/amlogic/clk/g12b/g12b.c b/drivers/amlogic/clk/g12b/g12b.c index e2e6840..ed74928 100644 --- a/drivers/amlogic/clk/g12b/g12b.c +++ b/drivers/amlogic/clk/g12b/g12b.c @@ -26,19 +26,19 @@ #include "../clkc.h" #include "../g12a/g12a.h" -static struct meson_clk_pll g12b_sys1_pll = { +static struct meson_clk_pll g12b_sys_pll = { .m = { - .reg_off = HHI_SYS1_PLL_CNTL0, + .reg_off = HHI_SYS_PLL_CNTL0, .shift = 0, .width = 9, }, .n = { - .reg_off = HHI_SYS1_PLL_CNTL0, + .reg_off = HHI_SYS_PLL_CNTL0, .shift = 10, .width = 5, }, .od = { - .reg_off = HHI_SYS1_PLL_CNTL0, + .reg_off = HHI_SYS_PLL_CNTL0, .shift = 16, .width = 3, }, @@ -46,7 +46,7 @@ static struct meson_clk_pll g12b_sys1_pll = { .rate_count = ARRAY_SIZE(g12a_pll_rate_table), .lock = &clk_lock, .hw.init = &(struct clk_init_data){ - .name = "sys1_pll", + .name = "sys_pll", .ops = &meson_g12a_pll_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, @@ -118,7 +118,7 @@ static struct meson_clk_cpu g12b_cpu_clk = { .name = "cpub_clk", .ops = &meson_clk_cpu_ops, .parent_names = (const char *[]){ "cpub_fixedpll_p", - "sys1_pll"}, + "sys_pll"}, .num_parents = 2, .flags = CLK_GET_RATE_NOCACHE, }, @@ -211,13 +211,13 @@ static struct clk_gate cts_gdc_axi_clk_gate = { }; static struct clk_hw *g12b_clk_hws[] = { - [CLKID_SYS1_PLL - CLKID_G12B_ADD_BASE] = &g12b_sys1_pll.hw, +// [CLKID_SYS_PLL - CLKID_G12B_ADD_BASE] = &g12b_sys_pll.hw, [CLKID_CPUB_FCLK_P - CLKID_G12B_ADD_BASE] = &g12b_cpu_fclk_p.hw, [CLKID_CPUB_CLK - CLKID_G12B_ADD_BASE] = &g12b_cpu_clk.mux.hw, }; static struct meson_clk_pll *const g12b_clk_plls[] = { - &g12b_sys1_pll, + &g12b_sys_pll, }; #if 0 static struct clk_gate *g12b_clk_gates[] = { @@ -270,6 +270,13 @@ static void __init g12b_clkc_init(struct device_node *np) /* * register all clks */ + clks[CLKID_SYS_PLL] = clk_register(NULL, &g12b_sys_pll.hw); + if (IS_ERR(clks[CLKID_SYS_PLL])) { + pr_err("%s: failed to register %s\n", __func__, + clk_hw_get_name(&g12b_sys_pll.hw)); + goto iounmap; + } + for (clkid = 0; clkid < ARRAY_SIZE(g12b_clk_hws); clkid++) { if (g12b_clk_hws[clkid]) { clks[clkid + CLKID_G12B_ADD_BASE] diff --git a/drivers/amlogic/cpu_version/meson64_cpu.c b/drivers/amlogic/cpu_version/meson64_cpu.c index 6772d6c..ea48b73 100644 --- a/drivers/amlogic/cpu_version/meson64_cpu.c +++ b/drivers/amlogic/cpu_version/meson64_cpu.c @@ -61,11 +61,17 @@ int arch_big_cpu(int cpu) } EXPORT_SYMBOL(arch_big_cpu); +static unsigned int cpu_version_init; int __init meson_cpu_version_init(void) { unsigned int ver; struct device_node *cpu_version; + if (!cpu_version_init) + cpu_version_init = 1; + else + return 0; + cpu_version = of_find_node_by_name(NULL, "cpu_version"); if (cpu_version) assist_hw_rev = of_iomap(cpu_version, 0); diff --git a/include/dt-bindings/clock/amlogic,g12a-clkc.h b/include/dt-bindings/clock/amlogic,g12a-clkc.h index 97bce55..8f403eb 100644 --- a/include/dt-bindings/clock/amlogic,g12a-clkc.h +++ b/include/dt-bindings/clock/amlogic,g12a-clkc.h @@ -259,11 +259,11 @@ /*G12B clk*/ #define CLKID_G12B_ADD_BASE (CLKID_MISC_BASE + 9) -#define CLKID_SYS1_PLL (CLKID_G12B_ADD_BASE + 0) -#define CLKID_CPUB_FCLK_P (CLKID_G12B_ADD_BASE + 1) -#define CLKID_CPUB_CLK (CLKID_G12B_ADD_BASE + 2) -#define CLKID_GDC_CORE_CLK_COMP (CLKID_G12B_ADD_BASE + 3) -#define CLKID_GDC_AXI_CLK_COMP (CLKID_G12B_ADD_BASE + 4) +#define CLKID_CPUB_FCLK_P (CLKID_G12B_ADD_BASE + 0) +#define CLKID_CPUB_CLK (CLKID_G12B_ADD_BASE + 1) +#define CLKID_GDC_CORE_CLK_COMP (CLKID_G12B_ADD_BASE + 2) +#define CLKID_GDC_AXI_CLK_COMP (CLKID_G12B_ADD_BASE + 3) +#define CLKID_SYS1_PLL (CLKID_G12B_ADD_BASE + 4) #define CLKID_AO_BASE (CLKID_G12B_ADD_BASE + 5) #define CLKID_AO_CLK81 (CLKID_AO_BASE + 0) -- 2.7.4