[PATCH v2 1/1] arm64: dts: rockchip: rk3528: Add CPU frequency scaling support
Alexey Charkov
alchark at gmail.com
Thu Jul 10 08:59:11 PDT 2025
On Thu, Jul 10, 2025 at 7:09 PM Jonas Karlman <jonas at kwiboo.se> wrote:
>
> Hi Heiko and Chukun,
>
> On 7/10/2025 1:45 PM, Heiko Stuebner wrote:
> > Am Freitag, 20. Juni 2025, 12:00:10 Mitteleuropäische Sommerzeit schrieb Chukun Pan:
> >> By default, the CPUs on RK3528 operates at 1.5GHz. Add CPU frequency and
> >> voltage mapping to the device tree to enable dynamic scaling via cpufreq.
> >>
> >> The OPP values come from downstream kernel[1]. Both 408MHz and 600MHz
> >> frequencies use the normal PLL, so use the corresponding highest voltage.
> >>
> >> The voltage used for other frequencies can't be less than above (875mV).
> >> Therefore, 816MHz to 1200MHz also uses the corresponding highest voltage.
> >
> > There has often been the argument that selecting a frequency that has the
> > same voltage as a faster frequency does not save any power.
> >
> > Hence I remember that we dropped slower frequencies on other socs
> > that share the same voltage with a higher frequency.
>
> One possible difference here is that the actual CPU rate is controlled
> by a PVTPLL where TF-A will configure a osc ring-length based on the
> requested rate and Linux only configure the regulator voltage.
>
> I have no idea if the configuration made by TF-A will have any affect on
> power usage, but I suggest we keep all opp here because both TF-A and
> Linux is involved in configuring the CPU rate.
It seems that PVTPLL usage shouldn't change the equation here. As long
as the voltage stays the same, it should always be preferable to run
the core faster (i.e. at a shorter osc-ring length) so that it can go
to idle sooner, given that idle states are less power-hungry than any
of the active states.
What DOES change the equation is the different voltage that downstream
DTs define for different OTP programmed leakage values, as they make
different top frequencies correspond to a given voltage for cores with
different leakage values.
> The measured rate can typically be read from a PVTPLL status reg, it
> will be different depending on the ring-length, voltage and silicon
> quality for the rates >= 816 MHz.
>
> >
> >>
> >> The remaining 1416MHz to 2016MHz use a voltage close to actual frequency.
> >>
> >> [1] https://github.com/rockchip-linux/kernel/blob/develop-5.10/arch/arm64/boot/dts/rockchip/rk3528.dtsi
> >>
> >> Signed-off-by: Chukun Pan <amadeus at jmu.edu.cn>
> >> ---
> >> arch/arm64/boot/dts/rockchip/rk3528.dtsi | 64 ++++++++++++++++++++++++
> >> 1 file changed, 64 insertions(+)
> >>
> >> diff --git a/arch/arm64/boot/dts/rockchip/rk3528.dtsi b/arch/arm64/boot/dts/rockchip/rk3528.dtsi
> >> index 829f980ea353..5cb7f10b79ed 100644
> >> --- a/arch/arm64/boot/dts/rockchip/rk3528.dtsi
> >> +++ b/arch/arm64/boot/dts/rockchip/rk3528.dtsi
> >> @@ -53,6 +53,7 @@ cpu0: cpu at 0 {
> >> device_type = "cpu";
> >> enable-method = "psci";
> >> clocks = <&scmi_clk SCMI_CLK_CPU>;
> >> + operating-points-v2 = <&cpu_opp_table>;
> >> };
> >>
> >> cpu1: cpu at 1 {
> >> @@ -61,6 +62,7 @@ cpu1: cpu at 1 {
> >> device_type = "cpu";
> >> enable-method = "psci";
> >> clocks = <&scmi_clk SCMI_CLK_CPU>;
> >> + operating-points-v2 = <&cpu_opp_table>;
> >> };
> >>
> >> cpu2: cpu at 2 {
> >> @@ -69,6 +71,7 @@ cpu2: cpu at 2 {
> >> device_type = "cpu";
> >> enable-method = "psci";
> >> clocks = <&scmi_clk SCMI_CLK_CPU>;
> >> + operating-points-v2 = <&cpu_opp_table>;
> >> };
> >>
> >> cpu3: cpu at 3 {
> >> @@ -77,6 +80,67 @@ cpu3: cpu at 3 {
> >> device_type = "cpu";
> >> enable-method = "psci";
> >> clocks = <&scmi_clk SCMI_CLK_CPU>;
> >> + operating-points-v2 = <&cpu_opp_table>;
> >> + };
> >> + };
> >> +
> >> + cpu_opp_table: opp-table-cpu {
>
> This node should be placed after the firmware node for the nodes to be
> in alphabetical order.
>
> Regards,
> Jonas
>
> >> + compatible = "operating-points-v2";
> >> + opp-shared;
> >> +
> >> + opp-408000000 {
> >> + opp-hz = /bits/ 64 <408000000>;
> >> + opp-microvolt = <875000 875000 1100000>;
> >> + clock-latency-ns = <40000>;
> >> + opp-suspend;
> >> + };
> >> +
> >> + opp-600000000 {
> >> + opp-hz = /bits/ 64 <600000000>;
> >> + opp-microvolt = <875000 875000 1100000>;
> >> + clock-latency-ns = <40000>;
> >> + };
> >> +
> >> + opp-816000000 {
> >> + opp-hz = /bits/ 64 <816000000>;
> >> + opp-microvolt = <875000 875000 1100000>;
> >> + clock-latency-ns = <40000>;
> >> + };
> >> +
> >> + opp-1008000000 {
> >> + opp-hz = /bits/ 64 <1008000000>;
> >> + opp-microvolt = <875000 875000 1100000>;
> >> + clock-latency-ns = <40000>;
> >> + };
I.e. here the mainline kernel will always choose opp-1008000000 as
long as the regulator voltage is 875000 uV, unless explicitly
prevented from doing so by userspace. Whereas the BSP kernel [1] would
request different frequencies for different silicon, e.g.
opp-1200000000 for a silicon specimen with a leakage value of L4 and
opp-1416000000 for a silicon specimen with a leakage value of L8 - all
for the same regulator voltage of 875000 uV.
So my 2 cents would be: no added benefit in having "lower frequency,
same voltage" OPPs defined here until we implement an OPP driver
reading the NVMEM programmed leakage values and selecting different
*-L* voltages for each OPP depending on those. Once there is this
support in the drivers, those OPPs can be added together with
leakage-specific voltages (opp-microvolt-L0..11).
Right now OPP values with frequencies lower than 1008000000 won't be
selected by any of the energy-aware cpufreq governors anyway, because
their voltages are the same. Exercise for the reader: try to convince
e.g. the "schedutil" governor to select anything below 1008000000
without touching
/sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq :) This may
change if OPP tuning logic is implemented such as in [2]: that will
try and find the _voltage_ resulting in PVTPLL providing a frequency
closest to what cpufreq requested, and use that for the in-memory OPP
table instead of what was provided by the DTS.
[1] https://github.com/rockchip-linux/kernel/blob/develop-5.10/arch/arm64/boot/dts/rockchip/rk3528.dtsi
[2] https://github.com/rockchip-linux/kernel/blob/develop-6.1/drivers/soc/rockchip/rockchip_opp_select.c#L842-L994
Best regards,
Alexey
> >> + opp-1200000000 {
> >> + opp-hz = /bits/ 64 <1200000000>;
> >> + opp-microvolt = <900000 900000 1100000>;
> >> + clock-latency-ns = <40000>;
> >> + };
> >> +
> >> + opp-1416000000 {
> >> + opp-hz = /bits/ 64 <1416000000>;
> >> + opp-microvolt = <925000 925000 1100000>;
> >> + clock-latency-ns = <40000>;
> >> + };
> >> +
> >> + opp-1608000000 {
> >> + opp-hz = /bits/ 64 <1608000000>;
> >> + opp-microvolt = <975000 975000 1100000>;
> >> + clock-latency-ns = <40000>;
> >> + };
> >> +
> >> + opp-1800000000 {
> >> + opp-hz = /bits/ 64 <1800000000>;
> >> + opp-microvolt = <1037500 1037500 1100000>;
> >> + clock-latency-ns = <40000>;
> >> + };
> >> +
> >> + opp-2016000000 {
> >> + opp-hz = /bits/ 64 <2016000000>;
> >> + opp-microvolt = <1100000 1100000 1100000>;
> >> + clock-latency-ns = <40000>;
> >> };
> >> };
> >>
> >>
> >
> >
> >
> >
>
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip
More information about the Linux-rockchip
mailing list