root/arch/powerpc/platforms/83xx/suspend-asm.S

/* [<][>][^][v][top][bottom][index][help] */
   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

/* [<][>][^][v][top][bottom][index][help] */