1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Enter and leave deep sleep state on MPC83xx
4  *
5  * Copyright (c) 2006-2008 Freescale Semiconductor, Inc.
6  * Author: Scott Wood <scottwood@freescale.com>
7  */
8 
9 #include <asm/page.h>
10 #include <asm/ppc_asm.h>
11 #include <asm/reg.h>
12 #include <asm/asm-offsets.h>
13 
14 #define SS_MEMSAVE	0x00 /* First 8 bytes of RAM */
15 #define SS_HID		0x08 /* 3 HIDs */
16 #define SS_IABR		0x14 /* 2 IABRs */
17 #define SS_IBCR		0x1c
18 #define SS_DABR		0x20 /* 2 DABRs */
19 #define SS_DBCR		0x28
20 #define SS_SP		0x2c
21 #define SS_SR		0x30 /* 16 segment registers */
22 #define SS_R2		0x70
23 #define SS_MSR		0x74
24 #define SS_SDR1		0x78
25 #define SS_LR		0x7c
26 #define SS_SPRG		0x80 /* 8 SPRGs */
27 #define SS_DBAT		0xa0 /* 8 DBATs */
28 #define SS_IBAT		0xe0 /* 8 IBATs */
29 #define SS_TB		0x120
30 #define SS_CR		0x128
31 #define SS_GPREG	0x12c /* r12-r31 */
32 #define STATE_SAVE_SIZE 0x17c
33 
34 	.section .data
35 	.align	5
36 
37 mpc83xx_sleep_save_area:
38 	.space	STATE_SAVE_SIZE
39 immrbase:
40 	.long	0
41 
42 	.section .text
43 	.align	5
44 
45 	/* r3 = physical address of IMMR */
46 _GLOBAL(mpc83xx_enter_deep_sleep)
47 	lis	r4, immrbase@ha
48 	stw	r3, immrbase@l(r4)
49 
50 	/* The first 2 words of memory are used to communicate with the
51 	 * bootloader, to tell it how to resume.
52 	 *
53 	 * The first word is the magic number 0xf5153ae5, and the second
54 	 * is the pointer to mpc83xx_deep_resume.
55 	 *
56 	 * The original content of these two words is saved in SS_MEMSAVE.
57 	 */
58 
59 	lis	r3, mpc83xx_sleep_save_area@h
60 	ori	r3, r3, mpc83xx_sleep_save_area@l
61 
62 	lis	r4, KERNELBASE@h
63 	lwz	r5, 0(r4)
64 	lwz	r6, 4(r4)
65 
66 	stw	r5, SS_MEMSAVE+0(r3)
67 	stw	r6, SS_MEMSAVE+4(r3)
68 
69 	mfspr	r5, SPRN_HID0
70 	mfspr	r6, SPRN_HID1
71 	mfspr	r7, SPRN_HID2
72 
73 	stw	r5, SS_HID+0(r3)
74 	stw	r6, SS_HID+4(r3)
75 	stw	r7, SS_HID+8(r3)
76 
77 	mfspr	r4, SPRN_IABR
78 	mfspr	r5, SPRN_IABR2
79 	mfspr	r6, SPRN_IBCR
80 	mfspr	r7, SPRN_DABR
81 	mfspr	r8, SPRN_DABR2
82 	mfspr	r9, SPRN_DBCR
83 
84 	stw	r4, SS_IABR+0(r3)
85 	stw	r5, SS_IABR+4(r3)
86 	stw	r6, SS_IBCR(r3)
87 	stw	r7, SS_DABR+0(r3)
88 	stw	r8, SS_DABR+4(r3)
89 	stw	r9, SS_DBCR(r3)
90 
91 	mfspr	r4, SPRN_SPRG0
92 	mfspr	r5, SPRN_SPRG1
93 	mfspr	r6, SPRN_SPRG2
94 	mfspr	r7, SPRN_SPRG3
95 	mfsdr1	r8
96 
97 	stw	r4, SS_SPRG+0(r3)
98 	stw	r5, SS_SPRG+4(r3)
99 	stw	r6, SS_SPRG+8(r3)
100 	stw	r7, SS_SPRG+12(r3)
101 	stw	r8, SS_SDR1(r3)
102 
103 	mfspr	r4, SPRN_SPRG4
104 	mfspr	r5, SPRN_SPRG5
105 	mfspr	r6, SPRN_SPRG6
106 	mfspr	r7, SPRN_SPRG7
107 
108 	stw	r4, SS_SPRG+16(r3)
109 	stw	r5, SS_SPRG+20(r3)
110 	stw	r6, SS_SPRG+24(r3)
111 	stw	r7, SS_SPRG+28(r3)
112 
113 	mfspr	r4, SPRN_DBAT0U
114 	mfspr	r5, SPRN_DBAT0L
115 	mfspr	r6, SPRN_DBAT1U
116 	mfspr	r7, SPRN_DBAT1L
117 
118 	stw	r4, SS_DBAT+0x00(r3)
119 	stw	r5, SS_DBAT+0x04(r3)
120 	stw	r6, SS_DBAT+0x08(r3)
121 	stw	r7, SS_DBAT+0x0c(r3)
122 
123 	mfspr	r4, SPRN_DBAT2U
124 	mfspr	r5, SPRN_DBAT2L
125 	mfspr	r6, SPRN_DBAT3U
126 	mfspr	r7, SPRN_DBAT3L
127 
128 	stw	r4, SS_DBAT+0x10(r3)
129 	stw	r5, SS_DBAT+0x14(r3)
130 	stw	r6, SS_DBAT+0x18(r3)
131 	stw	r7, SS_DBAT+0x1c(r3)
132 
133 	mfspr	r4, SPRN_DBAT4U
134 	mfspr	r5, SPRN_DBAT4L
135 	mfspr	r6, SPRN_DBAT5U
136 	mfspr	r7, SPRN_DBAT5L
137 
138 	stw	r4, SS_DBAT+0x20(r3)
139 	stw	r5, SS_DBAT+0x24(r3)
140 	stw	r6, SS_DBAT+0x28(r3)
141 	stw	r7, SS_DBAT+0x2c(r3)
142 
143 	mfspr	r4, SPRN_DBAT6U
144 	mfspr	r5, SPRN_DBAT6L
145 	mfspr	r6, SPRN_DBAT7U
146 	mfspr	r7, SPRN_DBAT7L
147 
148 	stw	r4, SS_DBAT+0x30(r3)
149 	stw	r5, SS_DBAT+0x34(r3)
150 	stw	r6, SS_DBAT+0x38(r3)
151 	stw	r7, SS_DBAT+0x3c(r3)
152 
153 	mfspr	r4, SPRN_IBAT0U
154 	mfspr	r5, SPRN_IBAT0L
155 	mfspr	r6, SPRN_IBAT1U
156 	mfspr	r7, SPRN_IBAT1L
157 
158 	stw	r4, SS_IBAT+0x00(r3)
159 	stw	r5, SS_IBAT+0x04(r3)
160 	stw	r6, SS_IBAT+0x08(r3)
161 	stw	r7, SS_IBAT+0x0c(r3)
162 
163 	mfspr	r4, SPRN_IBAT2U
164 	mfspr	r5, SPRN_IBAT2L
165 	mfspr	r6, SPRN_IBAT3U
166 	mfspr	r7, SPRN_IBAT3L
167 
168 	stw	r4, SS_IBAT+0x10(r3)
169 	stw	r5, SS_IBAT+0x14(r3)
170 	stw	r6, SS_IBAT+0x18(r3)
171 	stw	r7, SS_IBAT+0x1c(r3)
172 
173 	mfspr	r4, SPRN_IBAT4U
174 	mfspr	r5, SPRN_IBAT4L
175 	mfspr	r6, SPRN_IBAT5U
176 	mfspr	r7, SPRN_IBAT5L
177 
178 	stw	r4, SS_IBAT+0x20(r3)
179 	stw	r5, SS_IBAT+0x24(r3)
180 	stw	r6, SS_IBAT+0x28(r3)
181 	stw	r7, SS_IBAT+0x2c(r3)
182 
183 	mfspr	r4, SPRN_IBAT6U
184 	mfspr	r5, SPRN_IBAT6L
185 	mfspr	r6, SPRN_IBAT7U
186 	mfspr	r7, SPRN_IBAT7L
187 
188 	stw	r4, SS_IBAT+0x30(r3)
189 	stw	r5, SS_IBAT+0x34(r3)
190 	stw	r6, SS_IBAT+0x38(r3)
191 	stw	r7, SS_IBAT+0x3c(r3)
192 
193 	mfmsr	r4
194 	mflr	r5
195 	mfcr	r6
196 
197 	stw	r4, SS_MSR(r3)
198 	stw	r5, SS_LR(r3)
199 	stw	r6, SS_CR(r3)
200 	stw	r1, SS_SP(r3)
201 	stw	r2, SS_R2(r3)
202 
203 1:	mftbu	r4
204 	mftb	r5
205 	mftbu	r6
206 	cmpw	r4, r6
207 	bne	1b
208 
209 	stw	r4, SS_TB+0(r3)
210 	stw	r5, SS_TB+4(r3)
211 
212 	stmw	r12, SS_GPREG(r3)
213 
214 	li	r4, 0
215 	addi	r6, r3, SS_SR-4
216 1:	mfsrin	r5, r4
217 	stwu	r5, 4(r6)
218 	addis	r4, r4, 0x1000
219 	cmpwi	r4, 0
220 	bne	1b
221 
222 	/* Disable machine checks and critical exceptions */
223 	mfmsr	r4
224 	rlwinm	r4, r4, 0, ~MSR_CE
225 	rlwinm	r4, r4, 0, ~MSR_ME
226 	mtmsr	r4
227 	isync
228 
229 #define TMP_VIRT_IMMR		0xf0000000
230 #define DEFAULT_IMMR_VALUE	0xff400000
231 #define IMMRBAR_BASE		0x0000
232 
233 	lis	r4, immrbase@ha
234 	lwz	r4, immrbase@l(r4)
235 
236 	/* Use DBAT0 to address the current IMMR space */
237 
238 	ori	r4, r4, 0x002a
239 	mtspr	SPRN_DBAT0L, r4
240 	lis	r8, TMP_VIRT_IMMR@h
241 	ori	r4, r8, 0x001e	/* 1 MByte accessible from Kernel Space only */
242 	mtspr	SPRN_DBAT0U, r4
243 	isync
244 
245 	/* Use DBAT1 to address the original IMMR space */
246 
247 	lis	r4, DEFAULT_IMMR_VALUE@h
248 	ori	r4, r4, 0x002a
249 	mtspr	SPRN_DBAT1L, r4
250 	lis	r9, (TMP_VIRT_IMMR + 0x01000000)@h
251 	ori	r4, r9, 0x001e	/* 1 MByte accessible from Kernel Space only */
252 	mtspr	SPRN_DBAT1U, r4
253 	isync
254 
255 	/* Use DBAT2 to address the beginning of RAM.  This isn't done
256 	 * using the normal virtual mapping, because with page debugging
257 	 * enabled it will be read-only.
258 	 */
259 
260 	li	r4, 0x0002
261 	mtspr	SPRN_DBAT2L, r4
262 	lis	r4, KERNELBASE@h
263 	ori	r4, r4, 0x001e	/* 1 MByte accessible from Kernel Space only */
264 	mtspr	SPRN_DBAT2U, r4
265 	isync
266 
267 	/* Flush the cache with our BAT, as there will be TLB misses
268 	 * otherwise if page debugging is enabled, and these misses
269 	 * will disturb the PLRU algorithm.
270 	 */
271 
272 	bl	__flush_disable_L1
273 
274 	/* Keep the i-cache enabled, so the hack below for low-boot
275 	 * flash will work.
276 	 */
277 	mfspr	r3, SPRN_HID0
278 	ori	r3, r3, HID0_ICE
279 	mtspr	SPRN_HID0, r3
280 	isync
281 
282 	lis	r6, 0xf515
283 	ori	r6, r6, 0x3ae5
284 
285 	lis	r7, mpc83xx_deep_resume@h
286 	ori	r7, r7, mpc83xx_deep_resume@l
287 	tophys(r7, r7)
288 
289 	lis	r5, KERNELBASE@h
290 	stw	r6, 0(r5)
291 	stw	r7, 4(r5)
292 
293 	/* Reset BARs */
294 
295 	li	r4, 0
296 	stw	r4, 0x0024(r8)
297 	stw	r4, 0x002c(r8)
298 	stw	r4, 0x0034(r8)
299 	stw	r4, 0x003c(r8)
300 	stw	r4, 0x0064(r8)
301 	stw	r4, 0x006c(r8)
302 
303 	/* Rev 1 of the 8313 has problems with wakeup events that are
304 	 * pending during the transition to deep sleep state (such as if
305 	 * the PCI host sets the state to D3 and then D0 in rapid
306 	 * succession).  This check shrinks the race window somewhat.
307 	 *
308 	 * See erratum PCI23, though the problem is not limited
309 	 * to PCI.
310 	 */
311 
312 	lwz	r3, 0x0b04(r8)
313 	andi.	r3, r3, 1
314 	bne-	mpc83xx_deep_resume
315 
316 	/* Move IMMR back to the default location, following the
317 	 * procedure specified in the MPC8313 manual.
318 	 */
319 	lwz	r4, IMMRBAR_BASE(r8)
320 	isync
321 	lis	r4, DEFAULT_IMMR_VALUE@h
322 	stw	r4, IMMRBAR_BASE(r8)
323 	lis	r4, KERNELBASE@h
324 	lwz	r4, 0(r4)
325 	isync
326 	lwz	r4, IMMRBAR_BASE(r9)
327 	mr	r8, r9
328 	isync
329 
330 	/* Check the Reset Configuration Word to see whether flash needs
331 	 * to be mapped at a low address or a high address.
332 	 */
333 
334 	lwz	r4, 0x0904(r8)
335 	andis.	r4, r4, 0x0400
336 	li	r4, 0
337 	beq	boot_low
338 	lis	r4, 0xff80
339 boot_low:
340 	stw	r4, 0x0020(r8)
341 	lis	r7, 0x8000
342 	ori	r7, r7, 0x0016
343 
344 	mfspr	r5, SPRN_HID0
345 	rlwinm	r5, r5, 0, ~(HID0_DOZE | HID0_NAP)
346 	oris	r5, r5, HID0_SLEEP@h
347 	mtspr	SPRN_HID0, r5
348 	isync
349 
350 	mfmsr	r5
351 	oris	r5, r5, MSR_POW@h
352 
353 	/* Enable the flash mapping at the appropriate address.  This
354 	 * mapping will override the RAM mapping if booting low, so there's
355 	 * no need to disable the latter.  This must be done inside the same
356 	 * cache line as setting MSR_POW, so that no instruction fetches
357 	 * from RAM happen after the flash mapping is turned on.
358 	 */
359 
360 	.align	5
361 	stw	r7, 0x0024(r8)
362 	sync
363 	isync
364 	mtmsr	r5
365 	isync
366 1:	b	1b
367 
368 mpc83xx_deep_resume:
369 	lis	r4, 1f@h
370 	ori	r4, r4, 1f@l
371 	tophys(r4, r4)
372 	mtsrr0	r4
373 
374 	mfmsr	r4
375 	rlwinm	r4, r4, 0, ~(MSR_IR | MSR_DR)
376 	mtsrr1	r4
377 
378 	rfi
379 
380 1:	tlbia
381 	bl	__inval_enable_L1
382 
383 	lis	r3, mpc83xx_sleep_save_area@h
384 	ori	r3, r3, mpc83xx_sleep_save_area@l
385 	tophys(r3, r3)
386 
387 	lwz	r5, SS_MEMSAVE+0(r3)
388 	lwz	r6, SS_MEMSAVE+4(r3)
389 
390 	stw	r5, 0(0)
391 	stw	r6, 4(0)
392 
393 	lwz	r5, SS_HID+0(r3)
394 	lwz	r6, SS_HID+4(r3)
395 	lwz	r7, SS_HID+8(r3)
396 
397 	mtspr	SPRN_HID0, r5
398 	mtspr	SPRN_HID1, r6
399 	mtspr	SPRN_HID2, r7
400 
401 	lwz	r4, SS_IABR+0(r3)
402 	lwz	r5, SS_IABR+4(r3)
403 	lwz	r6, SS_IBCR(r3)
404 	lwz	r7, SS_DABR+0(r3)
405 	lwz	r8, SS_DABR+4(r3)
406 	lwz	r9, SS_DBCR(r3)
407 
408 	mtspr	SPRN_IABR, r4
409 	mtspr	SPRN_IABR2, r5
410 	mtspr	SPRN_IBCR, r6
411 	mtspr	SPRN_DABR, r7
412 	mtspr	SPRN_DABR2, r8
413 	mtspr	SPRN_DBCR, r9
414 
415 	li	r4, 0
416 	addi	r6, r3, SS_SR-4
417 1:	lwzu	r5, 4(r6)
418 	mtsrin	r5, r4
419 	addis	r4, r4, 0x1000
420 	cmpwi	r4, 0
421 	bne	1b
422 
423 	lwz	r4, SS_DBAT+0x00(r3)
424 	lwz	r5, SS_DBAT+0x04(r3)
425 	lwz	r6, SS_DBAT+0x08(r3)
426 	lwz	r7, SS_DBAT+0x0c(r3)
427 
428 	mtspr	SPRN_DBAT0U, r4
429 	mtspr	SPRN_DBAT0L, r5
430 	mtspr	SPRN_DBAT1U, r6
431 	mtspr	SPRN_DBAT1L, r7
432 
433 	lwz	r4, SS_DBAT+0x10(r3)
434 	lwz	r5, SS_DBAT+0x14(r3)
435 	lwz	r6, SS_DBAT+0x18(r3)
436 	lwz	r7, SS_DBAT+0x1c(r3)
437 
438 	mtspr	SPRN_DBAT2U, r4
439 	mtspr	SPRN_DBAT2L, r5
440 	mtspr	SPRN_DBAT3U, r6
441 	mtspr	SPRN_DBAT3L, r7
442 
443 	lwz	r4, SS_DBAT+0x20(r3)
444 	lwz	r5, SS_DBAT+0x24(r3)
445 	lwz	r6, SS_DBAT+0x28(r3)
446 	lwz	r7, SS_DBAT+0x2c(r3)
447 
448 	mtspr	SPRN_DBAT4U, r4
449 	mtspr	SPRN_DBAT4L, r5
450 	mtspr	SPRN_DBAT5U, r6
451 	mtspr	SPRN_DBAT5L, r7
452 
453 	lwz	r4, SS_DBAT+0x30(r3)
454 	lwz	r5, SS_DBAT+0x34(r3)
455 	lwz	r6, SS_DBAT+0x38(r3)
456 	lwz	r7, SS_DBAT+0x3c(r3)
457 
458 	mtspr	SPRN_DBAT6U, r4
459 	mtspr	SPRN_DBAT6L, r5
460 	mtspr	SPRN_DBAT7U, r6
461 	mtspr	SPRN_DBAT7L, r7
462 
463 	lwz	r4, SS_IBAT+0x00(r3)
464 	lwz	r5, SS_IBAT+0x04(r3)
465 	lwz	r6, SS_IBAT+0x08(r3)
466 	lwz	r7, SS_IBAT+0x0c(r3)
467 
468 	mtspr	SPRN_IBAT0U, r4
469 	mtspr	SPRN_IBAT0L, r5
470 	mtspr	SPRN_IBAT1U, r6
471 	mtspr	SPRN_IBAT1L, r7
472 
473 	lwz	r4, SS_IBAT+0x10(r3)
474 	lwz	r5, SS_IBAT+0x14(r3)
475 	lwz	r6, SS_IBAT+0x18(r3)
476 	lwz	r7, SS_IBAT+0x1c(r3)
477 
478 	mtspr	SPRN_IBAT2U, r4
479 	mtspr	SPRN_IBAT2L, r5
480 	mtspr	SPRN_IBAT3U, r6
481 	mtspr	SPRN_IBAT3L, r7
482 
483 	lwz	r4, SS_IBAT+0x20(r3)
484 	lwz	r5, SS_IBAT+0x24(r3)
485 	lwz	r6, SS_IBAT+0x28(r3)
486 	lwz	r7, SS_IBAT+0x2c(r3)
487 
488 	mtspr	SPRN_IBAT4U, r4
489 	mtspr	SPRN_IBAT4L, r5
490 	mtspr	SPRN_IBAT5U, r6
491 	mtspr	SPRN_IBAT5L, r7
492 
493 	lwz	r4, SS_IBAT+0x30(r3)
494 	lwz	r5, SS_IBAT+0x34(r3)
495 	lwz	r6, SS_IBAT+0x38(r3)
496 	lwz	r7, SS_IBAT+0x3c(r3)
497 
498 	mtspr	SPRN_IBAT6U, r4
499 	mtspr	SPRN_IBAT6L, r5
500 	mtspr	SPRN_IBAT7U, r6
501 	mtspr	SPRN_IBAT7L, r7
502 
503 	lwz	r4, SS_SPRG+16(r3)
504 	lwz	r5, SS_SPRG+20(r3)
505 	lwz	r6, SS_SPRG+24(r3)
506 	lwz	r7, SS_SPRG+28(r3)
507 
508 	mtspr	SPRN_SPRG4, r4
509 	mtspr	SPRN_SPRG5, r5
510 	mtspr	SPRN_SPRG6, r6
511 	mtspr	SPRN_SPRG7, r7
512 
513 	lwz	r4, SS_SPRG+0(r3)
514 	lwz	r5, SS_SPRG+4(r3)
515 	lwz	r6, SS_SPRG+8(r3)
516 	lwz	r7, SS_SPRG+12(r3)
517 	lwz	r8, SS_SDR1(r3)
518 
519 	mtspr	SPRN_SPRG0, r4
520 	mtspr	SPRN_SPRG1, r5
521 	mtspr	SPRN_SPRG2, r6
522 	mtspr	SPRN_SPRG3, r7
523 	mtsdr1	r8
524 
525 	lwz	r4, SS_MSR(r3)
526 	lwz	r5, SS_LR(r3)
527 	lwz	r6, SS_CR(r3)
528 	lwz	r1, SS_SP(r3)
529 	lwz	r2, SS_R2(r3)
530 
531 	mtsrr1	r4
532 	mtsrr0	r5
533 	mtcr	r6
534 
535 	li	r4, 0
536 	mtspr	SPRN_TBWL, r4
537 
538 	lwz	r4, SS_TB+0(r3)
539 	lwz	r5, SS_TB+4(r3)
540 
541 	mtspr	SPRN_TBWU, r4
542 	mtspr	SPRN_TBWL, r5
543 
544 	lmw	r12, SS_GPREG(r3)
545 
546 	/* Kick decrementer */
547 	li	r0, 1
548 	mtdec	r0
549 
550 	rfi
551 _ASM_NOKPROBE_SYMBOL(mpc83xx_deep_resume)
552