Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aca79d2b authored by Vaidyanathan Srinivasan's avatar Vaidyanathan Srinivasan Committed by Benjamin Herrenschmidt
Browse files

powerpc/powernv: Add context management for Fast Sleep



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: default avatarVaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
[Changelog modified by Preeti U. Murthy <preeti@linux.vnet.ibm.com>]
Signed-off-by: default avatarPreeti U. Murthy <preeti@linux.vnet.ibm.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 1b783955
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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);
+8 −2
Original line number Diff line number Diff line
@@ -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 */
+44 −19
Original line number Diff line number Diff line
@@ -20,17 +20,27 @@

#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)