Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Enter and leave deep sleep state on MPC83xx
0004  *
0005  * Copyright (c) 2006-2008 Freescale Semiconductor, Inc.
0006  * Author: Scott Wood <scottwood@freescale.com>
0007  */
0008 
0009 #include <asm/page.h>
0010 #include <asm/ppc_asm.h>
0011 #include <asm/reg.h>
0012 #include <asm/asm-offsets.h>
0013 
0014 #define SS_MEMSAVE  0x00 /* First 8 bytes of RAM */
0015 #define SS_HID      0x08 /* 3 HIDs */
0016 #define SS_IABR     0x14 /* 2 IABRs */
0017 #define SS_IBCR     0x1c
0018 #define SS_DABR     0x20 /* 2 DABRs */
0019 #define SS_DBCR     0x28
0020 #define SS_SP       0x2c
0021 #define SS_SR       0x30 /* 16 segment registers */
0022 #define SS_R2       0x70
0023 #define SS_MSR      0x74
0024 #define SS_SDR1     0x78
0025 #define SS_LR       0x7c
0026 #define SS_SPRG     0x80 /* 8 SPRGs */
0027 #define SS_DBAT     0xa0 /* 8 DBATs */
0028 #define SS_IBAT     0xe0 /* 8 IBATs */
0029 #define SS_TB       0x120
0030 #define SS_CR       0x128
0031 #define SS_GPREG    0x12c /* r12-r31 */
0032 #define STATE_SAVE_SIZE 0x17c
0033 
0034     .section .data
0035     .align  5
0036 
0037 mpc83xx_sleep_save_area:
0038     .space  STATE_SAVE_SIZE
0039 immrbase:
0040     .long   0
0041 
0042     .section .text
0043     .align  5
0044 
0045     /* r3 = physical address of IMMR */
0046 _GLOBAL(mpc83xx_enter_deep_sleep)
0047     lis r4, immrbase@ha
0048     stw r3, immrbase@l(r4)
0049 
0050     /* The first 2 words of memory are used to communicate with the
0051      * bootloader, to tell it how to resume.
0052      *
0053      * The first word is the magic number 0xf5153ae5, and the second
0054      * is the pointer to mpc83xx_deep_resume.
0055      *
0056      * The original content of these two words is saved in SS_MEMSAVE.
0057      */
0058 
0059     lis r3, mpc83xx_sleep_save_area@h
0060     ori r3, r3, mpc83xx_sleep_save_area@l
0061 
0062     lis r4, KERNELBASE@h
0063     lwz r5, 0(r4)
0064     lwz r6, 4(r4)
0065 
0066     stw r5, SS_MEMSAVE+0(r3)
0067     stw r6, SS_MEMSAVE+4(r3)
0068 
0069     mfspr   r5, SPRN_HID0
0070     mfspr   r6, SPRN_HID1
0071     mfspr   r7, SPRN_HID2
0072 
0073     stw r5, SS_HID+0(r3)
0074     stw r6, SS_HID+4(r3)
0075     stw r7, SS_HID+8(r3)
0076 
0077     mfspr   r4, SPRN_IABR
0078     mfspr   r5, SPRN_IABR2
0079     mfspr   r6, SPRN_IBCR
0080     mfspr   r7, SPRN_DABR
0081     mfspr   r8, SPRN_DABR2
0082     mfspr   r9, SPRN_DBCR
0083 
0084     stw r4, SS_IABR+0(r3)
0085     stw r5, SS_IABR+4(r3)
0086     stw r6, SS_IBCR(r3)
0087     stw r7, SS_DABR+0(r3)
0088     stw r8, SS_DABR+4(r3)
0089     stw r9, SS_DBCR(r3)
0090 
0091     mfspr   r4, SPRN_SPRG0
0092     mfspr   r5, SPRN_SPRG1
0093     mfspr   r6, SPRN_SPRG2
0094     mfspr   r7, SPRN_SPRG3
0095     mfsdr1  r8
0096 
0097     stw r4, SS_SPRG+0(r3)
0098     stw r5, SS_SPRG+4(r3)
0099     stw r6, SS_SPRG+8(r3)
0100     stw r7, SS_SPRG+12(r3)
0101     stw r8, SS_SDR1(r3)
0102 
0103     mfspr   r4, SPRN_SPRG4
0104     mfspr   r5, SPRN_SPRG5
0105     mfspr   r6, SPRN_SPRG6
0106     mfspr   r7, SPRN_SPRG7
0107 
0108     stw r4, SS_SPRG+16(r3)
0109     stw r5, SS_SPRG+20(r3)
0110     stw r6, SS_SPRG+24(r3)
0111     stw r7, SS_SPRG+28(r3)
0112 
0113     mfspr   r4, SPRN_DBAT0U
0114     mfspr   r5, SPRN_DBAT0L
0115     mfspr   r6, SPRN_DBAT1U
0116     mfspr   r7, SPRN_DBAT1L
0117 
0118     stw r4, SS_DBAT+0x00(r3)
0119     stw r5, SS_DBAT+0x04(r3)
0120     stw r6, SS_DBAT+0x08(r3)
0121     stw r7, SS_DBAT+0x0c(r3)
0122 
0123     mfspr   r4, SPRN_DBAT2U
0124     mfspr   r5, SPRN_DBAT2L
0125     mfspr   r6, SPRN_DBAT3U
0126     mfspr   r7, SPRN_DBAT3L
0127 
0128     stw r4, SS_DBAT+0x10(r3)
0129     stw r5, SS_DBAT+0x14(r3)
0130     stw r6, SS_DBAT+0x18(r3)
0131     stw r7, SS_DBAT+0x1c(r3)
0132 
0133     mfspr   r4, SPRN_DBAT4U
0134     mfspr   r5, SPRN_DBAT4L
0135     mfspr   r6, SPRN_DBAT5U
0136     mfspr   r7, SPRN_DBAT5L
0137 
0138     stw r4, SS_DBAT+0x20(r3)
0139     stw r5, SS_DBAT+0x24(r3)
0140     stw r6, SS_DBAT+0x28(r3)
0141     stw r7, SS_DBAT+0x2c(r3)
0142 
0143     mfspr   r4, SPRN_DBAT6U
0144     mfspr   r5, SPRN_DBAT6L
0145     mfspr   r6, SPRN_DBAT7U
0146     mfspr   r7, SPRN_DBAT7L
0147 
0148     stw r4, SS_DBAT+0x30(r3)
0149     stw r5, SS_DBAT+0x34(r3)
0150     stw r6, SS_DBAT+0x38(r3)
0151     stw r7, SS_DBAT+0x3c(r3)
0152 
0153     mfspr   r4, SPRN_IBAT0U
0154     mfspr   r5, SPRN_IBAT0L
0155     mfspr   r6, SPRN_IBAT1U
0156     mfspr   r7, SPRN_IBAT1L
0157 
0158     stw r4, SS_IBAT+0x00(r3)
0159     stw r5, SS_IBAT+0x04(r3)
0160     stw r6, SS_IBAT+0x08(r3)
0161     stw r7, SS_IBAT+0x0c(r3)
0162 
0163     mfspr   r4, SPRN_IBAT2U
0164     mfspr   r5, SPRN_IBAT2L
0165     mfspr   r6, SPRN_IBAT3U
0166     mfspr   r7, SPRN_IBAT3L
0167 
0168     stw r4, SS_IBAT+0x10(r3)
0169     stw r5, SS_IBAT+0x14(r3)
0170     stw r6, SS_IBAT+0x18(r3)
0171     stw r7, SS_IBAT+0x1c(r3)
0172 
0173     mfspr   r4, SPRN_IBAT4U
0174     mfspr   r5, SPRN_IBAT4L
0175     mfspr   r6, SPRN_IBAT5U
0176     mfspr   r7, SPRN_IBAT5L
0177 
0178     stw r4, SS_IBAT+0x20(r3)
0179     stw r5, SS_IBAT+0x24(r3)
0180     stw r6, SS_IBAT+0x28(r3)
0181     stw r7, SS_IBAT+0x2c(r3)
0182 
0183     mfspr   r4, SPRN_IBAT6U
0184     mfspr   r5, SPRN_IBAT6L
0185     mfspr   r6, SPRN_IBAT7U
0186     mfspr   r7, SPRN_IBAT7L
0187 
0188     stw r4, SS_IBAT+0x30(r3)
0189     stw r5, SS_IBAT+0x34(r3)
0190     stw r6, SS_IBAT+0x38(r3)
0191     stw r7, SS_IBAT+0x3c(r3)
0192 
0193     mfmsr   r4
0194     mflr    r5
0195     mfcr    r6
0196 
0197     stw r4, SS_MSR(r3)
0198     stw r5, SS_LR(r3)
0199     stw r6, SS_CR(r3)
0200     stw r1, SS_SP(r3)
0201     stw r2, SS_R2(r3)
0202 
0203 1:  mftbu   r4
0204     mftb    r5
0205     mftbu   r6
0206     cmpw    r4, r6
0207     bne 1b
0208 
0209     stw r4, SS_TB+0(r3)
0210     stw r5, SS_TB+4(r3)
0211 
0212     stmw    r12, SS_GPREG(r3)
0213 
0214     li  r4, 0
0215     addi    r6, r3, SS_SR-4
0216 1:  mfsrin  r5, r4
0217     stwu    r5, 4(r6)
0218     addis   r4, r4, 0x1000
0219     cmpwi   r4, 0
0220     bne 1b
0221 
0222     /* Disable machine checks and critical exceptions */
0223     mfmsr   r4
0224     rlwinm  r4, r4, 0, ~MSR_CE
0225     rlwinm  r4, r4, 0, ~MSR_ME
0226     mtmsr   r4
0227     isync
0228 
0229 #define TMP_VIRT_IMMR       0xf0000000
0230 #define DEFAULT_IMMR_VALUE  0xff400000
0231 #define IMMRBAR_BASE        0x0000
0232 
0233     lis r4, immrbase@ha
0234     lwz r4, immrbase@l(r4)
0235 
0236     /* Use DBAT0 to address the current IMMR space */
0237 
0238     ori r4, r4, 0x002a
0239     mtspr   SPRN_DBAT0L, r4
0240     lis r8, TMP_VIRT_IMMR@h
0241     ori r4, r8, 0x001e  /* 1 MByte accessible from Kernel Space only */
0242     mtspr   SPRN_DBAT0U, r4
0243     isync
0244 
0245     /* Use DBAT1 to address the original IMMR space */
0246 
0247     lis r4, DEFAULT_IMMR_VALUE@h
0248     ori r4, r4, 0x002a
0249     mtspr   SPRN_DBAT1L, r4
0250     lis r9, (TMP_VIRT_IMMR + 0x01000000)@h
0251     ori r4, r9, 0x001e  /* 1 MByte accessible from Kernel Space only */
0252     mtspr   SPRN_DBAT1U, r4
0253     isync
0254 
0255     /* Use DBAT2 to address the beginning of RAM.  This isn't done
0256      * using the normal virtual mapping, because with page debugging
0257      * enabled it will be read-only.
0258      */
0259 
0260     li  r4, 0x0002
0261     mtspr   SPRN_DBAT2L, r4
0262     lis r4, KERNELBASE@h
0263     ori r4, r4, 0x001e  /* 1 MByte accessible from Kernel Space only */
0264     mtspr   SPRN_DBAT2U, r4
0265     isync
0266 
0267     /* Flush the cache with our BAT, as there will be TLB misses
0268      * otherwise if page debugging is enabled, and these misses
0269      * will disturb the PLRU algorithm.
0270      */
0271 
0272     bl  __flush_disable_L1
0273 
0274     /* Keep the i-cache enabled, so the hack below for low-boot
0275      * flash will work.
0276      */
0277     mfspr   r3, SPRN_HID0
0278     ori r3, r3, HID0_ICE
0279     mtspr   SPRN_HID0, r3
0280     isync
0281 
0282     lis r6, 0xf515
0283     ori r6, r6, 0x3ae5
0284 
0285     lis r7, mpc83xx_deep_resume@h
0286     ori r7, r7, mpc83xx_deep_resume@l
0287     tophys(r7, r7)
0288 
0289     lis r5, KERNELBASE@h
0290     stw r6, 0(r5)
0291     stw r7, 4(r5)
0292 
0293     /* Reset BARs */
0294 
0295     li  r4, 0
0296     stw r4, 0x0024(r8)
0297     stw r4, 0x002c(r8)
0298     stw r4, 0x0034(r8)
0299     stw r4, 0x003c(r8)
0300     stw r4, 0x0064(r8)
0301     stw r4, 0x006c(r8)
0302 
0303     /* Rev 1 of the 8313 has problems with wakeup events that are
0304      * pending during the transition to deep sleep state (such as if
0305      * the PCI host sets the state to D3 and then D0 in rapid
0306      * succession).  This check shrinks the race window somewhat.
0307      *
0308      * See erratum PCI23, though the problem is not limited
0309      * to PCI.
0310      */
0311 
0312     lwz r3, 0x0b04(r8)
0313     andi.   r3, r3, 1
0314     bne-    mpc83xx_deep_resume
0315 
0316     /* Move IMMR back to the default location, following the
0317      * procedure specified in the MPC8313 manual.
0318      */
0319     lwz r4, IMMRBAR_BASE(r8)
0320     isync
0321     lis r4, DEFAULT_IMMR_VALUE@h
0322     stw r4, IMMRBAR_BASE(r8)
0323     lis r4, KERNELBASE@h
0324     lwz r4, 0(r4)
0325     isync
0326     lwz r4, IMMRBAR_BASE(r9)
0327     mr  r8, r9
0328     isync
0329 
0330     /* Check the Reset Configuration Word to see whether flash needs
0331      * to be mapped at a low address or a high address.
0332      */
0333 
0334     lwz r4, 0x0904(r8)
0335     andis.  r4, r4, 0x0400
0336     li  r4, 0
0337     beq boot_low
0338     lis r4, 0xff80
0339 boot_low:
0340     stw r4, 0x0020(r8)
0341     lis r7, 0x8000
0342     ori r7, r7, 0x0016
0343 
0344     mfspr   r5, SPRN_HID0
0345     rlwinm  r5, r5, 0, ~(HID0_DOZE | HID0_NAP)
0346     oris    r5, r5, HID0_SLEEP@h
0347     mtspr   SPRN_HID0, r5
0348     isync
0349 
0350     mfmsr   r5
0351     oris    r5, r5, MSR_POW@h
0352 
0353     /* Enable the flash mapping at the appropriate address.  This
0354      * mapping will override the RAM mapping if booting low, so there's
0355      * no need to disable the latter.  This must be done inside the same
0356      * cache line as setting MSR_POW, so that no instruction fetches
0357      * from RAM happen after the flash mapping is turned on.
0358      */
0359 
0360     .align  5
0361     stw r7, 0x0024(r8)
0362     sync
0363     isync
0364     mtmsr   r5
0365     isync
0366 1:  b   1b
0367 
0368 mpc83xx_deep_resume:
0369     lis r4, 1f@h
0370     ori r4, r4, 1f@l
0371     tophys(r4, r4)
0372     mtsrr0  r4
0373 
0374     mfmsr   r4
0375     rlwinm  r4, r4, 0, ~(MSR_IR | MSR_DR)
0376     mtsrr1  r4
0377 
0378     rfi
0379 
0380 1:  tlbia
0381     bl  __inval_enable_L1
0382 
0383     lis r3, mpc83xx_sleep_save_area@h
0384     ori r3, r3, mpc83xx_sleep_save_area@l
0385     tophys(r3, r3)
0386 
0387     lwz r5, SS_MEMSAVE+0(r3)
0388     lwz r6, SS_MEMSAVE+4(r3)
0389 
0390     stw r5, 0(0)
0391     stw r6, 4(0)
0392 
0393     lwz r5, SS_HID+0(r3)
0394     lwz r6, SS_HID+4(r3)
0395     lwz r7, SS_HID+8(r3)
0396 
0397     mtspr   SPRN_HID0, r5
0398     mtspr   SPRN_HID1, r6
0399     mtspr   SPRN_HID2, r7
0400 
0401     lwz r4, SS_IABR+0(r3)
0402     lwz r5, SS_IABR+4(r3)
0403     lwz r6, SS_IBCR(r3)
0404     lwz r7, SS_DABR+0(r3)
0405     lwz r8, SS_DABR+4(r3)
0406     lwz r9, SS_DBCR(r3)
0407 
0408     mtspr   SPRN_IABR, r4
0409     mtspr   SPRN_IABR2, r5
0410     mtspr   SPRN_IBCR, r6
0411     mtspr   SPRN_DABR, r7
0412     mtspr   SPRN_DABR2, r8
0413     mtspr   SPRN_DBCR, r9
0414 
0415     li  r4, 0
0416     addi    r6, r3, SS_SR-4
0417 1:  lwzu    r5, 4(r6)
0418     mtsrin  r5, r4
0419     addis   r4, r4, 0x1000
0420     cmpwi   r4, 0
0421     bne 1b
0422 
0423     lwz r4, SS_DBAT+0x00(r3)
0424     lwz r5, SS_DBAT+0x04(r3)
0425     lwz r6, SS_DBAT+0x08(r3)
0426     lwz r7, SS_DBAT+0x0c(r3)
0427 
0428     mtspr   SPRN_DBAT0U, r4
0429     mtspr   SPRN_DBAT0L, r5
0430     mtspr   SPRN_DBAT1U, r6
0431     mtspr   SPRN_DBAT1L, r7
0432 
0433     lwz r4, SS_DBAT+0x10(r3)
0434     lwz r5, SS_DBAT+0x14(r3)
0435     lwz r6, SS_DBAT+0x18(r3)
0436     lwz r7, SS_DBAT+0x1c(r3)
0437 
0438     mtspr   SPRN_DBAT2U, r4
0439     mtspr   SPRN_DBAT2L, r5
0440     mtspr   SPRN_DBAT3U, r6
0441     mtspr   SPRN_DBAT3L, r7
0442 
0443     lwz r4, SS_DBAT+0x20(r3)
0444     lwz r5, SS_DBAT+0x24(r3)
0445     lwz r6, SS_DBAT+0x28(r3)
0446     lwz r7, SS_DBAT+0x2c(r3)
0447 
0448     mtspr   SPRN_DBAT4U, r4
0449     mtspr   SPRN_DBAT4L, r5
0450     mtspr   SPRN_DBAT5U, r6
0451     mtspr   SPRN_DBAT5L, r7
0452 
0453     lwz r4, SS_DBAT+0x30(r3)
0454     lwz r5, SS_DBAT+0x34(r3)
0455     lwz r6, SS_DBAT+0x38(r3)
0456     lwz r7, SS_DBAT+0x3c(r3)
0457 
0458     mtspr   SPRN_DBAT6U, r4
0459     mtspr   SPRN_DBAT6L, r5
0460     mtspr   SPRN_DBAT7U, r6
0461     mtspr   SPRN_DBAT7L, r7
0462 
0463     lwz r4, SS_IBAT+0x00(r3)
0464     lwz r5, SS_IBAT+0x04(r3)
0465     lwz r6, SS_IBAT+0x08(r3)
0466     lwz r7, SS_IBAT+0x0c(r3)
0467 
0468     mtspr   SPRN_IBAT0U, r4
0469     mtspr   SPRN_IBAT0L, r5
0470     mtspr   SPRN_IBAT1U, r6
0471     mtspr   SPRN_IBAT1L, r7
0472 
0473     lwz r4, SS_IBAT+0x10(r3)
0474     lwz r5, SS_IBAT+0x14(r3)
0475     lwz r6, SS_IBAT+0x18(r3)
0476     lwz r7, SS_IBAT+0x1c(r3)
0477 
0478     mtspr   SPRN_IBAT2U, r4
0479     mtspr   SPRN_IBAT2L, r5
0480     mtspr   SPRN_IBAT3U, r6
0481     mtspr   SPRN_IBAT3L, r7
0482 
0483     lwz r4, SS_IBAT+0x20(r3)
0484     lwz r5, SS_IBAT+0x24(r3)
0485     lwz r6, SS_IBAT+0x28(r3)
0486     lwz r7, SS_IBAT+0x2c(r3)
0487 
0488     mtspr   SPRN_IBAT4U, r4
0489     mtspr   SPRN_IBAT4L, r5
0490     mtspr   SPRN_IBAT5U, r6
0491     mtspr   SPRN_IBAT5L, r7
0492 
0493     lwz r4, SS_IBAT+0x30(r3)
0494     lwz r5, SS_IBAT+0x34(r3)
0495     lwz r6, SS_IBAT+0x38(r3)
0496     lwz r7, SS_IBAT+0x3c(r3)
0497 
0498     mtspr   SPRN_IBAT6U, r4
0499     mtspr   SPRN_IBAT6L, r5
0500     mtspr   SPRN_IBAT7U, r6
0501     mtspr   SPRN_IBAT7L, r7
0502 
0503     lwz r4, SS_SPRG+16(r3)
0504     lwz r5, SS_SPRG+20(r3)
0505     lwz r6, SS_SPRG+24(r3)
0506     lwz r7, SS_SPRG+28(r3)
0507 
0508     mtspr   SPRN_SPRG4, r4
0509     mtspr   SPRN_SPRG5, r5
0510     mtspr   SPRN_SPRG6, r6
0511     mtspr   SPRN_SPRG7, r7
0512 
0513     lwz r4, SS_SPRG+0(r3)
0514     lwz r5, SS_SPRG+4(r3)
0515     lwz r6, SS_SPRG+8(r3)
0516     lwz r7, SS_SPRG+12(r3)
0517     lwz r8, SS_SDR1(r3)
0518 
0519     mtspr   SPRN_SPRG0, r4
0520     mtspr   SPRN_SPRG1, r5
0521     mtspr   SPRN_SPRG2, r6
0522     mtspr   SPRN_SPRG3, r7
0523     mtsdr1  r8
0524 
0525     lwz r4, SS_MSR(r3)
0526     lwz r5, SS_LR(r3)
0527     lwz r6, SS_CR(r3)
0528     lwz r1, SS_SP(r3)
0529     lwz r2, SS_R2(r3)
0530 
0531     mtsrr1  r4
0532     mtsrr0  r5
0533     mtcr    r6
0534 
0535     li  r4, 0
0536     mtspr   SPRN_TBWL, r4
0537 
0538     lwz r4, SS_TB+0(r3)
0539     lwz r5, SS_TB+4(r3)
0540 
0541     mtspr   SPRN_TBWU, r4
0542     mtspr   SPRN_TBWL, r5
0543 
0544     lmw r12, SS_GPREG(r3)
0545 
0546     /* Kick decrementer */
0547     li  r0, 1
0548     mtdec   r0
0549 
0550     rfi
0551 _ASM_NOKPROBE_SYMBOL(mpc83xx_deep_resume)