Merge branch 'topic/nomm' into for-linus
[pandora-kernel.git] / arch / arm / mach-s3c64xx / sleep.S
1 /* linux/arch/arm/plat-s3c64xx/sleep.S
2  *
3  * Copyright 2008 Openmoko, Inc.
4  * Copyright 2008 Simtec Electronics
5  *      Ben Dooks <ben@simtec.co.uk>
6  *      http://armlinux.simtec.co.uk/
7  *
8  * S3C64XX CPU sleep code
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13 */
14
15 #include <linux/linkage.h>
16 #include <asm/assembler.h>
17 #include <mach/map.h>
18
19 #undef S3C64XX_VA_GPIO
20 #define S3C64XX_VA_GPIO (0x0)
21
22 #include <mach/regs-gpio.h>
23 #include <mach/gpio-bank-n.h>
24
25 #define LL_UART (S3C_PA_UART + (0x400 * CONFIG_S3C_LOWLEVEL_UART_PORT))
26
27         .text
28
29         /* s3c_cpu_save
30          *
31          * Save enough processor state to allow the restart of the pm.c
32          * code after resume.
33          *
34          * entry:
35          *      r0 = pointer to the save block
36         */
37
38 ENTRY(s3c_cpu_save)
39         stmfd   sp!, { r4 - r12, lr }
40
41         mrc     p15, 0, r4, c13, c0, 0  @ FCSE/PID
42         mrc     p15, 0, r5, c3, c0, 0   @ Domain ID
43         mrc     p15, 0, r6, c2, c0, 0   @ Translation Table BASE0
44         mrc     p15, 0, r7, c2, c0, 1   @ Translation Table BASE1
45         mrc     p15, 0, r8, c2, c0, 2   @ Translation Table Control
46         mrc     p15, 0, r9, c1, c0, 0   @ Control register
47         mrc     p15, 0, r10, c1, c0, 1  @ Auxiliary control register
48         mrc     p15, 0, r11, c1, c0, 2  @ Co-processor access controls
49
50         stmia   r0, { r4 - r13 }        @ Save CP registers and SP
51
52         @@ save our state to ram
53         bl      s3c_pm_cb_flushcache
54
55         @@ call final suspend code
56         ldr     r0, =pm_cpu_sleep
57         ldr     pc, [r0]
58         
59         @@ return to the caller, after the MMU is turned on.
60         @@ restore the last bits of the stack and return.
61 resume_with_mmu:
62         ldmfd   sp!, { r4 - r12, pc }   @ return, from sp from s3c_cpu_save
63
64         .data
65
66         /* the next bit is code, but it requires easy access to the
67          * s3c_sleep_save_phys data before the MMU is switched on, so
68          * we store the code that needs this variable in the .data where
69          * the value can be written to (the .text segment is RO).
70         */
71
72         .global s3c_sleep_save_phys
73 s3c_sleep_save_phys:
74         .word   0
75
76         /* Sleep magic, the word before the resume entry point so that the
77          * bootloader can check for a resumeable image. */
78
79         .word   0x2bedf00d
80
81         /* s3c_cpu_reusme
82          *
83          * This is the entry point, stored by whatever method the bootloader
84          * requires to get the kernel runnign again. This code expects to be
85          * entered with no caches live and the MMU disabled. It will then
86          * restore the MMU and other basic CP registers saved and restart
87          * the kernel C code to finish the resume code.
88         */
89
90 ENTRY(s3c_cpu_resume)
91         msr     cpsr_c, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
92         ldr     r2, =LL_UART            /* for debug */
93
94 #ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
95         /* Initialise the GPIO state if we are debugging via the SMDK LEDs,
96          * as the uboot version supplied resets these to inputs during the
97          * resume checks.
98         */
99
100         ldr     r3, =S3C64XX_PA_GPIO
101         ldr     r0, [ r3, #S3C64XX_GPNCON ]
102         bic     r0, r0, #(S3C64XX_GPN_CONMASK(12) | S3C64XX_GPN_CONMASK(13) | \
103                           S3C64XX_GPN_CONMASK(14) | S3C64XX_GPN_CONMASK(15))
104         orr     r0, r0, #(S3C64XX_GPN_OUTPUT(12) | S3C64XX_GPN_OUTPUT(13) | \
105                           S3C64XX_GPN_OUTPUT(14) | S3C64XX_GPN_OUTPUT(15))
106         str     r0, [ r3, #S3C64XX_GPNCON ]
107
108         ldr     r0, [ r3, #S3C64XX_GPNDAT ]
109         bic     r0, r0, #0xf << 12                      @ GPN12..15
110         orr     r0, r0, #1 << 15                        @ GPN15
111         str     r0, [ r3, #S3C64XX_GPNDAT ]
112 #endif
113
114         /* __v6_setup from arch/arm/mm/proc-v6.S, ensure that the caches
115          * are thoroughly cleaned just in case the bootloader didn't do it
116          * for us. */
117         mov     r0, #0
118         mcr     p15, 0, r0, c7, c14, 0          @ clean+invalidate D cache
119         mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
120         mcr     p15, 0, r0, c7, c15, 0          @ clean+invalidate cache
121         mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
122         @@mcr   p15, 0, r0, c8, c7, 0           @ invalidate I + D TLBs
123         @@mcr   p15, 0, r0, c7, c7, 0           @ Invalidate I + D caches
124
125         ldr     r0, s3c_sleep_save_phys
126         ldmia   r0, { r4 - r13 }
127
128         mcr     p15, 0, r4, c13, c0, 0  @ FCSE/PID
129         mcr     p15, 0, r5, c3, c0, 0   @ Domain ID
130         mcr     p15, 0, r6, c2, c0, 0   @ Translation Table BASE0
131         mcr     p15, 0, r7, c2, c0, 1   @ Translation Table BASE1
132         mcr     p15, 0, r8, c2, c0, 2   @ Translation Table Control
133         mcr     p15, 0, r10, c1, c0, 1  @ Auxiliary control register
134
135         mov     r0, #0                  @ restore copro access controls
136         mcr     p15, 0, r11, c1, c0, 2  @ Co-processor access controls
137         mcr     p15, 0, r0, c7, c5, 4
138
139         ldr     r2, =resume_with_mmu
140         mcr     p15, 0, r9, c1, c0, 0           /* turn mmu back on */
141         nop
142         mov     pc, r2                          /* jump back */
143
144         .end