clk: meson: meson8b: add the CPU clock post divider clocks
authorMartin Blumenstingl <martin.blumenstingl@googlemail.com>
Thu, 22 Nov 2018 21:40:17 +0000 (22:40 +0100)
committerNeil Armstrong <narmstrong@baylibre.com>
Fri, 23 Nov 2018 14:11:58 +0000 (15:11 +0100)
There are four CPU clock post dividers:
- ABP
- PERIPH (used for the ARM global timer and ARM TWD timer)
- AXI
- L2 DRAM

Each of these clocks consists of two clocks:
- a mux to select between "cpu_clk" divided by 2, 3, 4, 5, 6, 7 or 8
- a "_clk_dis" gate. The public S805 datasheet states that this should
  be set to 1 to disable the clock, the default value is 0. There is
  also a hint that these are "just in case" bits which only exist in
  case the corresponding mux implementation does not allow glitch-free
  parent changes (the muxes are designed in a way that the clock can
  stay enabled when changing the mux). It's still good practise to
  describe this clock even if we're not supposed to modify it. Thus
  this uses the read-only gate ops.

Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Acked-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://lkml.kernel.org/r/20181122214017.25643-5-martin.blumenstingl@googlemail.com
drivers/clk/meson/meson8b.c
drivers/clk/meson/meson8b.h

index 010dccc86b5d9cc234f0845784b226e2eb1e550c..f906a9f0eefd8d5712617350fb6813c3c39e44d8 100644 (file)
@@ -704,6 +704,227 @@ static struct clk_regmap meson8b_nand_clk_gate = {
        },
 };
 
+static struct clk_fixed_factor meson8b_cpu_clk_div2 = {
+       .mult = 1,
+       .div = 2,
+       .hw.init = &(struct clk_init_data){
+               .name = "cpu_clk_div2",
+               .ops = &clk_fixed_factor_ops,
+               .parent_names = (const char *[]){ "cpu_clk" },
+               .num_parents = 1,
+       },
+};
+
+static struct clk_fixed_factor meson8b_cpu_clk_div3 = {
+       .mult = 1,
+       .div = 3,
+       .hw.init = &(struct clk_init_data){
+               .name = "cpu_clk_div3",
+               .ops = &clk_fixed_factor_ops,
+               .parent_names = (const char *[]){ "cpu_clk" },
+               .num_parents = 1,
+       },
+};
+
+static struct clk_fixed_factor meson8b_cpu_clk_div4 = {
+       .mult = 1,
+       .div = 4,
+       .hw.init = &(struct clk_init_data){
+               .name = "cpu_clk_div4",
+               .ops = &clk_fixed_factor_ops,
+               .parent_names = (const char *[]){ "cpu_clk" },
+               .num_parents = 1,
+       },
+};
+
+static struct clk_fixed_factor meson8b_cpu_clk_div5 = {
+       .mult = 1,
+       .div = 5,
+       .hw.init = &(struct clk_init_data){
+               .name = "cpu_clk_div5",
+               .ops = &clk_fixed_factor_ops,
+               .parent_names = (const char *[]){ "cpu_clk" },
+               .num_parents = 1,
+       },
+};
+
+static struct clk_fixed_factor meson8b_cpu_clk_div6 = {
+       .mult = 1,
+       .div = 6,
+       .hw.init = &(struct clk_init_data){
+               .name = "cpu_clk_div6",
+               .ops = &clk_fixed_factor_ops,
+               .parent_names = (const char *[]){ "cpu_clk" },
+               .num_parents = 1,
+       },
+};
+
+static struct clk_fixed_factor meson8b_cpu_clk_div7 = {
+       .mult = 1,
+       .div = 7,
+       .hw.init = &(struct clk_init_data){
+               .name = "cpu_clk_div7",
+               .ops = &clk_fixed_factor_ops,
+               .parent_names = (const char *[]){ "cpu_clk" },
+               .num_parents = 1,
+       },
+};
+
+static struct clk_fixed_factor meson8b_cpu_clk_div8 = {
+       .mult = 1,
+       .div = 8,
+       .hw.init = &(struct clk_init_data){
+               .name = "cpu_clk_div8",
+               .ops = &clk_fixed_factor_ops,
+               .parent_names = (const char *[]){ "cpu_clk" },
+               .num_parents = 1,
+       },
+};
+
+static u32 mux_table_abp[] = { 1, 2, 3, 4, 5, 6, 7 };
+static struct clk_regmap meson8b_abp_clk_sel = {
+       .data = &(struct clk_regmap_mux_data){
+               .offset = HHI_SYS_CPU_CLK_CNTL1,
+               .mask = 0x7,
+               .shift = 3,
+               .table = mux_table_abp,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "abp_clk_sel",
+               .ops = &clk_regmap_mux_ops,
+               .parent_names = (const char *[]){ "cpu_clk_div2",
+                                                 "cpu_clk_div3",
+                                                 "cpu_clk_div4",
+                                                 "cpu_clk_div5",
+                                                 "cpu_clk_div6",
+                                                 "cpu_clk_div7",
+                                                 "cpu_clk_div8", },
+               .num_parents = 7,
+       },
+};
+
+static struct clk_regmap meson8b_abp_clk_gate = {
+       .data = &(struct clk_regmap_gate_data){
+               .offset = HHI_SYS_CPU_CLK_CNTL1,
+               .bit_idx = 16,
+               .flags = CLK_GATE_SET_TO_DISABLE,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "abp_clk_dis",
+               .ops = &clk_regmap_gate_ro_ops,
+               .parent_names = (const char *[]){ "abp_clk_sel" },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_regmap meson8b_periph_clk_sel = {
+       .data = &(struct clk_regmap_mux_data){
+               .offset = HHI_SYS_CPU_CLK_CNTL1,
+               .mask = 0x7,
+               .shift = 6,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "periph_clk_sel",
+               .ops = &clk_regmap_mux_ops,
+               .parent_names = (const char *[]){ "cpu_clk_div2",
+                                                 "cpu_clk_div3",
+                                                 "cpu_clk_div4",
+                                                 "cpu_clk_div5",
+                                                 "cpu_clk_div6",
+                                                 "cpu_clk_div7",
+                                                 "cpu_clk_div8", },
+               .num_parents = 7,
+       },
+};
+
+static struct clk_regmap meson8b_periph_clk_gate = {
+       .data = &(struct clk_regmap_gate_data){
+               .offset = HHI_SYS_CPU_CLK_CNTL1,
+               .bit_idx = 17,
+               .flags = CLK_GATE_SET_TO_DISABLE,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "periph_clk_dis",
+               .ops = &clk_regmap_gate_ro_ops,
+               .parent_names = (const char *[]){ "periph_clk_sel" },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static u32 mux_table_axi[] = { 1, 2, 3, 4, 5, 6, 7 };
+static struct clk_regmap meson8b_axi_clk_sel = {
+       .data = &(struct clk_regmap_mux_data){
+               .offset = HHI_SYS_CPU_CLK_CNTL1,
+               .mask = 0x7,
+               .shift = 9,
+               .table = mux_table_axi,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "axi_clk_sel",
+               .ops = &clk_regmap_mux_ops,
+               .parent_names = (const char *[]){ "cpu_clk_div2",
+                                                 "cpu_clk_div3",
+                                                 "cpu_clk_div4",
+                                                 "cpu_clk_div5",
+                                                 "cpu_clk_div6",
+                                                 "cpu_clk_div7",
+                                                 "cpu_clk_div8", },
+               .num_parents = 7,
+       },
+};
+
+static struct clk_regmap meson8b_axi_clk_gate = {
+       .data = &(struct clk_regmap_gate_data){
+               .offset = HHI_SYS_CPU_CLK_CNTL1,
+               .bit_idx = 18,
+               .flags = CLK_GATE_SET_TO_DISABLE,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "axi_clk_dis",
+               .ops = &clk_regmap_gate_ro_ops,
+               .parent_names = (const char *[]){ "axi_clk_sel" },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_regmap meson8b_l2_dram_clk_sel = {
+       .data = &(struct clk_regmap_mux_data){
+               .offset = HHI_SYS_CPU_CLK_CNTL1,
+               .mask = 0x7,
+               .shift = 12,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "l2_dram_clk_sel",
+               .ops = &clk_regmap_mux_ops,
+               .parent_names = (const char *[]){ "cpu_clk_div2",
+                                                 "cpu_clk_div3",
+                                                 "cpu_clk_div4",
+                                                 "cpu_clk_div5",
+                                                 "cpu_clk_div6",
+                                                 "cpu_clk_div7",
+                                                 "cpu_clk_div8", },
+               .num_parents = 7,
+       },
+};
+
+static struct clk_regmap meson8b_l2_dram_clk_gate = {
+       .data = &(struct clk_regmap_gate_data){
+               .offset = HHI_SYS_CPU_CLK_CNTL1,
+               .bit_idx = 19,
+               .flags = CLK_GATE_SET_TO_DISABLE,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "l2_dram_clk_dis",
+               .ops = &clk_regmap_gate_ro_ops,
+               .parent_names = (const char *[]){ "l2_dram_clk_sel" },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
 /* Everything Else (EE) domain gates */
 
 static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0);
@@ -905,6 +1126,21 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
                [CLKID_PLL_FIXED_DCO]       = &meson8b_fixed_pll_dco.hw,
                [CLKID_PLL_VID_DCO]         = &meson8b_vid_pll_dco.hw,
                [CLKID_PLL_SYS_DCO]         = &meson8b_sys_pll_dco.hw,
+               [CLKID_CPU_CLK_DIV2]        = &meson8b_cpu_clk_div2.hw,
+               [CLKID_CPU_CLK_DIV3]        = &meson8b_cpu_clk_div3.hw,
+               [CLKID_CPU_CLK_DIV4]        = &meson8b_cpu_clk_div4.hw,
+               [CLKID_CPU_CLK_DIV5]        = &meson8b_cpu_clk_div5.hw,
+               [CLKID_CPU_CLK_DIV6]        = &meson8b_cpu_clk_div6.hw,
+               [CLKID_CPU_CLK_DIV7]        = &meson8b_cpu_clk_div7.hw,
+               [CLKID_CPU_CLK_DIV8]        = &meson8b_cpu_clk_div8.hw,
+               [CLKID_ABP_SEL]             = &meson8b_abp_clk_sel.hw,
+               [CLKID_ABP]                 = &meson8b_abp_clk_gate.hw,
+               [CLKID_PERIPH_SEL]          = &meson8b_periph_clk_sel.hw,
+               [CLKID_PERIPH]              = &meson8b_periph_clk_gate.hw,
+               [CLKID_AXI_SEL]             = &meson8b_axi_clk_sel.hw,
+               [CLKID_AXI]                 = &meson8b_axi_clk_gate.hw,
+               [CLKID_L2_DRAM_SEL]         = &meson8b_l2_dram_clk_sel.hw,
+               [CLKID_L2_DRAM]             = &meson8b_l2_dram_clk_gate.hw,
                [CLK_NR_CLKS]               = NULL,
        },
        .num = CLK_NR_CLKS,
@@ -1016,6 +1252,14 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = {
        &meson8b_fixed_pll_dco,
        &meson8b_vid_pll_dco,
        &meson8b_sys_pll_dco,
+       &meson8b_abp_clk_sel,
+       &meson8b_abp_clk_gate,
+       &meson8b_periph_clk_sel,
+       &meson8b_periph_clk_gate,
+       &meson8b_axi_clk_sel,
+       &meson8b_axi_clk_gate,
+       &meson8b_l2_dram_clk_sel,
+       &meson8b_l2_dram_clk_gate,
 };
 
 static const struct meson8b_clk_reset_line {
index 9cba34c6cb92bd152a1cea5bb271e39abbe7ce4b..0abb331162ab914959fb2c4c4fa2b1e449ea848d 100644 (file)
 #define CLKID_PLL_FIXED_DCO    113
 #define CLKID_PLL_VID_DCO      114
 #define CLKID_PLL_SYS_DCO      115
+#define CLKID_CPU_CLK_DIV2     116
+#define CLKID_CPU_CLK_DIV3     117
+#define CLKID_CPU_CLK_DIV4     118
+#define CLKID_CPU_CLK_DIV5     119
+#define CLKID_CPU_CLK_DIV6     120
+#define CLKID_CPU_CLK_DIV7     121
+#define CLKID_CPU_CLK_DIV8     122
+#define CLKID_ABP_SEL          123
+#define CLKID_PERIPH_SEL       125
+#define CLKID_AXI_SEL          127
+#define CLKID_L2_DRAM_SEL      129
 
-#define CLK_NR_CLKS            116
+#define CLK_NR_CLKS            131
 
 /*
  * include the CLKID and RESETID that have