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