diff options
author | Shreyas B. Prabhu <shreyas@linux.vnet.ibm.com> | 2014-07-29 11:19:21 +0530 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2014-07-30 10:56:17 +1000 |
commit | 792d0bd30859d6c3a9bd0f91bf5a78f6b9aa7058 (patch) | |
tree | 530d20353d112666891a3e25da1ebb6343b79fa7 /hw/slw.c | |
parent | d5aed5be5a63f991b80458b3a8eedaa26e203639 (diff) | |
download | skiboot-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.c | 16 |
1 files changed, 10 insertions, 6 deletions
@@ -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); } } |