Path: blob/master/arch/powerpc/platforms/83xx/suspend-asm.S
10819 views
/*1* Enter and leave deep sleep state on MPC83xx2*3* Copyright (c) 2006-2008 Freescale Semiconductor, Inc.4* Author: Scott Wood <[email protected]>5*6* This program is free software; you can redistribute it and/or modify it7* under the terms of the GNU General Public License version 2 as published8* by the Free Software Foundation.9*/1011#include <asm/page.h>12#include <asm/ppc_asm.h>13#include <asm/reg.h>14#include <asm/asm-offsets.h>1516#define SS_MEMSAVE 0x00 /* First 8 bytes of RAM */17#define SS_HID 0x08 /* 3 HIDs */18#define SS_IABR 0x14 /* 2 IABRs */19#define SS_IBCR 0x1c20#define SS_DABR 0x20 /* 2 DABRs */21#define SS_DBCR 0x2822#define SS_SP 0x2c23#define SS_SR 0x30 /* 16 segment registers */24#define SS_R2 0x7025#define SS_MSR 0x7426#define SS_SDR1 0x7827#define SS_LR 0x7c28#define SS_SPRG 0x80 /* 4 SPRGs */29#define SS_DBAT 0x90 /* 8 DBATs */30#define SS_IBAT 0xd0 /* 8 IBATs */31#define SS_TB 0x11032#define SS_CR 0x11833#define SS_GPREG 0x11c /* r12-r31 */34#define STATE_SAVE_SIZE 0x16c3536.section .data37.align 53839mpc83xx_sleep_save_area:40.space STATE_SAVE_SIZE41immrbase:42.long 04344.section .text45.align 54647/* r3 = physical address of IMMR */48_GLOBAL(mpc83xx_enter_deep_sleep)49lis r4, immrbase@ha50stw r3, immrbase@l(r4)5152/* The first 2 words of memory are used to communicate with the53* bootloader, to tell it how to resume.54*55* The first word is the magic number 0xf5153ae5, and the second56* is the pointer to mpc83xx_deep_resume.57*58* The original content of these two words is saved in SS_MEMSAVE.59*/6061lis r3, mpc83xx_sleep_save_area@h62ori r3, r3, mpc83xx_sleep_save_area@l6364lis r4, KERNELBASE@h65lwz r5, 0(r4)66lwz r6, 4(r4)6768stw r5, SS_MEMSAVE+0(r3)69stw r6, SS_MEMSAVE+4(r3)7071mfspr r5, SPRN_HID072mfspr r6, SPRN_HID173mfspr r7, SPRN_HID27475stw r5, SS_HID+0(r3)76stw r6, SS_HID+4(r3)77stw r7, SS_HID+8(r3)7879mfspr r4, SPRN_IABR80mfspr r5, SPRN_IABR281mfspr r6, SPRN_IBCR82mfspr r7, SPRN_DABR83mfspr r8, SPRN_DABR284mfspr r9, SPRN_DBCR8586stw r4, SS_IABR+0(r3)87stw r5, SS_IABR+4(r3)88stw r6, SS_IBCR(r3)89stw r7, SS_DABR+0(r3)90stw r8, SS_DABR+4(r3)91stw r9, SS_DBCR(r3)9293mfspr r4, SPRN_SPRG094mfspr r5, SPRN_SPRG195mfspr r6, SPRN_SPRG296mfspr r7, SPRN_SPRG397mfsdr1 r89899stw r4, SS_SPRG+0(r3)100stw r5, SS_SPRG+4(r3)101stw r6, SS_SPRG+8(r3)102stw r7, SS_SPRG+12(r3)103stw r8, SS_SDR1(r3)104105mfspr r4, SPRN_DBAT0U106mfspr r5, SPRN_DBAT0L107mfspr r6, SPRN_DBAT1U108mfspr r7, SPRN_DBAT1L109110stw r4, SS_DBAT+0x00(r3)111stw r5, SS_DBAT+0x04(r3)112stw r6, SS_DBAT+0x08(r3)113stw r7, SS_DBAT+0x0c(r3)114115mfspr r4, SPRN_DBAT2U116mfspr r5, SPRN_DBAT2L117mfspr r6, SPRN_DBAT3U118mfspr r7, SPRN_DBAT3L119120stw r4, SS_DBAT+0x10(r3)121stw r5, SS_DBAT+0x14(r3)122stw r6, SS_DBAT+0x18(r3)123stw r7, SS_DBAT+0x1c(r3)124125mfspr r4, SPRN_DBAT4U126mfspr r5, SPRN_DBAT4L127mfspr r6, SPRN_DBAT5U128mfspr r7, SPRN_DBAT5L129130stw r4, SS_DBAT+0x20(r3)131stw r5, SS_DBAT+0x24(r3)132stw r6, SS_DBAT+0x28(r3)133stw r7, SS_DBAT+0x2c(r3)134135mfspr r4, SPRN_DBAT6U136mfspr r5, SPRN_DBAT6L137mfspr r6, SPRN_DBAT7U138mfspr r7, SPRN_DBAT7L139140stw r4, SS_DBAT+0x30(r3)141stw r5, SS_DBAT+0x34(r3)142stw r6, SS_DBAT+0x38(r3)143stw r7, SS_DBAT+0x3c(r3)144145mfspr r4, SPRN_IBAT0U146mfspr r5, SPRN_IBAT0L147mfspr r6, SPRN_IBAT1U148mfspr r7, SPRN_IBAT1L149150stw r4, SS_IBAT+0x00(r3)151stw r5, SS_IBAT+0x04(r3)152stw r6, SS_IBAT+0x08(r3)153stw r7, SS_IBAT+0x0c(r3)154155mfspr r4, SPRN_IBAT2U156mfspr r5, SPRN_IBAT2L157mfspr r6, SPRN_IBAT3U158mfspr r7, SPRN_IBAT3L159160stw r4, SS_IBAT+0x10(r3)161stw r5, SS_IBAT+0x14(r3)162stw r6, SS_IBAT+0x18(r3)163stw r7, SS_IBAT+0x1c(r3)164165mfspr r4, SPRN_IBAT4U166mfspr r5, SPRN_IBAT4L167mfspr r6, SPRN_IBAT5U168mfspr r7, SPRN_IBAT5L169170stw r4, SS_IBAT+0x20(r3)171stw r5, SS_IBAT+0x24(r3)172stw r6, SS_IBAT+0x28(r3)173stw r7, SS_IBAT+0x2c(r3)174175mfspr r4, SPRN_IBAT6U176mfspr r5, SPRN_IBAT6L177mfspr r6, SPRN_IBAT7U178mfspr r7, SPRN_IBAT7L179180stw r4, SS_IBAT+0x30(r3)181stw r5, SS_IBAT+0x34(r3)182stw r6, SS_IBAT+0x38(r3)183stw r7, SS_IBAT+0x3c(r3)184185mfmsr r4186mflr r5187mfcr r6188189stw r4, SS_MSR(r3)190stw r5, SS_LR(r3)191stw r6, SS_CR(r3)192stw r1, SS_SP(r3)193stw r2, SS_R2(r3)1941951: mftbu r4196mftb r5197mftbu r6198cmpw r4, r6199bne 1b200201stw r4, SS_TB+0(r3)202stw r5, SS_TB+4(r3)203204stmw r12, SS_GPREG(r3)205206li r4, 0207addi r6, r3, SS_SR-42081: mfsrin r5, r4209stwu r5, 4(r6)210addis r4, r4, 0x1000211cmpwi r4, 0212bne 1b213214/* Disable machine checks and critical exceptions */215mfmsr r4216rlwinm r4, r4, 0, ~MSR_CE217rlwinm r4, r4, 0, ~MSR_ME218mtmsr r4219isync220221#define TMP_VIRT_IMMR 0xf0000000222#define DEFAULT_IMMR_VALUE 0xff400000223#define IMMRBAR_BASE 0x0000224225lis r4, immrbase@ha226lwz r4, immrbase@l(r4)227228/* Use DBAT0 to address the current IMMR space */229230ori r4, r4, 0x002a231mtspr SPRN_DBAT0L, r4232lis r8, TMP_VIRT_IMMR@h233ori r4, r8, 0x001e /* 1 MByte accessible from Kernel Space only */234mtspr SPRN_DBAT0U, r4235isync236237/* Use DBAT1 to address the original IMMR space */238239lis r4, DEFAULT_IMMR_VALUE@h240ori r4, r4, 0x002a241mtspr SPRN_DBAT1L, r4242lis r9, (TMP_VIRT_IMMR + 0x01000000)@h243ori r4, r9, 0x001e /* 1 MByte accessible from Kernel Space only */244mtspr SPRN_DBAT1U, r4245isync246247/* Use DBAT2 to address the beginning of RAM. This isn't done248* using the normal virtual mapping, because with page debugging249* enabled it will be read-only.250*/251252li r4, 0x0002253mtspr SPRN_DBAT2L, r4254lis r4, KERNELBASE@h255ori r4, r4, 0x001e /* 1 MByte accessible from Kernel Space only */256mtspr SPRN_DBAT2U, r4257isync258259/* Flush the cache with our BAT, as there will be TLB misses260* otherwise if page debugging is enabled, and these misses261* will disturb the PLRU algorithm.262*/263264bl __flush_disable_L1265266/* Keep the i-cache enabled, so the hack below for low-boot267* flash will work.268*/269mfspr r3, SPRN_HID0270ori r3, r3, HID0_ICE271mtspr SPRN_HID0, r3272isync273274lis r6, 0xf515275ori r6, r6, 0x3ae5276277lis r7, mpc83xx_deep_resume@h278ori r7, r7, mpc83xx_deep_resume@l279tophys(r7, r7)280281lis r5, KERNELBASE@h282stw r6, 0(r5)283stw r7, 4(r5)284285/* Reset BARs */286287li r4, 0288stw r4, 0x0024(r8)289stw r4, 0x002c(r8)290stw r4, 0x0034(r8)291stw r4, 0x003c(r8)292stw r4, 0x0064(r8)293stw r4, 0x006c(r8)294295/* Rev 1 of the 8313 has problems with wakeup events that are296* pending during the transition to deep sleep state (such as if297* the PCI host sets the state to D3 and then D0 in rapid298* succession). This check shrinks the race window somewhat.299*300* See erratum PCI23, though the problem is not limited301* to PCI.302*/303304lwz r3, 0x0b04(r8)305andi. r3, r3, 1306bne- mpc83xx_deep_resume307308/* Move IMMR back to the default location, following the309* procedure specified in the MPC8313 manual.310*/311lwz r4, IMMRBAR_BASE(r8)312isync313lis r4, DEFAULT_IMMR_VALUE@h314stw r4, IMMRBAR_BASE(r8)315lis r4, KERNELBASE@h316lwz r4, 0(r4)317isync318lwz r4, IMMRBAR_BASE(r9)319mr r8, r9320isync321322/* Check the Reset Configuration Word to see whether flash needs323* to be mapped at a low address or a high address.324*/325326lwz r4, 0x0904(r8)327andis. r4, r4, 0x0400328li r4, 0329beq boot_low330lis r4, 0xff80331boot_low:332stw r4, 0x0020(r8)333lis r7, 0x8000334ori r7, r7, 0x0016335336mfspr r5, SPRN_HID0337rlwinm r5, r5, 0, ~(HID0_DOZE | HID0_NAP)338oris r5, r5, HID0_SLEEP@h339mtspr SPRN_HID0, r5340isync341342mfmsr r5343oris r5, r5, MSR_POW@h344345/* Enable the flash mapping at the appropriate address. This346* mapping will override the RAM mapping if booting low, so there's347* no need to disable the latter. This must be done inside the same348* cache line as setting MSR_POW, so that no instruction fetches349* from RAM happen after the flash mapping is turned on.350*/351352.align 5353stw r7, 0x0024(r8)354sync355isync356mtmsr r5357isync3581: b 1b359360mpc83xx_deep_resume:361lis r4, 1f@h362ori r4, r4, 1f@l363tophys(r4, r4)364mtsrr0 r4365366mfmsr r4367rlwinm r4, r4, 0, ~(MSR_IR | MSR_DR)368mtsrr1 r4369370rfi3713721: tlbia373bl __inval_enable_L1374375lis r3, mpc83xx_sleep_save_area@h376ori r3, r3, mpc83xx_sleep_save_area@l377tophys(r3, r3)378379lwz r5, SS_MEMSAVE+0(r3)380lwz r6, SS_MEMSAVE+4(r3)381382stw r5, 0(0)383stw r6, 4(0)384385lwz r5, SS_HID+0(r3)386lwz r6, SS_HID+4(r3)387lwz r7, SS_HID+8(r3)388389mtspr SPRN_HID0, r5390mtspr SPRN_HID1, r6391mtspr SPRN_HID2, r7392393lwz r4, SS_IABR+0(r3)394lwz r5, SS_IABR+4(r3)395lwz r6, SS_IBCR(r3)396lwz r7, SS_DABR+0(r3)397lwz r8, SS_DABR+4(r3)398lwz r9, SS_DBCR(r3)399400mtspr SPRN_IABR, r4401mtspr SPRN_IABR2, r5402mtspr SPRN_IBCR, r6403mtspr SPRN_DABR, r7404mtspr SPRN_DABR2, r8405mtspr SPRN_DBCR, r9406407li r4, 0408addi r6, r3, SS_SR-44091: lwzu r5, 4(r6)410mtsrin r5, r4411addis r4, r4, 0x1000412cmpwi r4, 0413bne 1b414415lwz r4, SS_DBAT+0x00(r3)416lwz r5, SS_DBAT+0x04(r3)417lwz r6, SS_DBAT+0x08(r3)418lwz r7, SS_DBAT+0x0c(r3)419420mtspr SPRN_DBAT0U, r4421mtspr SPRN_DBAT0L, r5422mtspr SPRN_DBAT1U, r6423mtspr SPRN_DBAT1L, r7424425lwz r4, SS_DBAT+0x10(r3)426lwz r5, SS_DBAT+0x14(r3)427lwz r6, SS_DBAT+0x18(r3)428lwz r7, SS_DBAT+0x1c(r3)429430mtspr SPRN_DBAT2U, r4431mtspr SPRN_DBAT2L, r5432mtspr SPRN_DBAT3U, r6433mtspr SPRN_DBAT3L, r7434435lwz r4, SS_DBAT+0x20(r3)436lwz r5, SS_DBAT+0x24(r3)437lwz r6, SS_DBAT+0x28(r3)438lwz r7, SS_DBAT+0x2c(r3)439440mtspr SPRN_DBAT4U, r4441mtspr SPRN_DBAT4L, r5442mtspr SPRN_DBAT5U, r6443mtspr SPRN_DBAT5L, r7444445lwz r4, SS_DBAT+0x30(r3)446lwz r5, SS_DBAT+0x34(r3)447lwz r6, SS_DBAT+0x38(r3)448lwz r7, SS_DBAT+0x3c(r3)449450mtspr SPRN_DBAT6U, r4451mtspr SPRN_DBAT6L, r5452mtspr SPRN_DBAT7U, r6453mtspr SPRN_DBAT7L, r7454455lwz r4, SS_IBAT+0x00(r3)456lwz r5, SS_IBAT+0x04(r3)457lwz r6, SS_IBAT+0x08(r3)458lwz r7, SS_IBAT+0x0c(r3)459460mtspr SPRN_IBAT0U, r4461mtspr SPRN_IBAT0L, r5462mtspr SPRN_IBAT1U, r6463mtspr SPRN_IBAT1L, r7464465lwz r4, SS_IBAT+0x10(r3)466lwz r5, SS_IBAT+0x14(r3)467lwz r6, SS_IBAT+0x18(r3)468lwz r7, SS_IBAT+0x1c(r3)469470mtspr SPRN_IBAT2U, r4471mtspr SPRN_IBAT2L, r5472mtspr SPRN_IBAT3U, r6473mtspr SPRN_IBAT3L, r7474475lwz r4, SS_IBAT+0x20(r3)476lwz r5, SS_IBAT+0x24(r3)477lwz r6, SS_IBAT+0x28(r3)478lwz r7, SS_IBAT+0x2c(r3)479480mtspr SPRN_IBAT4U, r4481mtspr SPRN_IBAT4L, r5482mtspr SPRN_IBAT5U, r6483mtspr SPRN_IBAT5L, r7484485lwz r4, SS_IBAT+0x30(r3)486lwz r5, SS_IBAT+0x34(r3)487lwz r6, SS_IBAT+0x38(r3)488lwz r7, SS_IBAT+0x3c(r3)489490mtspr SPRN_IBAT6U, r4491mtspr SPRN_IBAT6L, r5492mtspr SPRN_IBAT7U, r6493mtspr SPRN_IBAT7L, r7494495lwz r4, SS_SPRG+0(r3)496lwz r5, SS_SPRG+4(r3)497lwz r6, SS_SPRG+8(r3)498lwz r7, SS_SPRG+12(r3)499lwz r8, SS_SDR1(r3)500501mtspr SPRN_SPRG0, r4502mtspr SPRN_SPRG1, r5503mtspr SPRN_SPRG2, r6504mtspr SPRN_SPRG3, r7505mtsdr1 r8506507lwz r4, SS_MSR(r3)508lwz r5, SS_LR(r3)509lwz r6, SS_CR(r3)510lwz r1, SS_SP(r3)511lwz r2, SS_R2(r3)512513mtsrr1 r4514mtsrr0 r5515mtcr r6516517li r4, 0518mtspr SPRN_TBWL, r4519520lwz r4, SS_TB+0(r3)521lwz r5, SS_TB+4(r3)522523mtspr SPRN_TBWU, r4524mtspr SPRN_TBWL, r5525526lmw r12, SS_GPREG(r3)527528/* Kick decrementer */529li r0, 1530mtdec r0531532rfi533534535