summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/powernv/smp.c
diff options
context:
space:
mode:
authorShreyas B. Prabhu <shreyas@linux.vnet.ibm.com>2014-12-09 19:56:53 +0100
committerMichael Ellerman <mpe@ellerman.id.au>2014-12-15 00:46:41 +0100
commit77b54e9f213f76a23736940cf94bcd765fc00f40 (patch)
treec07273530b9f15c65b48ed147e0b1aabecf55f96 /arch/powerpc/platforms/powernv/smp.c
parentpowernv/cpuidle: Redesign idle states management (diff)
downloadlinux-77b54e9f213f76a23736940cf94bcd765fc00f40.tar.xz
linux-77b54e9f213f76a23736940cf94bcd765fc00f40.zip
powernv/powerpc: Add winkle support for offline cpus
Winkle is a deep idle state supported in power8 chips. A core enters winkle when all the threads of the core enter winkle. In this state power supply to the entire chiplet i.e core, private L2 and private L3 is turned off. As a result it gives higher powersavings compared to sleep. But entering winkle results in a total hypervisor state loss. Hence the hypervisor context has to be preserved before entering winkle and restored upon wake up. Power-on Reset Engine (PORE) is a dedicated engine which is responsible for powering on the chiplet during wake up. It can be programmed to restore the register contests of a few specific registers. This patch uses PORE to restore register state wherever possible and uses stack to save and restore rest of the necessary registers. With hypervisor state restore things fall under three categories- per-core state, per-subcore state and per-thread state. To manage this, extend the infrastructure introduced for sleep. Mainly we add a paca variable subcore_sibling_mask. Using this and the core_idle_state we can distingush first thread in core and subcore. Signed-off-by: Shreyas B. Prabhu <shreyas@linux.vnet.ibm.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: linuxppc-dev@lists.ozlabs.org Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/platforms/powernv/smp.c')
-rw-r--r--arch/powerpc/platforms/powernv/smp.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c
index c0691d0fb385..6c551a28e899 100644
--- a/arch/powerpc/platforms/powernv/smp.c
+++ b/arch/powerpc/platforms/powernv/smp.c
@@ -167,12 +167,17 @@ static void pnv_smp_cpu_kill_self(void)
*/
mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1);
while (!generic_check_cpu_restart(cpu)) {
+
ppc64_runlatch_off();
- if ((idle_states & OPAL_PM_SLEEP_ENABLED) ||
+
+ if (idle_states & OPAL_PM_WINKLE_ENABLED)
+ srr1 = power7_winkle();
+ else if ((idle_states & OPAL_PM_SLEEP_ENABLED) ||
(idle_states & OPAL_PM_SLEEP_ENABLED_ER1))
srr1 = power7_sleep();
else
srr1 = power7_nap(1);
+
ppc64_runlatch_on();
/*