Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.8.
  1/*
  2 *  This file contains the power_save function for Power7 CPUs.
  3 *
  4 *  This program is free software; you can redistribute it and/or
  5 *  modify it under the terms of the GNU General Public License
  6 *  as published by the Free Software Foundation; either version
  7 *  2 of the License, or (at your option) any later version.
  8 */
  9
 10#include <linux/threads.h>
 11#include <asm/processor.h>
 12#include <asm/page.h>
 13#include <asm/cputable.h>
 14#include <asm/thread_info.h>
 15#include <asm/ppc_asm.h>
 16#include <asm/asm-offsets.h>
 17#include <asm/ppc-opcode.h>
 18#include <asm/hw_irq.h>
 19#include <asm/kvm_book3s_asm.h>
 20#include <asm/opal.h>
 21
 22#undef DEBUG
 23
 24/* Idle state entry routines */
 25
 26#define	IDLE_STATE_ENTER_SEQ(IDLE_INST)				\
 27	/* Magic NAP/SLEEP/WINKLE mode enter sequence */	\
 28	std	r0,0(r1);					\
 29	ptesync;						\
 30	ld	r0,0(r1);					\
 311:	cmp	cr0,r0,r0;					\
 32	bne	1b;						\
 33	IDLE_INST;						\
 34	b	.
 35
 36	.text
 37
 38/*
 39 * Pass requested state in r3:
 40 * 	0 - nap
 41 * 	1 - sleep
 42 */
 43_GLOBAL(power7_powersave_common)
 44	/* Use r3 to pass state nap/sleep/winkle */
 45	/* NAP is a state loss, we create a regs frame on the
 46	 * stack, fill it up with the state we care about and
 47	 * stick a pointer to it in PACAR1. We really only
 48	 * need to save PC, some CR bits and the NV GPRs,
 49	 * but for now an interrupt frame will do.
 50	 */
 51	mflr	r0
 52	std	r0,16(r1)
 53	stdu	r1,-INT_FRAME_SIZE(r1)
 54	std	r0,_LINK(r1)
 55	std	r0,_NIP(r1)
 56
 57#ifndef CONFIG_SMP
 58	/* Make sure FPU, VSX etc... are flushed as we may lose
 59	 * state when going to nap mode
 60	 */
 61	bl	.discard_lazy_cpu_state
 62#endif /* CONFIG_SMP */
 63
 64	/* Hard disable interrupts */
 65	mfmsr	r9
 66	rldicl	r9,r9,48,1
 67	rotldi	r9,r9,16
 68	mtmsrd	r9,1			/* hard-disable interrupts */
 69
 70	/* Check if something happened while soft-disabled */
 71	lbz	r0,PACAIRQHAPPENED(r13)
 72	cmpwi	cr0,r0,0
 73	beq	1f
 74	addi	r1,r1,INT_FRAME_SIZE
 75	ld	r0,16(r1)
 76	mtlr	r0
 77	blr
 78
 791:	/* We mark irqs hard disabled as this is the state we'll
 80	 * be in when returning and we need to tell arch_local_irq_restore()
 81	 * about it
 82	 */
 83	li	r0,PACA_IRQ_HARD_DIS
 84	stb	r0,PACAIRQHAPPENED(r13)
 85
 86	/* We haven't lost state ... yet */
 87	li	r0,0
 88	stb	r0,PACA_NAPSTATELOST(r13)
 89
 90	/* Continue saving state */
 91	SAVE_GPR(2, r1)
 92	SAVE_NVGPRS(r1)
 93	mfcr	r4
 94	std	r4,_CCR(r1)
 95	std	r9,_MSR(r1)
 96	std	r1,PACAR1(r13)
 97
 98_GLOBAL(power7_enter_nap_mode)
 99#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
100	/* Tell KVM we're napping */
101	li	r4,KVM_HWTHREAD_IN_NAP
102	stb	r4,HSTATE_HWTHREAD_STATE(r13)
103#endif
104	cmpwi	cr0,r3,1
105	beq	2f
106	IDLE_STATE_ENTER_SEQ(PPC_NAP)
107	/* No return */
1082:	IDLE_STATE_ENTER_SEQ(PPC_SLEEP)
109	/* No return */
110
111_GLOBAL(power7_idle)
112	/* Now check if user or arch enabled NAP mode */
113	LOAD_REG_ADDRBASE(r3,powersave_nap)
114	lwz	r4,ADDROFF(powersave_nap)(r3)
115	cmpwi	0,r4,0
116	beqlr
117	/* fall through */
118
119_GLOBAL(power7_nap)
120	li	r3,0
121	b	power7_powersave_common
122	/* No return */
123
124_GLOBAL(power7_sleep)
125	li	r3,1
126	b	power7_powersave_common
127	/* No return */
128
129_GLOBAL(power7_wakeup_tb_loss)
130	ld	r2,PACATOC(r13);
131	ld	r1,PACAR1(r13)
132
133	/* Time base re-sync */
134	li	r0,OPAL_RESYNC_TIMEBASE
135	LOAD_REG_ADDR(r11,opal);
136	ld	r12,8(r11);
137	ld	r2,0(r11);
138	mtctr	r12
139	bctrl
140
141	/* TODO: Check r3 for failure */
142
143	REST_NVGPRS(r1)
144	REST_GPR(2, r1)
145	ld	r3,_CCR(r1)
146	ld	r4,_MSR(r1)
147	ld	r5,_NIP(r1)
148	addi	r1,r1,INT_FRAME_SIZE
149	mtcr	r3
150	mfspr	r3,SPRN_SRR1		/* Return SRR1 */
151	mtspr	SPRN_SRR1,r4
152	mtspr	SPRN_SRR0,r5
153	rfid
154
155_GLOBAL(power7_wakeup_loss)
156	ld	r1,PACAR1(r13)
157	REST_NVGPRS(r1)
158	REST_GPR(2, r1)
159	ld	r3,_CCR(r1)
160	ld	r4,_MSR(r1)
161	ld	r5,_NIP(r1)
162	addi	r1,r1,INT_FRAME_SIZE
163	mtcr	r3
164	mtspr	SPRN_SRR1,r4
165	mtspr	SPRN_SRR0,r5
166	rfid
167
168_GLOBAL(power7_wakeup_noloss)
169	lbz	r0,PACA_NAPSTATELOST(r13)
170	cmpwi	r0,0
171	bne	.power7_wakeup_loss
172	ld	r1,PACAR1(r13)
173	ld	r4,_MSR(r1)
174	ld	r5,_NIP(r1)
175	addi	r1,r1,INT_FRAME_SIZE
176	mtspr	SPRN_SRR1,r4
177	mtspr	SPRN_SRR0,r5
178	rfid