[Skiboot] [PATCH v2] slw: Set PSSCR value for idle states

Shilpasri G Bhat shilpa.bhat at linux.vnet.ibm.com
Wed Sep 28 04:05:35 AEST 2016


PSSCR(Processor Stop Status and Control Register) is an SPR whose
contents control the operation of stop instruction. Currently in DT,
the value of PSSCR only included RL(Requested Level) for each idle
state. This patch adds MTL(Maximum Transistion Level), TR(Transistion
Rate), ESL(Enable State Loss) and EC(Exit Criterion) bits for idle
state in the PSSCR configuration. It also adds new idle states
stop0_lite, stop1_lite and stop2_lite which are no state loss versions
of stop0, stop1 and stop2 respectively. The lite variant has EC and
ESL bits of PSSCR set to 0. The thread entering a lite variant of stop
state will not lose any state and will wakeup at next instruction
following stop if MSR.EE=0 or at the corresponding interrupt handler
if MSR.EE=1. This will reduce the exit latency of the idle state and
hardware will not allocate the thread resources to other threads while
in power saving mode.

Signed-off-by: Shilpasri G Bhat <shilpa.bhat at linux.vnet.ibm.com>
---
Changes from v1:
- Removed OPAL_PM_WAKEUP_AT_NEXT_INST flag
- Added PSSCR register value and mask for each idle state
- Modified commit message and log

 hw/slw.c           | 92 +++++++++++++++++++++++++++++++++++++++++++++---------
 include/opal-api.h | 15 +++++++++
 2 files changed, 93 insertions(+), 14 deletions(-)

diff --git a/hw/slw.c b/hw/slw.c
index b916069..7abae1c 100644
--- a/hw/slw.c
+++ b/hw/slw.c
@@ -480,6 +480,20 @@ static struct cpu_idle_states power8_cpu_idle_states[] = {
  */
 static struct cpu_idle_states power9_cpu_idle_states[] = {
 	{
+		.name = "stop0_lite", /* Enter stop0 with no state loss */
+		.latency_ns = 200,
+		.residency_ns = 2000,
+		.flags = 0*OPAL_PM_DEC_STOP \
+		       | 0*OPAL_PM_TIMEBASE_STOP  \
+		       | 0*OPAL_PM_LOSE_USER_CONTEXT \
+		       | 0*OPAL_PM_LOSE_HYP_CONTEXT \
+		       | 0*OPAL_PM_LOSE_FULL_CONTEXT \
+		       | 1*OPAL_PM_STOP_INST_FAST,
+		.pm_ctrl_reg_val = OPAL_PM_PSSCR_RL(0) \
+				 | OPAL_PM_PSSCR_MTL(3) \
+				 | OPAL_PM_PSSCR_TR(3),
+		.pm_ctrl_reg_mask = OPAL_PM_PSSCR_MASK },
+	{
 		.name = "stop0",
 		.latency_ns = 300,
 		.residency_ns = 3000,
@@ -489,8 +503,26 @@ static struct cpu_idle_states power9_cpu_idle_states[] = {
 		       | 0*OPAL_PM_LOSE_HYP_CONTEXT \
 		       | 0*OPAL_PM_LOSE_FULL_CONTEXT \
 		       | 1*OPAL_PM_STOP_INST_FAST,
-		.pm_ctrl_reg_val = 0,
-		.pm_ctrl_reg_mask = 0xF },
+		.pm_ctrl_reg_val = OPAL_PM_PSSCR_RL(0) \
+				 | OPAL_PM_PSSCR_MTL(3) \
+				 | OPAL_PM_PSSCR_TR(3) \
+				 | OPAL_PM_PSSCR_ESL \
+				 | OPAL_PM_PSSCR_EC,
+		.pm_ctrl_reg_mask = OPAL_PM_PSSCR_MASK },
+	{
+		.name = "stop1_lite", /* Enter stop1 with no state loss */
+		.latency_ns = 4900,
+		.residency_ns = 49000,
+		.flags = 0*OPAL_PM_DEC_STOP \
+		       | 0*OPAL_PM_TIMEBASE_STOP  \
+		       | 1*OPAL_PM_LOSE_USER_CONTEXT \
+		       | 0*OPAL_PM_LOSE_HYP_CONTEXT \
+		       | 0*OPAL_PM_LOSE_FULL_CONTEXT \
+		       | 1*OPAL_PM_STOP_INST_FAST,
+		.pm_ctrl_reg_val = OPAL_PM_PSSCR_RL(1) \
+				 | OPAL_PM_PSSCR_MTL(3) \
+				 | OPAL_PM_PSSCR_TR(3),
+		.pm_ctrl_reg_mask = OPAL_PM_PSSCR_MASK },
 	{
 		.name = "stop1",
 		.latency_ns = 5000,
@@ -501,8 +533,26 @@ static struct cpu_idle_states power9_cpu_idle_states[] = {
 		       | 0*OPAL_PM_LOSE_HYP_CONTEXT \
 		       | 0*OPAL_PM_LOSE_FULL_CONTEXT \
 		       | 1*OPAL_PM_STOP_INST_FAST,
-		.pm_ctrl_reg_val = 1,
-		.pm_ctrl_reg_mask = 0xF },
+		.pm_ctrl_reg_val = OPAL_PM_PSSCR_RL(1) \
+				 | OPAL_PM_PSSCR_MTL(3) \
+				 | OPAL_PM_PSSCR_TR(3) \
+				 | OPAL_PM_PSSCR_ESL \
+				 | OPAL_PM_PSSCR_EC,
+		.pm_ctrl_reg_mask = OPAL_PM_PSSCR_MASK },
+	{
+		.name = "stop2_lite", /* Enter stop2 with no state loss */
+		.latency_ns = 9900,
+		.residency_ns = 99000,
+		.flags = 0*OPAL_PM_DEC_STOP \
+		       | 0*OPAL_PM_TIMEBASE_STOP  \
+		       | 1*OPAL_PM_LOSE_USER_CONTEXT \
+		       | 0*OPAL_PM_LOSE_HYP_CONTEXT \
+		       | 0*OPAL_PM_LOSE_FULL_CONTEXT \
+		       | 1*OPAL_PM_STOP_INST_FAST,
+		.pm_ctrl_reg_val = OPAL_PM_PSSCR_RL(2) \
+				 | OPAL_PM_PSSCR_MTL(3) \
+				 | OPAL_PM_PSSCR_TR(3),
+		.pm_ctrl_reg_mask = OPAL_PM_PSSCR_MASK },
 	{
 		.name = "stop2",
 		.latency_ns = 10000,
@@ -513,9 +563,12 @@ static struct cpu_idle_states power9_cpu_idle_states[] = {
 		       | 0*OPAL_PM_LOSE_HYP_CONTEXT \
 		       | 0*OPAL_PM_LOSE_FULL_CONTEXT \
 		       | 1*OPAL_PM_STOP_INST_FAST,
-		.pm_ctrl_reg_val = 2,
-		.pm_ctrl_reg_mask = 0xF },
-
+		.pm_ctrl_reg_val = OPAL_PM_PSSCR_RL(2) \
+				 | OPAL_PM_PSSCR_MTL(3) \
+				 | OPAL_PM_PSSCR_TR(3) \
+				 | OPAL_PM_PSSCR_ESL \
+				 | OPAL_PM_PSSCR_EC,
+		.pm_ctrl_reg_mask = OPAL_PM_PSSCR_MASK },
 	{
 		.name = "stop4",
 		.latency_ns = 100000,
@@ -526,8 +579,12 @@ static struct cpu_idle_states power9_cpu_idle_states[] = {
 		       | 1*OPAL_PM_LOSE_HYP_CONTEXT \
 		       | 1*OPAL_PM_LOSE_FULL_CONTEXT \
 		       | 1*OPAL_PM_STOP_INST_DEEP,
-		.pm_ctrl_reg_val = 4,
-		.pm_ctrl_reg_mask = 0xF },
+		.pm_ctrl_reg_val = OPAL_PM_PSSCR_RL(4) \
+				 | OPAL_PM_PSSCR_MTL(7) \
+				 | OPAL_PM_PSSCR_TR(3) \
+				 | OPAL_PM_PSSCR_ESL \
+				 | OPAL_PM_PSSCR_EC,
+		.pm_ctrl_reg_mask = OPAL_PM_PSSCR_MASK },
 
 	{
 		.name = "stop8",
@@ -539,9 +596,12 @@ static struct cpu_idle_states power9_cpu_idle_states[] = {
 		       | 1*OPAL_PM_LOSE_HYP_CONTEXT \
 		       | 1*OPAL_PM_LOSE_FULL_CONTEXT \
 		       | 1*OPAL_PM_STOP_INST_DEEP,
-		.pm_ctrl_reg_val = 0x8,
-		.pm_ctrl_reg_mask = 0xF },
-
+		.pm_ctrl_reg_val = OPAL_PM_PSSCR_RL(8) \
+				 | OPAL_PM_PSSCR_MTL(11) \
+				 | OPAL_PM_PSSCR_TR(3) \
+				 | OPAL_PM_PSSCR_ESL \
+				 | OPAL_PM_PSSCR_EC,
+		.pm_ctrl_reg_mask = OPAL_PM_PSSCR_MASK },
 
 	{
 		.name = "stop11",
@@ -553,8 +613,12 @@ static struct cpu_idle_states power9_cpu_idle_states[] = {
 		       | 1*OPAL_PM_LOSE_HYP_CONTEXT \
 		       | 1*OPAL_PM_LOSE_FULL_CONTEXT \
 		       | 1*OPAL_PM_STOP_INST_DEEP,
-		.pm_ctrl_reg_val = 0xB,
-		.pm_ctrl_reg_mask = 0xF },
+		.pm_ctrl_reg_val = OPAL_PM_PSSCR_RL(11) \
+				 | OPAL_PM_PSSCR_MTL(11) \
+				 | OPAL_PM_PSSCR_TR(3) \
+				 | OPAL_PM_PSSCR_ESL \
+				 | OPAL_PM_PSSCR_EC,
+		.pm_ctrl_reg_mask = OPAL_PM_PSSCR_MASK },
 
 };
 /* Add device tree properties to describe idle states */
diff --git a/include/opal-api.h b/include/opal-api.h
index f607a41..239068f 100644
--- a/include/opal-api.h
+++ b/include/opal-api.h
@@ -209,6 +209,21 @@
 #define OPAL_PM_DEEPWINKLE_PMICR	0x0000000000300000UL
 #define OPAL_PM_WINKLE_PMICR_MASK	0x0000000000300000UL
 
+#define OPAL_PM_PSSCR_RL_MASK		0x000000000000000FUL
+#define OPAL_PM_PSSCR_MTL_MASK		0x00000000000000F0UL
+#define OPAL_PM_PSSCR_TR_MASK		0x0000000000000300UL
+#define OPAL_PM_PSSCR_ESL		PPC_BIT(42)
+#define OPAL_PM_PSSCR_EC		PPC_BIT(43)
+
+#define OPAL_PM_PSSCR_MASK		OPAL_PM_PSSCR_RL_MASK | \
+					OPAL_PM_PSSCR_MTL_MASK | \
+					OPAL_PM_PSSCR_TR_MASK | \
+					OPAL_PM_PSSCR_ESL | \
+					OPAL_PM_PSSCR_EC
+
+#define OPAL_PM_PSSCR_RL(l)		(l)
+#define OPAL_PM_PSSCR_MTL(l)		((l) << 4)
+#define OPAL_PM_PSSCR_TR(l)		((l) << 8)
 
 /*
  * Flags for stop states. Use 2 bits to distinguish between
-- 
1.8.3.1



More information about the Skiboot mailing list