powerpc/powernv: Add context management for Fast Sleep
[firefly-linux-kernel-4.4.55.git] / arch / powerpc / kernel / idle_power7.S
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)