158 lines
4.9 KiB
Diff
158 lines
4.9 KiB
Diff
|
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
|
||
|
|