ARM: Tegra: Move cache disable to flush function
[linux-3.10.git] / arch / arm / mach-tegra / sleep.S
1 /*
2  * arch/arm/mach-tegra/sleep.S
3  *
4  * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved.
5  * Copyright (c) 2011, Google, Inc.
6  *
7  * Author: Colin Cross <ccross@android.com>
8  *         Gary King <gking@nvidia.com>
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 as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
18  * more details.
19  *
20  * You should have received a copy of the GNU General Public License along
21  * with this program; if not, write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
23  */
24
25 #include <linux/const.h>
26 #include <linux/init.h>
27 #include <linux/linkage.h>
28
29 #include <asm/assembler.h>
30 #include <asm/cache.h>
31 #include <asm/domain.h>
32 #include <asm/memory.h>
33 #include <asm/page.h>
34 #include <asm/ptrace.h>
35 #include <asm/asm-offsets.h>
36 #include <asm/glue-cache.h>
37 #include <asm/glue-proc.h>
38 #include <asm/cp15.h>
39
40 #include "iomap.h"
41
42 #include "sleep.h"
43 #include "flowctrl.h"
44
45 #define CLK_RESET_CCLK_BURST            0x20
46 #define CLK_RESET_CCLK_DIVIDER          0x24
47
48 #define TEGRA_PMC_VIRT          (TEGRA_PMC_BASE - IO_APB_PHYS + IO_APB_VIRT)
49
50 #define TEGRA_FLOW_CTRL_VIRT (TEGRA_FLOW_CTRL_BASE - IO_PPSB_PHYS \
51                                         + IO_PPSB_VIRT)
52
53 /*
54  * tegra_pen_lock
55  *
56  * spinlock implementation with no atomic test-and-set and no coherence
57  * using Peterson's algorithm on strongly-ordered registers
58  * used to synchronize a cpu waking up from wfi with entering lp2 on idle
59  *
60  * SCRATCH37 = r1 = !turn (inverted from Peterson's algorithm)
61  * on cpu 0:
62  * SCRATCH38 = r2 = flag[0]
63  * SCRATCH39 = r3 = flag[1]
64  * on cpu1:
65  * SCRATCH39 = r2 = flag[1]
66  * SCRATCH38 = r3 = flag[0]
67  *
68  * must be called with MMU on
69  * corrupts r0-r3, r12
70  */
71 ENTRY(tegra_pen_lock)
72         mov32   r3, TEGRA_PMC_VIRT
73         cpu_id  r0
74         add     r1, r3, #PMC_SCRATCH37
75         cmp     r0, #0
76         addeq   r2, r3, #PMC_SCRATCH38
77         addeq   r3, r3, #PMC_SCRATCH39
78         addne   r2, r3, #PMC_SCRATCH39
79         addne   r3, r3, #PMC_SCRATCH38
80
81         mov     r12, #1
82         str     r12, [r2]               @ flag[cpu] = 1
83         dsb
84         str     r12, [r1]               @ !turn = cpu
85 1:      dsb
86         ldr     r12, [r3]
87         cmp     r12, #1                 @ flag[!cpu] == 1?
88         ldreq   r12, [r1]
89         cmpeq   r12, r0                 @ !turn == cpu?
90         beq     1b                      @ while !turn == cpu && flag[!cpu] == 1
91
92         mov     pc, lr                  @ locked
93 ENDPROC(tegra_pen_lock)
94
95 ENTRY(tegra_pen_unlock)
96         dsb
97         mov32   r3, TEGRA_PMC_VIRT
98         cpu_id  r0
99         cmp     r0, #0
100         addeq   r2, r3, #PMC_SCRATCH38
101         addne   r2, r3, #PMC_SCRATCH39
102         mov     r12, #0
103         str     r12, [r2]
104         mov     pc, lr
105 ENDPROC(tegra_pen_unlock)
106
107
108 /*
109  * tegra_cpu_exit_coherency
110  *
111  * Exits SMP coherency.
112  * corrupts r4-r5
113  */
114 ENTRY(tegra_cpu_exit_coherency)
115         exit_smp r4, r5
116         mov     pc, lr
117 ENDPROC(tegra_cpu_exit_coherency)
118
119 /*
120  * tegra_flush_cache
121  *
122  * clean & invalidate inner cache
123  *
124  * Disable is needed before flush to prevent allocations during flush
125  * When cache is disabled, we cannot push to stack.
126  */
127 ENTRY(tegra_flush_cache)
128         stmfd   sp!, {r4-r5, r7, r9-r11, lr}
129         dmb                                     @ ensure ordering
130
131         /* Disable the data cache */
132         mrc     p15, 0, r2, c1, c0, 0
133         bic     r2, r2, #CR_C
134         dsb
135         mcr     p15, 0, r2, c1, c0, 0
136
137         bl      v7_flush_dcache_all
138
139         ldmfd   sp!, {r4-r5, r7, r9-r11, lr}
140         mov     pc, lr
141 ENDPROC(tegra_flush_cache)
142
143 /*
144  * tegra_flush_l1_cache
145  *
146  * clean & invalidate the L1 cache
147  *
148  * The flush_cache_all flushes all caches within level of coherence, this
149  * may not be desired if all we need is to flush L1 only. Therefore this
150  * function is implemented to flush the L1 cache only.
151  *
152  * Disable is needed before flush to prevent allocations during flush
153  * When cache is disabled, we cannot push to stack.
154  *
155  * Corrupted registers: r0-r7, r9-r11
156  */
157 ENTRY(tegra_flush_l1_cache)
158         stmfd   sp!, {r4-r5, r7, r9-r11, lr}
159         dmb                                     @ ensure ordering with previous memory accesses
160
161         /* Disable the data cache */
162         mrc     p15, 0, r2, c1, c0, 0
163         bic     r2, r2, #CR_C
164         dsb
165         mcr     p15, 0, r2, c1, c0, 0
166
167         mov     r10, #0
168 #ifdef CONFIG_PREEMPT
169         save_and_disable_irqs_notrace r9
170 #endif
171         mcr     p15, 2, r10, c0, c0, 0          @ select cache level 0
172         isb
173         mrc     p15, 1, r1, c0, c0, 0           @ read the new csidr
174 #ifdef CONFIG_PREEMPT
175         restore_irqs_notrace r9
176 #endif
177         and     r2, r1, #7                                      @ extract the length of the cache lines
178         add     r2, r2, #4                                      @ add 4 (line length offset)
179         ldr     r4, =0x3ff
180         ands    r4, r4, r1, lsr #3              @ find maximum number on the way size
181         clz     r5, r4                                          @ find bit position of way size increment
182         ldr     r7, =0x7fff
183         ands    r7, r7, r1, lsr #13             @ extract max number of the index size
184 1001:
185         mov     r9, r4                                          @ create working copy of max way size
186 1002:
187         orr     r11, r10, r9, lsl r5            @ factor way and cache number into r11
188         orr     r11, r11, r7, lsl r2            @ factor index number into r11
189         mcr     p15, 0, r11, c7, c14, 2         @ op=c10/c14, clean/flush by set/way
190         subs    r9, r9, #1                              @ decrement the way
191         bge     1002b
192         subs    r7, r7, #1                              @ decrement the index
193         bge     1001b
194         mcr     p15, 2, r10, c0, c0, 0          @ restore cache level 0
195         isb
196         dsb
197         ldmfd   sp!, {r4-r5, r7, r9-r11, lr}
198         mov     pc, lr
199 ENDPROC(tegra_flush_l1_cache)
200
201 #ifdef CONFIG_PM_SLEEP
202 /*
203  * tegra_sleep_cpu_finish(unsigned long int)
204  *
205  * enters suspend in LP2 by turning off the mmu and jumping to
206  * tegra?_tear_down_cpu
207  */
208 ENTRY(tegra_sleep_cpu_finish)
209         bl      tegra_cpu_exit_coherency
210
211 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
212         mov32   r1, tegra2_tear_down_cpu
213 #else
214         mov32   r1, tegra3_tear_down_cpu
215 #endif
216         add     r1, r1, r0
217         b       tegra_turn_off_mmu
218 ENDPROC(tegra_sleep_cpu_finish)
219
220 /*
221  * tegra_turn_off_mmu
222  *
223  * r0 = v2p
224  * r1 = physical address to jump to with mmu off
225  */
226 ENTRY(tegra_turn_off_mmu)
227         /*
228          * change page table pointer to tegra_pgd_phys, so that IRAM
229          * and MMU shut-off will be mapped virtual == physical
230          */
231         mrc     p15, 0, r2, c2, c0, 0   @ TTB 0
232         mov32   r3, ~PAGE_MASK
233         and     r2, r2, r3
234         ldr     r3, tegra_pgd_phys_address
235         ldr     r3, [r3]
236         orr     r3, r3, r2
237         mov     r2, #0
238         mcr     p15, 0, r2, c13, c0, 1  @ reserved context
239         isb
240         mcr     p15, 0, r3, c2, c0, 0   @ TTB 0
241         isb
242
243         mov     r2, #0
244         mcr     p15, 0, r2, c8, c3, 0   @ invalidate TLB
245         mcr     p15, 0, r2, c7, c5, 6   @ flush BTAC
246         mcr     p15, 0, r2, c7, c5, 0   @ flush instruction cache
247
248         mov32   r3, tegra_shut_off_mmu
249         add     r3, r3, r0
250         mov     r0, r1
251         mov     pc, r3
252 ENDPROC(tegra_turn_off_mmu)
253
254 tegra_pgd_phys_address:
255         .word   tegra_pgd_phys
256
257 /*
258  * tegra_shut_off_mmu
259  *
260  * r0 = physical address to jump to with mmu off
261  *
262  * called with VA=PA mapping
263  * turns off MMU, icache, dcache and branch prediction
264  */
265         .align  L1_CACHE_SHIFT
266 tegra_shut_off_mmu:
267         mrc     p15, 0, r3, c1, c0, 0
268         movw    r2, #CR_I | CR_Z | CR_C | CR_M
269         bic     r3, r3, r2
270         dsb
271         mcr     p15, 0, r3, c1, c0, 0
272         isb
273         mov     pc, r0
274
275 /*
276  * tegra_cpu_clk32k
277  *
278  * In LP2 the normal cpu clock pllx will be turned off. Switch the CPU to pllp
279  */
280 ENTRY(tegra_cpu_pllp)
281         /* in LP2 idle (SDRAM active), set the CPU burst policy to PLLP */
282         mov32   r5, TEGRA_CLK_RESET_BASE
283         mov     r0, #(2 << 28)                  @ burst policy = run mode
284         orr     r0, r0, #(4 << 4)               @ use PLLP in run mode burst
285         str     r0, [r5, #CLK_RESET_CCLK_BURST]
286         mov     r0, #0
287         str     r0, [r5, #CLK_RESET_CCLK_DIVIDER]
288         mov     pc, lr
289 ENDPROC(tegra_cpu_pllp)
290 #endif
291
292 #ifdef CONFIG_TRUSTED_FOUNDATIONS
293 /*
294  * Issue SMC with ctx kept on an uncached stack
295  */
296 .macro smc_issue_smc tmp
297         cpu_id  \tmp
298         cmp     \tmp, #0
299         bne     .
300         mov     r3, #0
301         mov     r4, #0
302         dsb
303         smc     #0
304 .endm
305
306 ENTRY(tegra_generic_smc_uncached)
307 #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_CACHE_L2X0)
308         mov32   r3, tegra_cpu_context           @ borrow CPU0's non-cached
309         ldr     r3, [r3]                        @ context grows up
310         stmia   r3, {r4-r12, sp, lr}
311
312         smc_issue_smc r5
313
314         mov32   r3, tegra_cpu_context           @ borrow CPU0's non-cached
315         ldr     r3, [r3]                        @ context grows up
316         ldmia   r3, {r4-r12, sp, pc}
317 #else
318         mov     pc, lr
319 #endif
320 ENDPROC(tegra_generic_smc_uncached)
321
322 /*
323  * Issue SMC with ctx kept on a cacheable stack
324  *     (args in R0, R1, R2 and R3 holds save/restore ptr)
325  */
326 ENTRY(tegra_generic_smc_cached)
327         stmia   r3, {r4-r12, sp, lr}
328         adr     r4, __tegra_smc_current_ctx     @ save current ptr
329         str     r3, [r4]
330
331         smc_issue_smc r5
332
333         adr     r4, __tegra_smc_current_ctx     @ restore from saved ptr
334         ldr     r3, [r4]
335         ldmia   r3, {r4-r12, sp, pc}
336 ENDPROC(tegra_generic_smc_cached)
337         .type   __tegra_smc_current_ctx, %object
338 __tegra_smc_current_ctx:
339         .long   0
340         .size   __tegra_smc_current_ctx, . - __tegra_smc_current_ctx
341
342 #define TEGRA_SMC_SAVED_WORDS   11
343
344 /* SMC issued using the current cacheable SP stack */
345 ENTRY(tegra_generic_smc)
346         mov     r3, sp                                  @ use current stack
347         sub     r3, #(TEGRA_SMC_SAVED_WORDS << 2)       @ context grows up
348         b       tegra_generic_smc_cached
349 ENDPROC(tegra_generic_smc)
350
351 /* SMC issued using a local cacheable stack */
352 ENTRY(tegra_generic_smc_local)
353         adr     r3, __tegra_smc_stack                   @ use local stack
354         b       tegra_generic_smc_cached
355 ENDPROC(tegra_generic_smc_local)
356
357         .align  L1_CACHE_SHIFT
358         .type   __tegra_smc_stack, %object
359 __tegra_smc_stack:
360         .rept   TEGRA_SMC_SAVED_WORDS
361         .long   0
362         .endr
363         .size   __tegra_smc_stack, . - __tegra_smc_stack
364 #endif