aboutsummaryrefslogtreecommitdiff
path: root/hw/slw.c
diff options
context:
space:
mode:
authorShreyas B. Prabhu <shreyas@linux.vnet.ibm.com>2014-07-29 11:19:21 +0530
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-07-30 10:56:17 +1000
commit792d0bd30859d6c3a9bd0f91bf5a78f6b9aa7058 (patch)
tree530d20353d112666891a3e25da1ebb6343b79fa7 /hw/slw.c
parentd5aed5be5a63f991b80458b3a8eedaa26e203639 (diff)
downloadskiboot-792d0bd30859d6c3a9bd0f91bf5a78f6b9aa7058.zip
skiboot-792d0bd30859d6c3a9bd0f91bf5a78f6b9aa7058.tar.gz
skiboot-792d0bd30859d6c3a9bd0f91bf5a78f6b9aa7058.tar.bz2
slw: Enable fast sleep and deep winkle while initializing core
Power8 hardware supports deep idle states like sleep and winkle. Both sleep and winkle have fast/deep modes. Behaviour of each mode - Fast sleep Stop clocks to Core and L2 cache. Drop Core & L2 voltage to retention. Leave shared L3 cache running Deep sleep Power OFF the core and private L2 cache. Leave shared L3 cache running. Fast winkle Stop clocks to entire chiplet. Drop chiplet voltage to retention. Deep winkle Power OFF the entire chiplet. Requires restore/re-init to wakeup. PM GP1 register allows us to select fast/deep modes for sleep and winkle. Currently we are setting PM GP1 register to use fast sleep and fast winkle. Change it such that, sleep will use fast mode and winkle will use deep mode. With deep winkle enabled, hotplug framework in kernel can send cores to winkle when cpus are offlined. Signed-off-by: Shreyas B. Prabhu <shreyas@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'hw/slw.c')
-rw-r--r--hw/slw.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/hw/slw.c b/hw/slw.c
index cecfbf7..e945cb1 100644
--- a/hw/slw.c
+++ b/hw/slw.c
@@ -317,15 +317,19 @@ static bool slw_set_deep_mode(struct proc_chip *chip, struct cpu_thread *c)
return true;
}
-static bool slw_set_fast_mode(struct proc_chip *chip, struct cpu_thread *c)
+static bool slw_set_idle_mode(struct proc_chip *chip, struct cpu_thread *c)
{
uint32_t core = pir_to_core_id(c->pir);
uint64_t tmp;
int rc;
- /* Init PM GP1 for fast mode or deep mode */
+ /*
+ * PM GP1 allows fast/deep mode to be selected independently for sleep
+ * and winkle. Init PM GP1 so that sleep happens in fast mode and
+ * winkle happens in deep mode.
+ */
rc = xscom_write(chip->id, XSCOM_ADDR_P8_EX_SLAVE(core, EX_PM_GP1),
- EX_PM_SETUP_GP1_FAST_SLEEP);
+ EX_PM_SETUP_GP1_FAST_SLEEP_DEEP_WINKLE);
if (rc) {
log_simple_error(&e_info(OPAL_RC_SLW_SET),
"SLW: Failed to write PM_GP1\n");
@@ -390,7 +394,7 @@ static bool slw_prepare_core(struct proc_chip *chip, struct cpu_thread *c)
return true;
}
-static bool fastsleep_prepare_core(struct proc_chip *chip, struct cpu_thread *c)
+static bool idle_prepare_core(struct proc_chip *chip, struct cpu_thread *c)
{
DBG("FASTSLEEP: Prepare core %x:%x\n",
chip->id, pir_to_core_id(c->pir));
@@ -399,7 +403,7 @@ static bool fastsleep_prepare_core(struct proc_chip *chip, struct cpu_thread *c)
return false;
if(!slw_set_overrides(chip, c))
return false;
- if(!slw_set_fast_mode(chip, c))
+ if(!slw_set_idle_mode(chip, c))
return false;
if(!slw_get_idle_state_history(chip, c))
return false;
@@ -859,7 +863,7 @@ static void slw_init_chip(struct proc_chip *chip)
/* At power ON setup inits for fast-sleep */
for_each_available_core_in_chip(c, chip->id) {
- fastsleep_prepare_core(chip, c);
+ idle_prepare_core(chip, c);
}
}