[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