]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
powerpc/powernv: Add context management for Fast Sleep
authorVaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
Wed, 26 Feb 2014 00:08:25 +0000 (05:38 +0530)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Wed, 5 Mar 2014 04:56:31 +0000 (15:56 +1100)
Before adding Fast-Sleep into the cpuidle framework, some low level
support needs to be added to enable it. This includes saving and
restoring of certain registers at entry and exit time of this state
respectively just like we do in the NAP idle state.

Signed-off-by: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
[Changelog modified by Preeti U. Murthy <preeti@linux.vnet.ibm.com>]
Signed-off-by: Preeti U. Murthy <preeti@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/include/asm/processor.h
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kernel/idle_power7.S

index b62de43ae5f344a02d6096af7842c3799c192b93..d660dc36831afd5420c6da1dc1a35e9ee9eb6234 100644 (file)
@@ -450,6 +450,7 @@ enum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_POWERSAVE_OFF};
 
 extern int powersave_nap;      /* set if nap mode can be used in idle loop */
 extern void power7_nap(void);
+extern void power7_sleep(void);
 extern void flush_instruction_cache(void);
 extern void hard_reset_now(void);
 extern void poweroff_now(void);
index 38d507306a111dc40f06028c90d5014e2fedd817..b01a9cb441e453ca72ef4fe856c954193521bdaa 100644 (file)
@@ -121,9 +121,10 @@ BEGIN_FTR_SECTION
        cmpwi   cr1,r13,2
        /* Total loss of HV state is fatal, we could try to use the
         * PIR to locate a PACA, then use an emergency stack etc...
-        * but for now, let's just stay stuck here
+        * OPAL v3 based powernv platforms have new idle states
+        * which fall in this catagory.
         */
-       bgt     cr1,.
+       bgt     cr1,8f
        GET_PACA(r13)
 
 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
@@ -141,6 +142,11 @@ BEGIN_FTR_SECTION
        beq     cr1,2f
        b       .power7_wakeup_noloss
 2:     b       .power7_wakeup_loss
+
+       /* Fast Sleep wakeup on PowerNV */
+8:     GET_PACA(r13)
+       b       .power7_wakeup_loss
+
 9:
 END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
 #endif /* CONFIG_PPC_P7_NAP */
index 3fdef0f0c67fa959e631a4ccee2d3a330001fa44..14f78bec62c49e712f02e0836a40fb30cfd41c26 100644 (file)
 
 #undef DEBUG
 
-       .text
+/* Idle state entry routines */
 
-_GLOBAL(power7_idle)
-       /* Now check if user or arch enabled NAP mode */
-       LOAD_REG_ADDRBASE(r3,powersave_nap)
-       lwz     r4,ADDROFF(powersave_nap)(r3)
-       cmpwi   0,r4,0
-       beqlr
-       /* fall through */
+#define        IDLE_STATE_ENTER_SEQ(IDLE_INST)                         \
+       /* Magic NAP/SLEEP/WINKLE mode enter sequence */        \
+       std     r0,0(r1);                                       \
+       ptesync;                                                \
+       ld      r0,0(r1);                                       \
+1:     cmp     cr0,r0,r0;                                      \
+       bne     1b;                                             \
+       IDLE_INST;                                              \
+       b       .
 
-_GLOBAL(power7_nap)
+       .text
+
+/*
+ * Pass requested state in r3:
+ *     0 - nap
+ *     1 - sleep
+ */
+_GLOBAL(power7_powersave_common)
+       /* Use r3 to pass state nap/sleep/winkle */
        /* NAP is a state loss, we create a regs frame on the
         * stack, fill it up with the state we care about and
         * stick a pointer to it in PACAR1. We really only
@@ -79,8 +89,8 @@ _GLOBAL(power7_nap)
        /* Continue saving state */
        SAVE_GPR(2, r1)
        SAVE_NVGPRS(r1)
-       mfcr    r3
-       std     r3,_CCR(r1)
+       mfcr    r4
+       std     r4,_CCR(r1)
        std     r9,_MSR(r1)
        std     r1,PACAR1(r13)
 
@@ -90,15 +100,30 @@ _GLOBAL(power7_enter_nap_mode)
        li      r4,KVM_HWTHREAD_IN_NAP
        stb     r4,HSTATE_HWTHREAD_STATE(r13)
 #endif
+       cmpwi   cr0,r3,1
+       beq     2f
+       IDLE_STATE_ENTER_SEQ(PPC_NAP)
+       /* No return */
+2:     IDLE_STATE_ENTER_SEQ(PPC_SLEEP)
+       /* No return */
 
-       /* Magic NAP mode enter sequence */
-       std     r0,0(r1)
-       ptesync
-       ld      r0,0(r1)
-1:     cmp     cr0,r0,r0
-       bne     1b
-       PPC_NAP
-       b       .
+_GLOBAL(power7_idle)
+       /* Now check if user or arch enabled NAP mode */
+       LOAD_REG_ADDRBASE(r3,powersave_nap)
+       lwz     r4,ADDROFF(powersave_nap)(r3)
+       cmpwi   0,r4,0
+       beqlr
+       /* fall through */
+
+_GLOBAL(power7_nap)
+       li      r3,0
+       b       power7_powersave_common
+       /* No return */
+
+_GLOBAL(power7_sleep)
+       li      r3,1
+       b       power7_powersave_common
+       /* No return */
 
 _GLOBAL(power7_wakeup_loss)
        ld      r1,PACAR1(r13)