[PATCH v4 2/6] clk: renesas: rcar-gen3: Add Z2 clock divider support
Simon Horman
horms at verge.net.au
Mon Jan 29 06:24:02 PST 2018
On Fri, Jan 05, 2018 at 03:35:13PM +0100, Geert Uytterhoeven wrote:
> Hi Simon,
>
> On Fri, Jan 5, 2018 at 3:04 PM, Simon Horman <horms at verge.net.au> wrote:
> > On Wed, Jan 03, 2018 at 01:47:08PM +0100, Geert Uytterhoeven wrote:
> >> On Wed, Jan 3, 2018 at 1:18 PM, Simon Horman <horms+renesas at verge.net.au> wrote:
> >> > From: Takeshi Kihara <takeshi.kihara.df at renesas.com>
> >> >
> >> > This patch adds Z2 clock divider support for R-Car Gen3 SoC.
> >> >
> >> > Signed-off-by: Takeshi Kihara <takeshi.kihara.df at renesas.com>
> >> > Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
>
> >> As the CPG/MSSR driver now has suspend/resume support, do we need
> >> a notifier to restore the Z or Z2 registers? Or is that handled automatically
> >> by cpufreq during system resume, for both the primary and the secondary
> >> CPU cores?
> >
> > I am a bit unsure.
> >
> > When using the A57 cores, which is the default case, the Z clk is queried
> > by CPUFreq on resume. It appears that on my system its already set to the
> > correct value but I assume if it was not then it would be reset. However,
> > this does not cover Z2 clk. So perhaps to be safe we need to register
> > notifiers and make sure they they play nicely with CPUFreq?
>
> Of course the CPU is special: unlike many other devices, it must be running
> when the kernel is reentered upon system resume.
> It may be running using a different frequency setting, though.
> However, following "opp-suspend", the system will always suspend with the
> Z clock running at 1.5GHz, which is the default?
> So Z is probably OK.
>
> It's more interesting to check what happens when the little cores are
> enabled as well (unfortunately that requires different firmware).
> 1. Does cpufreq handle them correctly when they are onlined again during
> system resume?
I tested this by updating the firmware on an H3 ES2.0 / Salvator-XS
using the instructions at
https://elinux.org/R-Car/Virtualization#Enabling_HYP_Support
I also fleshed out the opts table for the little CPUs using the following
from the 3.6.0 BSP:
diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
index 1485e6a8e112..671c2d7ed6d0 100644
--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
@@ -219,7 +219,17 @@
compatible = "operating-points-v2";
opp-shared;
- opp-1200000000 {
+ opp at 800000000 {
+ opp-hz = /bits/ 64 <800000000>;
+ opp-microvolt = <820000>;
+ clock-latency-ns = <300000>;
+ };
+ opp at 1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = <820000>;
+ clock-latency-ns = <300000>;
+ };
+ opp at 1200000000 {
opp-hz = /bits/ 64 <1200000000>;
opp-microvolt = <820000>;
clock-latency-ns = <300000>;
And fixed the out-by-one bug you pointed out elsewhere in this thread:
diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c
index a7d68cefda9c..0c8fe10d57fe 100644
--- a/drivers/clk/renesas/rcar-gen3-cpg.c
+++ b/drivers/clk/renesas/rcar-gen3-cpg.c
@@ -94,7 +94,7 @@ static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw,
u32 val;
val = clk_readl(zclk->reg) & zclk->mask;
- mult = 32 - (val >> (__ffs(zclk->mask) - 1));
+ mult = 32 - (val >> __ffs(zclk->mask));
/* Factor of 2 is for fixed divider */
return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult, 32 * 2);
@@ -129,7 +129,7 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate,
return -EBUSY;
val = clk_readl(zclk->reg) & ~zclk->mask;
- val |= ((32 - mult) << (__ffs(zclk->mask) - 1)) & zclk->mask;
+ val |= ((32 - mult) << __ffs(zclk->mask)) & zclk->mask;
clk_writel(val, zclk->reg);
/*
With these changes in place CPUFreq seems to work for both BIG and little
CPUS. And the frequencies seem to be correct after S2RAM.
# cd /sys/devices/system/cpu/
# grep . cpu*/cpufreq/scaling_available_frequencies
cpu0/cpufreq/scaling_available_frequencies:500000 1000000 1500000
...
cpu4/cpufreq/scaling_available_frequencies:800000 1000000 1200000
...
# grep grep -E -w "pll[01]|z|z2" /sys/kernel/debug/clk/clk_summary
grep: pll[01]|z|z2: No such file or directory
# grep -E -w "pll[01]|z|z2" /sys/kernel/debug/clk/clk_summary
z2 0 0 1198080000 0 0
.pll1 1 1 3194880000 0 0
.pll0 0 0 2995200000 0 0
z 0 0 1497600000 0 0
# echo 500000 > cpu0/cpufreq/scaling_max_freq
# echo 800000 > cpu4/cpufreq/scaling_max_freq
# grep . cpu*/cpufreq/*cur*
cpu0/cpufreq/cpuinfo_cur_freq:468000
cpu0/cpufreq/scaling_cur_freq:500000
...
cpu4/cpufreq/cpuinfo_cur_freq:786240
cpu4/cpufreq/scaling_cur_freq:786240
...
# grep -E -w "pll[01]|z|z2" /sys/kernel/debug/clk/clk_summary
z2 0 0 786240000 0 0
.pll1 1 1 3194880000 0 0
.pll0 0 0 2995200000 0 0
z 0 0 468000000 0 0
# i2cset -f -y 7 0x30 0x20 0x0F
# echo mem > /sys/power/state
...
[ 203.289585] Restarting tasks ... done.
[ 203.299250] PM: suspend exit
# grep . cpu*/cpufreq/*cur*
cpu0/cpufreq/cpuinfo_cur_freq:468000
cpu0/cpufreq/scaling_cur_freq:500000
...
cpu4/cpufreq/cpuinfo_cur_freq:786240
cpu4/cpufreq/scaling_cur_freq:800000
...
# grep -E -w "pll[01]|z|z2" /sys/kernel/debug/clk/clk_summary
z2 0 0 786240000 0 0
.pll1 1 1 3194880000 0 0
.pll0 0 0 2995200000 0 0
z 0 0 468000000 0 0
> 2. What happens if you offline all big cores, and enter system suspend
> running with little cores only?
> Perhaps that's prevented by the "opp-suspend" property as well?
I am unable to take CPU0 offline.
More information about the linux-arm-kernel
mailing list