diff mbox series

[v4,6/6] arm64: dts: rockchip: Add OPP data for CPU cores on RK3588

Message ID 20240506-rk-dts-additions-v4-6-271023ddfd40@gmail.com (mailing list archive)
State New
Headers show
Series RK3588 and Rock 5B dts additions: thermal, OPP and fan | expand

Commit Message

Alexey Charkov May 6, 2024, 9:36 a.m. UTC
By default the CPUs on RK3588 start up in a conservative performance
mode. Add frequency and voltage mappings to the device tree to enable
dynamic scaling via cpufreq.

OPP values are adapted from Radxa's downstream kernel for Rock 5B [1],
stripping them down to the minimum frequency and voltage combinations
as expected by the generic upstream cpufreq-dt driver, and also dropping
those OPPs that don't differ in voltage but only in frequency (keeping
the top frequency OPP in each case).

Note that this patch ignores voltage scaling for the CPU memory
interface which the downstream kernel does through a custom cpufreq
driver, and which is why the downstream version has two sets of voltage
values for each OPP (the second one being meant for the memory
interface supply regulator). This is done instead via regulator
coupling between CPU and memory interface supplies on affected boards.

This has been tested on Rock 5B with u-boot 2023.11 compiled from
Collabora's integration tree [2] with binary bl31 and appears to be
stable both under active cooling and passive cooling (with throttling)

[1] https://github.com/radxa/kernel/blob/stable-5.10-rock5/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
[2] https://gitlab.collabora.com/hardware-enablement/rockchip-3588/u-boot

Signed-off-by: Alexey Charkov <alchark@gmail.com>
---
 arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 122 ++++++++++++++++++++++++++++++
 1 file changed, 122 insertions(+)

Comments

Quentin Schulz May 8, 2024, 9:12 a.m. UTC | #1
Hi Alexey,

On 5/6/24 11:36 AM, Alexey Charkov wrote:
> By default the CPUs on RK3588 start up in a conservative performance
> mode. Add frequency and voltage mappings to the device tree to enable
> dynamic scaling via cpufreq.
> 
> OPP values are adapted from Radxa's downstream kernel for Rock 5B [1],
> stripping them down to the minimum frequency and voltage combinations
> as expected by the generic upstream cpufreq-dt driver, and also dropping
> those OPPs that don't differ in voltage but only in frequency (keeping
> the top frequency OPP in each case).
> 
> Note that this patch ignores voltage scaling for the CPU memory
> interface which the downstream kernel does through a custom cpufreq
> driver, and which is why the downstream version has two sets of voltage
> values for each OPP (the second one being meant for the memory
> interface supply regulator). This is done instead via regulator
> coupling between CPU and memory interface supplies on affected boards.
> 

I'm not sure this is everything we need though.

For the LITTLE cores cluster, all OPPs up to 1.416GHz are using the same 
opp-supported-hw, however the ones above, aren't.

1.608GHz, 1.704GHz and 1.8GHz are all using different opp-supported-hw.

Similarly, for the big cores clusters, all OPPs up to 1.608GHz are using 
the same opp-supported-hw, but not the ones above.

1.8GHz and 2.016GHz, 2.208GHz, 2.256GHz, 2.304GHz, 2.352GHz and 2.4GHz 
all have a different opp-supported-hw.

The values in that array are coming from cpu leakage (different for 
LITTLE, big0 and big1 clusters) and "specification serial number" 
(whatever that means), those are coming from the SoC OTP. In the 
downstream kernel from Rockchip, the former value is called "SoC 
Version" and the latter "Speed Grade".

I think this may have something to do with "binning" and I would see the 
ones above the "common" OPPs as "overclocking". Not all CPUs would 
support them and some may not run stable at some lower frequency than 
their stable max. Adding Kever from Rockchip in Cc to have some input on 
the need to support those.

Cheers,
Quentin
Dragan Simic May 8, 2024, 9:29 a.m. UTC | #2
Hello Quentin,

On 2024-05-08 11:12, Quentin Schulz wrote:
> On 5/6/24 11:36 AM, Alexey Charkov wrote:
>> By default the CPUs on RK3588 start up in a conservative performance
>> mode. Add frequency and voltage mappings to the device tree to enable
>> dynamic scaling via cpufreq.
>> 
>> OPP values are adapted from Radxa's downstream kernel for Rock 5B [1],
>> stripping them down to the minimum frequency and voltage combinations
>> as expected by the generic upstream cpufreq-dt driver, and also 
>> dropping
>> those OPPs that don't differ in voltage but only in frequency (keeping
>> the top frequency OPP in each case).
>> 
>> Note that this patch ignores voltage scaling for the CPU memory
>> interface which the downstream kernel does through a custom cpufreq
>> driver, and which is why the downstream version has two sets of 
>> voltage
>> values for each OPP (the second one being meant for the memory
>> interface supply regulator). This is done instead via regulator
>> coupling between CPU and memory interface supplies on affected boards.
> 
> I'm not sure this is everything we need though.
> 
> For the LITTLE cores cluster, all OPPs up to 1.416GHz are using the
> same opp-supported-hw, however the ones above, aren't.
> 
> 1.608GHz, 1.704GHz and 1.8GHz are all using different opp-supported-hw.
> 
> Similarly, for the big cores clusters, all OPPs up to 1.608GHz are
> using the same opp-supported-hw, but not the ones above.
> 
> 1.8GHz and 2.016GHz, 2.208GHz, 2.256GHz, 2.304GHz, 2.352GHz and 2.4GHz
> all have a different opp-supported-hw.
> 
> The values in that array are coming from cpu leakage (different for
> LITTLE, big0 and big1 clusters) and "specification serial number"
> (whatever that means), those are coming from the SoC OTP. In the
> downstream kernel from Rockchip, the former value is called "SoC
> Version" and the latter "Speed Grade".
> 
> I think this may have something to do with "binning" and I would see
> the ones above the "common" OPPs as "overclocking". Not all CPUs would
> support them and some may not run stable at some lower frequency than
> their stable max. Adding Kever from Rockchip in Cc to have some input
> on the need to support those.

Good point.  We should remove the OPPs for both clusters that aren't
supported by all RK3588(s) binnings, to be on the safe side.

I'll hopefully dive into supporting different Rockchip binnings rather
soon.  There's even more about that, and not just with the RK3588(s),
which I think I'll get all covered.
Alexey Charkov May 8, 2024, 9:43 a.m. UTC | #3
Hi Quentin,

On Wed, May 8, 2024 at 1:12 PM Quentin Schulz <quentin.schulz@cherry.de> wrote:
>
> Hi Alexey,
>
> On 5/6/24 11:36 AM, Alexey Charkov wrote:
> > By default the CPUs on RK3588 start up in a conservative performance
> > mode. Add frequency and voltage mappings to the device tree to enable
> > dynamic scaling via cpufreq.
> >
> > OPP values are adapted from Radxa's downstream kernel for Rock 5B [1],
> > stripping them down to the minimum frequency and voltage combinations
> > as expected by the generic upstream cpufreq-dt driver, and also dropping
> > those OPPs that don't differ in voltage but only in frequency (keeping
> > the top frequency OPP in each case).
> >
> > Note that this patch ignores voltage scaling for the CPU memory
> > interface which the downstream kernel does through a custom cpufreq
> > driver, and which is why the downstream version has two sets of voltage
> > values for each OPP (the second one being meant for the memory
> > interface supply regulator). This is done instead via regulator
> > coupling between CPU and memory interface supplies on affected boards.
> >
>
> I'm not sure this is everything we need though.
>
> For the LITTLE cores cluster, all OPPs up to 1.416GHz are using the same
> opp-supported-hw, however the ones above, aren't.

Thanks a lot for pointing this out - could you please elaborate which
downstream kernel you referred to?

> 1.608GHz, 1.704GHz and 1.8GHz are all using different opp-supported-hw.

In Radxa's downstream kernel source that I looked at [1] the LITTLE
core cluster has all OPPs listed with opp-supported-hw = <0xff
0xffff>;

> Similarly, for the big cores clusters, all OPPs up to 1.608GHz are using
> the same opp-supported-hw, but not the ones above.
>
> 1.8GHz and 2.016GHz, 2.208GHz, 2.256GHz, 2.304GHz, 2.352GHz and 2.4GHz
> all have a different opp-supported-hw.

Hmm, only 2.256GHz, 2.304GHz and 2.352GHz in the sources I'm looking
at have a different opp-supported-hw = <0xff 0x0>; (but note that I
dropped them all from my patch here)

> The values in that array are coming from cpu leakage (different for
> LITTLE, big0 and big1 clusters) and "specification serial number"
> (whatever that means), those are coming from the SoC OTP. In the
> downstream kernel from Rockchip, the former value is called "SoC
> Version" and the latter "Speed Grade".

From what I understood by studying Radxa's downstream kernel sources
and TF-A sources [2], the "leakage" in NVMEM cells drives the
selection of power-optimized voltage levels (opp-microvolt-L1 through
opp-microvolt-L7) for each OPP depending on a OTP-programmed silicon
quality metric, whereas in my patch I only kept the most conservative
voltage values for each OPP (i.e. highest-voltage default ones) and
not the power-optimized ones.

So the proposed patch should (supposedly?) work on any silicon, only
the heat death of the universe becomes marginally closer :)

> I think this may have something to do with "binning" and I would see the
> ones above the "common" OPPs as "overclocking". Not all CPUs would
> support them and some may not run stable at some lower frequency than
> their stable max. Adding Kever from Rockchip in Cc to have some input on
> the need to support those.

Would be great to understand those in more detail, indeed!

Thanks a lot,
Alexey

[1] https://github.com/radxa/kernel/blob/c428536281d69aeb2b3480f65b2b227210b61535/arch/arm64/boot/dts/rockchip/rk3588s.dtsi#L588
[2] https://lore.kernel.org/linux-rockchip/CABjd4YzTL=5S7cS8ACNAYVa730WA3iGd5L_wP1Vn9=f83RCORA@mail.gmail.com/
Quentin Schulz May 8, 2024, 10:50 a.m. UTC | #4
Hi Alexey,

On 5/8/24 11:43 AM, Alexey Charkov wrote:
> Hi Quentin,
> 
> On Wed, May 8, 2024 at 1:12 PM Quentin Schulz <quentin.schulz@cherry.de> wrote:
>>
>> Hi Alexey,
>>
>> On 5/6/24 11:36 AM, Alexey Charkov wrote:
>>> By default the CPUs on RK3588 start up in a conservative performance
>>> mode. Add frequency and voltage mappings to the device tree to enable
>>> dynamic scaling via cpufreq.
>>>
>>> OPP values are adapted from Radxa's downstream kernel for Rock 5B [1],
>>> stripping them down to the minimum frequency and voltage combinations
>>> as expected by the generic upstream cpufreq-dt driver, and also dropping
>>> those OPPs that don't differ in voltage but only in frequency (keeping
>>> the top frequency OPP in each case).
>>>
>>> Note that this patch ignores voltage scaling for the CPU memory
>>> interface which the downstream kernel does through a custom cpufreq
>>> driver, and which is why the downstream version has two sets of voltage
>>> values for each OPP (the second one being meant for the memory
>>> interface supply regulator). This is done instead via regulator
>>> coupling between CPU and memory interface supplies on affected boards.
>>>
>>
>> I'm not sure this is everything we need though.
>>
>> For the LITTLE cores cluster, all OPPs up to 1.416GHz are using the same
>> opp-supported-hw, however the ones above, aren't.
> 
> Thanks a lot for pointing this out - could you please elaborate which
> downstream kernel you referred to?
> 

The one provided by Rockchip directly :) No intermediates.

I can give you the one we use on our products at the moment: 
https://git.embedded.cherry.de/tiger-linux.git/ (or jaguar-linux, 
doesn't matter).

The one that is (publicly) "maintained" by Rockchip is:
https://github.com/rockchip-linux/kernel/tree/develop-5.10

 From Cherry's git repo:
"""
$ rg -B1 --color never -N opp-supported-hw 
arch/arm64/boot/dts/rockchip/rk3588s.dtsi
		opp-408000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-600000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-816000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-1008000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-1200000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-1416000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-1608000000 {
			opp-supported-hw = <0xfb 0xffff>;
--
		opp-1704000000 {
			opp-supported-hw = <0x02 0xffff>;
--
		opp-1800000000 {
			opp-supported-hw = <0xf9 0xffff>;
--
		opp-408000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-600000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-816000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-1008000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-1200000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-1416000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-1608000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-1800000000 {
			opp-supported-hw = <0xfb 0xffff>;
--
		opp-2016000000 {
			opp-supported-hw = <0xfb 0xffff>;
--
		opp-2208000000 {
			opp-supported-hw = <0xf9 0xffff>;
--
		opp-2256000000 {
			opp-supported-hw = <0xf9 0x13>;
--
		opp-2304000000 {
			opp-supported-hw = <0xf9 0x24>;
--
		opp-2352000000 {
			opp-supported-hw = <0xf9 0x48>;
--
		opp-2400000000 {
			opp-supported-hw = <0xf9 0x80>;
--
		opp-408000000 {
			opp-supported-hw = <0xff 0x0ffff>;
--
		opp-600000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-816000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-1008000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-1200000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-1416000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-1608000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-1800000000 {
			opp-supported-hw = <0xfb 0xffff>;
--
		opp-2016000000 {
			opp-supported-hw = <0xfb 0xffff>;
--
		opp-2208000000 {
			opp-supported-hw = <0xf9 0xffff>;
--
		opp-2256000000 {
			opp-supported-hw = <0xf9 0x13>;
--
		opp-2304000000 {
			opp-supported-hw = <0xf9 0x24>;
--
		opp-2352000000 {
			opp-supported-hw = <0xf9 0x48>;
--
		opp-2400000000 {
			opp-supported-hw = <0xf9 0x80>;
--
		opp-300000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-400000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-500000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-600000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-700000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-800000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-900000000 {
			opp-supported-hw = <0xfb 0xffff>;
--
		opp-1000000000 {
			opp-supported-hw = <0xfb 0xffff>;
--
		opp-300000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-400000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-500000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-600000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-700000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-800000000 {
			opp-supported-hw = <0xff 0xffff>;
--
		opp-900000000 {
			opp-supported-hw = <0xfb 0xffff>;
--
		opp-1000000000 {
			opp-supported-hw = <0xfb 0xffff>;
"""

In order: LITTLE, big0, big1, DMC (memory), GPU and then NPU OPP table.

Looking at the 6.1 development branch from Rockchip 
(https://github.com/JeffyCN/mirrors/blob/kernel-6.1). The LITTLE cluster 
OPPs seem to all be using the same opp-supported-hw entry now (but 
different from the one in 5.10). But, the big cluster OPPs in 6.1 are 
matching the one in 5.10 (that is, not the ones from Radxa).

>> 1.608GHz, 1.704GHz and 1.8GHz are all using different opp-supported-hw.
> 
> In Radxa's downstream kernel source that I looked at [1] the LITTLE
> core cluster has all OPPs listed with opp-supported-hw = <0xff
> 0xffff>;
> 
>> Similarly, for the big cores clusters, all OPPs up to 1.608GHz are using
>> the same opp-supported-hw, but not the ones above.
>>
>> 1.8GHz and 2.016GHz, 2.208GHz, 2.256GHz, 2.304GHz, 2.352GHz and 2.4GHz
>> all have a different opp-supported-hw.
> 
> Hmm, only 2.256GHz, 2.304GHz and 2.352GHz in the sources I'm looking
> at have a different opp-supported-hw = <0xff 0x0>; (but note that I
> dropped them all from my patch here)
> 

Seems to be a change made by Radxa folks: 
https://github.com/radxa/kernel/commit/cf277d5eb46ef55517afffa10d48dd71bdd00c61 
(yay to no commit log \o/)

>> The values in that array are coming from cpu leakage (different for
>> LITTLE, big0 and big1 clusters) and "specification serial number"
>> (whatever that means), those are coming from the SoC OTP. In the
>> downstream kernel from Rockchip, the former value is called "SoC
>> Version" and the latter "Speed Grade".
> 
>  From what I understood by studying Radxa's downstream kernel sources
> and TF-A sources [2], the "leakage" in NVMEM cells drives the
> selection of power-optimized voltage levels (opp-microvolt-L1 through
> opp-microvolt-L7) for each OPP depending on a OTP-programmed silicon
> quality metric, whereas in my patch I only kept the most conservative
> voltage values for each OPP (i.e. highest-voltage default ones) and
> not the power-optimized ones.
> 
> So the proposed patch should (supposedly?) work on any silicon, only
> the heat death of the universe becomes marginally closer :)
> 

An OPP from the DT is selected if _opp_is_supported returns true. This 
is based on supported_hw member of the opp_table, which we set through 
dev_pm_opp_set_supported_hw. This is called by 
drivers/cpufreq/rockchip-cpufreq.c with two values: SoC Version and 
Speed Grade. The SoC version is a bitmap set by rk3588_get_soc_info by 
reading specification_serial_number region in the OTP and reading the 
first byte. If it is anything but 0xd (RK3588M) or 0xa (RK3588J), it is 
BIT(0).

To know if the opp is supported, you extract the first value of the 
array and mask it with the value gotten from rk3588_get_soc_info (the 
bitfield). This means that for RK3588 (and not the M or J variant), the 
first value of the OPP opp-supported-hw is a match if it is an odd 
number, so only opp-1704000000 in LITTLE cluster is excluded (on that 
sole match).

The second value in opp-supported-hw seems to be derived somehow from 
the cpu_leakage OTP. This is likely the same rabbit hole you dug two 
months ago, so I'll trust your findings there to avoid getting my hands 
dirty :)

In summary, false alarm (but still surprising changes made by Radxa 
here, not that they matter if they only run their kernel on "pure" 
RK3588). Sorry for the noise, and thanks for the explanations :)

I'm surprised that we removed the lowest frequencies at the same 
voltage, are they not even allowing us to save a teeny tiny bit of power 
consumption? (I'm asking because I'm pretty sure we'll eventually get 
customers complaining the CPU freq doesn't go in super low frequency "so 
this must be a way to consume less power in idle!").

Cheers,
Quentin
Dragan Simic May 8, 2024, 10:56 a.m. UTC | #5
On 2024-05-08 12:50, Quentin Schulz wrote:
> I'm surprised that we removed the lowest frequencies at the same
> voltage, are they not even allowing us to save a teeny tiny bit of
> power consumption? (I'm asking because I'm pretty sure we'll
> eventually get customers complaining the CPU freq doesn't go in super
> low frequency "so this must be a way to consume less power in idle!").

Same-voltage, different-frequency OPPs are seen as inefficient, although
I don't share the same opinion.  While the jury is still out, perhaps we
can omit them, and possibly add them later.
diff mbox series

Patch

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
index 57c2d998ae75..85c25d5efdad 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
@@ -97,6 +97,7 @@  cpu_l0: cpu@0 {
 			clocks = <&scmi_clk SCMI_CLK_CPUL>;
 			assigned-clocks = <&scmi_clk SCMI_CLK_CPUL>;
 			assigned-clock-rates = <816000000>;
+			operating-points-v2 = <&cluster0_opp_table>;
 			cpu-idle-states = <&CPU_SLEEP>;
 			i-cache-size = <32768>;
 			i-cache-line-size = <64>;
@@ -116,6 +117,7 @@  cpu_l1: cpu@100 {
 			enable-method = "psci";
 			capacity-dmips-mhz = <530>;
 			clocks = <&scmi_clk SCMI_CLK_CPUL>;
+			operating-points-v2 = <&cluster0_opp_table>;
 			cpu-idle-states = <&CPU_SLEEP>;
 			i-cache-size = <32768>;
 			i-cache-line-size = <64>;
@@ -135,6 +137,7 @@  cpu_l2: cpu@200 {
 			enable-method = "psci";
 			capacity-dmips-mhz = <530>;
 			clocks = <&scmi_clk SCMI_CLK_CPUL>;
+			operating-points-v2 = <&cluster0_opp_table>;
 			cpu-idle-states = <&CPU_SLEEP>;
 			i-cache-size = <32768>;
 			i-cache-line-size = <64>;
@@ -154,6 +157,7 @@  cpu_l3: cpu@300 {
 			enable-method = "psci";
 			capacity-dmips-mhz = <530>;
 			clocks = <&scmi_clk SCMI_CLK_CPUL>;
+			operating-points-v2 = <&cluster0_opp_table>;
 			cpu-idle-states = <&CPU_SLEEP>;
 			i-cache-size = <32768>;
 			i-cache-line-size = <64>;
@@ -175,6 +179,7 @@  cpu_b0: cpu@400 {
 			clocks = <&scmi_clk SCMI_CLK_CPUB01>;
 			assigned-clocks = <&scmi_clk SCMI_CLK_CPUB01>;
 			assigned-clock-rates = <816000000>;
+			operating-points-v2 = <&cluster1_opp_table>;
 			cpu-idle-states = <&CPU_SLEEP>;
 			i-cache-size = <65536>;
 			i-cache-line-size = <64>;
@@ -194,6 +199,7 @@  cpu_b1: cpu@500 {
 			enable-method = "psci";
 			capacity-dmips-mhz = <1024>;
 			clocks = <&scmi_clk SCMI_CLK_CPUB01>;
+			operating-points-v2 = <&cluster1_opp_table>;
 			cpu-idle-states = <&CPU_SLEEP>;
 			i-cache-size = <65536>;
 			i-cache-line-size = <64>;
@@ -215,6 +221,7 @@  cpu_b2: cpu@600 {
 			clocks = <&scmi_clk SCMI_CLK_CPUB23>;
 			assigned-clocks = <&scmi_clk SCMI_CLK_CPUB23>;
 			assigned-clock-rates = <816000000>;
+			operating-points-v2 = <&cluster2_opp_table>;
 			cpu-idle-states = <&CPU_SLEEP>;
 			i-cache-size = <65536>;
 			i-cache-line-size = <64>;
@@ -234,6 +241,7 @@  cpu_b3: cpu@700 {
 			enable-method = "psci";
 			capacity-dmips-mhz = <1024>;
 			clocks = <&scmi_clk SCMI_CLK_CPUB23>;
+			operating-points-v2 = <&cluster2_opp_table>;
 			cpu-idle-states = <&CPU_SLEEP>;
 			i-cache-size = <65536>;
 			i-cache-line-size = <64>;
@@ -348,6 +356,120 @@  l3_cache: l3-cache {
 		};
 	};
 
+	cluster0_opp_table: opp-table-cluster0 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-1008000000 {
+			opp-hz = /bits/ 64 <1008000000>;
+			opp-microvolt = <675000 675000 950000>;
+			clock-latency-ns = <40000>;
+		};
+		opp-1200000000 {
+			opp-hz = /bits/ 64 <1200000000>;
+			opp-microvolt = <712500 712500 950000>;
+			clock-latency-ns = <40000>;
+		};
+		opp-1416000000 {
+			opp-hz = /bits/ 64 <1416000000>;
+			opp-microvolt = <762500 762500 950000>;
+			clock-latency-ns = <40000>;
+			opp-suspend;
+		};
+		opp-1608000000 {
+			opp-hz = /bits/ 64 <1608000000>;
+			opp-microvolt = <850000 850000 950000>;
+			clock-latency-ns = <40000>;
+		};
+		opp-1800000000 {
+			opp-hz = /bits/ 64 <1800000000>;
+			opp-microvolt = <950000 950000 950000>;
+			clock-latency-ns = <40000>;
+		};
+	};
+
+	cluster1_opp_table: opp-table-cluster1 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-1200000000 {
+			opp-hz = /bits/ 64 <1200000000>;
+			opp-microvolt = <675000 675000 1000000>;
+			clock-latency-ns = <40000>;
+		};
+		opp-1416000000 {
+			opp-hz = /bits/ 64 <1416000000>;
+			opp-microvolt = <725000 725000 1000000>;
+			clock-latency-ns = <40000>;
+		};
+		opp-1608000000 {
+			opp-hz = /bits/ 64 <1608000000>;
+			opp-microvolt = <762500 762500 1000000>;
+			clock-latency-ns = <40000>;
+		};
+		opp-1800000000 {
+			opp-hz = /bits/ 64 <1800000000>;
+			opp-microvolt = <850000 850000 1000000>;
+			clock-latency-ns = <40000>;
+		};
+		opp-2016000000 {
+			opp-hz = /bits/ 64 <2016000000>;
+			opp-microvolt = <925000 925000 1000000>;
+			clock-latency-ns = <40000>;
+		};
+		opp-2208000000 {
+			opp-hz = /bits/ 64 <2208000000>;
+			opp-microvolt = <987500 987500 1000000>;
+			clock-latency-ns = <40000>;
+		};
+		opp-2400000000 {
+			opp-hz = /bits/ 64 <2400000000>;
+			opp-microvolt = <1000000 1000000 1000000>;
+			clock-latency-ns = <40000>;
+		};
+	};
+
+	cluster2_opp_table: opp-table-cluster2 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-1200000000 {
+			opp-hz = /bits/ 64 <1200000000>;
+			opp-microvolt = <675000 675000 1000000>;
+			clock-latency-ns = <40000>;
+		};
+		opp-1416000000 {
+			opp-hz = /bits/ 64 <1416000000>;
+			opp-microvolt = <725000 725000 1000000>;
+			clock-latency-ns = <40000>;
+		};
+		opp-1608000000 {
+			opp-hz = /bits/ 64 <1608000000>;
+			opp-microvolt = <762500 762500 1000000>;
+			clock-latency-ns = <40000>;
+		};
+		opp-1800000000 {
+			opp-hz = /bits/ 64 <1800000000>;
+			opp-microvolt = <850000 850000 1000000>;
+			clock-latency-ns = <40000>;
+		};
+		opp-2016000000 {
+			opp-hz = /bits/ 64 <2016000000>;
+			opp-microvolt = <925000 925000 1000000>;
+			clock-latency-ns = <40000>;
+		};
+		opp-2208000000 {
+			opp-hz = /bits/ 64 <2208000000>;
+			opp-microvolt = <987500 987500 1000000>;
+			clock-latency-ns = <40000>;
+		};
+		opp-2400000000 {
+			opp-hz = /bits/ 64 <2400000000>;
+			opp-microvolt = <1000000 1000000 1000000>;
+			clock-latency-ns = <40000>;
+		};
+	};
+
 	display_subsystem: display-subsystem {
 		compatible = "rockchip,display-subsystem";
 		ports = <&vop_out>;