[PATCH] arm64: dts: qcom: sm8150: Add support for deep CPU cluster idle

Subsystems: arm/qualcomm mailing list, arm/qualcomm support, the rest

STALE2024d LANDED

Landed in mainline as b2e3f897684c on 2021-01-12.

4 messages, 3 authors, 2021-01-12 · open the first message on its own page

[PATCH] arm64: dts: qcom: sm8150: Add support for deep CPU cluster idle

From: Danny Lin <hidden>
Date: 2021-01-05 20:11:45

This commit adds support for deep idling of the entire unified DynamIQ
CPU cluster on sm8150. In this idle state, the LLCC (Last-Level Cache
Controller) is powered off and the AOP (Always-On Processor) enters a
low-power sleep state.

I'm not sure what the per-CPU 0x400000f4 idle state previously
contributed by Qualcomm as the "cluster sleep" state is, but the
downstream kernel has no such state. The real deep cluster idle state
is 0x41000c244, composed of:

    Cluster idle state: (0xc24) << 4 = 0xc240
    Is reset state: 1 << 30 = 0x40000000
    Affinity level: 1 << 24 = 0x1000000
    CPU idle state: 0x4 (power collapse)

This setup can be replicated with the PSCI power domain cpuidle driver,
which utilizes OSI to enter cluster idle when the last active CPU
enters idle.

The cluster idle state cannot be used as a plain cpuidle state because
it requires that all CPUs in the cluster are idling.

Signed-off-by: Danny Lin <redacted>
---
 arch/arm64/boot/dts/qcom/sm8150.dtsi | 91 ++++++++++++++++++++++------
 1 file changed, 73 insertions(+), 18 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi
index 309e00b6fa44..8956c6986744 100644
--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
@@ -52,10 +52,10 @@ CPU0: cpu@0 {
 			enable-method = "psci";
 			capacity-dmips-mhz = <488>;
 			dynamic-power-coefficient = <232>;
-			cpu-idle-states = <&LITTLE_CPU_SLEEP_0
-					   &CLUSTER_SLEEP_0>;
 			next-level-cache = <&L2_0>;
 			qcom,freq-domain = <&cpufreq_hw 0>;
+			power-domains = <&CPU_PD0>;
+			power-domain-names = "psci";
 			#cooling-cells = <2>;
 			L2_0: l2-cache {
 				compatible = "cache";
@@ -73,10 +73,10 @@ CPU1: cpu@100 {
 			enable-method = "psci";
 			capacity-dmips-mhz = <488>;
 			dynamic-power-coefficient = <232>;
-			cpu-idle-states = <&LITTLE_CPU_SLEEP_0
-					   &CLUSTER_SLEEP_0>;
 			next-level-cache = <&L2_100>;
 			qcom,freq-domain = <&cpufreq_hw 0>;
+			power-domains = <&CPU_PD1>;
+			power-domain-names = "psci";
 			#cooling-cells = <2>;
 			L2_100: l2-cache {
 				compatible = "cache";
@@ -92,10 +92,10 @@ CPU2: cpu@200 {
 			enable-method = "psci";
 			capacity-dmips-mhz = <488>;
 			dynamic-power-coefficient = <232>;
-			cpu-idle-states = <&LITTLE_CPU_SLEEP_0
-					   &CLUSTER_SLEEP_0>;
 			next-level-cache = <&L2_200>;
 			qcom,freq-domain = <&cpufreq_hw 0>;
+			power-domains = <&CPU_PD2>;
+			power-domain-names = "psci";
 			#cooling-cells = <2>;
 			L2_200: l2-cache {
 				compatible = "cache";
@@ -110,10 +110,10 @@ CPU3: cpu@300 {
 			enable-method = "psci";
 			capacity-dmips-mhz = <488>;
 			dynamic-power-coefficient = <232>;
-			cpu-idle-states = <&LITTLE_CPU_SLEEP_0
-					   &CLUSTER_SLEEP_0>;
 			next-level-cache = <&L2_300>;
 			qcom,freq-domain = <&cpufreq_hw 0>;
+			power-domains = <&CPU_PD3>;
+			power-domain-names = "psci";
 			#cooling-cells = <2>;
 			L2_300: l2-cache {
 				compatible = "cache";
@@ -128,10 +128,10 @@ CPU4: cpu@400 {
 			enable-method = "psci";
 			capacity-dmips-mhz = <1024>;
 			dynamic-power-coefficient = <369>;
-			cpu-idle-states = <&BIG_CPU_SLEEP_0
-					   &CLUSTER_SLEEP_0>;
 			next-level-cache = <&L2_400>;
 			qcom,freq-domain = <&cpufreq_hw 1>;
+			power-domains = <&CPU_PD4>;
+			power-domain-names = "psci";
 			#cooling-cells = <2>;
 			L2_400: l2-cache {
 				compatible = "cache";
@@ -146,10 +146,10 @@ CPU5: cpu@500 {
 			enable-method = "psci";
 			capacity-dmips-mhz = <1024>;
 			dynamic-power-coefficient = <369>;
-			cpu-idle-states = <&BIG_CPU_SLEEP_0
-					   &CLUSTER_SLEEP_0>;
 			next-level-cache = <&L2_500>;
 			qcom,freq-domain = <&cpufreq_hw 1>;
+			power-domains = <&CPU_PD5>;
+			power-domain-names = "psci";
 			#cooling-cells = <2>;
 			L2_500: l2-cache {
 				compatible = "cache";
@@ -164,10 +164,10 @@ CPU6: cpu@600 {
 			enable-method = "psci";
 			capacity-dmips-mhz = <1024>;
 			dynamic-power-coefficient = <369>;
-			cpu-idle-states = <&BIG_CPU_SLEEP_0
-					   &CLUSTER_SLEEP_0>;
 			next-level-cache = <&L2_600>;
 			qcom,freq-domain = <&cpufreq_hw 1>;
+			power-domains = <&CPU_PD6>;
+			power-domain-names = "psci";
 			#cooling-cells = <2>;
 			L2_600: l2-cache {
 				compatible = "cache";
@@ -182,10 +182,10 @@ CPU7: cpu@700 {
 			enable-method = "psci";
 			capacity-dmips-mhz = <1024>;
 			dynamic-power-coefficient = <421>;
-			cpu-idle-states = <&BIG_CPU_SLEEP_0
-					   &CLUSTER_SLEEP_0>;
 			next-level-cache = <&L2_700>;
 			qcom,freq-domain = <&cpufreq_hw 2>;
+			power-domains = <&CPU_PD7>;
+			power-domain-names = "psci";
 			#cooling-cells = <2>;
 			L2_700: l2-cache {
 				compatible = "cache";
@@ -251,11 +251,13 @@ BIG_CPU_SLEEP_0: cpu-sleep-1-0 {
 				min-residency-us = <4488>;
 				local-timer-stop;
 			};
+		};
 
+		domain-idle-states {
 			CLUSTER_SLEEP_0: cluster-sleep-0 {
-				compatible = "arm,idle-state";
+				compatible = "domain-idle-state";
 				idle-state-name = "cluster-power-collapse";
-				arm,psci-suspend-param = <0x400000F4>;
+				arm,psci-suspend-param = <0x4100c244>;
 				entry-latency-us = <3263>;
 				exit-latency-us = <6562>;
 				min-residency-us = <9987>;
@@ -291,6 +293,59 @@ pmu {
 	psci {
 		compatible = "arm,psci-1.0";
 		method = "smc";
+
+		CPU_PD0: cpu0 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_PD>;
+			domain-idle-states = <&LITTLE_CPU_SLEEP_0>;
+		};
+
+		CPU_PD1: cpu1 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_PD>;
+			domain-idle-states = <&LITTLE_CPU_SLEEP_0>;
+		};
+
+		CPU_PD2: cpu2 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_PD>;
+			domain-idle-states = <&LITTLE_CPU_SLEEP_0>;
+		};
+
+		CPU_PD3: cpu3 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_PD>;
+			domain-idle-states = <&LITTLE_CPU_SLEEP_0>;
+		};
+
+		CPU_PD4: cpu4 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_PD>;
+			domain-idle-states = <&BIG_CPU_SLEEP_0>;
+		};
+
+		CPU_PD5: cpu5 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_PD>;
+			domain-idle-states = <&BIG_CPU_SLEEP_0>;
+		};
+
+		CPU_PD6: cpu6 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_PD>;
+			domain-idle-states = <&BIG_CPU_SLEEP_0>;
+		};
+
+		CPU_PD7: cpu7 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_PD>;
+			domain-idle-states = <&BIG_CPU_SLEEP_0>;
+		};
+
+		CLUSTER_PD: cpu-cluster0 {
+			#power-domain-cells = <0>;
+			domain-idle-states = <&CLUSTER_SLEEP_0>;
+		};
 	};
 
 	reserved-memory {
-- 
2.29.2

Re: [PATCH] arm64: dts: qcom: sm8150: Add support for deep CPU cluster idle

From: Bjorn Andersson <hidden>
Date: 2021-01-05 23:06:16

On Tue 05 Jan 12:10 PST 2021, Danny Lin wrote:
This commit adds support for deep idling of the entire unified DynamIQ
CPU cluster on sm8150. In this idle state, the LLCC (Last-Level Cache
Controller) is powered off and the AOP (Always-On Processor) enters a
low-power sleep state.

I'm not sure what the per-CPU 0x400000f4 idle state previously
contributed by Qualcomm as the "cluster sleep" state is, but the
downstream kernel has no such state. The real deep cluster idle state
is 0x41000c244, composed of:

    Cluster idle state: (0xc24) << 4 = 0xc240
    Is reset state: 1 << 30 = 0x40000000
    Affinity level: 1 << 24 = 0x1000000
    CPU idle state: 0x4 (power collapse)

This setup can be replicated with the PSCI power domain cpuidle driver,
which utilizes OSI to enter cluster idle when the last active CPU
enters idle.

The cluster idle state cannot be used as a plain cpuidle state because
it requires that all CPUs in the cluster are idling.
This looks quite reasonable to me.

@Ulf, this seems to be the first attempt at wiring up the domain idle
pieces upstream, would you mind having a look?

The SM8150 pretty much identical to RB3 in this regard.

Regards,
Bjorn
quoted hunk
Signed-off-by: Danny Lin <redacted>
---
 arch/arm64/boot/dts/qcom/sm8150.dtsi | 91 ++++++++++++++++++++++------
 1 file changed, 73 insertions(+), 18 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi
index 309e00b6fa44..8956c6986744 100644
--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
@@ -52,10 +52,10 @@ CPU0: cpu@0 {
 			enable-method = "psci";
 			capacity-dmips-mhz = <488>;
 			dynamic-power-coefficient = <232>;
-			cpu-idle-states = <&LITTLE_CPU_SLEEP_0
-					   &CLUSTER_SLEEP_0>;
 			next-level-cache = <&L2_0>;
 			qcom,freq-domain = <&cpufreq_hw 0>;
+			power-domains = <&CPU_PD0>;
+			power-domain-names = "psci";
 			#cooling-cells = <2>;
 			L2_0: l2-cache {
 				compatible = "cache";
@@ -73,10 +73,10 @@ CPU1: cpu@100 {
 			enable-method = "psci";
 			capacity-dmips-mhz = <488>;
 			dynamic-power-coefficient = <232>;
-			cpu-idle-states = <&LITTLE_CPU_SLEEP_0
-					   &CLUSTER_SLEEP_0>;
 			next-level-cache = <&L2_100>;
 			qcom,freq-domain = <&cpufreq_hw 0>;
+			power-domains = <&CPU_PD1>;
+			power-domain-names = "psci";
 			#cooling-cells = <2>;
 			L2_100: l2-cache {
 				compatible = "cache";
@@ -92,10 +92,10 @@ CPU2: cpu@200 {
 			enable-method = "psci";
 			capacity-dmips-mhz = <488>;
 			dynamic-power-coefficient = <232>;
-			cpu-idle-states = <&LITTLE_CPU_SLEEP_0
-					   &CLUSTER_SLEEP_0>;
 			next-level-cache = <&L2_200>;
 			qcom,freq-domain = <&cpufreq_hw 0>;
+			power-domains = <&CPU_PD2>;
+			power-domain-names = "psci";
 			#cooling-cells = <2>;
 			L2_200: l2-cache {
 				compatible = "cache";
@@ -110,10 +110,10 @@ CPU3: cpu@300 {
 			enable-method = "psci";
 			capacity-dmips-mhz = <488>;
 			dynamic-power-coefficient = <232>;
-			cpu-idle-states = <&LITTLE_CPU_SLEEP_0
-					   &CLUSTER_SLEEP_0>;
 			next-level-cache = <&L2_300>;
 			qcom,freq-domain = <&cpufreq_hw 0>;
+			power-domains = <&CPU_PD3>;
+			power-domain-names = "psci";
 			#cooling-cells = <2>;
 			L2_300: l2-cache {
 				compatible = "cache";
@@ -128,10 +128,10 @@ CPU4: cpu@400 {
 			enable-method = "psci";
 			capacity-dmips-mhz = <1024>;
 			dynamic-power-coefficient = <369>;
-			cpu-idle-states = <&BIG_CPU_SLEEP_0
-					   &CLUSTER_SLEEP_0>;
 			next-level-cache = <&L2_400>;
 			qcom,freq-domain = <&cpufreq_hw 1>;
+			power-domains = <&CPU_PD4>;
+			power-domain-names = "psci";
 			#cooling-cells = <2>;
 			L2_400: l2-cache {
 				compatible = "cache";
@@ -146,10 +146,10 @@ CPU5: cpu@500 {
 			enable-method = "psci";
 			capacity-dmips-mhz = <1024>;
 			dynamic-power-coefficient = <369>;
-			cpu-idle-states = <&BIG_CPU_SLEEP_0
-					   &CLUSTER_SLEEP_0>;
 			next-level-cache = <&L2_500>;
 			qcom,freq-domain = <&cpufreq_hw 1>;
+			power-domains = <&CPU_PD5>;
+			power-domain-names = "psci";
 			#cooling-cells = <2>;
 			L2_500: l2-cache {
 				compatible = "cache";
@@ -164,10 +164,10 @@ CPU6: cpu@600 {
 			enable-method = "psci";
 			capacity-dmips-mhz = <1024>;
 			dynamic-power-coefficient = <369>;
-			cpu-idle-states = <&BIG_CPU_SLEEP_0
-					   &CLUSTER_SLEEP_0>;
 			next-level-cache = <&L2_600>;
 			qcom,freq-domain = <&cpufreq_hw 1>;
+			power-domains = <&CPU_PD6>;
+			power-domain-names = "psci";
 			#cooling-cells = <2>;
 			L2_600: l2-cache {
 				compatible = "cache";
@@ -182,10 +182,10 @@ CPU7: cpu@700 {
 			enable-method = "psci";
 			capacity-dmips-mhz = <1024>;
 			dynamic-power-coefficient = <421>;
-			cpu-idle-states = <&BIG_CPU_SLEEP_0
-					   &CLUSTER_SLEEP_0>;
 			next-level-cache = <&L2_700>;
 			qcom,freq-domain = <&cpufreq_hw 2>;
+			power-domains = <&CPU_PD7>;
+			power-domain-names = "psci";
 			#cooling-cells = <2>;
 			L2_700: l2-cache {
 				compatible = "cache";
@@ -251,11 +251,13 @@ BIG_CPU_SLEEP_0: cpu-sleep-1-0 {
 				min-residency-us = <4488>;
 				local-timer-stop;
 			};
+		};
 
+		domain-idle-states {
 			CLUSTER_SLEEP_0: cluster-sleep-0 {
-				compatible = "arm,idle-state";
+				compatible = "domain-idle-state";
 				idle-state-name = "cluster-power-collapse";
-				arm,psci-suspend-param = <0x400000F4>;
+				arm,psci-suspend-param = <0x4100c244>;
 				entry-latency-us = <3263>;
 				exit-latency-us = <6562>;
 				min-residency-us = <9987>;
@@ -291,6 +293,59 @@ pmu {
 	psci {
 		compatible = "arm,psci-1.0";
 		method = "smc";
+
+		CPU_PD0: cpu0 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_PD>;
+			domain-idle-states = <&LITTLE_CPU_SLEEP_0>;
+		};
+
+		CPU_PD1: cpu1 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_PD>;
+			domain-idle-states = <&LITTLE_CPU_SLEEP_0>;
+		};
+
+		CPU_PD2: cpu2 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_PD>;
+			domain-idle-states = <&LITTLE_CPU_SLEEP_0>;
+		};
+
+		CPU_PD3: cpu3 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_PD>;
+			domain-idle-states = <&LITTLE_CPU_SLEEP_0>;
+		};
+
+		CPU_PD4: cpu4 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_PD>;
+			domain-idle-states = <&BIG_CPU_SLEEP_0>;
+		};
+
+		CPU_PD5: cpu5 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_PD>;
+			domain-idle-states = <&BIG_CPU_SLEEP_0>;
+		};
+
+		CPU_PD6: cpu6 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_PD>;
+			domain-idle-states = <&BIG_CPU_SLEEP_0>;
+		};
+
+		CPU_PD7: cpu7 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_PD>;
+			domain-idle-states = <&BIG_CPU_SLEEP_0>;
+		};
+
+		CLUSTER_PD: cpu-cluster0 {
+			#power-domain-cells = <0>;
+			domain-idle-states = <&CLUSTER_SLEEP_0>;
+		};
 	};
 
 	reserved-memory {
-- 
2.29.2

Re: [PATCH] arm64: dts: qcom: sm8150: Add support for deep CPU cluster idle

From: Ulf Hansson <hidden>
Date: 2021-01-12 10:10:55

+ Lina

On Wed, 6 Jan 2021 at 00:05, Bjorn Andersson [off-list ref] wrote:
On Tue 05 Jan 12:10 PST 2021, Danny Lin wrote:
quoted
This commit adds support for deep idling of the entire unified DynamIQ
CPU cluster on sm8150. In this idle state, the LLCC (Last-Level Cache
Controller) is powered off and the AOP (Always-On Processor) enters a
low-power sleep state.

I'm not sure what the per-CPU 0x400000f4 idle state previously
contributed by Qualcomm as the "cluster sleep" state is, but the
downstream kernel has no such state. The real deep cluster idle state
is 0x41000c244, composed of:

    Cluster idle state: (0xc24) << 4 = 0xc240
    Is reset state: 1 << 30 = 0x40000000
    Affinity level: 1 << 24 = 0x1000000
    CPU idle state: 0x4 (power collapse)

This setup can be replicated with the PSCI power domain cpuidle driver,
which utilizes OSI to enter cluster idle when the last active CPU
enters idle.

The cluster idle state cannot be used as a plain cpuidle state because
it requires that all CPUs in the cluster are idling.
This looks quite reasonable to me.

@Ulf, this seems to be the first attempt at wiring up the domain idle
pieces upstream, would you mind having a look?
Certainly I can have a look, but I could find the original posted
patch. I had a look at the below changes and it looks good to me. Feel
free to add my reviewed-by tag for it.

Also note, the db410c was the first one to support this as introduced
in commit e37131556801 for v5.6. You may have a look at
arch/arm64/boot/dts/qcom/msm8916.dtsi.

Kind regards
Uffe
The SM8150 pretty much identical to RB3 in this regard.

Regards,
Bjorn
quoted
Signed-off-by: Danny Lin <redacted>
---
 arch/arm64/boot/dts/qcom/sm8150.dtsi | 91 ++++++++++++++++++++++------
 1 file changed, 73 insertions(+), 18 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi
index 309e00b6fa44..8956c6986744 100644
--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
@@ -52,10 +52,10 @@ CPU0: cpu@0 {
                      enable-method = "psci";
                      capacity-dmips-mhz = <488>;
                      dynamic-power-coefficient = <232>;
-                     cpu-idle-states = <&LITTLE_CPU_SLEEP_0
-                                        &CLUSTER_SLEEP_0>;
                      next-level-cache = <&L2_0>;
                      qcom,freq-domain = <&cpufreq_hw 0>;
+                     power-domains = <&CPU_PD0>;
+                     power-domain-names = "psci";
                      #cooling-cells = <2>;
                      L2_0: l2-cache {
                              compatible = "cache";
@@ -73,10 +73,10 @@ CPU1: cpu@100 {
                      enable-method = "psci";
                      capacity-dmips-mhz = <488>;
                      dynamic-power-coefficient = <232>;
-                     cpu-idle-states = <&LITTLE_CPU_SLEEP_0
-                                        &CLUSTER_SLEEP_0>;
                      next-level-cache = <&L2_100>;
                      qcom,freq-domain = <&cpufreq_hw 0>;
+                     power-domains = <&CPU_PD1>;
+                     power-domain-names = "psci";
                      #cooling-cells = <2>;
                      L2_100: l2-cache {
                              compatible = "cache";
@@ -92,10 +92,10 @@ CPU2: cpu@200 {
                      enable-method = "psci";
                      capacity-dmips-mhz = <488>;
                      dynamic-power-coefficient = <232>;
-                     cpu-idle-states = <&LITTLE_CPU_SLEEP_0
-                                        &CLUSTER_SLEEP_0>;
                      next-level-cache = <&L2_200>;
                      qcom,freq-domain = <&cpufreq_hw 0>;
+                     power-domains = <&CPU_PD2>;
+                     power-domain-names = "psci";
                      #cooling-cells = <2>;
                      L2_200: l2-cache {
                              compatible = "cache";
@@ -110,10 +110,10 @@ CPU3: cpu@300 {
                      enable-method = "psci";
                      capacity-dmips-mhz = <488>;
                      dynamic-power-coefficient = <232>;
-                     cpu-idle-states = <&LITTLE_CPU_SLEEP_0
-                                        &CLUSTER_SLEEP_0>;
                      next-level-cache = <&L2_300>;
                      qcom,freq-domain = <&cpufreq_hw 0>;
+                     power-domains = <&CPU_PD3>;
+                     power-domain-names = "psci";
                      #cooling-cells = <2>;
                      L2_300: l2-cache {
                              compatible = "cache";
@@ -128,10 +128,10 @@ CPU4: cpu@400 {
                      enable-method = "psci";
                      capacity-dmips-mhz = <1024>;
                      dynamic-power-coefficient = <369>;
-                     cpu-idle-states = <&BIG_CPU_SLEEP_0
-                                        &CLUSTER_SLEEP_0>;
                      next-level-cache = <&L2_400>;
                      qcom,freq-domain = <&cpufreq_hw 1>;
+                     power-domains = <&CPU_PD4>;
+                     power-domain-names = "psci";
                      #cooling-cells = <2>;
                      L2_400: l2-cache {
                              compatible = "cache";
@@ -146,10 +146,10 @@ CPU5: cpu@500 {
                      enable-method = "psci";
                      capacity-dmips-mhz = <1024>;
                      dynamic-power-coefficient = <369>;
-                     cpu-idle-states = <&BIG_CPU_SLEEP_0
-                                        &CLUSTER_SLEEP_0>;
                      next-level-cache = <&L2_500>;
                      qcom,freq-domain = <&cpufreq_hw 1>;
+                     power-domains = <&CPU_PD5>;
+                     power-domain-names = "psci";
                      #cooling-cells = <2>;
                      L2_500: l2-cache {
                              compatible = "cache";
@@ -164,10 +164,10 @@ CPU6: cpu@600 {
                      enable-method = "psci";
                      capacity-dmips-mhz = <1024>;
                      dynamic-power-coefficient = <369>;
-                     cpu-idle-states = <&BIG_CPU_SLEEP_0
-                                        &CLUSTER_SLEEP_0>;
                      next-level-cache = <&L2_600>;
                      qcom,freq-domain = <&cpufreq_hw 1>;
+                     power-domains = <&CPU_PD6>;
+                     power-domain-names = "psci";
                      #cooling-cells = <2>;
                      L2_600: l2-cache {
                              compatible = "cache";
@@ -182,10 +182,10 @@ CPU7: cpu@700 {
                      enable-method = "psci";
                      capacity-dmips-mhz = <1024>;
                      dynamic-power-coefficient = <421>;
-                     cpu-idle-states = <&BIG_CPU_SLEEP_0
-                                        &CLUSTER_SLEEP_0>;
                      next-level-cache = <&L2_700>;
                      qcom,freq-domain = <&cpufreq_hw 2>;
+                     power-domains = <&CPU_PD7>;
+                     power-domain-names = "psci";
                      #cooling-cells = <2>;
                      L2_700: l2-cache {
                              compatible = "cache";
@@ -251,11 +251,13 @@ BIG_CPU_SLEEP_0: cpu-sleep-1-0 {
                              min-residency-us = <4488>;
                              local-timer-stop;
                      };
+             };

+             domain-idle-states {
                      CLUSTER_SLEEP_0: cluster-sleep-0 {
-                             compatible = "arm,idle-state";
+                             compatible = "domain-idle-state";
                              idle-state-name = "cluster-power-collapse";
-                             arm,psci-suspend-param = <0x400000F4>;
+                             arm,psci-suspend-param = <0x4100c244>;
                              entry-latency-us = <3263>;
                              exit-latency-us = <6562>;
                              min-residency-us = <9987>;
@@ -291,6 +293,59 @@ pmu {
      psci {
              compatible = "arm,psci-1.0";
              method = "smc";
+
+             CPU_PD0: cpu0 {
+                     #power-domain-cells = <0>;
+                     power-domains = <&CLUSTER_PD>;
+                     domain-idle-states = <&LITTLE_CPU_SLEEP_0>;
+             };
+
+             CPU_PD1: cpu1 {
+                     #power-domain-cells = <0>;
+                     power-domains = <&CLUSTER_PD>;
+                     domain-idle-states = <&LITTLE_CPU_SLEEP_0>;
+             };
+
+             CPU_PD2: cpu2 {
+                     #power-domain-cells = <0>;
+                     power-domains = <&CLUSTER_PD>;
+                     domain-idle-states = <&LITTLE_CPU_SLEEP_0>;
+             };
+
+             CPU_PD3: cpu3 {
+                     #power-domain-cells = <0>;
+                     power-domains = <&CLUSTER_PD>;
+                     domain-idle-states = <&LITTLE_CPU_SLEEP_0>;
+             };
+
+             CPU_PD4: cpu4 {
+                     #power-domain-cells = <0>;
+                     power-domains = <&CLUSTER_PD>;
+                     domain-idle-states = <&BIG_CPU_SLEEP_0>;
+             };
+
+             CPU_PD5: cpu5 {
+                     #power-domain-cells = <0>;
+                     power-domains = <&CLUSTER_PD>;
+                     domain-idle-states = <&BIG_CPU_SLEEP_0>;
+             };
+
+             CPU_PD6: cpu6 {
+                     #power-domain-cells = <0>;
+                     power-domains = <&CLUSTER_PD>;
+                     domain-idle-states = <&BIG_CPU_SLEEP_0>;
+             };
+
+             CPU_PD7: cpu7 {
+                     #power-domain-cells = <0>;
+                     power-domains = <&CLUSTER_PD>;
+                     domain-idle-states = <&BIG_CPU_SLEEP_0>;
+             };
+
+             CLUSTER_PD: cpu-cluster0 {
+                     #power-domain-cells = <0>;
+                     domain-idle-states = <&CLUSTER_SLEEP_0>;
+             };
      };

      reserved-memory {
--
2.29.2

Re: [PATCH] arm64: dts: qcom: sm8150: Add support for deep CPU cluster idle

From: Bjorn Andersson <hidden>
Date: 2021-01-12 14:23:45

On Tue 12 Jan 04:09 CST 2021, Ulf Hansson wrote:
+ Lina

On Wed, 6 Jan 2021 at 00:05, Bjorn Andersson [off-list ref] wrote:
quoted
On Tue 05 Jan 12:10 PST 2021, Danny Lin wrote:
quoted
This commit adds support for deep idling of the entire unified DynamIQ
CPU cluster on sm8150. In this idle state, the LLCC (Last-Level Cache
Controller) is powered off and the AOP (Always-On Processor) enters a
low-power sleep state.

I'm not sure what the per-CPU 0x400000f4 idle state previously
contributed by Qualcomm as the "cluster sleep" state is, but the
downstream kernel has no such state. The real deep cluster idle state
is 0x41000c244, composed of:

    Cluster idle state: (0xc24) << 4 = 0xc240
    Is reset state: 1 << 30 = 0x40000000
    Affinity level: 1 << 24 = 0x1000000
    CPU idle state: 0x4 (power collapse)

This setup can be replicated with the PSCI power domain cpuidle driver,
which utilizes OSI to enter cluster idle when the last active CPU
enters idle.

The cluster idle state cannot be used as a plain cpuidle state because
it requires that all CPUs in the cluster are idling.
This looks quite reasonable to me.

@Ulf, this seems to be the first attempt at wiring up the domain idle
pieces upstream, would you mind having a look?
Certainly I can have a look, but I could find the original posted
patch. I had a look at the below changes and it looks good to me. Feel
free to add my reviewed-by tag for it.
Thank you.
Also note, the db410c was the first one to support this as introduced
in commit e37131556801 for v5.6. You may have a look at
arch/arm64/boot/dts/qcom/msm8916.dtsi.
For some reason I failed to find that commit while looking for your work
on the subject, thanks for pointing it out!

Regards,
Bjorn
Kind regards
Uffe
quoted
The SM8150 pretty much identical to RB3 in this regard.

Regards,
Bjorn
quoted
Signed-off-by: Danny Lin <redacted>
---
 arch/arm64/boot/dts/qcom/sm8150.dtsi | 91 ++++++++++++++++++++++------
 1 file changed, 73 insertions(+), 18 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi
index 309e00b6fa44..8956c6986744 100644
--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
@@ -52,10 +52,10 @@ CPU0: cpu@0 {
                      enable-method = "psci";
                      capacity-dmips-mhz = <488>;
                      dynamic-power-coefficient = <232>;
-                     cpu-idle-states = <&LITTLE_CPU_SLEEP_0
-                                        &CLUSTER_SLEEP_0>;
                      next-level-cache = <&L2_0>;
                      qcom,freq-domain = <&cpufreq_hw 0>;
+                     power-domains = <&CPU_PD0>;
+                     power-domain-names = "psci";
                      #cooling-cells = <2>;
                      L2_0: l2-cache {
                              compatible = "cache";
@@ -73,10 +73,10 @@ CPU1: cpu@100 {
                      enable-method = "psci";
                      capacity-dmips-mhz = <488>;
                      dynamic-power-coefficient = <232>;
-                     cpu-idle-states = <&LITTLE_CPU_SLEEP_0
-                                        &CLUSTER_SLEEP_0>;
                      next-level-cache = <&L2_100>;
                      qcom,freq-domain = <&cpufreq_hw 0>;
+                     power-domains = <&CPU_PD1>;
+                     power-domain-names = "psci";
                      #cooling-cells = <2>;
                      L2_100: l2-cache {
                              compatible = "cache";
@@ -92,10 +92,10 @@ CPU2: cpu@200 {
                      enable-method = "psci";
                      capacity-dmips-mhz = <488>;
                      dynamic-power-coefficient = <232>;
-                     cpu-idle-states = <&LITTLE_CPU_SLEEP_0
-                                        &CLUSTER_SLEEP_0>;
                      next-level-cache = <&L2_200>;
                      qcom,freq-domain = <&cpufreq_hw 0>;
+                     power-domains = <&CPU_PD2>;
+                     power-domain-names = "psci";
                      #cooling-cells = <2>;
                      L2_200: l2-cache {
                              compatible = "cache";
@@ -110,10 +110,10 @@ CPU3: cpu@300 {
                      enable-method = "psci";
                      capacity-dmips-mhz = <488>;
                      dynamic-power-coefficient = <232>;
-                     cpu-idle-states = <&LITTLE_CPU_SLEEP_0
-                                        &CLUSTER_SLEEP_0>;
                      next-level-cache = <&L2_300>;
                      qcom,freq-domain = <&cpufreq_hw 0>;
+                     power-domains = <&CPU_PD3>;
+                     power-domain-names = "psci";
                      #cooling-cells = <2>;
                      L2_300: l2-cache {
                              compatible = "cache";
@@ -128,10 +128,10 @@ CPU4: cpu@400 {
                      enable-method = "psci";
                      capacity-dmips-mhz = <1024>;
                      dynamic-power-coefficient = <369>;
-                     cpu-idle-states = <&BIG_CPU_SLEEP_0
-                                        &CLUSTER_SLEEP_0>;
                      next-level-cache = <&L2_400>;
                      qcom,freq-domain = <&cpufreq_hw 1>;
+                     power-domains = <&CPU_PD4>;
+                     power-domain-names = "psci";
                      #cooling-cells = <2>;
                      L2_400: l2-cache {
                              compatible = "cache";
@@ -146,10 +146,10 @@ CPU5: cpu@500 {
                      enable-method = "psci";
                      capacity-dmips-mhz = <1024>;
                      dynamic-power-coefficient = <369>;
-                     cpu-idle-states = <&BIG_CPU_SLEEP_0
-                                        &CLUSTER_SLEEP_0>;
                      next-level-cache = <&L2_500>;
                      qcom,freq-domain = <&cpufreq_hw 1>;
+                     power-domains = <&CPU_PD5>;
+                     power-domain-names = "psci";
                      #cooling-cells = <2>;
                      L2_500: l2-cache {
                              compatible = "cache";
@@ -164,10 +164,10 @@ CPU6: cpu@600 {
                      enable-method = "psci";
                      capacity-dmips-mhz = <1024>;
                      dynamic-power-coefficient = <369>;
-                     cpu-idle-states = <&BIG_CPU_SLEEP_0
-                                        &CLUSTER_SLEEP_0>;
                      next-level-cache = <&L2_600>;
                      qcom,freq-domain = <&cpufreq_hw 1>;
+                     power-domains = <&CPU_PD6>;
+                     power-domain-names = "psci";
                      #cooling-cells = <2>;
                      L2_600: l2-cache {
                              compatible = "cache";
@@ -182,10 +182,10 @@ CPU7: cpu@700 {
                      enable-method = "psci";
                      capacity-dmips-mhz = <1024>;
                      dynamic-power-coefficient = <421>;
-                     cpu-idle-states = <&BIG_CPU_SLEEP_0
-                                        &CLUSTER_SLEEP_0>;
                      next-level-cache = <&L2_700>;
                      qcom,freq-domain = <&cpufreq_hw 2>;
+                     power-domains = <&CPU_PD7>;
+                     power-domain-names = "psci";
                      #cooling-cells = <2>;
                      L2_700: l2-cache {
                              compatible = "cache";
@@ -251,11 +251,13 @@ BIG_CPU_SLEEP_0: cpu-sleep-1-0 {
                              min-residency-us = <4488>;
                              local-timer-stop;
                      };
+             };

+             domain-idle-states {
                      CLUSTER_SLEEP_0: cluster-sleep-0 {
-                             compatible = "arm,idle-state";
+                             compatible = "domain-idle-state";
                              idle-state-name = "cluster-power-collapse";
-                             arm,psci-suspend-param = <0x400000F4>;
+                             arm,psci-suspend-param = <0x4100c244>;
                              entry-latency-us = <3263>;
                              exit-latency-us = <6562>;
                              min-residency-us = <9987>;
@@ -291,6 +293,59 @@ pmu {
      psci {
              compatible = "arm,psci-1.0";
              method = "smc";
+
+             CPU_PD0: cpu0 {
+                     #power-domain-cells = <0>;
+                     power-domains = <&CLUSTER_PD>;
+                     domain-idle-states = <&LITTLE_CPU_SLEEP_0>;
+             };
+
+             CPU_PD1: cpu1 {
+                     #power-domain-cells = <0>;
+                     power-domains = <&CLUSTER_PD>;
+                     domain-idle-states = <&LITTLE_CPU_SLEEP_0>;
+             };
+
+             CPU_PD2: cpu2 {
+                     #power-domain-cells = <0>;
+                     power-domains = <&CLUSTER_PD>;
+                     domain-idle-states = <&LITTLE_CPU_SLEEP_0>;
+             };
+
+             CPU_PD3: cpu3 {
+                     #power-domain-cells = <0>;
+                     power-domains = <&CLUSTER_PD>;
+                     domain-idle-states = <&LITTLE_CPU_SLEEP_0>;
+             };
+
+             CPU_PD4: cpu4 {
+                     #power-domain-cells = <0>;
+                     power-domains = <&CLUSTER_PD>;
+                     domain-idle-states = <&BIG_CPU_SLEEP_0>;
+             };
+
+             CPU_PD5: cpu5 {
+                     #power-domain-cells = <0>;
+                     power-domains = <&CLUSTER_PD>;
+                     domain-idle-states = <&BIG_CPU_SLEEP_0>;
+             };
+
+             CPU_PD6: cpu6 {
+                     #power-domain-cells = <0>;
+                     power-domains = <&CLUSTER_PD>;
+                     domain-idle-states = <&BIG_CPU_SLEEP_0>;
+             };
+
+             CPU_PD7: cpu7 {
+                     #power-domain-cells = <0>;
+                     power-domains = <&CLUSTER_PD>;
+                     domain-idle-states = <&BIG_CPU_SLEEP_0>;
+             };
+
+             CLUSTER_PD: cpu-cluster0 {
+                     #power-domain-cells = <0>;
+                     domain-idle-states = <&CLUSTER_SLEEP_0>;
+             };
      };

      reserved-memory {
--
2.29.2
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help