build/patch/kernel/archive/sunxi-5.15/patches.megous/arm64-dts-allwinner-a64-h5-Add-CPU-idle-states.patch

158 lines
4.9 KiB
Diff
Raw Normal View History

From 93e8deccd1317f9731d9487314497de59becdb00 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 13 Mar 2021 23:54:25 -0600
Subject: [PATCH 278/478] arm64: dts: allwinner: a64/h5: Add CPU idle states
Powering off idle CPUs saves about 30 mW compared to using WFI only.
Additional power savings are possible by idling the L2 and downclocking
the cluster when all CPUs are idle.
Entry and exit latency were measured using a logic analyzer, with GPIO
pins toggled in Linux after the calls to trace_cpu_idle() in
cpuidle_enter_state(), and in the power management firmware after CPU
power-off completes and immediately after detecting an interrupt.
800 us and 1500 us are worst-case values, largely driven by the fact
that the power management firmware is single threaded. It can only
handle commands to power off CPUs one at a time, and it cannot process
any commands while powering on a CPU in response to an interrupt.
The cluster suspend process reliably takes 36 us; I rounded this up to
50 us. If all CPUs enter the cluster idle state at the same time, exit
latency is actually reduced, because there is no contention in that
case. However, if only some CPUs enter the cluster idle state, behavior
is the same as for CPU idle.
Polling delay for the power management firmware to detect a pending
interrupt is insignificant; it is less than 20 us.
min-residency was chosen as the point where enabling the idle state
consumed no more average power than disabling the idle state at a
variety of interrupt rates.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 26 +++++++++++++++++++
arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi | 26 +++++++++++++++++++
2 files changed, 52 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 54747e99dfee..29ef980a39e2 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -54,6 +54,7 @@ cpu0: cpu@0 {
clocks = <&ccu CLK_CPUX>;
clock-names = "cpu";
#cooling-cells = <2>;
+ cpu-idle-states = <&cpu_sleep>, <&cluster_sleep>;
};
cpu1: cpu@1 {
@@ -65,6 +66,7 @@ cpu1: cpu@1 {
clocks = <&ccu CLK_CPUX>;
clock-names = "cpu";
#cooling-cells = <2>;
+ cpu-idle-states = <&cpu_sleep>, <&cluster_sleep>;
};
cpu2: cpu@2 {
@@ -76,6 +78,7 @@ cpu2: cpu@2 {
clocks = <&ccu CLK_CPUX>;
clock-names = "cpu";
#cooling-cells = <2>;
+ cpu-idle-states = <&cpu_sleep>, <&cluster_sleep>;
};
cpu3: cpu@3 {
@@ -87,6 +90,29 @@ cpu3: cpu@3 {
clocks = <&ccu CLK_CPUX>;
clock-names = "cpu";
#cooling-cells = <2>;
+ cpu-idle-states = <&cpu_sleep>, <&cluster_sleep>;
+ };
+
+ idle-states {
+ entry-method = "psci";
+
+ cpu_sleep: cpu-sleep {
+ compatible = "arm,idle-state";
+ local-timer-stop;
+ entry-latency-us = <800>;
+ exit-latency-us = <1500>;
+ min-residency-us = <25000>;
+ arm,psci-suspend-param = <0x00010003>;
+ };
+
+ cluster_sleep: cluster-sleep {
+ compatible = "arm,idle-state";
+ local-timer-stop;
+ entry-latency-us = <850>;
+ exit-latency-us = <1500>;
+ min-residency-us = <50000>;
+ arm,psci-suspend-param = <0x01010013>;
+ };
};
L2: l2-cache {
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
index e85695031a6b..02cc9be868f0 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
@@ -18,6 +18,7 @@ cpu0: cpu@0 {
clocks = <&ccu CLK_CPUX>;
clock-latency-ns = <244144>; /* 8 32k periods */
#cooling-cells = <2>;
+ cpu-idle-states = <&cpu_sleep>, <&cluster_sleep>;
};
cpu1: cpu@1 {
@@ -28,6 +29,7 @@ cpu1: cpu@1 {
clocks = <&ccu CLK_CPUX>;
clock-latency-ns = <244144>; /* 8 32k periods */
#cooling-cells = <2>;
+ cpu-idle-states = <&cpu_sleep>, <&cluster_sleep>;
};
cpu2: cpu@2 {
@@ -38,6 +40,7 @@ cpu2: cpu@2 {
clocks = <&ccu CLK_CPUX>;
clock-latency-ns = <244144>; /* 8 32k periods */
#cooling-cells = <2>;
+ cpu-idle-states = <&cpu_sleep>, <&cluster_sleep>;
};
cpu3: cpu@3 {
@@ -48,6 +51,29 @@ cpu3: cpu@3 {
clocks = <&ccu CLK_CPUX>;
clock-latency-ns = <244144>; /* 8 32k periods */
#cooling-cells = <2>;
+ cpu-idle-states = <&cpu_sleep>, <&cluster_sleep>;
+ };
+
+ idle-states {
+ entry-method = "psci";
+
+ cpu_sleep: cpu-sleep {
+ compatible = "arm,idle-state";
+ local-timer-stop;
+ entry-latency-us = <800>;
+ exit-latency-us = <1500>;
+ min-residency-us = <25000>;
+ arm,psci-suspend-param = <0x00010003>;
+ };
+
+ cluster_sleep: cluster-sleep {
+ compatible = "arm,idle-state";
+ local-timer-stop;
+ entry-latency-us = <850>;
+ exit-latency-us = <1500>;
+ min-residency-us = <50000>;
+ arm,psci-suspend-param = <0x01010013>;
+ };
};
};
--
2.35.3