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 <mach/hardware.h> 30#include <mach/map.h> 31 32#include <mach/regs-gpio.h> 33#include <mach/regs-clock.h> 34#include <mach/regs-mem.h> 35#include <plat/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 /* s3c_cpu_save 45 * 46 * entry: 47 * r0 = save address (virtual addr of s3c_sleep_save_phys) 48 */ 49 50ENTRY(s3c_cpu_save) 51 stmfd sp!, { r4 - r12, lr } 52 53 @@ store co-processor registers 54 55 mrc p15, 0, r4, c13, c0, 0 @ PID 56 mrc p15, 0, r5, c3, c0, 0 @ Domain ID 57 mrc p15, 0, r6, c2, c0, 0 @ translation table base address 58 mrc p15, 0, r7, c1, c0, 0 @ control register 59 60 stmia r0, { r4 - r13 } 61 62 @@ write our state back to RAM 63 bl s3c_pm_cb_flushcache 64 65 @@ jump to final code to send system to sleep 66 ldr r0, =pm_cpu_sleep 67 @@ldr pc, [ r0 ] 68 ldr r0, [ r0 ] 69 mov pc, r0 70 71 @@ return to the caller, after having the MMU 72 @@ turned on, this restores the last bits from the 73 @@ stack 74resume_with_mmu: 75 ldmfd sp!, { r4 - r12, pc } 76 77 .ltorg 78 79 @@ the next bits sit in the .data segment, even though they 80 @@ happen to be code... the s3c_sleep_save_phys needs to be 81 @@ accessed by the resume code before it can restore the MMU. 82 @@ This means that the variable has to be close enough for the 83 @@ code to read it... since the .text segment needs to be RO, 84 @@ the data segment can be the only place to put this code. 85 86 .data 87 88 .global s3c_sleep_save_phys 89s3c_sleep_save_phys: 90 .word 0 91 92 93 /* sleep magic, to allow the bootloader to check for an valid 94 * image to resume to. Must be the first word before the 95 * s3c_cpu_resume entry. 96 */ 97 98 .word 0x2bedf00d 99 100 /* s3c_cpu_resume 101 * 102 * resume code entry for bootloader to call 103 * 104 * we must put this code here in the data segment as we have no 105 * other way of restoring the stack pointer after sleep, and we 106 * must not write to the code segment (code is read-only) 107 */ 108 109ENTRY(s3c_cpu_resume) 110 mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE 111 msr cpsr_c, r0 112 113 @@ load UART to allow us to print the two characters for 114 @@ resume debug 115 116 mov r2, #S3C24XX_PA_UART & 0xff000000 117 orr r2, r2, #S3C24XX_PA_UART & 0xff000 118 119 120#ifdef CONFIG_DEBUG_RESUME 121 mov r3, #'L' 122 strb r3, [ r2, #S3C2410_UTXH ] 1231001: 124 ldrb r14, [ r3, #S3C2410_UTRSTAT ] 125 tst r14, #S3C2410_UTRSTAT_TXE 126 beq 1001b 127#endif /* CONFIG_DEBUG_RESUME */ 128 129 mov r1, #0 130 mcr p15, 0, r1, c8, c7, 0 @@ invalidate I & D TLBs 131 mcr p15, 0, r1, c7, c7, 0 @@ invalidate I & D caches 132 133 ldr r0, s3c_sleep_save_phys @ address of restore block 134 ldmia r0, { r4 - r13 } 135 136 mcr p15, 0, r4, c13, c0, 0 @ PID 137 mcr p15, 0, r5, c3, c0, 0 @ Domain ID 138 mcr p15, 0, r6, c2, c0, 0 @ translation table base 139 140#ifdef CONFIG_DEBUG_RESUME 141 mov r3, #'R' 142 strb r3, [ r2, #S3C2410_UTXH ] 143#endif 144 145 ldr r2, =resume_with_mmu 146 mcr p15, 0, r7, c1, c0, 0 @ turn on MMU, etc 147 nop @ second-to-last before mmu 148 mov pc, r2 @ go back to virtual address 149 150 .ltorg 151