xref: /OK3568_Linux_fs/kernel/arch/powerpc/platforms/powermac/sleep.S (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun/* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun/*
3*4882a593Smuzhiyun * This file contains sleep low-level functions for PowerBook G3.
4*4882a593Smuzhiyun *    Copyright (C) 1999 Benjamin Herrenschmidt (benh@kernel.crashing.org)
5*4882a593Smuzhiyun *    and Paul Mackerras (paulus@samba.org).
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun#include <asm/processor.h>
9*4882a593Smuzhiyun#include <asm/page.h>
10*4882a593Smuzhiyun#include <asm/ppc_asm.h>
11*4882a593Smuzhiyun#include <asm/cputable.h>
12*4882a593Smuzhiyun#include <asm/cache.h>
13*4882a593Smuzhiyun#include <asm/thread_info.h>
14*4882a593Smuzhiyun#include <asm/asm-offsets.h>
15*4882a593Smuzhiyun#include <asm/mmu.h>
16*4882a593Smuzhiyun#include <asm/feature-fixups.h>
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun#define MAGIC	0x4c617273	/* 'Lars' */
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun/*
21*4882a593Smuzhiyun * Structure for storing CPU registers on the stack.
22*4882a593Smuzhiyun */
23*4882a593Smuzhiyun#define SL_SP		0
24*4882a593Smuzhiyun#define SL_PC		4
25*4882a593Smuzhiyun#define SL_MSR		8
26*4882a593Smuzhiyun#define SL_SDR1		0xc
27*4882a593Smuzhiyun#define SL_SPRG0	0x10	/* 4 sprg's */
28*4882a593Smuzhiyun#define SL_DBAT0	0x20
29*4882a593Smuzhiyun#define SL_IBAT0	0x28
30*4882a593Smuzhiyun#define SL_DBAT1	0x30
31*4882a593Smuzhiyun#define SL_IBAT1	0x38
32*4882a593Smuzhiyun#define SL_DBAT2	0x40
33*4882a593Smuzhiyun#define SL_IBAT2	0x48
34*4882a593Smuzhiyun#define SL_DBAT3	0x50
35*4882a593Smuzhiyun#define SL_IBAT3	0x58
36*4882a593Smuzhiyun#define SL_DBAT4	0x60
37*4882a593Smuzhiyun#define SL_IBAT4	0x68
38*4882a593Smuzhiyun#define SL_DBAT5	0x70
39*4882a593Smuzhiyun#define SL_IBAT5	0x78
40*4882a593Smuzhiyun#define SL_DBAT6	0x80
41*4882a593Smuzhiyun#define SL_IBAT6	0x88
42*4882a593Smuzhiyun#define SL_DBAT7	0x90
43*4882a593Smuzhiyun#define SL_IBAT7	0x98
44*4882a593Smuzhiyun#define SL_TB		0xa0
45*4882a593Smuzhiyun#define SL_R2		0xa8
46*4882a593Smuzhiyun#define SL_CR		0xac
47*4882a593Smuzhiyun#define SL_LR		0xb0
48*4882a593Smuzhiyun#define SL_R12		0xb4	/* r12 to r31 */
49*4882a593Smuzhiyun#define SL_SIZE		(SL_R12 + 80)
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun	.section .text
52*4882a593Smuzhiyun	.align	5
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun#if defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ_PMAC) || \
55*4882a593Smuzhiyun    (defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32))
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun/* This gets called by via-pmu.c late during the sleep process.
58*4882a593Smuzhiyun * The PMU was already send the sleep command and will shut us down
59*4882a593Smuzhiyun * soon. We need to save all that is needed and setup the wakeup
60*4882a593Smuzhiyun * vector that will be called by the ROM on wakeup
61*4882a593Smuzhiyun */
62*4882a593Smuzhiyun_GLOBAL(low_sleep_handler)
63*4882a593Smuzhiyun#ifndef CONFIG_PPC_BOOK3S_32
64*4882a593Smuzhiyun	blr
65*4882a593Smuzhiyun#else
66*4882a593Smuzhiyun	mflr	r0
67*4882a593Smuzhiyun	lis	r11,sleep_storage@ha
68*4882a593Smuzhiyun	addi	r11,r11,sleep_storage@l
69*4882a593Smuzhiyun	stw	r0,SL_LR(r11)
70*4882a593Smuzhiyun	mfcr	r0
71*4882a593Smuzhiyun	stw	r0,SL_CR(r11)
72*4882a593Smuzhiyun	stw	r1,SL_SP(r11)
73*4882a593Smuzhiyun	stw	r2,SL_R2(r11)
74*4882a593Smuzhiyun	stmw	r12,SL_R12(r11)
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun	/* Save MSR & SDR1 */
77*4882a593Smuzhiyun	mfmsr	r4
78*4882a593Smuzhiyun	stw	r4,SL_MSR(r11)
79*4882a593Smuzhiyun	mfsdr1	r4
80*4882a593Smuzhiyun	stw	r4,SL_SDR1(r11)
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun	/* Get a stable timebase and save it */
83*4882a593Smuzhiyun1:	mftbu	r4
84*4882a593Smuzhiyun	stw	r4,SL_TB(r11)
85*4882a593Smuzhiyun	mftb	r5
86*4882a593Smuzhiyun	stw	r5,SL_TB+4(r11)
87*4882a593Smuzhiyun	mftbu	r3
88*4882a593Smuzhiyun	cmpw	r3,r4
89*4882a593Smuzhiyun	bne	1b
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun	/* Save SPRGs */
92*4882a593Smuzhiyun	mfsprg	r4,0
93*4882a593Smuzhiyun	stw	r4,SL_SPRG0(r11)
94*4882a593Smuzhiyun	mfsprg	r4,1
95*4882a593Smuzhiyun	stw	r4,SL_SPRG0+4(r11)
96*4882a593Smuzhiyun	mfsprg	r4,2
97*4882a593Smuzhiyun	stw	r4,SL_SPRG0+8(r11)
98*4882a593Smuzhiyun	mfsprg	r4,3
99*4882a593Smuzhiyun	stw	r4,SL_SPRG0+12(r11)
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun	/* Save BATs */
102*4882a593Smuzhiyun	mfdbatu	r4,0
103*4882a593Smuzhiyun	stw	r4,SL_DBAT0(r11)
104*4882a593Smuzhiyun	mfdbatl	r4,0
105*4882a593Smuzhiyun	stw	r4,SL_DBAT0+4(r11)
106*4882a593Smuzhiyun	mfdbatu	r4,1
107*4882a593Smuzhiyun	stw	r4,SL_DBAT1(r11)
108*4882a593Smuzhiyun	mfdbatl	r4,1
109*4882a593Smuzhiyun	stw	r4,SL_DBAT1+4(r11)
110*4882a593Smuzhiyun	mfdbatu	r4,2
111*4882a593Smuzhiyun	stw	r4,SL_DBAT2(r11)
112*4882a593Smuzhiyun	mfdbatl	r4,2
113*4882a593Smuzhiyun	stw	r4,SL_DBAT2+4(r11)
114*4882a593Smuzhiyun	mfdbatu	r4,3
115*4882a593Smuzhiyun	stw	r4,SL_DBAT3(r11)
116*4882a593Smuzhiyun	mfdbatl	r4,3
117*4882a593Smuzhiyun	stw	r4,SL_DBAT3+4(r11)
118*4882a593Smuzhiyun	mfibatu	r4,0
119*4882a593Smuzhiyun	stw	r4,SL_IBAT0(r11)
120*4882a593Smuzhiyun	mfibatl	r4,0
121*4882a593Smuzhiyun	stw	r4,SL_IBAT0+4(r11)
122*4882a593Smuzhiyun	mfibatu	r4,1
123*4882a593Smuzhiyun	stw	r4,SL_IBAT1(r11)
124*4882a593Smuzhiyun	mfibatl	r4,1
125*4882a593Smuzhiyun	stw	r4,SL_IBAT1+4(r11)
126*4882a593Smuzhiyun	mfibatu	r4,2
127*4882a593Smuzhiyun	stw	r4,SL_IBAT2(r11)
128*4882a593Smuzhiyun	mfibatl	r4,2
129*4882a593Smuzhiyun	stw	r4,SL_IBAT2+4(r11)
130*4882a593Smuzhiyun	mfibatu	r4,3
131*4882a593Smuzhiyun	stw	r4,SL_IBAT3(r11)
132*4882a593Smuzhiyun	mfibatl	r4,3
133*4882a593Smuzhiyun	stw	r4,SL_IBAT3+4(r11)
134*4882a593Smuzhiyun
135*4882a593SmuzhiyunBEGIN_MMU_FTR_SECTION
136*4882a593Smuzhiyun	mfspr	r4,SPRN_DBAT4U
137*4882a593Smuzhiyun	stw	r4,SL_DBAT4(r11)
138*4882a593Smuzhiyun	mfspr	r4,SPRN_DBAT4L
139*4882a593Smuzhiyun	stw	r4,SL_DBAT4+4(r11)
140*4882a593Smuzhiyun	mfspr	r4,SPRN_DBAT5U
141*4882a593Smuzhiyun	stw	r4,SL_DBAT5(r11)
142*4882a593Smuzhiyun	mfspr	r4,SPRN_DBAT5L
143*4882a593Smuzhiyun	stw	r4,SL_DBAT5+4(r11)
144*4882a593Smuzhiyun	mfspr	r4,SPRN_DBAT6U
145*4882a593Smuzhiyun	stw	r4,SL_DBAT6(r11)
146*4882a593Smuzhiyun	mfspr	r4,SPRN_DBAT6L
147*4882a593Smuzhiyun	stw	r4,SL_DBAT6+4(r11)
148*4882a593Smuzhiyun	mfspr	r4,SPRN_DBAT7U
149*4882a593Smuzhiyun	stw	r4,SL_DBAT7(r11)
150*4882a593Smuzhiyun	mfspr	r4,SPRN_DBAT7L
151*4882a593Smuzhiyun	stw	r4,SL_DBAT7+4(r11)
152*4882a593Smuzhiyun	mfspr	r4,SPRN_IBAT4U
153*4882a593Smuzhiyun	stw	r4,SL_IBAT4(r11)
154*4882a593Smuzhiyun	mfspr	r4,SPRN_IBAT4L
155*4882a593Smuzhiyun	stw	r4,SL_IBAT4+4(r11)
156*4882a593Smuzhiyun	mfspr	r4,SPRN_IBAT5U
157*4882a593Smuzhiyun	stw	r4,SL_IBAT5(r11)
158*4882a593Smuzhiyun	mfspr	r4,SPRN_IBAT5L
159*4882a593Smuzhiyun	stw	r4,SL_IBAT5+4(r11)
160*4882a593Smuzhiyun	mfspr	r4,SPRN_IBAT6U
161*4882a593Smuzhiyun	stw	r4,SL_IBAT6(r11)
162*4882a593Smuzhiyun	mfspr	r4,SPRN_IBAT6L
163*4882a593Smuzhiyun	stw	r4,SL_IBAT6+4(r11)
164*4882a593Smuzhiyun	mfspr	r4,SPRN_IBAT7U
165*4882a593Smuzhiyun	stw	r4,SL_IBAT7(r11)
166*4882a593Smuzhiyun	mfspr	r4,SPRN_IBAT7L
167*4882a593Smuzhiyun	stw	r4,SL_IBAT7+4(r11)
168*4882a593SmuzhiyunEND_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun	/* Backup various CPU config stuffs */
171*4882a593Smuzhiyun	bl	__save_cpu_setup
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun	/* The ROM can wake us up via 2 different vectors:
174*4882a593Smuzhiyun	 *  - On wallstreet & lombard, we must write a magic
175*4882a593Smuzhiyun	 *    value 'Lars' at address 4 and a pointer to a
176*4882a593Smuzhiyun	 *    memory location containing the PC to resume from
177*4882a593Smuzhiyun	 *    at address 0.
178*4882a593Smuzhiyun	 *  - On Core99, we must store the wakeup vector at
179*4882a593Smuzhiyun	 *    address 0x80 and eventually it's parameters
180*4882a593Smuzhiyun	 *    at address 0x84. I've have some trouble with those
181*4882a593Smuzhiyun	 *    parameters however and I no longer use them.
182*4882a593Smuzhiyun	 */
183*4882a593Smuzhiyun	lis	r5,grackle_wake_up@ha
184*4882a593Smuzhiyun	addi	r5,r5,grackle_wake_up@l
185*4882a593Smuzhiyun	tophys(r5,r5)
186*4882a593Smuzhiyun	stw	r5,SL_PC(r11)
187*4882a593Smuzhiyun	lis	r4,KERNELBASE@h
188*4882a593Smuzhiyun	tophys(r5,r11)
189*4882a593Smuzhiyun	addi	r5,r5,SL_PC
190*4882a593Smuzhiyun	lis	r6,MAGIC@ha
191*4882a593Smuzhiyun	addi	r6,r6,MAGIC@l
192*4882a593Smuzhiyun	stw	r5,0(r4)
193*4882a593Smuzhiyun	stw	r6,4(r4)
194*4882a593Smuzhiyun	/* Setup stuffs at 0x80-0x84 for Core99 */
195*4882a593Smuzhiyun	lis	r3,core99_wake_up@ha
196*4882a593Smuzhiyun	addi	r3,r3,core99_wake_up@l
197*4882a593Smuzhiyun	tophys(r3,r3)
198*4882a593Smuzhiyun	stw	r3,0x80(r4)
199*4882a593Smuzhiyun	stw	r5,0x84(r4)
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun	.globl	low_cpu_offline_self
202*4882a593Smuzhiyunlow_cpu_offline_self:
203*4882a593Smuzhiyun	/* Flush & disable all caches */
204*4882a593Smuzhiyun	bl	flush_disable_caches
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun	/* Turn off data relocation. */
207*4882a593Smuzhiyun	mfmsr	r3		/* Save MSR in r7 */
208*4882a593Smuzhiyun	rlwinm	r3,r3,0,28,26	/* Turn off DR bit */
209*4882a593Smuzhiyun	sync
210*4882a593Smuzhiyun	mtmsr	r3
211*4882a593Smuzhiyun	isync
212*4882a593Smuzhiyun
213*4882a593SmuzhiyunBEGIN_FTR_SECTION
214*4882a593Smuzhiyun	/* Flush any pending L2 data prefetches to work around HW bug */
215*4882a593Smuzhiyun	sync
216*4882a593Smuzhiyun	lis	r3,0xfff0
217*4882a593Smuzhiyun	lwz	r0,0(r3)	/* perform cache-inhibited load to ROM */
218*4882a593Smuzhiyun	sync			/* (caches are disabled at this point) */
219*4882a593SmuzhiyunEND_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun/*
222*4882a593Smuzhiyun * Set the HID0 and MSR for sleep.
223*4882a593Smuzhiyun */
224*4882a593Smuzhiyun	mfspr	r2,SPRN_HID0
225*4882a593Smuzhiyun	rlwinm	r2,r2,0,10,7	/* clear doze, nap */
226*4882a593Smuzhiyun	oris	r2,r2,HID0_SLEEP@h
227*4882a593Smuzhiyun	sync
228*4882a593Smuzhiyun	isync
229*4882a593Smuzhiyun	mtspr	SPRN_HID0,r2
230*4882a593Smuzhiyun	sync
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun/* This loop puts us back to sleep in case we have a spurrious
233*4882a593Smuzhiyun * wakeup so that the host bridge properly stays asleep. The
234*4882a593Smuzhiyun * CPU will be turned off, either after a known time (about 1
235*4882a593Smuzhiyun * second) on wallstreet & lombard, or as soon as the CPU enters
236*4882a593Smuzhiyun * SLEEP mode on core99
237*4882a593Smuzhiyun */
238*4882a593Smuzhiyun	mfmsr	r2
239*4882a593Smuzhiyun	oris	r2,r2,MSR_POW@h
240*4882a593Smuzhiyun1:	sync
241*4882a593Smuzhiyun	mtmsr	r2
242*4882a593Smuzhiyun	isync
243*4882a593Smuzhiyun	b	1b
244*4882a593Smuzhiyun_ASM_NOKPROBE_SYMBOL(low_cpu_offline_self)
245*4882a593Smuzhiyun/*
246*4882a593Smuzhiyun * Here is the resume code.
247*4882a593Smuzhiyun */
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun/*
251*4882a593Smuzhiyun * Core99 machines resume here
252*4882a593Smuzhiyun * r4 has the physical address of SL_PC(sp) (unused)
253*4882a593Smuzhiyun */
254*4882a593Smuzhiyun_GLOBAL(core99_wake_up)
255*4882a593Smuzhiyun	/* Make sure HID0 no longer contains any sleep bit and that data cache
256*4882a593Smuzhiyun	 * is disabled
257*4882a593Smuzhiyun	 */
258*4882a593Smuzhiyun	mfspr	r3,SPRN_HID0
259*4882a593Smuzhiyun	rlwinm	r3,r3,0,11,7		/* clear SLEEP, NAP, DOZE bits */
260*4882a593Smuzhiyun	rlwinm	3,r3,0,18,15		/* clear DCE, ICE */
261*4882a593Smuzhiyun	mtspr	SPRN_HID0,r3
262*4882a593Smuzhiyun	sync
263*4882a593Smuzhiyun	isync
264*4882a593Smuzhiyun
265*4882a593Smuzhiyun	/* sanitize MSR */
266*4882a593Smuzhiyun	mfmsr	r3
267*4882a593Smuzhiyun	ori	r3,r3,MSR_EE|MSR_IP
268*4882a593Smuzhiyun	xori	r3,r3,MSR_EE|MSR_IP
269*4882a593Smuzhiyun	sync
270*4882a593Smuzhiyun	isync
271*4882a593Smuzhiyun	mtmsr	r3
272*4882a593Smuzhiyun	sync
273*4882a593Smuzhiyun	isync
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun	/* Recover sleep storage */
276*4882a593Smuzhiyun	lis	r3,sleep_storage@ha
277*4882a593Smuzhiyun	addi	r3,r3,sleep_storage@l
278*4882a593Smuzhiyun	tophys(r3,r3)
279*4882a593Smuzhiyun	addi	r1,r3,SL_PC
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun	/* Pass thru to older resume code ... */
282*4882a593Smuzhiyun_ASM_NOKPROBE_SYMBOL(core99_wake_up)
283*4882a593Smuzhiyun/*
284*4882a593Smuzhiyun * Here is the resume code for older machines.
285*4882a593Smuzhiyun * r1 has the physical address of SL_PC(sp).
286*4882a593Smuzhiyun */
287*4882a593Smuzhiyun
288*4882a593Smuzhiyungrackle_wake_up:
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun	/* Restore the kernel's segment registers before
291*4882a593Smuzhiyun	 * we do any r1 memory access as we are not sure they
292*4882a593Smuzhiyun	 * are in a sane state above the first 256Mb region
293*4882a593Smuzhiyun	 */
294*4882a593Smuzhiyun	bl	load_segment_registers
295*4882a593Smuzhiyun	sync
296*4882a593Smuzhiyun	isync
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun	subi	r1,r1,SL_PC
299*4882a593Smuzhiyun
300*4882a593Smuzhiyun	/* Restore various CPU config stuffs */
301*4882a593Smuzhiyun	bl	__restore_cpu_setup
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun	/* Make sure all FPRs have been initialized */
304*4882a593Smuzhiyun	bl	reloc_offset
305*4882a593Smuzhiyun	bl	__init_fpu_registers
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun	/* Invalidate & enable L1 cache, we don't care about
308*4882a593Smuzhiyun	 * whatever the ROM may have tried to write to memory
309*4882a593Smuzhiyun	 */
310*4882a593Smuzhiyun	bl	__inval_enable_L1
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun	/* Restore the BATs, and SDR1.  Then we can turn on the MMU. */
313*4882a593Smuzhiyun	lwz	r4,SL_SDR1(r1)
314*4882a593Smuzhiyun	mtsdr1	r4
315*4882a593Smuzhiyun	lwz	r4,SL_SPRG0(r1)
316*4882a593Smuzhiyun	mtsprg	0,r4
317*4882a593Smuzhiyun	lwz	r4,SL_SPRG0+4(r1)
318*4882a593Smuzhiyun	mtsprg	1,r4
319*4882a593Smuzhiyun	lwz	r4,SL_SPRG0+8(r1)
320*4882a593Smuzhiyun	mtsprg	2,r4
321*4882a593Smuzhiyun	lwz	r4,SL_SPRG0+12(r1)
322*4882a593Smuzhiyun	mtsprg	3,r4
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun	lwz	r4,SL_DBAT0(r1)
325*4882a593Smuzhiyun	mtdbatu	0,r4
326*4882a593Smuzhiyun	lwz	r4,SL_DBAT0+4(r1)
327*4882a593Smuzhiyun	mtdbatl	0,r4
328*4882a593Smuzhiyun	lwz	r4,SL_DBAT1(r1)
329*4882a593Smuzhiyun	mtdbatu	1,r4
330*4882a593Smuzhiyun	lwz	r4,SL_DBAT1+4(r1)
331*4882a593Smuzhiyun	mtdbatl	1,r4
332*4882a593Smuzhiyun	lwz	r4,SL_DBAT2(r1)
333*4882a593Smuzhiyun	mtdbatu	2,r4
334*4882a593Smuzhiyun	lwz	r4,SL_DBAT2+4(r1)
335*4882a593Smuzhiyun	mtdbatl	2,r4
336*4882a593Smuzhiyun	lwz	r4,SL_DBAT3(r1)
337*4882a593Smuzhiyun	mtdbatu	3,r4
338*4882a593Smuzhiyun	lwz	r4,SL_DBAT3+4(r1)
339*4882a593Smuzhiyun	mtdbatl	3,r4
340*4882a593Smuzhiyun	lwz	r4,SL_IBAT0(r1)
341*4882a593Smuzhiyun	mtibatu	0,r4
342*4882a593Smuzhiyun	lwz	r4,SL_IBAT0+4(r1)
343*4882a593Smuzhiyun	mtibatl	0,r4
344*4882a593Smuzhiyun	lwz	r4,SL_IBAT1(r1)
345*4882a593Smuzhiyun	mtibatu	1,r4
346*4882a593Smuzhiyun	lwz	r4,SL_IBAT1+4(r1)
347*4882a593Smuzhiyun	mtibatl	1,r4
348*4882a593Smuzhiyun	lwz	r4,SL_IBAT2(r1)
349*4882a593Smuzhiyun	mtibatu	2,r4
350*4882a593Smuzhiyun	lwz	r4,SL_IBAT2+4(r1)
351*4882a593Smuzhiyun	mtibatl	2,r4
352*4882a593Smuzhiyun	lwz	r4,SL_IBAT3(r1)
353*4882a593Smuzhiyun	mtibatu	3,r4
354*4882a593Smuzhiyun	lwz	r4,SL_IBAT3+4(r1)
355*4882a593Smuzhiyun	mtibatl	3,r4
356*4882a593Smuzhiyun
357*4882a593SmuzhiyunBEGIN_MMU_FTR_SECTION
358*4882a593Smuzhiyun	lwz	r4,SL_DBAT4(r1)
359*4882a593Smuzhiyun	mtspr	SPRN_DBAT4U,r4
360*4882a593Smuzhiyun	lwz	r4,SL_DBAT4+4(r1)
361*4882a593Smuzhiyun	mtspr	SPRN_DBAT4L,r4
362*4882a593Smuzhiyun	lwz	r4,SL_DBAT5(r1)
363*4882a593Smuzhiyun	mtspr	SPRN_DBAT5U,r4
364*4882a593Smuzhiyun	lwz	r4,SL_DBAT5+4(r1)
365*4882a593Smuzhiyun	mtspr	SPRN_DBAT5L,r4
366*4882a593Smuzhiyun	lwz	r4,SL_DBAT6(r1)
367*4882a593Smuzhiyun	mtspr	SPRN_DBAT6U,r4
368*4882a593Smuzhiyun	lwz	r4,SL_DBAT6+4(r1)
369*4882a593Smuzhiyun	mtspr	SPRN_DBAT6L,r4
370*4882a593Smuzhiyun	lwz	r4,SL_DBAT7(r1)
371*4882a593Smuzhiyun	mtspr	SPRN_DBAT7U,r4
372*4882a593Smuzhiyun	lwz	r4,SL_DBAT7+4(r1)
373*4882a593Smuzhiyun	mtspr	SPRN_DBAT7L,r4
374*4882a593Smuzhiyun	lwz	r4,SL_IBAT4(r1)
375*4882a593Smuzhiyun	mtspr	SPRN_IBAT4U,r4
376*4882a593Smuzhiyun	lwz	r4,SL_IBAT4+4(r1)
377*4882a593Smuzhiyun	mtspr	SPRN_IBAT4L,r4
378*4882a593Smuzhiyun	lwz	r4,SL_IBAT5(r1)
379*4882a593Smuzhiyun	mtspr	SPRN_IBAT5U,r4
380*4882a593Smuzhiyun	lwz	r4,SL_IBAT5+4(r1)
381*4882a593Smuzhiyun	mtspr	SPRN_IBAT5L,r4
382*4882a593Smuzhiyun	lwz	r4,SL_IBAT6(r1)
383*4882a593Smuzhiyun	mtspr	SPRN_IBAT6U,r4
384*4882a593Smuzhiyun	lwz	r4,SL_IBAT6+4(r1)
385*4882a593Smuzhiyun	mtspr	SPRN_IBAT6L,r4
386*4882a593Smuzhiyun	lwz	r4,SL_IBAT7(r1)
387*4882a593Smuzhiyun	mtspr	SPRN_IBAT7U,r4
388*4882a593Smuzhiyun	lwz	r4,SL_IBAT7+4(r1)
389*4882a593Smuzhiyun	mtspr	SPRN_IBAT7L,r4
390*4882a593SmuzhiyunEND_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun	/* Flush all TLBs */
393*4882a593Smuzhiyun	lis	r4,0x1000
394*4882a593Smuzhiyun1:	addic.	r4,r4,-0x1000
395*4882a593Smuzhiyun	tlbie	r4
396*4882a593Smuzhiyun	blt	1b
397*4882a593Smuzhiyun	sync
398*4882a593Smuzhiyun
399*4882a593Smuzhiyun	/* Restore TB */
400*4882a593Smuzhiyun	li	r3,0
401*4882a593Smuzhiyun	mttbl	r3
402*4882a593Smuzhiyun	lwz	r3,SL_TB(r1)
403*4882a593Smuzhiyun	lwz	r4,SL_TB+4(r1)
404*4882a593Smuzhiyun	mttbu	r3
405*4882a593Smuzhiyun	mttbl	r4
406*4882a593Smuzhiyun
407*4882a593Smuzhiyun	/* Restore the callee-saved registers and return */
408*4882a593Smuzhiyun	lwz	r0,SL_CR(r1)
409*4882a593Smuzhiyun	mtcr	r0
410*4882a593Smuzhiyun	lwz	r2,SL_R2(r1)
411*4882a593Smuzhiyun	lmw	r12,SL_R12(r1)
412*4882a593Smuzhiyun
413*4882a593Smuzhiyun	/* restore the MSR and SP and turn on the MMU and return */
414*4882a593Smuzhiyun	lwz	r3,SL_MSR(r1)
415*4882a593Smuzhiyun	lwz	r4,SL_LR(r1)
416*4882a593Smuzhiyun	lwz	r1,SL_SP(r1)
417*4882a593Smuzhiyun	mtsrr0	r4
418*4882a593Smuzhiyun	mtsrr1	r3
419*4882a593Smuzhiyun	sync
420*4882a593Smuzhiyun	isync
421*4882a593Smuzhiyun	rfi
422*4882a593Smuzhiyun_ASM_NOKPROBE_SYMBOL(grackle_wake_up)
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun#endif /* defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ) */
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun	.section .bss
427*4882a593Smuzhiyun	.balign	L1_CACHE_BYTES
428*4882a593Smuzhiyunsleep_storage:
429*4882a593Smuzhiyun	.space SL_SIZE
430*4882a593Smuzhiyun	.balign	L1_CACHE_BYTES, 0
431*4882a593Smuzhiyun
432*4882a593Smuzhiyun#endif /* CONFIG_PPC_BOOK3S_32 */
433*4882a593Smuzhiyun	.section .text
434