aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>2016-09-27 23:35:35 +0530
committerStewart Smith <stewart@linux.vnet.ibm.com>2016-12-13 17:56:16 +1100
commit739063fb706f987df2a766a981abc75053244044 (patch)
tree4d117b8168ea8ceba424ad91ce4b45ef61002e53
parentb7b5302af73764c659346ba90f4933bf4502b64a (diff)
downloadskiboot-739063fb706f987df2a766a981abc75053244044.zip
skiboot-739063fb706f987df2a766a981abc75053244044.tar.gz
skiboot-739063fb706f987df2a766a981abc75053244044.tar.bz2
slw: Set PSSCR value for idle states
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@linux.vnet.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
-rw-r--r--hw/slw.c92
-rw-r--r--include/opal-api.h15
2 files changed, 93 insertions, 14 deletions
diff --git a/hw/slw.c b/hw/slw.c
index 32481fb..853ff6b 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 05ff51d..36471ae 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