upload tizen1.0 source
[kernel/linux-2.6.36.git] / arch / arm / mach-s5pv310 / sleep.S
1 /* linux/arch/arm/mach-s5pv310/sleep.S
2  *
3  * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4  *              http://www.samsung.com
5  *
6  * S5PV310 power Manager (Suspend-To-RAM) support
7  * Based on S3C2410 sleep code by:
8  *      Ben Dooks, (c) 2004 Simtec Electronics
9  *
10  * Based on PXA/SA1100 sleep code by:
11  *      Nicolas Pitre, (c) 2002 Monta Vista Software Inc
12  *      Cliff Brake, (c) 2001
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27 */
28
29 #include <linux/linkage.h>
30 #include <asm/assembler.h>
31 #include <asm/memory.h>
32 #include <asm/system.h>
33
34 #include <mach/regs-clock.h>
35 #include <mach/map.h>
36
37         .text
38
39         /* s3c_cpu_save
40          *
41          * entry:
42          *      r0 = save address (virtual addr of s3c_sleep_save_phys)
43         */
44
45 ENTRY(s3c_cpu_save)
46
47         stmfd   sp!, { r3 - r12, lr }
48
49         mrc     p15, 0, r4, c13, c0, 1  @ Context ID
50         mrc     p15, 0, r5, c3, c0, 0   @ Domain ID
51         mrc     p15, 0, r6, c2, c0, 0   @ Translation Table BASE0
52         mrc     p15, 0, r7, c2, c0, 1   @ Translation Table BASE1
53         mrc     p15, 0, r8, c2, c0, 2   @ Translation Table Control
54         mrc     p15, 0, r9, c1, c0, 0   @ Control register
55         mrc     p15, 0, r10, c1, c0, 1  @ Auxiliary control register
56         mrc     p15, 0, r11, c1, c0, 2  @ Co-processor access controls
57         mrc     p15, 0, r12, c10, c2, 0 @ Read PRRR
58         mrc     p15, 0, r3, c10, c2, 1  @ READ NMRR
59
60         stmia   r0!, { r3 - r13 }
61
62         mrs     r2, spsr
63         str     r2, [r0], #4
64
65         mrc     p15, 0, r3, c15, c0, 0  @ read power control register
66         str     r3, [r0], #4
67
68         mrc     p15, 0, r3, c15, c0, 1  @ read diagnostic register
69         str     r3, [r0], #4
70
71         mov     r2, r0
72
73         ldr     r0, =S5P_INFORM1
74         ldr     r0, [r0]
75         ldr     r1 ,=S5P_CHECK_SLEEP
76         cmp     r0, r1
77         bne     aftr_mode
78
79         bl      s3c_pm_cb_flushcache
80
81         bl      s5pv310_cpu_suspend
82
83         mov     r0, #0
84         ldmfd   sp!, { r3 - r12, pc }
85
86 aftr_mode:
87
88 #if defined(CONFIG_CPU_IDLE)
89         mov     r0, r13
90
91         /* r0 : Virtual address of current stack */
92         bl      s5p_aftr_cache_clean
93
94         bl      s5pv310_set_core0_pwroff
95         /*
96          * early wakeup condition
97          * return value is "0"
98          */
99         mov     r0, #0
100         ldmfd   sp!, { r3 - r12, pc }
101
102 #else
103         b       .
104 #endif
105 resume_with_mmu:
106         ldr     r0, =S5P_INFORM1
107         ldr     r0, [r0]
108         ldr     r1 ,=S5P_CHECK_SLEEP
109         cmp     r0, r1
110         bne     skip
111
112         ldr     r9, =(PAGE_OFFSET - PHYS_OFFSET)
113         add     r4, r4, r9
114         str     r12, [r4]
115 skip:
116         mov     r0, #1
117         ldmfd   sp!, { r3 - r12, pc }
118
119         .ltorg
120
121         .data
122
123         .global s3c_sleep_save_phys
124 s3c_sleep_save_phys:
125         .word   0
126
127         /* sleep magic, to allow the bootloader to check for an valid
128          * image to resume to. Must be the first word before the
129          * s3c_cpu_resume entry.
130         */
131
132         .word   0x2bedf00d
133
134         /* s3c_cpu_resume
135          *
136          * resume code entry for bootloader to call
137          *
138          * we must put this code here in the data segment as we have no
139          * other way of restoring the stack pointer after sleep, and we
140          * must not write to the code segment (code is read-only)
141         */
142
143 ENTRY(s3c_cpu_resume)
144         mov     r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
145         msr     cpsr_cxsf, r0
146
147         mov     r1, #0
148         mcr     p15, 0, r1, c8, c7, 0           @ invalidate TLBs
149         mcr     p15, 0, r1, c7, c5, 0           @ invalidate I Cache
150         dmb
151
152         ldr     r0, s3c_sleep_save_phys         @ address of restore block
153         ldmia   r0!, { r3 - r13 }
154
155         ldr     r1, [r0], #4
156         msr     spsr_cxsf, r1
157
158         dsb
159
160         ldr     r1, [r0], #4
161         mcr     p15, 0, r1, c15, c0, 0          @ write power control register
162
163         ldr     r1, [r0], #4
164         mcr     p15, 0, r1, c15, c0, 1          @ write diagnostic register
165
166         mcr     p15, 0, r4, c13, c0, 1          @ Context ID
167         mcr     p15, 0, r5, c3, c0, 0           @ Domain ID
168
169         mcr     p15, 0, r8, c2, c0, 2           @ Translation Table Control
170         mcr     p15, 0, r7, c2, c0, 1           @ Translation Table BASE1
171         mcr     p15, 0, r6, c2, c0, 0           @ Translation Table BASE0
172
173         mcr     p15, 0, r10, c1, c0, 1          @ Auxiliary control register
174
175         mov     r0, #0
176         mcr     p15, 0, r0, c8, c7, 0           @ Invalidate I & D TLB
177
178         mov     r0, #0                          @ restore copro access
179         mcr     p15, 0, r11, c1, c0, 2          @ Co-processor access
180         mcr     p15, 0, r0, c7, c5, 4
181
182         mcr     p15, 0, r12, c10, c2, 0         @ write PRRR
183         mcr     p15, 0, r3, c10, c2, 1          @ write NMRR
184
185         ldr     r0, =0x10020804
186         ldr     r0, [r0]
187         ldr     r1 ,=S5P_CHECK_SLEEP
188         cmp     r0, r1
189         beq     sleep_wakeup
190
191         /* SCU enable */
192         ldr     r1, =0x10500000
193         ldr     r0, [r1]
194         orr     r0, r0, #1
195         orr     r0, r0, #(1 << 5)
196         str     r0, [r1]
197
198         /* Outer cache TAG,DATA latency */
199         ldr     r1, =0x10502000
200         mov     r0, #0x110
201         str     r0, [r1, #0x108]
202         str     r0, [r1, #0x10C]
203
204         /* L2 cache prefetch control register */
205         ldr     r0, =0x30000007
206         str     r0, [r1, #0xF60]
207
208         /* Power control register setting*/
209         mov     r0, #0x3
210         str     r0, [r1, #0xF80]
211
212         ldr     r0, [r1, #0x104]
213         ldr     r2, =0x7c470001
214         ldr     r3, =0xc200ffff
215
216         and     r0, r0, r3
217         orr     r0, r0, r2
218         str     r0, [r1, #0x104]
219
220         /* Enable L2 cache */
221         mov     r0, #1
222         str     r0, [r1, #0x100]
223         b       common_wakeup
224
225 sleep_wakeup:
226         mov     r4, r6
227         mov     r4, r4, LSR #14
228         mov     r4, r4, LSL #14
229
230         ldr     r11, =0x10020800
231         ldr     r10, [r11, #0]
232         mov     r10, r10, LSR #18
233         bic     r10, r10, #0x3
234         orr     r4, r4, r10
235
236         mov     r10, r10, LSL #18
237         ldr     r5, =0x40e
238         orr     r10, r10, r5
239
240         ldr     r12, [r4]
241         str     r10, [r4]
242
243 common_wakeup:
244         isb
245         ldr     r2, =resume_with_mmu
246         mcr     p15, 0, r9, c1, c0, 0           @ turn on MMU, etc
247
248         nop
249         nop
250         nop
251         nop
252         nop                                     @ second-to-last before mmu
253
254         mov     pc, r2                          @ go back to virtual address
255
256         .ltorg
257