mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/2] arm64: dts: qcom: sdm630: Fix the CPU idle states
@ 2026-10-12  2:18 Fabricio Akio via B4 Relay
  2026-10-12  2:18 ` [PATCH 1/2] arm64: dts: qcom: sdm630: Drop the cluster " Fabricio Akio via B4 Relay
  2026-10-12  2:18 ` [PATCH 2/2] arm64: dts: qcom: sdm630: Fix the CPU retention idle state parameter Fabricio Akio via B4 Relay
  0 siblings, 2 replies; 5+ messages in thread
From: Fabricio Akio via B4 Relay @ 2026-10-12  2:18 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley
  Cc: Abel Vesa, Alexey Minnekhanov, Dmitry Baryshkov, Martin Botka,
	linux-arm-msm, devicetree, linux-kernel, Fabricio Akio

Of the five idle states sdm630.dtsi gives each CPU, four are never
entered. The three cluster states use PSCI parameters that are not in
the encoding the vendor kernel uses, and cpuidle records no successful
entry into them. Because they are the deepest states, an idle CPU
keeps choosing one, each attempt returns at once, and the CPU spends
its idle time retrying instead of sleeping. CPU retention sets the bit
that marks a state as losing context. The first patch drops the cluster
states, the second fixes the retention parameter.

Tested on a Motorola Moto X4 (SDM630), whose board file is not in
mainline yet, on sdm660-mainline's 7.2 kernel, whose idle states are
these: with the screen off and the charger input suspended, the
battery current drops from 277 mA to 117 mA.

This firmware denies platform-coordinated mode at boot ("psci:
[Firmware Bug]: failed to set PC mode: -3"), and the vendor kernel
requests a cluster state only from the last CPU of a cluster.
Restoring cluster idle that way, with the CPUs described as PSCI
power domains, is left for a later series.

---
Fabricio Akio (2):
      arm64: dts: qcom: sdm630: Drop the cluster idle states
      arm64: dts: qcom: sdm630: Fix the CPU retention idle state parameter

 arch/arm64/boot/dts/qcom/sdm630.dtsi | 112 ++++-------------------------------
 1 file changed, 10 insertions(+), 102 deletions(-)
---
base-commit: becb95e45ef0dda9ffb35156d909d3da7a2789c3
change-id: 20261011-sdm630-idle-states-84f3ac364b2c

Best regards,
--  
Fabricio Akio <fabricioakio@gmail.com>



^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/2] arm64: dts: qcom: sdm630: Drop the cluster idle states
  2026-10-12  2:18 [PATCH 0/2] arm64: dts: qcom: sdm630: Fix the CPU idle states Fabricio Akio via B4 Relay
@ 2026-10-12  2:18 ` Fabricio Akio via B4 Relay
  2026-10-15 13:51   ` Konrad Dybcio
  2026-10-12  2:18 ` [PATCH 2/2] arm64: dts: qcom: sdm630: Fix the CPU retention idle state parameter Fabricio Akio via B4 Relay
  1 sibling, 1 reply; 5+ messages in thread
From: Fabricio Akio via B4 Relay @ 2026-10-12  2:18 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley
  Cc: Abel Vesa, Alexey Minnekhanov, Dmitry Baryshkov, Martin Botka,
	linux-arm-msm, devicetree, linux-kernel, Fabricio Akio

From: Fabricio Akio <fabricioakio@gmail.com>

The cluster idle states use PSCI parameters 0x400000f2-0x400000f4. The
vendor kernel encodes a cluster state differently: it puts the cluster
mode in StateID bits 7:4 and sets an affinity-level field, bits 25:24,
to 1, so cluster power collapse is 0x41000043, and only the last
running CPU of a cluster requests one. A flat cpu-idle-states list
cannot express that condition.

cpuidle records no successful entry into any of these states, and every
request for one fails. Because they are the deepest, an idle CPU keeps
choosing one, each attempt returns at once, and the CPU spends its idle
time retrying instead of sleeping. On a Motorola Moto X4 (SDM630) with
the screen off, the CPUs made about 133,000 failed idle entries per
second and spent about 10% of the time in an idle state, and the
battery supplied 277 mA. Without these states they spend nearly all of
it in one, and the battery supplies 115 mA.

Fixes: b190fb010664 ("arm64: dts: qcom: sdm630: Add sdm630 dts file")
Signed-off-by: Fabricio Akio <fabricioakio@gmail.com>
---
 arch/arm64/boot/dts/qcom/sdm630.dtsi | 108 +++--------------------------------
 1 file changed, 8 insertions(+), 100 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi
index 3a1014804fb0..222ec5886818 100644
--- a/arch/arm64/boot/dts/qcom/sdm630.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi
@@ -55,11 +55,7 @@ cpu0: cpu@100 {
 			compatible = "arm,cortex-a53";
 			reg = <0x0 0x100>;
 			enable-method = "psci";
-			cpu-idle-states = <&perf_cpu_sleep_0
-						&perf_cpu_sleep_1
-						&perf_cluster_sleep_0
-						&perf_cluster_sleep_1
-						&perf_cluster_sleep_2>;
+			cpu-idle-states = <&perf_cpu_sleep_0 &perf_cpu_sleep_1>;
 			capacity-dmips-mhz = <1126>;
 			#cooling-cells = <2>;
 			next-level-cache = <&l2_1>;
@@ -75,11 +71,7 @@ cpu1: cpu@101 {
 			compatible = "arm,cortex-a53";
 			reg = <0x0 0x101>;
 			enable-method = "psci";
-			cpu-idle-states = <&perf_cpu_sleep_0
-						&perf_cpu_sleep_1
-						&perf_cluster_sleep_0
-						&perf_cluster_sleep_1
-						&perf_cluster_sleep_2>;
+			cpu-idle-states = <&perf_cpu_sleep_0 &perf_cpu_sleep_1>;
 			capacity-dmips-mhz = <1126>;
 			#cooling-cells = <2>;
 			next-level-cache = <&l2_1>;
@@ -90,11 +82,7 @@ cpu2: cpu@102 {
 			compatible = "arm,cortex-a53";
 			reg = <0x0 0x102>;
 			enable-method = "psci";
-			cpu-idle-states = <&perf_cpu_sleep_0
-						&perf_cpu_sleep_1
-						&perf_cluster_sleep_0
-						&perf_cluster_sleep_1
-						&perf_cluster_sleep_2>;
+			cpu-idle-states = <&perf_cpu_sleep_0 &perf_cpu_sleep_1>;
 			capacity-dmips-mhz = <1126>;
 			#cooling-cells = <2>;
 			next-level-cache = <&l2_1>;
@@ -105,11 +93,7 @@ cpu3: cpu@103 {
 			compatible = "arm,cortex-a53";
 			reg = <0x0 0x103>;
 			enable-method = "psci";
-			cpu-idle-states = <&perf_cpu_sleep_0
-						&perf_cpu_sleep_1
-						&perf_cluster_sleep_0
-						&perf_cluster_sleep_1
-						&perf_cluster_sleep_2>;
+			cpu-idle-states = <&perf_cpu_sleep_0 &perf_cpu_sleep_1>;
 			capacity-dmips-mhz = <1126>;
 			#cooling-cells = <2>;
 			next-level-cache = <&l2_1>;
@@ -120,11 +104,7 @@ cpu4: cpu@0 {
 			compatible = "arm,cortex-a53";
 			reg = <0x0 0x0>;
 			enable-method = "psci";
-			cpu-idle-states = <&pwr_cpu_sleep_0
-						&pwr_cpu_sleep_1
-						&pwr_cluster_sleep_0
-						&pwr_cluster_sleep_1
-						&pwr_cluster_sleep_2>;
+			cpu-idle-states = <&pwr_cpu_sleep_0 &pwr_cpu_sleep_1>;
 			capacity-dmips-mhz = <1024>;
 			#cooling-cells = <2>;
 			next-level-cache = <&l2_0>;
@@ -140,11 +120,7 @@ cpu5: cpu@1 {
 			compatible = "arm,cortex-a53";
 			reg = <0x0 0x1>;
 			enable-method = "psci";
-			cpu-idle-states = <&pwr_cpu_sleep_0
-						&pwr_cpu_sleep_1
-						&pwr_cluster_sleep_0
-						&pwr_cluster_sleep_1
-						&pwr_cluster_sleep_2>;
+			cpu-idle-states = <&pwr_cpu_sleep_0 &pwr_cpu_sleep_1>;
 			capacity-dmips-mhz = <1024>;
 			#cooling-cells = <2>;
 			next-level-cache = <&l2_0>;
@@ -155,11 +131,7 @@ cpu6: cpu@2 {
 			compatible = "arm,cortex-a53";
 			reg = <0x0 0x2>;
 			enable-method = "psci";
-			cpu-idle-states = <&pwr_cpu_sleep_0
-						&pwr_cpu_sleep_1
-						&pwr_cluster_sleep_0
-						&pwr_cluster_sleep_1
-						&pwr_cluster_sleep_2>;
+			cpu-idle-states = <&pwr_cpu_sleep_0 &pwr_cpu_sleep_1>;
 			capacity-dmips-mhz = <1024>;
 			#cooling-cells = <2>;
 			next-level-cache = <&l2_0>;
@@ -170,11 +142,7 @@ cpu7: cpu@3 {
 			compatible = "arm,cortex-a53";
 			reg = <0x0 0x3>;
 			enable-method = "psci";
-			cpu-idle-states = <&pwr_cpu_sleep_0
-						&pwr_cpu_sleep_1
-						&pwr_cluster_sleep_0
-						&pwr_cluster_sleep_1
-						&pwr_cluster_sleep_2>;
+			cpu-idle-states = <&pwr_cpu_sleep_0 &pwr_cpu_sleep_1>;
 			capacity-dmips-mhz = <1024>;
 			#cooling-cells = <2>;
 			next-level-cache = <&l2_0>;
@@ -258,66 +226,6 @@ perf_cpu_sleep_1: cpu-sleep-1-1 {
 				min-residency-us = <1000>;
 				local-timer-stop;
 			};
-
-			pwr_cluster_sleep_0: cluster-sleep-0-0 {
-				compatible = "arm,idle-state";
-				idle-state-name = "pwr-cluster-dynamic-retention";
-				arm,psci-suspend-param = <0x400000f2>;
-				entry-latency-us = <284>;
-				exit-latency-us = <384>;
-				min-residency-us = <9987>;
-				local-timer-stop;
-			};
-
-			pwr_cluster_sleep_1: cluster-sleep-0-1 {
-				compatible = "arm,idle-state";
-				idle-state-name = "pwr-cluster-retention";
-				arm,psci-suspend-param = <0x400000f3>;
-				entry-latency-us = <338>;
-				exit-latency-us = <423>;
-				min-residency-us = <9987>;
-				local-timer-stop;
-			};
-
-			pwr_cluster_sleep_2: cluster-sleep-0-2 {
-				compatible = "arm,idle-state";
-				idle-state-name = "pwr-cluster-retention";
-				arm,psci-suspend-param = <0x400000f4>;
-				entry-latency-us = <515>;
-				exit-latency-us = <1821>;
-				min-residency-us = <9987>;
-				local-timer-stop;
-			};
-
-			perf_cluster_sleep_0: cluster-sleep-1-0 {
-				compatible = "arm,idle-state";
-				idle-state-name = "perf-cluster-dynamic-retention";
-				arm,psci-suspend-param = <0x400000f2>;
-				entry-latency-us = <272>;
-				exit-latency-us = <329>;
-				min-residency-us = <9987>;
-				local-timer-stop;
-			};
-
-			perf_cluster_sleep_1: cluster-sleep-1-1 {
-				compatible = "arm,idle-state";
-				idle-state-name = "perf-cluster-retention";
-				arm,psci-suspend-param = <0x400000f3>;
-				entry-latency-us = <332>;
-				exit-latency-us = <368>;
-				min-residency-us = <9987>;
-				local-timer-stop;
-			};
-
-			perf_cluster_sleep_2: cluster-sleep-1-2 {
-				compatible = "arm,idle-state";
-				idle-state-name = "perf-cluster-retention";
-				arm,psci-suspend-param = <0x400000f4>;
-				entry-latency-us = <545>;
-				exit-latency-us = <1609>;
-				min-residency-us = <9987>;
-				local-timer-stop;
-			};
 		};
 	};
 

-- 
2.56.0



^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 2/2] arm64: dts: qcom: sdm630: Fix the CPU retention idle state parameter
  2026-10-12  2:18 [PATCH 0/2] arm64: dts: qcom: sdm630: Fix the CPU idle states Fabricio Akio via B4 Relay
  2026-10-12  2:18 ` [PATCH 1/2] arm64: dts: qcom: sdm630: Drop the cluster " Fabricio Akio via B4 Relay
@ 2026-10-12  2:18 ` Fabricio Akio via B4 Relay
  2026-10-15 13:41   ` Konrad Dybcio
  1 sibling, 1 reply; 5+ messages in thread
From: Fabricio Akio via B4 Relay @ 2026-10-12  2:18 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley
  Cc: Abel Vesa, Alexey Minnekhanov, Dmitry Baryshkov, Martin Botka,
	linux-arm-msm, devicetree, linux-kernel, Fabricio Akio

From: Fabricio Akio <fabricioakio@gmail.com>

The CPU retention states set bit 30 of their PSCI power_state, which
marks a state that loses context. Retention keeps it, and the vendor
kernel requests it as 0x00000002.

With bit 30 set, no entry into these states succeeds on a Motorola Moto
X4 (SDM630). With it clear they are entered about 50 times per second
across the CPUs, and the failed idle entries across all states drop
from about 30 to about 9 per second.

Fixes: b190fb010664 ("arm64: dts: qcom: sdm630: Add sdm630 dts file")
Signed-off-by: Fabricio Akio <fabricioakio@gmail.com>
---
 arch/arm64/boot/dts/qcom/sdm630.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi
index 222ec5886818..a58bad0fb638 100644
--- a/arch/arm64/boot/dts/qcom/sdm630.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi
@@ -192,7 +192,7 @@ idle-states {
 			pwr_cpu_sleep_0: cpu-sleep-0-0 {
 				compatible = "arm,idle-state";
 				idle-state-name = "pwr-retention";
-				arm,psci-suspend-param = <0x40000002>;
+				arm,psci-suspend-param = <0x00000002>;
 				entry-latency-us = <338>;
 				exit-latency-us = <423>;
 				min-residency-us = <200>;
@@ -211,7 +211,7 @@ pwr_cpu_sleep_1: cpu-sleep-0-1 {
 			perf_cpu_sleep_0: cpu-sleep-1-0 {
 				compatible = "arm,idle-state";
 				idle-state-name = "perf-retention";
-				arm,psci-suspend-param = <0x40000002>;
+				arm,psci-suspend-param = <0x00000002>;
 				entry-latency-us = <154>;
 				exit-latency-us = <87>;
 				min-residency-us = <200>;

-- 
2.56.0



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/2] arm64: dts: qcom: sdm630: Fix the CPU retention idle state parameter
  2026-10-12  2:18 ` [PATCH 2/2] arm64: dts: qcom: sdm630: Fix the CPU retention idle state parameter Fabricio Akio via B4 Relay
@ 2026-10-15 13:41   ` Konrad Dybcio
  0 siblings, 0 replies; 5+ messages in thread
From: Konrad Dybcio @ 2026-10-15 13:41 UTC (permalink / raw)
  To: fabricioakio, Bjorn Andersson, Konrad Dybcio, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: Abel Vesa, Alexey Minnekhanov, Dmitry Baryshkov, Martin Botka,
	linux-arm-msm, devicetree, linux-kernel

On 10/12/26 4:18 AM, Fabricio Akio via B4 Relay wrote:
> From: Fabricio Akio <fabricioakio@gmail.com>
> 
> The CPU retention states set bit 30 of their PSCI power_state, which
> marks a state that loses context. Retention keeps it, and the vendor
> kernel requests it as 0x00000002.
> 
> With bit 30 set, no entry into these states succeeds on a Motorola Moto
> X4 (SDM630). With it clear they are entered about 50 times per second
> across the CPUs, and the failed idle entries across all states drop
> from about 30 to about 9 per second.
> 
> Fixes: b190fb010664 ("arm64: dts: qcom: sdm630: Add sdm630 dts file")
> Signed-off-by: Fabricio Akio <fabricioakio@gmail.com>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>

Konrad

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] arm64: dts: qcom: sdm630: Drop the cluster idle states
  2026-10-12  2:18 ` [PATCH 1/2] arm64: dts: qcom: sdm630: Drop the cluster " Fabricio Akio via B4 Relay
@ 2026-10-15 13:51   ` Konrad Dybcio
  0 siblings, 0 replies; 5+ messages in thread
From: Konrad Dybcio @ 2026-10-15 13:51 UTC (permalink / raw)
  To: fabricioakio, Bjorn Andersson, Konrad Dybcio, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: Abel Vesa, Alexey Minnekhanov, Dmitry Baryshkov, Martin Botka,
	linux-arm-msm, devicetree, linux-kernel

On 10/12/26 4:18 AM, Fabricio Akio via B4 Relay wrote:
> From: Fabricio Akio <fabricioakio@gmail.com>
> 
> The cluster idle states use PSCI parameters 0x400000f2-0x400000f4. The
> vendor kernel encodes a cluster state differently: it puts the cluster
> mode in StateID bits 7:4 and sets an affinity-level field, bits 25:24,
> to 1, so cluster power collapse is 0x41000043, and only the last
> running CPU of a cluster requests one. A flat cpu-idle-states list
> cannot express that condition.
> 
> cpuidle records no successful entry into any of these states, and every
> request for one fails. Because they are the deepest, an idle CPU keeps
> choosing one, each attempt returns at once, and the CPU spends its idle
> time retrying instead of sleeping. On a Motorola Moto X4 (SDM630) with
> the screen off, the CPUs made about 133,000 failed idle entries per
> second and spent about 10% of the time in an idle state, and the
> battery supplied 277 mA. Without these states they spend nearly all of
> it in one, and the battery supplies 115 mA.
> 
> Fixes: b190fb010664 ("arm64: dts: qcom: sdm630: Add sdm630 dts file")
> Signed-off-by: Fabricio Akio <fabricioakio@gmail.com>
> ---

I threw an LLM at the downstream tree and it decoded the states to:

C2D, no cluster state	2		0x00000002
C3, no cluster state	3		0x40000003
pwr/perf L2 D2D + C2D	L2 2		0x01000022
pwr/perf L2 D2D + C3	L2 2		0x41000023
pwr/perf L2 D2E + C3	L2 3		0x41000033
pwr/perf L2 D4 + C3	L2 4		0x41000043
System PC + L2 D4 + C3	sys3, L2 4	0x42000343

sorry for getting it wrong years ago!

Konrad

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-10-15 13:51 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-12  2:18 [PATCH 0/2] arm64: dts: qcom: sdm630: Fix the CPU idle states Fabricio Akio via B4 Relay
2026-10-12  2:18 ` [PATCH 1/2] arm64: dts: qcom: sdm630: Drop the cluster " Fabricio Akio via B4 Relay
2026-10-15 13:51   ` Konrad Dybcio
2026-10-12  2:18 ` [PATCH 2/2] arm64: dts: qcom: sdm630: Fix the CPU retention idle state parameter Fabricio Akio via B4 Relay
2026-10-15 13:41   ` Konrad Dybcio

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®