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