[PATCH v2 1/1] arm64: dts: rockchip: rk3528: Add CPU frequency scaling support

Willy Tarreau w at 1wt.eu
Sun Jul 27 10:09:47 PDT 2025


Hello,

On Sun, Jul 20, 2025 at 10:00:10PM +0800, Chukun Pan wrote:
> Hi,
> 
> > > Because the actual frequency generated by 850mV is closer to 1008MHz.
> >
> > Which likely means that you have an -L5 chip. It will be different on
> > other chips - it's a lottery of silicon quality.
> 
> The rk3528 board I have has -L3 and -L5 levels.
> -L3 level tested at 850mV (mainline kernel) actual frequency is 1055MHz.
> 
> Frankly speaking, I have always doubted whether the voltage value of BSP
> is correct. The voltage of BSP kernel at 1800MHz and 2016MHz is too low,
> and no board can reach the corresponding actual frequency.
> For example, if we set the CPU frequency to 2016MHz when running the BSP
> kernel, the actual frequency can only reach 1800MHz.

I've tried the patch on my E20C and am seeing a frequency drop compared
to cpufreq disabled (2016 MHz stock frequency). By default, without the
OPP, my CPU cores are showing the following frequencies:

  # ncpu=$(nproc);for ((i=0; i<ncpu;i ++)); do echo -n "$(taskset -c $i ./mhz -c -i) " ;done;echo
  2008 2011 2012 2010 

There's always the same distribution with core 0 being slightly lower,
then core 3, then 1 and 2, very likely due to leakage and PVTM adjustments.

In idle it's consuming 906 mW. After enabling the OPP, I've tried again
and this time I'm seeing this:

  # ncpu=$(nproc);for ((i=0; i<ncpu;i ++)); do echo -n "$(taskset -c $i ./mhz -c -i) " ;done;echo
  1891 1895 1894 1893 

It's missing ~120 MHz as if we were not using the correct multiples. The
power draw is also lower, at 864 mW.

I've tested each of the OPP in turn and measured the idle power consumption
and the effective frequency (measured on core 1):

    OPP     MHz    mW
   408000   394   795
   600000   593   797
   816000   908   800
  1008000  1100   801
  1200000  1306   808
  1416000  1372   812
  1608000  1576   818
  1800000  1744   836
  2016000  1896   856

It's interesting to note that 816, 1008 and 1200 MHz result in a higher
frequency than configured, but upper ones result in slightly smaller
frequencies (~2%, might just be a measurement error), particularly for
the last one which is 6% lower.

I noticed a missing entry for 2 GHz in clk-rk3528.c so I've added it,
expecting that it would solve the problem:

--- a/drivers/clk/rockchip/clk-rk3528.c
+++ b/drivers/clk/rockchip/clk-rk3528.c
@@ -25,6 +25,7 @@ enum rk3528_plls {
 };
 
 static struct rockchip_pll_rate_table rk3528_pll_rates[] = {
+       RK3036_PLL_RATE(2016000000, 1, 84, 1, 1, 1, 0),
        RK3036_PLL_RATE(1896000000, 1, 79, 1, 1, 1, 0),
        RK3036_PLL_RATE(1800000000, 1, 75, 1, 1, 1, 0),
        RK3036_PLL_RATE(1704000000, 1, 71, 1, 1, 1, 0),

But it had no effect at all, the frequency remains limited to 1896 MHz.

One thing I'm noticing is that with the OPP patches applied, my CPU
voltage measures 1.094V. Without it, it's 100mV above, at 1.194V. So
I tried to change the opp-microvolts in the DTS, setting them to 1.2V,
and I reverted the change above since it had no effect.

And indeed, this unlocked the upper OPP, but now the CPU is running at
2.1 GHz, and at 900mW idle:

  $ ncpu=$(nproc);for ((i=0; i<ncpu;i ++)); do echo -n "$(taskset -c $i ./mhz -c -i) " ;done;echo
  2091 2094 2094 2092 

So it's clear that something in the hardware is having fun with our
settings, and adjusting the frequency also based on the delivered
voltage.

I tried other voltages without changing the frequency and here's what 
I'm measuring (configured mhz, measured mhz, configured voltage,
measured voltage):

  Opp-MHz  MHz  Opp-mV  mV
   stock  2012  stock  1194
    2016  1896   1100  1094
    2016  1944   1125  1117
    2016  1998   1150  1144
    2016  2040   1175  1167
    2016  2094   1200  1194

At least the configured voltage is always respected. So I'm wondering
what's done in the stock settings. Maybe it's set to a higher voltage
to ensure stability even on low-quality bins, and configures a lower
frequency ? Applying a ratio above would indicate that the stock OPP at
1194 mV above is in fact 2012*2016/2094=1944 MHz. It indeed corresponds
to a multiple of 24 MHz.

And bingo, trying to set it in opp-hz gives me the stock frequency and
voltage on this device:

  2009 2012 2013 2011

So what should we conclude from this ? Is the 1.1V configured in the OPP
the official maximum ? If so, given that the E20C runs at 1.2V stock, how
can we be sure it will not fail on devices that work fine at 1.2V at stock
frequency and are not necessarily well tested at 1.1 ? Shouldn't we raise
the max voltage a little bit to match what vendors do ? Similarly, if we'd
set 1.2V with the 2016MHz OPP, it would result in a higher frequency on
some devices like mine, possibly resulting in instabilities on some
devices. On the other hand, the trouble caused by that PVTM stuff is also
the one that adjusts our frequency based on the voltage and requested one,
presumably in order to work reliably at that voltage.

Or maybe we could simply raise the voltage a little bit. The table above
shows that at 1.15V we're close to the configured OPP and still below the
stock voltage. This is not critical, but I find it a bit annoying that
enabling cpufreq results in lower performance than without!

Another observation is that I thought it was the boot loader that was
presetting the voltage and frequency, and that's not even the case: under
u-boot, I'm measuring 944mV. So it's just linux that sets it when booting.
Maybe it instead indicates that one voltage regulator driver's default
setting is a bit high for this chip and should not set the CPU voltage
to 1.2V, hence not make the device run at this frequency to start with ?

I can run more tests next weekend if needed.

Cheers,
Willy



More information about the linux-arm-kernel mailing list