2018-11-24 07:41:05

by Martin Blumenstingl

[permalink] [raw]
Subject: [PATCH v2 0/4] Meson8b: add the CPU clock post-dividers

This is the successor to my previous series "meson8b: add the CPU_DIV16
clock for the ARM TWD" from [0]. I decided to not send this as v2 of
the original series because the PERIPH clock is not the CPU_DIV16 clock.
It's not clear whether a CPU_DIV16 clock exists.

With this series we get all the CPU_CLK post-dividers as listed in the
public S805 datasheet [1] on pages 31 and 32:
- ABP
- PERIPH (used as input for the ARM global timer and ARM TWD timer)
- AXI
- L2 DRAM

Each of these clocks has a register called "..._CLK_DIS" which is
documented as a "just in case" bit:
"Set to 1 to manually disable the [...] clock when changing the mux
selection. Typically this bit is set to 0 since the clock muxes can
switch without glitches."
Since we're not supposed to touch that register we're using the new
read-only gate clk_ops to ensure that nothing accidentally modifies
these bits.

The result of this is that we can use the PERIPH clock which clocks
the ARM TWD timer. I will send a separate series to add the TWD timer.


changes since v1 at [2]:
- added new patch 2 "clk: meson: clk-regmap: add read-only gate ops"
- switched from CLK_IS_CRITICAL to the new clk_regmap_gate_ro_ops
so we're consistent with all other read-only clocks
- collected Jerome's Acked-by tags (thanks!)


[0] http://lists.infradead.org/pipermail/linux-amlogic/2018-July/007890.html
[1] https://dn.odroid.com/S805/Datasheet/S805_Datasheet%20V0.8%2020150126.pdf
[2] https://patchwork.kernel.org/cover/10687023/


Martin Blumenstingl (4):
dt-bindings: clock: meson8b: export the CPU post dividers
clk: meson: clk-regmap: add read-only gate ops
clk: meson: meson8b: rename cpu_div2/cpu_div3 to
cpu_in_div2/cpu_in_div3
clk: meson: meson8b: add the CPU clock post divider clocks

drivers/clk/meson/clk-regmap.c | 5 +
drivers/clk/meson/clk-regmap.h | 1 +
drivers/clk/meson/meson8b.c | 264 ++++++++++++++++++++++-
drivers/clk/meson/meson8b.h | 17 +-
include/dt-bindings/clock/meson8b-clkc.h | 4 +
5 files changed, 278 insertions(+), 13 deletions(-)

--
2.19.1



2018-11-24 07:41:10

by Martin Blumenstingl

[permalink] [raw]
Subject: [PATCH v2 1/4] dt-bindings: clock: meson8b: export the CPU post dividers

There are four CPU clock post dividers:
- ABP
- PERIPH (used as input for the ARM global timer and ARM TWD timer)
- AXI
- L2 DRAM

Export these so we can use them in .dts files.

Signed-off-by: Martin Blumenstingl <[email protected]>
Acked-by: Jerome Brunet <[email protected]>
---
include/dt-bindings/clock/meson8b-clkc.h | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/include/dt-bindings/clock/meson8b-clkc.h b/include/dt-bindings/clock/meson8b-clkc.h
index a60f47b49231..5fe2923382d0 100644
--- a/include/dt-bindings/clock/meson8b-clkc.h
+++ b/include/dt-bindings/clock/meson8b-clkc.h
@@ -103,5 +103,9 @@
#define CLKID_MPLL1 94
#define CLKID_MPLL2 95
#define CLKID_NAND_CLK 112
+#define CLKID_ABP 124
+#define CLKID_PERIPH 126
+#define CLKID_AXI 128
+#define CLKID_L2_DRAM 130

#endif /* __MESON8B_CLKC_H */
--
2.19.1


2018-11-24 07:41:16

by Martin Blumenstingl

[permalink] [raw]
Subject: [PATCH v2 2/4] clk: meson: clk-regmap: add read-only gate ops

Some of the gate clocks are described as "just in case" bits in the
datasheet. Examples are the ABP, PERIPH, AXI and L2 DRAM clocks on
Meson8b.
The datasheet suggests that these bits are not touched. The full
explanation is:
"Set to 1 to manually disable the [...] clock when changing the mux
selection. Typically this bit is set to 0 since the clock muxes can
switch without glitches.".

This adds new read-only ops for gate clocks so we can describe these
clocks in our clock controller drivers while ensuring that we can't
accidentally modify the registers.

Signed-off-by: Martin Blumenstingl <[email protected]>
---
drivers/clk/meson/clk-regmap.c | 5 +++++
drivers/clk/meson/clk-regmap.h | 1 +
2 files changed, 6 insertions(+)

diff --git a/drivers/clk/meson/clk-regmap.c b/drivers/clk/meson/clk-regmap.c
index 305ee307c003..c515f67322a3 100644
--- a/drivers/clk/meson/clk-regmap.c
+++ b/drivers/clk/meson/clk-regmap.c
@@ -50,6 +50,11 @@ const struct clk_ops clk_regmap_gate_ops = {
};
EXPORT_SYMBOL_GPL(clk_regmap_gate_ops);

+const struct clk_ops clk_regmap_gate_ro_ops = {
+ .is_enabled = clk_regmap_gate_is_enabled,
+};
+EXPORT_SYMBOL_GPL(clk_regmap_gate_ro_ops);
+
static unsigned long clk_regmap_div_recalc_rate(struct clk_hw *hw,
unsigned long prate)
{
diff --git a/drivers/clk/meson/clk-regmap.h b/drivers/clk/meson/clk-regmap.h
index ed2d4348dbe2..e9c5728d40eb 100644
--- a/drivers/clk/meson/clk-regmap.h
+++ b/drivers/clk/meson/clk-regmap.h
@@ -51,6 +51,7 @@ clk_get_regmap_gate_data(struct clk_regmap *clk)
}

extern const struct clk_ops clk_regmap_gate_ops;
+extern const struct clk_ops clk_regmap_gate_ro_ops;

/**
* struct clk_regmap_div_data - regmap backed adjustable divider specific data
--
2.19.1


2018-11-24 07:41:28

by Martin Blumenstingl

[permalink] [raw]
Subject: [PATCH v2 4/4] clk: meson: meson8b: add the CPU clock post divider clocks

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 <[email protected]>
Acked-by: Jerome Brunet <[email protected]>
---
drivers/clk/meson/meson8b.c | 244 ++++++++++++++++++++++++++++++++++++
drivers/clk/meson/meson8b.h | 13 +-
2 files changed, 256 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c
index 010dccc86b5d..f906a9f0eefd 100644
--- a/drivers/clk/meson/meson8b.c
+++ b/drivers/clk/meson/meson8b.c
@@ -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 {
diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h
index 9cba34c6cb92..0abb331162ab 100644
--- a/drivers/clk/meson/meson8b.h
+++ b/drivers/clk/meson/meson8b.h
@@ -78,8 +78,19 @@
#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
--
2.19.1


2018-11-24 07:42:31

by Martin Blumenstingl

[permalink] [raw]
Subject: [PATCH v2 3/4] clk: meson: meson8b: rename cpu_div2/cpu_div3 to cpu_in_div2/cpu_in_div3

The "cpu_div2" and "cpu_div3" take "cpu_in" as input and divide that by
2 or 3. The clock controller can also generate various CPU clock
post-dividers (2, 3, 4, 5, 6, 7, 8) which are derived from "cpu_clk".
When adding support for these post-dividers our clock naming could be
misleading as we have "cpu_div2" as well as "cpu_clk_div2".
Rename the existing "cpu_in" dividers so the name of the divider's
parent is part of the divider clock's name.

Signed-off-by: Martin Blumenstingl <[email protected]>
Acked-by: Jerome Brunet <[email protected]>
---
drivers/clk/meson/meson8b.c | 20 ++++++++++----------
drivers/clk/meson/meson8b.h | 4 ++--
2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c
index b3bdc7e05441..010dccc86b5d 100644
--- a/drivers/clk/meson/meson8b.c
+++ b/drivers/clk/meson/meson8b.c
@@ -560,11 +560,11 @@ static struct clk_regmap meson8b_cpu_in_sel = {
},
};

-static struct clk_fixed_factor meson8b_cpu_div2 = {
+static struct clk_fixed_factor meson8b_cpu_in_div2 = {
.mult = 1,
.div = 2,
.hw.init = &(struct clk_init_data){
- .name = "cpu_div2",
+ .name = "cpu_in_div2",
.ops = &clk_fixed_factor_ops,
.parent_names = (const char *[]){ "cpu_in_sel" },
.num_parents = 1,
@@ -572,11 +572,11 @@ static struct clk_fixed_factor meson8b_cpu_div2 = {
},
};

-static struct clk_fixed_factor meson8b_cpu_div3 = {
+static struct clk_fixed_factor meson8b_cpu_in_div3 = {
.mult = 1,
.div = 3,
.hw.init = &(struct clk_init_data){
- .name = "cpu_div3",
+ .name = "cpu_in_div3",
.ops = &clk_fixed_factor_ops,
.parent_names = (const char *[]){ "cpu_in_sel" },
.num_parents = 1,
@@ -626,12 +626,12 @@ static struct clk_regmap meson8b_cpu_scale_out_sel = {
.ops = &clk_regmap_mux_ops,
/*
* NOTE: We are skipping the parent with value 0x2 (which is
- * "cpu_div3") because it results in a duty cycle of 33% which
- * makes the system unstable and can result in a lockup of the
- * whole system.
+ * "cpu_in_div3") because it results in a duty cycle of 33%
+ * which makes the system unstable and can result in a lockup
+ * of the whole system.
*/
.parent_names = (const char *[]) { "cpu_in_sel",
- "cpu_div2",
+ "cpu_in_div2",
"cpu_scale_div" },
.num_parents = 3,
.flags = CLK_SET_RATE_PARENT,
@@ -889,8 +889,8 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
[CLKID_MPLL1_DIV] = &meson8b_mpll1_div.hw,
[CLKID_MPLL2_DIV] = &meson8b_mpll2_div.hw,
[CLKID_CPU_IN_SEL] = &meson8b_cpu_in_sel.hw,
- [CLKID_CPU_DIV2] = &meson8b_cpu_div2.hw,
- [CLKID_CPU_DIV3] = &meson8b_cpu_div3.hw,
+ [CLKID_CPU_IN_DIV2] = &meson8b_cpu_in_div2.hw,
+ [CLKID_CPU_IN_DIV3] = &meson8b_cpu_in_div3.hw,
[CLKID_CPU_SCALE_DIV] = &meson8b_cpu_scale_div.hw,
[CLKID_CPU_SCALE_OUT_SEL] = &meson8b_cpu_scale_out_sel.hw,
[CLKID_MPLL_PREDIV] = &meson8b_mpll_prediv.hw,
diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h
index 1c6fb180e6a2..9cba34c6cb92 100644
--- a/drivers/clk/meson/meson8b.h
+++ b/drivers/clk/meson/meson8b.h
@@ -63,8 +63,8 @@
#define CLKID_MPLL1_DIV 97
#define CLKID_MPLL2_DIV 98
#define CLKID_CPU_IN_SEL 99
-#define CLKID_CPU_DIV2 100
-#define CLKID_CPU_DIV3 101
+#define CLKID_CPU_IN_DIV2 100
+#define CLKID_CPU_IN_DIV3 101
#define CLKID_CPU_SCALE_DIV 102
#define CLKID_CPU_SCALE_OUT_SEL 103
#define CLKID_MPLL_PREDIV 104
--
2.19.1


2018-11-24 08:36:14

by Neil Armstrong

[permalink] [raw]
Subject: Re: [PATCH v2 2/4] clk: meson: clk-regmap: add read-only gate ops

On 22/11/2018 22:40, Martin Blumenstingl wrote:
> Some of the gate clocks are described as "just in case" bits in the
> datasheet. Examples are the ABP, PERIPH, AXI and L2 DRAM clocks on
> Meson8b.
> The datasheet suggests that these bits are not touched. The full
> explanation is:
> "Set to 1 to manually disable the [...] clock when changing the mux
> selection. Typically this bit is set to 0 since the clock muxes can
> switch without glitches.".
>
> This adds new read-only ops for gate clocks so we can describe these
> clocks in our clock controller drivers while ensuring that we can't
> accidentally modify the registers.
>
> Signed-off-by: Martin Blumenstingl <[email protected]>
> ---
> drivers/clk/meson/clk-regmap.c | 5 +++++
> drivers/clk/meson/clk-regmap.h | 1 +
> 2 files changed, 6 insertions(+)
>
> diff --git a/drivers/clk/meson/clk-regmap.c b/drivers/clk/meson/clk-regmap.c
> index 305ee307c003..c515f67322a3 100644
> --- a/drivers/clk/meson/clk-regmap.c
> +++ b/drivers/clk/meson/clk-regmap.c
> @@ -50,6 +50,11 @@ const struct clk_ops clk_regmap_gate_ops = {
> };
> EXPORT_SYMBOL_GPL(clk_regmap_gate_ops);
>
> +const struct clk_ops clk_regmap_gate_ro_ops = {
> + .is_enabled = clk_regmap_gate_is_enabled,
> +};
> +EXPORT_SYMBOL_GPL(clk_regmap_gate_ro_ops);
> +
> static unsigned long clk_regmap_div_recalc_rate(struct clk_hw *hw,
> unsigned long prate)
> {
> diff --git a/drivers/clk/meson/clk-regmap.h b/drivers/clk/meson/clk-regmap.h
> index ed2d4348dbe2..e9c5728d40eb 100644
> --- a/drivers/clk/meson/clk-regmap.h
> +++ b/drivers/clk/meson/clk-regmap.h
> @@ -51,6 +51,7 @@ clk_get_regmap_gate_data(struct clk_regmap *clk)
> }
>
> extern const struct clk_ops clk_regmap_gate_ops;
> +extern const struct clk_ops clk_regmap_gate_ro_ops;
>
> /**
> * struct clk_regmap_div_data - regmap backed adjustable divider specific data
>

Acked-by: Neil Armstrong <[email protected]>

2018-11-24 08:38:32

by Neil Armstrong

[permalink] [raw]
Subject: Re: [PATCH v2 0/4] Meson8b: add the CPU clock post-dividers

On 22/11/2018 22:40, Martin Blumenstingl wrote:
> This is the successor to my previous series "meson8b: add the CPU_DIV16
> clock for the ARM TWD" from [0]. I decided to not send this as v2 of
> the original series because the PERIPH clock is not the CPU_DIV16 clock.
> It's not clear whether a CPU_DIV16 clock exists.
>
> With this series we get all the CPU_CLK post-dividers as listed in the
> public S805 datasheet [1] on pages 31 and 32:
> - ABP
> - PERIPH (used as input for the ARM global timer and ARM TWD timer)
> - AXI
> - L2 DRAM
>
> Each of these clocks has a register called "..._CLK_DIS" which is
> documented as a "just in case" bit:
> "Set to 1 to manually disable the [...] clock when changing the mux
> selection. Typically this bit is set to 0 since the clock muxes can
> switch without glitches."
> Since we're not supposed to touch that register we're using the new
> read-only gate clk_ops to ensure that nothing accidentally modifies
> these bits.
>
> The result of this is that we can use the PERIPH clock which clocks
> the ARM TWD timer. I will send a separate series to add the TWD timer.
>
>
> changes since v1 at [2]:
> - added new patch 2 "clk: meson: clk-regmap: add read-only gate ops"
> - switched from CLK_IS_CRITICAL to the new clk_regmap_gate_ro_ops
> so we're consistent with all other read-only clocks
> - collected Jerome's Acked-by tags (thanks!)
>
>
> [0] http://lists.infradead.org/pipermail/linux-amlogic/2018-July/007890.html
> [1] https://dn.odroid.com/S805/Datasheet/S805_Datasheet%20V0.8%2020150126.pdf
> [2] https://patchwork.kernel.org/cover/10687023/
>
>
> Martin Blumenstingl (4):
> dt-bindings: clock: meson8b: export the CPU post dividers
> clk: meson: clk-regmap: add read-only gate ops
> clk: meson: meson8b: rename cpu_div2/cpu_div3 to
> cpu_in_div2/cpu_in_div3
> clk: meson: meson8b: add the CPU clock post divider clocks
>
> drivers/clk/meson/clk-regmap.c | 5 +
> drivers/clk/meson/clk-regmap.h | 1 +
> drivers/clk/meson/meson8b.c | 264 ++++++++++++++++++++++-
> drivers/clk/meson/meson8b.h | 17 +-
> include/dt-bindings/clock/meson8b-clkc.h | 4 +
> 5 files changed, 278 insertions(+), 13 deletions(-)


Applied, with the bindings on next/headers

Neil

2018-11-24 08:39:58

by Neil Armstrong

[permalink] [raw]
Subject: Re: [PATCH v2 1/4] dt-bindings: clock: meson8b: export the CPU post dividers

On 22/11/2018 22:40, Martin Blumenstingl wrote:
> There are four CPU clock post dividers:
> - ABP
> - PERIPH (used as input for the ARM global timer and ARM TWD timer)
> - AXI
> - L2 DRAM
>
> Export these so we can use them in .dts files.
>
> Signed-off-by: Martin Blumenstingl <[email protected]>
> Acked-by: Jerome Brunet <[email protected]>
> ---
> include/dt-bindings/clock/meson8b-clkc.h | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/include/dt-bindings/clock/meson8b-clkc.h b/include/dt-bindings/clock/meson8b-clkc.h
> index a60f47b49231..5fe2923382d0 100644
> --- a/include/dt-bindings/clock/meson8b-clkc.h
> +++ b/include/dt-bindings/clock/meson8b-clkc.h
> @@ -103,5 +103,9 @@
> #define CLKID_MPLL1 94
> #define CLKID_MPLL2 95
> #define CLKID_NAND_CLK 112
> +#define CLKID_ABP 124
> +#define CLKID_PERIPH 126
> +#define CLKID_AXI 128
> +#define CLKID_L2_DRAM 130
>
> #endif /* __MESON8B_CLKC_H */
>

Kevin,

Martin asked my a tag for this patch since he has a dependency on it.

You can find it here :

The following changes since commit 651022382c7f8da46cb4872a545ee1da6d097d2a:

Linux 4.20-rc1 (2018-11-04 15:37:52 -0800)

are available in the Git repository at:

git://github.com/BayLibre/clk-meson.git tags/meson-clk-headers-4.21-1

for you to fetch changes up to 8e1dd17c8b0e3f8c66ed2a3f88a440d36135e589:

dt-bindings: clock: meson8b: export the CPU post dividers (2018-11-23 15:11:55 +0100)

----------------------------------------------------------------
Update for meson clocks bindings targeted at v4.21:
- Export Meson8b CPU post dividers

----------------------------------------------------------------
Martin Blumenstingl (1):
dt-bindings: clock: meson8b: export the CPU post dividers

include/dt-bindings/clock/meson8b-clkc.h | 4 ++++
1 file changed, 4 insertions(+)

Neil

2018-11-24 08:51:00

by Martin Blumenstingl

[permalink] [raw]
Subject: Re: [PATCH v2 0/4] Meson8b: add the CPU clock post-dividers

On Fri, Nov 23, 2018 at 3:40 PM Neil Armstrong <[email protected]> wrote:
>
> On 22/11/2018 22:40, Martin Blumenstingl wrote:
> > This is the successor to my previous series "meson8b: add the CPU_DIV16
> > clock for the ARM TWD" from [0]. I decided to not send this as v2 of
> > the original series because the PERIPH clock is not the CPU_DIV16 clock.
> > It's not clear whether a CPU_DIV16 clock exists.
> >
> > With this series we get all the CPU_CLK post-dividers as listed in the
> > public S805 datasheet [1] on pages 31 and 32:
> > - ABP
> > - PERIPH (used as input for the ARM global timer and ARM TWD timer)
> > - AXI
> > - L2 DRAM
> >
> > Each of these clocks has a register called "..._CLK_DIS" which is
> > documented as a "just in case" bit:
> > "Set to 1 to manually disable the [...] clock when changing the mux
> > selection. Typically this bit is set to 0 since the clock muxes can
> > switch without glitches."
> > Since we're not supposed to touch that register we're using the new
> > read-only gate clk_ops to ensure that nothing accidentally modifies
> > these bits.
> >
> > The result of this is that we can use the PERIPH clock which clocks
> > the ARM TWD timer. I will send a separate series to add the TWD timer.
> >
> >
> > changes since v1 at [2]:
> > - added new patch 2 "clk: meson: clk-regmap: add read-only gate ops"
> > - switched from CLK_IS_CRITICAL to the new clk_regmap_gate_ro_ops
> > so we're consistent with all other read-only clocks
> > - collected Jerome's Acked-by tags (thanks!)
> >
> >
> > [0] http://lists.infradead.org/pipermail/linux-amlogic/2018-July/007890.html
> > [1] https://dn.odroid.com/S805/Datasheet/S805_Datasheet%20V0.8%2020150126.pdf
> > [2] https://patchwork.kernel.org/cover/10687023/
> >
> >
> > Martin Blumenstingl (4):
> > dt-bindings: clock: meson8b: export the CPU post dividers
> > clk: meson: clk-regmap: add read-only gate ops
> > clk: meson: meson8b: rename cpu_div2/cpu_div3 to
> > cpu_in_div2/cpu_in_div3
> > clk: meson: meson8b: add the CPU clock post divider clocks
> >
> > drivers/clk/meson/clk-regmap.c | 5 +
> > drivers/clk/meson/clk-regmap.h | 1 +
> > drivers/clk/meson/meson8b.c | 264 ++++++++++++++++++++++-
> > drivers/clk/meson/meson8b.h | 17 +-
> > include/dt-bindings/clock/meson8b-clkc.h | 4 +
> > 5 files changed, 278 insertions(+), 13 deletions(-)
>
>
> Applied, with the bindings on next/headers
awesome, thank you Neil!
you even gave Kevin a tag with only the headers included - good for me
since I can sent the corresponding .dts patches now.


Regards
Martin