From: Martin Blumenstingl Date: Sun, 24 Mar 2019 15:11:04 +0000 (+0100) Subject: clk: meson: meson8b: add the VPU clock trees X-Git-Tag: v5.15~6321^2~6^4~1^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=41785ce562491db935471b31211481941a65c68f;p=platform%2Fkernel%2Flinux-starfive.git clk: meson: meson8b: add the VPU clock trees The VPU clock tree is slightly different on all three supported SoCs: Meson8 only has an input mux (which chooses between "fclk_div4", "fclk_div3", "fclk_div5" and "fclk_div7"), a divider and a gate. Meson8b has two VPU clock trees, each with an input mux (using the same parents as the input mux on Meson8), divider and a gates. The final VPU clock is a glitch-free mux which chooses between VPU_1 and VPU_2. Meson8m2 uses a similar clock tree as Meson8b but the last input clock is different: instead of using "fclk_div7" as input Meson8m2 uses "gp_pll". This was probably done in hardware to improve the accuracy of the clock because fclk_div7 gives us 2550MHz / 7 = 364.286MHz while GP_PLL can achieve 364.0MHz. Signed-off-by: Martin Blumenstingl Reviewed-by: Neil Armstrong Acked-by: Jerome Brunet Signed-off-by: Neil Armstrong Link: https://lkml.kernel.org/r/20190324151104.18397-5-martin.blumenstingl@googlemail.com --- diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index 0d08f1ef..8e091c2 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -1761,6 +1761,147 @@ static struct clk_regmap meson8m2_gp_pll = { }, }; +static const char * const mmeson8b_vpu_0_1_parent_names[] = { + "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7" +}; + +static const char * const mmeson8m2_vpu_0_1_parent_names[] = { + "fclk_div4", "fclk_div3", "fclk_div5", "gp_pll" +}; + +static struct clk_regmap meson8b_vpu_0_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_VPU_CLK_CNTL, + .mask = 0x3, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu_0_sel", + .ops = &clk_regmap_mux_ops, + .parent_names = mmeson8b_vpu_0_1_parent_names, + .num_parents = ARRAY_SIZE(mmeson8b_vpu_0_1_parent_names), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap meson8m2_vpu_0_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_VPU_CLK_CNTL, + .mask = 0x3, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu_0_sel", + .ops = &clk_regmap_mux_ops, + .parent_names = mmeson8m2_vpu_0_1_parent_names, + .num_parents = ARRAY_SIZE(mmeson8m2_vpu_0_1_parent_names), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap meson8b_vpu_0_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_VPU_CLK_CNTL, + .shift = 0, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu_0_div", + .ops = &clk_regmap_divider_ops, + .parent_names = (const char *[]){ "vpu_0_sel" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap meson8b_vpu_0 = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_VPU_CLK_CNTL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "vpu_0", + .ops = &clk_regmap_gate_ops, + .parent_names = (const char *[]){ "vpu_0_div" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap meson8b_vpu_1_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_VPU_CLK_CNTL, + .mask = 0x3, + .shift = 25, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu_1_sel", + .ops = &clk_regmap_mux_ops, + .parent_names = mmeson8b_vpu_0_1_parent_names, + .num_parents = ARRAY_SIZE(mmeson8b_vpu_0_1_parent_names), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap meson8m2_vpu_1_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_VPU_CLK_CNTL, + .mask = 0x3, + .shift = 25, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu_1_sel", + .ops = &clk_regmap_mux_ops, + .parent_names = mmeson8m2_vpu_0_1_parent_names, + .num_parents = ARRAY_SIZE(mmeson8m2_vpu_0_1_parent_names), + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap meson8b_vpu_1_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_VPU_CLK_CNTL, + .shift = 16, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu_1_div", + .ops = &clk_regmap_divider_ops, + .parent_names = (const char *[]){ "vpu_1_sel" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap meson8b_vpu_1 = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_VPU_CLK_CNTL, + .bit_idx = 24, + }, + .hw.init = &(struct clk_init_data) { + .name = "vpu_1", + .ops = &clk_regmap_gate_ops, + .parent_names = (const char *[]){ "vpu_1_div" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap meson8b_vpu = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_VPU_CLK_CNTL, + .mask = 1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "vpu", + .ops = &clk_regmap_mux_ops, + .parent_names = (const char *[]){ "vpu_0", "vpu_1" }, + .num_parents = 2, + .flags = CLK_SET_RATE_NO_REPARENT, + }, +}; + /* Everything Else (EE) domain gates */ static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0); @@ -2024,6 +2165,9 @@ static struct clk_hw_onecell_data meson8_hw_onecell_data = { [CLKID_MALI_0_SEL] = &meson8b_mali_0_sel.hw, [CLKID_MALI_0_DIV] = &meson8b_mali_0_div.hw, [CLKID_MALI] = &meson8b_mali_0.hw, + [CLKID_VPU_0_SEL] = &meson8b_vpu_0_sel.hw, + [CLKID_VPU_0_DIV] = &meson8b_vpu_0_div.hw, + [CLKID_VPU] = &meson8b_vpu_0.hw, [CLK_NR_CLKS] = NULL, }, .num = CLK_NR_CLKS, @@ -2210,6 +2354,13 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = { [CLKID_MALI_1_DIV] = &meson8b_mali_1_div.hw, [CLKID_MALI_1] = &meson8b_mali_1.hw, [CLKID_MALI] = &meson8b_mali.hw, + [CLKID_VPU_0_SEL] = &meson8b_vpu_0_sel.hw, + [CLKID_VPU_0_DIV] = &meson8b_vpu_0_div.hw, + [CLKID_VPU_0] = &meson8b_vpu_0.hw, + [CLKID_VPU_1_SEL] = &meson8b_vpu_1_sel.hw, + [CLKID_VPU_1_DIV] = &meson8b_vpu_1_div.hw, + [CLKID_VPU_1] = &meson8b_vpu_1.hw, + [CLKID_VPU] = &meson8b_vpu.hw, [CLK_NR_CLKS] = NULL, }, .num = CLK_NR_CLKS, @@ -2398,6 +2549,13 @@ static struct clk_hw_onecell_data meson8m2_hw_onecell_data = { [CLKID_MALI] = &meson8b_mali.hw, [CLKID_GP_PLL_DCO] = &meson8m2_gp_pll_dco.hw, [CLKID_GP_PLL] = &meson8m2_gp_pll.hw, + [CLKID_VPU_0_SEL] = &meson8m2_vpu_0_sel.hw, + [CLKID_VPU_0_DIV] = &meson8b_vpu_0_div.hw, + [CLKID_VPU_0] = &meson8b_vpu_0.hw, + [CLKID_VPU_1_SEL] = &meson8m2_vpu_1_sel.hw, + [CLKID_VPU_1_DIV] = &meson8b_vpu_1_div.hw, + [CLKID_VPU_1] = &meson8b_vpu_1.hw, + [CLKID_VPU] = &meson8b_vpu.hw, [CLK_NR_CLKS] = NULL, }, .num = CLK_NR_CLKS, @@ -2562,6 +2720,15 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = { &meson8b_mali, &meson8m2_gp_pll_dco, &meson8m2_gp_pll, + &meson8b_vpu_0_sel, + &meson8m2_vpu_0_sel, + &meson8b_vpu_0_div, + &meson8b_vpu_0, + &meson8b_vpu_1_sel, + &meson8m2_vpu_1_sel, + &meson8b_vpu_1_div, + &meson8b_vpu_1, + &meson8b_vpu, }; static const struct meson8b_clk_reset_line { diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h index a45f710..e775f91 100644 --- a/drivers/clk/meson/meson8b.h +++ b/drivers/clk/meson/meson8b.h @@ -35,6 +35,7 @@ #define HHI_VID_DIVIDER_CNTL 0x198 /* 0x66 offset in data sheet */ #define HHI_SYS_CPU_CLK_CNTL0 0x19c /* 0x67 offset in data sheet */ #define HHI_MALI_CLK_CNTL 0x1b0 /* 0x6c offset in data sheet */ +#define HHI_VPU_CLK_CNTL 0x1bc /* 0x6f offset in data sheet */ #define HHI_HDMI_CLK_CNTL 0x1cc /* 0x73 offset in data sheet */ #define HHI_NAND_CLK_CNTL 0x25c /* 0x97 offset in data sheet */ #define HHI_MPLL_CNTL 0x280 /* 0xa0 offset in data sheet */ @@ -149,8 +150,14 @@ #define CLKID_MALI_1 180 #define CLKID_GP_PLL_DCO 181 #define CLKID_GP_PLL 182 +#define CLKID_VPU_0_SEL 183 +#define CLKID_VPU_0_DIV 184 +#define CLKID_VPU_0 185 +#define CLKID_VPU_1_SEL 186 +#define CLKID_VPU_1_DIV 187 +#define CLKID_VPU_1 189 -#define CLK_NR_CLKS 183 +#define CLK_NR_CLKS 191 /* * include the CLKID and RESETID that have