* [PATCH 0/7] clk: renesas: rcar-gen3: Add support for CPU core clock boost modes
@ 2021-03-26 12:00 Geert Uytterhoeven
2021-03-26 12:00 ` [PATCH 1/7] clk: renesas: rcar-gen3: Update Z clock rate formula in comments Geert Uytterhoeven
` (8 more replies)
0 siblings, 9 replies; 13+ messages in thread
From: Geert Uytterhoeven @ 2021-03-26 12:00 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd
Cc: Takeshi Kihara, linux-renesas-soc, linux-clk, Geert Uytterhoeven
Hi Mike, Stephen,
This patch series improves the accuracy of the CPU clock rate on R-Car
Gen3 SoCs, and adds support for CPU boost modes (marked "turbo-mode" in
the operating points table in DT).
As usual, it is preceded by a few small cleanups.
The easiest way to test this is by enabling
CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE, and writing the requested clock
rate to /sys/devices/system/cpu/cpufreq/policy$n/scaling_setspeed
(n=0 for the first cluster, n=2 or 4 for the second cluster).
Note that you need to do
echo 1 > /sys/devices/system/cpu/cpufreq/boost
before you can enable boost modes.
The PLL rates and CPU clock rates and voltages can be monitored in
/sys/kernel/debug/{clk/{z,z2,.pll[024]}/clk_rate,reg*/dvfs/cpu*/*uV}.
The DVFS voltage measured by the on-board max9611 can be monitored
remotely using iio-monitor.
This series has been tested on Salvator-(X)S (with R-Car H3 ES1.0, H3
ES2.0, M3-W, and M3-N) and Ebisu-4D (R-Car E3).
As boost modes may be unstable without increasing the CPU core voltage,
this series depends on "[PATCH 0/2] arm64: dts: renesas: Add cpu-supply
properties for DVFS"[1]. Hence I think it is better to postpone this to
v5.14.
Thanks for your comments!
[1] https://lore.kernel.org/r/20210326105009.1574424-1-geert+renesas@glider.be
Geert Uytterhoeven (7):
clk: renesas: rcar-gen3: Update Z clock rate formula in comments
clk: renesas: rcar-gen3: Make cpg_z_clk.mask u32
clk: renesas: rcar-gen3: Remove superfluous masking in
cpg_z_clk_set_rate()
clk: renesas: rcar-gen3: Grammar s/dependent of/dependent on/
clk: renesas: rcar-gen3: Increase Z clock accuracy
clk: renesas: rcar-gen3: Add custom clock for PLLs
clk: renesas: rcar-gen3: Add boost support to Z clocks
drivers/clk/renesas/rcar-gen3-cpg.c | 183 +++++++++++++++++++++++-----
1 file changed, 154 insertions(+), 29 deletions(-)
--
2.25.1
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 1/7] clk: renesas: rcar-gen3: Update Z clock rate formula in comments
2021-03-26 12:00 [PATCH 0/7] clk: renesas: rcar-gen3: Add support for CPU core clock boost modes Geert Uytterhoeven
@ 2021-03-26 12:00 ` Geert Uytterhoeven
2021-03-26 12:00 ` [PATCH 2/7] clk: renesas: rcar-gen3: Make cpg_z_clk.mask u32 Geert Uytterhoeven
` (7 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Geert Uytterhoeven @ 2021-03-26 12:00 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd
Cc: Takeshi Kihara, linux-renesas-soc, linux-clk, Geert Uytterhoeven
The fixed divider in the calculation of the Z and Z2 clock rates was
generalized from a hardcoded value of two to a parameterized value, but
the comments were not updated accordingly.
Fixes: 20cc05ba04a93f05 ("clk: renesas: rcar-gen3: Parameterise Z and Z2 clock fixed divisor")
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
drivers/clk/renesas/rcar-gen3-cpg.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c
index caa0f9414e45fe73..5edc85ab04b4430f 100644
--- a/drivers/clk/renesas/rcar-gen3-cpg.c
+++ b/drivers/clk/renesas/rcar-gen3-cpg.c
@@ -38,7 +38,8 @@
* Traits of this clock:
* prepare - clk_prepare only ensures that parents are prepared
* enable - clk_enable only ensures that parents are enabled
- * rate - rate is adjustable. clk->rate = (parent->rate * mult / 32 ) / 2
+ * rate - rate is adjustable.
+ * clk->rate = (parent->rate * mult / 32 ) / fixed_div
* parent - fixed parent. No clk_set_parent support
*/
#define CPG_FRQCRB 0x00000004
--
2.25.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 2/7] clk: renesas: rcar-gen3: Make cpg_z_clk.mask u32
2021-03-26 12:00 [PATCH 0/7] clk: renesas: rcar-gen3: Add support for CPU core clock boost modes Geert Uytterhoeven
2021-03-26 12:00 ` [PATCH 1/7] clk: renesas: rcar-gen3: Update Z clock rate formula in comments Geert Uytterhoeven
@ 2021-03-26 12:00 ` Geert Uytterhoeven
2021-03-26 12:00 ` [PATCH 3/7] clk: renesas: rcar-gen3: Remove superfluous masking in cpg_z_clk_set_rate() Geert Uytterhoeven
` (6 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Geert Uytterhoeven @ 2021-03-26 12:00 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd
Cc: Takeshi Kihara, linux-renesas-soc, linux-clk, Geert Uytterhoeven
cpg_z_clk.mask contains a mask for a 32-bit register.
Hence its size can be reduced from unsigned long to u32.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
drivers/clk/renesas/rcar-gen3-cpg.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c
index 5edc85ab04b4430f..e5edf1b908411643 100644
--- a/drivers/clk/renesas/rcar-gen3-cpg.c
+++ b/drivers/clk/renesas/rcar-gen3-cpg.c
@@ -50,8 +50,8 @@ struct cpg_z_clk {
struct clk_hw hw;
void __iomem *reg;
void __iomem *kick_reg;
- unsigned long mask;
unsigned int fixed_div;
+ u32 mask;
};
#define to_z_clk(_hw) container_of(_hw, struct cpg_z_clk, hw)
--
2.25.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 3/7] clk: renesas: rcar-gen3: Remove superfluous masking in cpg_z_clk_set_rate()
2021-03-26 12:00 [PATCH 0/7] clk: renesas: rcar-gen3: Add support for CPU core clock boost modes Geert Uytterhoeven
2021-03-26 12:00 ` [PATCH 1/7] clk: renesas: rcar-gen3: Update Z clock rate formula in comments Geert Uytterhoeven
2021-03-26 12:00 ` [PATCH 2/7] clk: renesas: rcar-gen3: Make cpg_z_clk.mask u32 Geert Uytterhoeven
@ 2021-03-26 12:00 ` Geert Uytterhoeven
2021-03-26 12:00 ` [PATCH 4/7] clk: renesas: rcar-gen3: Grammar s/dependent of/dependent on/ Geert Uytterhoeven
` (5 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Geert Uytterhoeven @ 2021-03-26 12:00 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd
Cc: Takeshi Kihara, linux-renesas-soc, linux-clk, Geert Uytterhoeven
Due to the clamping of mult, "(32 - mult) << __ffs(zclk->mask)" can
never exceed the mask.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
drivers/clk/renesas/rcar-gen3-cpg.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c
index e5edf1b908411643..cf0d049aa8c78115 100644
--- a/drivers/clk/renesas/rcar-gen3-cpg.c
+++ b/drivers/clk/renesas/rcar-gen3-cpg.c
@@ -104,8 +104,7 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate,
if (readl(zclk->kick_reg) & CPG_FRQCRB_KICK)
return -EBUSY;
- cpg_reg_modify(zclk->reg, zclk->mask,
- ((32 - mult) << __ffs(zclk->mask)) & zclk->mask);
+ cpg_reg_modify(zclk->reg, zclk->mask, (32 - mult) << __ffs(zclk->mask));
/*
* Set KICK bit in FRQCRB to update hardware setting and wait for
--
2.25.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 4/7] clk: renesas: rcar-gen3: Grammar s/dependent of/dependent on/
2021-03-26 12:00 [PATCH 0/7] clk: renesas: rcar-gen3: Add support for CPU core clock boost modes Geert Uytterhoeven
` (2 preceding siblings ...)
2021-03-26 12:00 ` [PATCH 3/7] clk: renesas: rcar-gen3: Remove superfluous masking in cpg_z_clk_set_rate() Geert Uytterhoeven
@ 2021-03-26 12:00 ` Geert Uytterhoeven
2021-03-26 12:00 ` [PATCH 5/7] clk: renesas: rcar-gen3: Increase Z clock accuracy Geert Uytterhoeven
` (4 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Geert Uytterhoeven @ 2021-03-26 12:00 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd
Cc: Takeshi Kihara, linux-renesas-soc, linux-clk, Geert Uytterhoeven
Fix grammar in comments for cpg_z_clk_set_rate().
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
drivers/clk/renesas/rcar-gen3-cpg.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c
index cf0d049aa8c78115..a241bf6e904f2f66 100644
--- a/drivers/clk/renesas/rcar-gen3-cpg.c
+++ b/drivers/clk/renesas/rcar-gen3-cpg.c
@@ -117,7 +117,7 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate,
*
* Using experimental measurements, it seems that no more than
* ~10 iterations are needed, independently of the CPU rate.
- * Since this value might be dependent of external xtal rate, pll1
+ * Since this value might be dependent on external xtal rate, pll1
* rate or even the other emulation clocks rate, use 1000 as a
* "super" safe value.
*/
--
2.25.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 5/7] clk: renesas: rcar-gen3: Increase Z clock accuracy
2021-03-26 12:00 [PATCH 0/7] clk: renesas: rcar-gen3: Add support for CPU core clock boost modes Geert Uytterhoeven
` (3 preceding siblings ...)
2021-03-26 12:00 ` [PATCH 4/7] clk: renesas: rcar-gen3: Grammar s/dependent of/dependent on/ Geert Uytterhoeven
@ 2021-03-26 12:00 ` Geert Uytterhoeven
2021-03-26 12:00 ` [PATCH 6/7] clk: renesas: rcar-gen3: Add custom clock for PLLs Geert Uytterhoeven
` (3 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Geert Uytterhoeven @ 2021-03-26 12:00 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd
Cc: Takeshi Kihara, linux-renesas-soc, linux-clk, Geert Uytterhoeven
Improve accuracy in the .determine_rate() callback for Z and Z2 clocks
by using rounded divisions. This is similar to the calculation of rates
and multipliers in the .recalc_rate() resp. set_rate() callbacks.
Sample impact for a few requested clock rates:
- R-Car H3:
- Z 500 MHz: 468 MHz => 515 MHz
- Z2 1000 MHz: 973 MHz => 1011 MHz
- R-Car M3-W:
- Z 500 MHz: 422 MHz => 516 MHz
- Z2 800 MHz: 750 MHz => 788 MHz
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
drivers/clk/renesas/rcar-gen3-cpg.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c
index a241bf6e904f2f66..6b389c1caca76f07 100644
--- a/drivers/clk/renesas/rcar-gen3-cpg.c
+++ b/drivers/clk/renesas/rcar-gen3-cpg.c
@@ -83,10 +83,10 @@ static int cpg_z_clk_determine_rate(struct clk_hw *hw,
if (max_mult < min_mult)
return -EINVAL;
- mult = div64_ul(req->rate * 32ULL, prate);
+ mult = DIV_ROUND_CLOSEST_ULL(req->rate * 32ULL, prate);
mult = clamp(mult, min_mult, max_mult);
- req->rate = div_u64((u64)prate * mult, 32);
+ req->rate = DIV_ROUND_CLOSEST_ULL((u64)prate * mult, 32);
return 0;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 6/7] clk: renesas: rcar-gen3: Add custom clock for PLLs
2021-03-26 12:00 [PATCH 0/7] clk: renesas: rcar-gen3: Add support for CPU core clock boost modes Geert Uytterhoeven
` (4 preceding siblings ...)
2021-03-26 12:00 ` [PATCH 5/7] clk: renesas: rcar-gen3: Increase Z clock accuracy Geert Uytterhoeven
@ 2021-03-26 12:00 ` Geert Uytterhoeven
2021-03-30 2:22 ` Stephen Boyd
2021-03-26 12:01 ` [PATCH 7/7] clk: renesas: rcar-gen3: Add boost support to Z clocks Geert Uytterhoeven
` (2 subsequent siblings)
8 siblings, 1 reply; 13+ messages in thread
From: Geert Uytterhoeven @ 2021-03-26 12:00 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd
Cc: Takeshi Kihara, linux-renesas-soc, linux-clk, Geert Uytterhoeven
Currently the PLLs are modeled as fixed factor clocks, based on initial
settings. However, enabling CPU boost clock rates requires increasing
the PLL clock rates.
Add a custom clock driver to model the PLL clocks. This will allow the
Z (CPU) clock driver to request changing the PLL clock rate.
Based on a patch in the BSP by Takeshi Kihara
<takeshi.kihara.df@renesas.com>.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
drivers/clk/renesas/rcar-gen3-cpg.c | 147 ++++++++++++++++++++++++----
1 file changed, 128 insertions(+), 19 deletions(-)
diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c
index 6b389c1caca76f07..cc9a116d7d093ce7 100644
--- a/drivers/clk/renesas/rcar-gen3-cpg.c
+++ b/drivers/clk/renesas/rcar-gen3-cpg.c
@@ -26,12 +26,127 @@
#include "rcar-cpg-lib.h"
#include "rcar-gen3-cpg.h"
-#define CPG_PLL0CR 0x00d8
+#define CPG_PLLECR 0x00d0 /* PLL Enable Control Register */
+
+#define CPG_PLLECR_PLLST(n) BIT(8 + (n)) /* PLLn Circuit Status */
+
+#define CPG_PLL0CR 0x00d8 /* PLLn Control Registers */
#define CPG_PLL2CR 0x002c
#define CPG_PLL4CR 0x01f4
+#define CPG_PLLnCR_STC_MASK GENMASK(30, 24) /* PLL Circuit Mult. Ratio */
+
#define CPG_RCKCR_CKSEL BIT(15) /* RCLK Clock Source Select */
+/* PLL Clocks */
+struct cpg_pll_clk {
+ struct clk_hw hw;
+ void __iomem *pllcr_reg;
+ void __iomem *pllecr_reg;
+ unsigned int fixed_mult;
+ u32 pllecr_pllst_mask;
+};
+
+#define to_pll_clk(_hw) container_of(_hw, struct cpg_pll_clk, hw)
+
+static unsigned long cpg_pll_clk_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct cpg_pll_clk *pll_clk = to_pll_clk(hw);
+ unsigned int mult;
+ u32 val;
+
+ val = readl(pll_clk->pllcr_reg) & CPG_PLLnCR_STC_MASK;
+ mult = (val >> __ffs(CPG_PLLnCR_STC_MASK)) + 1;
+
+ return parent_rate * mult * pll_clk->fixed_mult;
+}
+
+static int cpg_pll_clk_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ struct cpg_pll_clk *pll_clk = to_pll_clk(hw);
+ unsigned int min_mult, max_mult, mult;
+ unsigned long prate;
+
+ prate = req->best_parent_rate * pll_clk->fixed_mult;
+ min_mult = max(div64_ul(req->min_rate, prate), 1ULL);
+ max_mult = min(div64_ul(req->max_rate, prate), 128ULL);
+ if (max_mult < min_mult)
+ return -EINVAL;
+
+ mult = DIV_ROUND_CLOSEST_ULL(req->rate, prate);
+ mult = clamp(mult, min_mult, max_mult);
+
+ req->rate = prate * mult;
+ return 0;
+}
+
+static int cpg_pll_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct cpg_pll_clk *pll_clk = to_pll_clk(hw);
+ unsigned int mult, i;
+ u32 val;
+
+ mult = DIV_ROUND_CLOSEST_ULL(rate, parent_rate * pll_clk->fixed_mult);
+ mult = clamp(mult, 1U, 128U);
+
+ val = readl(pll_clk->pllcr_reg);
+ val &= ~CPG_PLLnCR_STC_MASK;
+ val |= (mult - 1) << __ffs(CPG_PLLnCR_STC_MASK);
+ writel(val, pll_clk->pllcr_reg);
+
+ for (i = 1000; i; i--) {
+ if (readl(pll_clk->pllecr_reg) & pll_clk->pllecr_pllst_mask)
+ return 0;
+
+ cpu_relax();
+ }
+
+ return -ETIMEDOUT;
+}
+
+static const struct clk_ops cpg_pll_clk_ops = {
+ .recalc_rate = cpg_pll_clk_recalc_rate,
+ .determine_rate = cpg_pll_clk_determine_rate,
+ .set_rate = cpg_pll_clk_set_rate,
+};
+
+static struct clk * __init cpg_pll_clk_register(const char *name,
+ const char *parent_name,
+ void __iomem *base,
+ unsigned int mult,
+ unsigned int offset,
+ unsigned int index)
+
+{
+ struct cpg_pll_clk *pll_clk;
+ struct clk_init_data init = {};
+ struct clk *clk;
+
+ pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL);
+ if (!pll_clk)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &cpg_pll_clk_ops;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ pll_clk->hw.init = &init;
+ pll_clk->pllcr_reg = base + offset;
+ pll_clk->pllecr_reg = base + CPG_PLLECR;
+ pll_clk->fixed_mult = mult; /* PLL refclk x (setting + 1) x mult */
+ pll_clk->pllecr_pllst_mask = CPG_PLLECR_PLLST(index);
+
+ clk = clk_register(NULL, &pll_clk->hw);
+ if (IS_ERR(clk))
+ kfree(pll_clk);
+
+ return clk;
+}
+
/*
* Z Clock & Z2 Clock
*
@@ -314,16 +429,13 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
case CLK_TYPE_GEN3_PLL0:
/*
- * PLL0 is a configurable multiplier clock. Register it as a
- * fixed factor clock for now as there's no generic multiplier
- * clock implementation and we currently have no need to change
- * the multiplier value.
+ * PLL0 is implemented as a custom clock, to change the
+ * multiplier when cpufreq changes between normal and boost
+ * modes.
*/
- value = readl(base + CPG_PLL0CR);
- mult = (((value >> 24) & 0x7f) + 1) * 2;
- if (cpg_quirks & PLL_ERRATA)
- mult *= 2;
- break;
+ mult = (cpg_quirks & PLL_ERRATA) ? 4 : 2;
+ return cpg_pll_clk_register(core->name, __clk_get_name(parent),
+ base, mult, CPG_PLL0CR, 0);
case CLK_TYPE_GEN3_PLL1:
mult = cpg_pll_config->pll1_mult;
@@ -332,16 +444,13 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
case CLK_TYPE_GEN3_PLL2:
/*
- * PLL2 is a configurable multiplier clock. Register it as a
- * fixed factor clock for now as there's no generic multiplier
- * clock implementation and we currently have no need to change
- * the multiplier value.
+ * PLL2 is implemented as a custom clock, to change the
+ * multiplier when cpufreq changes between normal and boost
+ * modes.
*/
- value = readl(base + CPG_PLL2CR);
- mult = (((value >> 24) & 0x7f) + 1) * 2;
- if (cpg_quirks & PLL_ERRATA)
- mult *= 2;
- break;
+ mult = (cpg_quirks & PLL_ERRATA) ? 4 : 2;
+ return cpg_pll_clk_register(core->name, __clk_get_name(parent),
+ base, mult, CPG_PLL2CR, 2);
case CLK_TYPE_GEN3_PLL3:
mult = cpg_pll_config->pll3_mult;
--
2.25.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 7/7] clk: renesas: rcar-gen3: Add boost support to Z clocks
2021-03-26 12:00 [PATCH 0/7] clk: renesas: rcar-gen3: Add support for CPU core clock boost modes Geert Uytterhoeven
` (5 preceding siblings ...)
2021-03-26 12:00 ` [PATCH 6/7] clk: renesas: rcar-gen3: Add custom clock for PLLs Geert Uytterhoeven
@ 2021-03-26 12:01 ` Geert Uytterhoeven
2021-03-30 2:21 ` [PATCH 0/7] clk: renesas: rcar-gen3: Add support for CPU core clock boost modes Stephen Boyd
2021-03-30 10:05 ` Yoshihiro Shimoda
8 siblings, 0 replies; 13+ messages in thread
From: Geert Uytterhoeven @ 2021-03-26 12:01 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd
Cc: Takeshi Kihara, linux-renesas-soc, linux-clk, Geert Uytterhoeven
Add support for switching the Z and Z2 clocks between normal and boost
modes, by requesting clock rate changes to parent PLLs.
Inspired by a patch in the BSP by Takeshi Kihara
<takeshi.kihara.df@renesas.com>.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
drivers/clk/renesas/rcar-gen3-cpg.c | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c
index cc9a116d7d093ce7..558191c99b48d1f1 100644
--- a/drivers/clk/renesas/rcar-gen3-cpg.c
+++ b/drivers/clk/renesas/rcar-gen3-cpg.c
@@ -165,6 +165,7 @@ struct cpg_z_clk {
struct clk_hw hw;
void __iomem *reg;
void __iomem *kick_reg;
+ unsigned long max_rate; /* Maximum rate for normal mode */
unsigned int fixed_div;
u32 mask;
};
@@ -190,7 +191,18 @@ static int cpg_z_clk_determine_rate(struct clk_hw *hw,
{
struct cpg_z_clk *zclk = to_z_clk(hw);
unsigned int min_mult, max_mult, mult;
- unsigned long prate;
+ unsigned long rate, prate;
+
+ rate = min(req->rate, req->max_rate);
+ if (rate <= zclk->max_rate) {
+ /* Set parent rate to initial value for normal modes */
+ prate = zclk->max_rate;
+ } else {
+ /* Set increased parent rate for boost modes */
+ prate = rate;
+ }
+ req->best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw),
+ prate * zclk->fixed_div);
prate = req->best_parent_rate / zclk->fixed_div;
min_mult = max(div64_ul(req->min_rate * 32ULL, prate), 1ULL);
@@ -198,7 +210,7 @@ static int cpg_z_clk_determine_rate(struct clk_hw *hw,
if (max_mult < min_mult)
return -EINVAL;
- mult = DIV_ROUND_CLOSEST_ULL(req->rate * 32ULL, prate);
+ mult = DIV_ROUND_CLOSEST_ULL(rate * 32ULL, prate);
mult = clamp(mult, min_mult, max_mult);
req->rate = DIV_ROUND_CLOSEST_ULL((u64)prate * mult, 32);
@@ -268,7 +280,7 @@ static struct clk * __init cpg_z_clk_register(const char *name,
init.name = name;
init.ops = &cpg_z_clk_ops;
- init.flags = 0;
+ init.flags = CLK_SET_RATE_PARENT;
init.parent_names = &parent_name;
init.num_parents = 1;
@@ -279,9 +291,13 @@ static struct clk * __init cpg_z_clk_register(const char *name,
zclk->fixed_div = div; /* PLLVCO x 1/div x SYS-CPU divider */
clk = clk_register(NULL, &zclk->hw);
- if (IS_ERR(clk))
+ if (IS_ERR(clk)) {
kfree(zclk);
+ return clk;
+ }
+ zclk->max_rate = clk_hw_get_rate(clk_hw_get_parent(&zclk->hw)) /
+ zclk->fixed_div;
return clk;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 0/7] clk: renesas: rcar-gen3: Add support for CPU core clock boost modes
2021-03-26 12:00 [PATCH 0/7] clk: renesas: rcar-gen3: Add support for CPU core clock boost modes Geert Uytterhoeven
` (6 preceding siblings ...)
2021-03-26 12:01 ` [PATCH 7/7] clk: renesas: rcar-gen3: Add boost support to Z clocks Geert Uytterhoeven
@ 2021-03-30 2:21 ` Stephen Boyd
2021-03-30 10:05 ` Yoshihiro Shimoda
8 siblings, 0 replies; 13+ messages in thread
From: Stephen Boyd @ 2021-03-30 2:21 UTC (permalink / raw)
To: Geert Uytterhoeven, Michael Turquette
Cc: Takeshi Kihara, linux-renesas-soc, linux-clk, Geert Uytterhoeven
Quoting Geert Uytterhoeven (2021-03-26 05:00:53)
> Hi Mike, Stephen,
>
> This patch series improves the accuracy of the CPU clock rate on R-Car
> Gen3 SoCs, and adds support for CPU boost modes (marked "turbo-mode" in
> the operating points table in DT).
> As usual, it is preceded by a few small cleanups.
>
> The easiest way to test this is by enabling
> CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE, and writing the requested clock
> rate to /sys/devices/system/cpu/cpufreq/policy$n/scaling_setspeed
> (n=0 for the first cluster, n=2 or 4 for the second cluster).
> Note that you need to do
>
> echo 1 > /sys/devices/system/cpu/cpufreq/boost
>
> before you can enable boost modes.
>
> The PLL rates and CPU clock rates and voltages can be monitored in
> /sys/kernel/debug/{clk/{z,z2,.pll[024]}/clk_rate,reg*/dvfs/cpu*/*uV}.
> The DVFS voltage measured by the on-board max9611 can be monitored
> remotely using iio-monitor.
>
> This series has been tested on Salvator-(X)S (with R-Car H3 ES1.0, H3
> ES2.0, M3-W, and M3-N) and Ebisu-4D (R-Car E3).
>
> As boost modes may be unstable without increasing the CPU core voltage,
> this series depends on "[PATCH 0/2] arm64: dts: renesas: Add cpu-supply
> properties for DVFS"[1]. Hence I think it is better to postpone this to
> v5.14.
>
> Thanks for your comments!
>
Acked-by: Stephen Boyd <sboyd@kernel.org>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 6/7] clk: renesas: rcar-gen3: Add custom clock for PLLs
2021-03-26 12:00 ` [PATCH 6/7] clk: renesas: rcar-gen3: Add custom clock for PLLs Geert Uytterhoeven
@ 2021-03-30 2:22 ` Stephen Boyd
2021-03-30 7:02 ` Geert Uytterhoeven
0 siblings, 1 reply; 13+ messages in thread
From: Stephen Boyd @ 2021-03-30 2:22 UTC (permalink / raw)
To: Geert Uytterhoeven, Michael Turquette
Cc: Takeshi Kihara, linux-renesas-soc, linux-clk, Geert Uytterhoeven
Quoting Geert Uytterhoeven (2021-03-26 05:00:59)
> +}
> +
> +static int cpg_pll_clk_set_rate(struct clk_hw *hw, unsigned long rate,
> + unsigned long parent_rate)
> +{
> + struct cpg_pll_clk *pll_clk = to_pll_clk(hw);
> + unsigned int mult, i;
> + u32 val;
> +
> + mult = DIV_ROUND_CLOSEST_ULL(rate, parent_rate * pll_clk->fixed_mult);
> + mult = clamp(mult, 1U, 128U);
> +
> + val = readl(pll_clk->pllcr_reg);
> + val &= ~CPG_PLLnCR_STC_MASK;
> + val |= (mult - 1) << __ffs(CPG_PLLnCR_STC_MASK);
> + writel(val, pll_clk->pllcr_reg);
> +
> + for (i = 1000; i; i--) {
> + if (readl(pll_clk->pllecr_reg) & pll_clk->pllecr_pllst_mask)
> + return 0;
> +
> + cpu_relax();
> + }
Why not readl_poll_timeout()?
> +
> + return -ETIMEDOUT;
> +}
> +
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 6/7] clk: renesas: rcar-gen3: Add custom clock for PLLs
2021-03-30 2:22 ` Stephen Boyd
@ 2021-03-30 7:02 ` Geert Uytterhoeven
2021-04-01 1:40 ` Stephen Boyd
0 siblings, 1 reply; 13+ messages in thread
From: Geert Uytterhoeven @ 2021-03-30 7:02 UTC (permalink / raw)
To: Stephen Boyd; +Cc: Michael Turquette, Takeshi Kihara, Linux-Renesas, linux-clk
Hi Stephen,
On Tue, Mar 30, 2021 at 4:22 AM Stephen Boyd <sboyd@kernel.org> wrote:
> Quoting Geert Uytterhoeven (2021-03-26 05:00:59)
> > +}
> > +
> > +static int cpg_pll_clk_set_rate(struct clk_hw *hw, unsigned long rate,
> > + unsigned long parent_rate)
> > +{
> > + struct cpg_pll_clk *pll_clk = to_pll_clk(hw);
> > + unsigned int mult, i;
> > + u32 val;
> > +
> > + mult = DIV_ROUND_CLOSEST_ULL(rate, parent_rate * pll_clk->fixed_mult);
> > + mult = clamp(mult, 1U, 128U);
> > +
> > + val = readl(pll_clk->pllcr_reg);
> > + val &= ~CPG_PLLnCR_STC_MASK;
> > + val |= (mult - 1) << __ffs(CPG_PLLnCR_STC_MASK);
> > + writel(val, pll_clk->pllcr_reg);
> > +
> > + for (i = 1000; i; i--) {
> > + if (readl(pll_clk->pllecr_reg) & pll_clk->pllecr_pllst_mask)
> > + return 0;
> > +
> > + cpu_relax();
> > + }
>
> Why not readl_poll_timeout()?
I had considered that. But then I noticed readl_poll_timeout() does not
call cpu_relax() if sleep_us == 0. Perhaps such a call should be added
(at the risk of introducing a subtle regression elsewhere)?
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 13+ messages in thread
* RE: [PATCH 0/7] clk: renesas: rcar-gen3: Add support for CPU core clock boost modes
2021-03-26 12:00 [PATCH 0/7] clk: renesas: rcar-gen3: Add support for CPU core clock boost modes Geert Uytterhoeven
` (7 preceding siblings ...)
2021-03-30 2:21 ` [PATCH 0/7] clk: renesas: rcar-gen3: Add support for CPU core clock boost modes Stephen Boyd
@ 2021-03-30 10:05 ` Yoshihiro Shimoda
8 siblings, 0 replies; 13+ messages in thread
From: Yoshihiro Shimoda @ 2021-03-30 10:05 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Takeshi Kihara, linux-renesas-soc, linux-clk, Michael Turquette,
Stephen Boyd
Hi Geert-san,
> From: Geert Uytterhoeven, Sent: Friday, March 26, 2021 9:01 PM
>
> Hi Mike, Stephen,
>
> This patch series improves the accuracy of the CPU clock rate on R-Car
> Gen3 SoCs, and adds support for CPU boost modes (marked "turbo-mode" in
> the operating points table in DT).
> As usual, it is preceded by a few small cleanups.
>
> The easiest way to test this is by enabling
> CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE, and writing the requested clock
> rate to /sys/devices/system/cpu/cpufreq/policy$n/scaling_setspeed
> (n=0 for the first cluster, n=2 or 4 for the second cluster).
> Note that you need to do
>
> echo 1 > /sys/devices/system/cpu/cpufreq/boost
>
> before you can enable boost modes.
>
> The PLL rates and CPU clock rates and voltages can be monitored in
> /sys/kernel/debug/{clk/{z,z2,.pll[024]}/clk_rate,reg*/dvfs/cpu*/*uV}.
> The DVFS voltage measured by the on-board max9611 can be monitored
> remotely using iio-monitor.
>
> This series has been tested on Salvator-(X)S (with R-Car H3 ES1.0, H3
> ES2.0, M3-W, and M3-N) and Ebisu-4D (R-Car E3).
Thank you for the patch!
Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
And, I tested on R-Car H3 ES3.0 and it worked. So,
Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
# I'm not sure adding Tested-by tag is suitable for patch 1 and 4 though...
> As boost modes may be unstable without increasing the CPU core voltage,
> this series depends on "[PATCH 0/2] arm64: dts: renesas: Add cpu-supply
> properties for DVFS"[1]. Hence I think it is better to postpone this to
> v5.14.
I think so.
Best regards,
Yoshihiro Shimoda
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 6/7] clk: renesas: rcar-gen3: Add custom clock for PLLs
2021-03-30 7:02 ` Geert Uytterhoeven
@ 2021-04-01 1:40 ` Stephen Boyd
0 siblings, 0 replies; 13+ messages in thread
From: Stephen Boyd @ 2021-04-01 1:40 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Michael Turquette, Takeshi Kihara, Linux-Renesas, linux-clk
Quoting Geert Uytterhoeven (2021-03-30 00:02:03)
> Hi Stephen,
>
> On Tue, Mar 30, 2021 at 4:22 AM Stephen Boyd <sboyd@kernel.org> wrote:
> > Quoting Geert Uytterhoeven (2021-03-26 05:00:59)
> > > +}
> > > +
> > > +static int cpg_pll_clk_set_rate(struct clk_hw *hw, unsigned long rate,
> > > + unsigned long parent_rate)
> > > +{
> > > + struct cpg_pll_clk *pll_clk = to_pll_clk(hw);
> > > + unsigned int mult, i;
> > > + u32 val;
> > > +
> > > + mult = DIV_ROUND_CLOSEST_ULL(rate, parent_rate * pll_clk->fixed_mult);
> > > + mult = clamp(mult, 1U, 128U);
> > > +
> > > + val = readl(pll_clk->pllcr_reg);
> > > + val &= ~CPG_PLLnCR_STC_MASK;
> > > + val |= (mult - 1) << __ffs(CPG_PLLnCR_STC_MASK);
> > > + writel(val, pll_clk->pllcr_reg);
> > > +
> > > + for (i = 1000; i; i--) {
> > > + if (readl(pll_clk->pllecr_reg) & pll_clk->pllecr_pllst_mask)
> > > + return 0;
> > > +
> > > + cpu_relax();
> > > + }
> >
> > Why not readl_poll_timeout()?
>
> I had considered that. But then I noticed readl_poll_timeout() does not
> call cpu_relax() if sleep_us == 0. Perhaps such a call should be added
> (at the risk of introducing a subtle regression elsewhere)?
>
Risk seems low. Maybe introduce a readl_poll_timeout_relaxed() if it's a
concern. At the least, a patch to document why it doesn't use
cpu_relax() right now would be good to have.
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2021-04-01 1:41 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-26 12:00 [PATCH 0/7] clk: renesas: rcar-gen3: Add support for CPU core clock boost modes Geert Uytterhoeven
2021-03-26 12:00 ` [PATCH 1/7] clk: renesas: rcar-gen3: Update Z clock rate formula in comments Geert Uytterhoeven
2021-03-26 12:00 ` [PATCH 2/7] clk: renesas: rcar-gen3: Make cpg_z_clk.mask u32 Geert Uytterhoeven
2021-03-26 12:00 ` [PATCH 3/7] clk: renesas: rcar-gen3: Remove superfluous masking in cpg_z_clk_set_rate() Geert Uytterhoeven
2021-03-26 12:00 ` [PATCH 4/7] clk: renesas: rcar-gen3: Grammar s/dependent of/dependent on/ Geert Uytterhoeven
2021-03-26 12:00 ` [PATCH 5/7] clk: renesas: rcar-gen3: Increase Z clock accuracy Geert Uytterhoeven
2021-03-26 12:00 ` [PATCH 6/7] clk: renesas: rcar-gen3: Add custom clock for PLLs Geert Uytterhoeven
2021-03-30 2:22 ` Stephen Boyd
2021-03-30 7:02 ` Geert Uytterhoeven
2021-04-01 1:40 ` Stephen Boyd
2021-03-26 12:01 ` [PATCH 7/7] clk: renesas: rcar-gen3: Add boost support to Z clocks Geert Uytterhoeven
2021-03-30 2:21 ` [PATCH 0/7] clk: renesas: rcar-gen3: Add support for CPU core clock boost modes Stephen Boyd
2021-03-30 10:05 ` Yoshihiro Shimoda
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.