1/* linux/arch/arm/plat-s3c24xx/sleep.S 2 * 3 * Copyright (c) 2004 Simtec Electronics 4 * Ben Dooks <ben@simtec.co.uk> 5 * 6 * S3C2410 Power Manager (Suspend-To-RAM) support 7 * 8 * Based on PXA/SA1100 sleep code by: 9 * Nicolas Pitre, (c) 2002 Monta Vista Software Inc 10 * Cliff Brake, (c) 2001 11 * 12 * This program is free software; you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License as published by 14 * the Free Software Foundation; either version 2 of the License, or 15 * (at your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program; if not, write to the Free Software 24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25*/ 26 27#include <linux/linkage.h> 28#include <asm/assembler.h> 29#include <asm/hardware.h> 30#include <asm/arch/map.h> 31 32#include <asm/arch/regs-gpio.h> 33#include <asm/arch/regs-clock.h> 34#include <asm/arch/regs-mem.h> 35#include <asm/arch/regs-serial.h> 36 37/* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not 38 * reset the UART configuration, only enable if you really need this! 39*/ 40//#define CONFIG_DEBUG_RESUME 41 42 .text 43 44 /* s3c2410_cpu_save 45 * 46 * save enough of the CPU state to allow us to re-start 47 * pm.c code. as we store items like the sp/lr, we will 48 * end up returning from this function when the cpu resumes 49 * so the return value is set to mark this. 50 * 51 * This arangement means we avoid having to flush the cache 52 * from this code. 53 * 54 * entry: 55 * r0 = pointer to save block 56 * 57 * exit: 58 * r0 = 0 => we stored everything 59 * 1 => resumed from sleep 60 */ 61 62ENTRY(s3c2410_cpu_save) 63 stmfd sp!, { r4 - r12, lr } 64 65 @@ store co-processor registers 66 67 mrc p15, 0, r4, c13, c0, 0 @ PID 68 mrc p15, 0, r5, c3, c0, 0 @ Domain ID 69 mrc p15, 0, r6, c2, c0, 0 @ translation table base address 70 mrc p15, 0, r7, c1, c0, 0 @ control register 71 72 stmia r0, { r4 - r13 } 73 74 mov r0, #0 75 ldmfd sp, { r4 - r12, pc } 76 77 @@ return to the caller, after having the MMU 78 @@ turned on, this restores the last bits from the 79 @@ stack 80resume_with_mmu: 81 mov r0, #1 82 ldmfd sp!, { r4 - r12, pc } 83 84 .ltorg 85 86 @@ the next bits sit in the .data segment, even though they 87 @@ happen to be code... the s3c2410_sleep_save_phys needs to be 88 @@ accessed by the resume code before it can restore the MMU. 89 @@ This means that the variable has to be close enough for the 90 @@ code to read it... since the .text segment needs to be RO, 91 @@ the data segment can be the only place to put this code. 92 93 .data 94 95 .global s3c2410_sleep_save_phys 96s3c2410_sleep_save_phys: 97 .word 0 98 99 /* s3c2410_cpu_resume 100 * 101 * resume code entry for bootloader to call 102 * 103 * we must put this code here in the data segment as we have no 104 * other way of restoring the stack pointer after sleep, and we 105 * must not write to the code segment (code is read-only) 106 */ 107 108ENTRY(s3c2410_cpu_resume) 109 mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE 110 msr cpsr_c, r0 111 112 @@ load UART to allow us to print the two characters for 113 @@ resume debug 114 115 mov r2, #S3C24XX_PA_UART & 0xff000000 116 orr r2, r2, #S3C24XX_PA_UART & 0xff000 117 118 119#ifdef CONFIG_DEBUG_RESUME 120 mov r3, #'L' 121 strb r3, [ r2, #S3C2410_UTXH ] 1221001: 123 ldrb r14, [ r3, #S3C2410_UTRSTAT ] 124 tst r14, #S3C2410_UTRSTAT_TXE 125 beq 1001b 126#endif /* CONFIG_DEBUG_RESUME */ 127 128 mov r1, #0 129 mcr p15, 0, r1, c8, c7, 0 @@ invalidate I & D TLBs 130 mcr p15, 0, r1, c7, c7, 0 @@ invalidate I & D caches 131 132 ldr r0, s3c2410_sleep_save_phys @ address of restore block 133 ldmia r0, { r4 - r13 } 134 135 mcr p15, 0, r4, c13, c0, 0 @ PID 136 mcr p15, 0, r5, c3, c0, 0 @ Domain ID 137 mcr p15, 0, r6, c2, c0, 0 @ translation table base 138 139#ifdef CONFIG_DEBUG_RESUME 140 mov r3, #'R' 141 strb r3, [ r2, #S3C2410_UTXH ] 142#endif 143 144 ldr r2, =resume_with_mmu 145 mcr p15, 0, r7, c1, c0, 0 @ turn on MMU, etc 146 nop @ second-to-last before mmu 147 mov pc, r2 @ go back to virtual address 148 149 .ltorg 150