Revert "arm: tegra: optimize L2 enable/disable paths for secureos"
[linux-3.10.git] / arch / arm / mach-tegra / headsmp.S
1 /*
2  * arch/arm/mach-tegra/headsmp.S
3  *
4  * CPU initialization routines for Tegra SoCs
5  *
6  * Copyright (c) 2009-2012, NVIDIA Corporation.
7  * Copyright (c) 2011 Google, Inc.
8  * Author: Colin Cross <ccross@android.com>
9  *         Gary King <gking@nvidia.com>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License.
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
21 #include <linux/linkage.h>
22 #include <linux/init.h>
23
24 #include <asm/assembler.h>
25 #include <asm/cache.h>
26 #include <asm/page.h>
27
28 #include "flowctrl.h"
29 #include "iomap.h"
30 #include "sleep.h"
31 #include "reset.h"
32
33 #define APB_MISC_GP_HIDREV      0x804
34 #define PMC_SCRATCH41   0x140
35
36 #define DEBUG_CPU_RESET_HANDLER 0       /* Non-zero enables debug code */
37
38 #define RESET_DATA(x)   ((TEGRA_RESET_##x)*4)
39
40 #ifdef CONFIG_SMP
41 /*
42  *      tegra_secondary_startup
43  *
44  *       Initial secondary processor boot vector; jumps to kernel's
45  *       secondary_startup routine. Used for initial boot and hotplug
46  *       of secondary CPUs.
47  */
48         __CPUINIT
49 ENTRY(tegra_secondary_startup)
50         bl      __invalidate_cpu_state
51         b       secondary_startup
52 ENDPROC(tegra_secondary_startup)
53 #endif
54
55         .section ".text.head", "ax"
56 #ifdef CONFIG_PM_SLEEP
57 /*
58  *      tegra_resume
59  *
60  *        CPU boot vector when restarting the a CPU following
61  *        an LP2 transition. Also branched to by LP0 and LP1 resume after
62  *        re-enabling sdram.
63  */
64 ENTRY(tegra_resume)
65         bl      __invalidate_cpu_state
66
67         cpu_id  r0
68         cmp     r0, #0                          @ CPU0?
69         bne     cpu_resume                      @ no
70
71 #ifndef CONFIG_ARCH_TEGRA_2x_SOC
72         @ Clear the flow controller flags for this CPU.
73         mov32   r2, TEGRA_FLOW_CTRL_BASE+8      @ CPU0 CSR
74         ldr     r1, [r2]
75         orr     r1, r1, #(1 << 15) | (1 << 14)  @ write to clear event & intr
76         movw    r0, #0x3FFD     @ enable, enable_ext, cluster_switch, immed, & bitmaps
77         bic     r1, r1, r0
78         str     r1, [r2]
79 #endif
80
81 #if defined(CONFIG_HAVE_ARM_SCU)
82         /* enable SCU */
83         mov32   r0, TEGRA_ARM_PERIF_BASE
84         ldr     r1, [r0]
85         orr     r1, r1, #1
86         orr     r1, r1, #(1 << 3)       @ Enable SCU speculative line fill.
87         orr     r1, r1, #(1 << 5)       @ Enable IC standby.
88         orr     r1, r1, #(1 << 6)       @ Enable SCU standby.
89         str     r1, [r0]
90 #endif
91
92 #ifdef CONFIG_TRUSTED_FOUNDATIONS
93         /* wake up (should have specified args?) */
94         bl      tegra_generic_smc
95 #endif
96
97         b       cpu_resume
98 ENDPROC(tegra_resume)
99 #endif
100
101 /*
102  *      __invalidate_cpu_state
103  *
104  *        Invalidates volatile CPU state (SCU tags, caches, branch address
105  *        arrays, exclusive monitor, etc.) so that they can be safely enabled
106  *        instruction caching and branch predicition enabled
107  */
108 __invalidate_cpu_state:
109         clrex
110         mov     r0, #0
111         mcr     p15, 0, r0, c1, c0, 1   @ disable SMP, prefetch, broadcast
112         isb
113         mcr     p15, 0, r0, c7, c5, 0   @ invalidate BTAC, i-cache
114         mcr     p15, 0, r0, c7, c5, 6   @ invalidate branch pred array
115         mcr     p15, 0, r0, c8, c5, 0   @ invalidate instruction TLB
116         mcr     p15, 0, r0, c8, c6, 0   @ invalidate data TLB
117         mcr     p15, 0, r0, c8, c7, 0   @ invalidate unified TLB
118         dsb
119         isb
120
121 #if defined(CONFIG_HAVE_ARM_SCU)
122         cpu_id  r0
123         cmp     r0, #0
124         mov32   r1, (TEGRA_ARM_PERIF_BASE + 0xC)
125         movne   r0, r0, lsl #2
126         movne   r2, #0xf
127         movne   r2, r2, lsl r0
128         strne   r2, [r1]                @ invalidate SCU tags for CPU
129 #else
130         /*      This is only needed for cluster 0 with integrated L2 cache */
131         mov32   r0, TEGRA_FLOW_CTRL_BASE+0x2c   @ CLUSTER_CONTROL
132         ldr     r0, [r0]
133         tst     r0, #1
134         bne     enable_icache_bp
135         mrc     p15, 0x1, r0, c9, c0, 2
136         and     r1, r0, #7
137         cmp     r1, #2
138         beq     enable_icache_bp
139         bic r0, r0, #7
140         orr r0, r0, #2
141         mcr p15, 0x1, r0, c9, c0, 2
142
143 #endif
144
145 enable_icache_bp:
146         dsb
147         mov     r0, #0x1800
148         mcr     p15, 0, r0, c1, c0, 0   @ enable branch prediction, i-cache
149         isb
150         /* fall through */
151
152 /*
153  *      tegra_invalidate_cache
154  *
155  *        Invalidates the L1 or L2 data cache (no clean) during initial boot of
156  *        a cpu. For architecture with external L2, invalidate L1 only. For
157  *        architecture with integrated L2 and SCU, invalidate L2 if current CPU
158  *        boots up with a power gated NC partition initially or power rail was
159  *        initially off, invalidates L1 in other cases
160  *
161  *        Corrupted registers: r0-r6
162  */
163 tegra_invalidate_cache:
164 #if defined(CONFIG_HAVE_ARM_SCU)
165         mov     r0, #0
166 #else
167         cpu_id  r0
168         cpu_to_csr_reg  r1, r0
169         mov32   r0, TEGRA_FLOW_CTRL_BASE
170         ldr     r0, [r0, r1]
171         tst     r0, #FLOW_CTRL_CSR_ENABLE_EXT_MASK
172         movne   r0, #2
173         moveq   r0, #0
174 #endif
175         mcr     p15, 2, r0, c0, c0, 0
176         mrc     p15, 1, r0, c0, c0, 0
177
178         movw    r1, #0x7fff
179         and     r2, r1, r0, lsr #13
180
181         movw    r1, #0x3ff
182
183         and     r3, r1, r0, lsr #3      @ NumWays - 1
184         add     r2, r2, #1      @ NumSets
185
186         and     r0, r0, #0x7
187         add     r0, r0, #4      @ SetShift
188
189         clz     r1, r3          @ WayShift
190         add     r4, r3, #1      @ NumWays
191 1:      sub     r2, r2, #1      @ NumSets--
192         mov     r3, r4          @ Temp = NumWays
193 2:      subs    r3, r3, #1      @ Temp--
194         mov     r5, r3, lsl r1
195         mov     r6, r2, lsl r0
196         orr     r5, r5, r6      @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
197         mcr     p15, 0, r5, c7, c6, 2
198         bgt     2b
199         cmp     r2, #0
200         bgt     1b
201 #if !defined(CONFIG_HAVE_ARM_SCU)
202         mov     r0, #0
203         mcr     p15, 2, r0, c0, c0, 0
204 #endif
205         dsb
206         isb
207         mov     pc, lr
208
209 /*
210  * __tegra_cpu_reset_handler_halt_failed:
211  *
212  * Alternate entry point for reset handler for cases where the
213  * WFI halt failed to take effect.
214  *
215  */
216         .align L1_CACHE_SHIFT
217 ENTRY(__tegra_cpu_reset_handler_start)
218
219 /*
220  * __tegra_cpu_reset_handler:
221  *
222  * Common handler for all CPU reset events.
223  *
224  * Register usage within the reset handler:
225  *
226  *      R7  = CPU present (to the OS) mask
227  *      R8  = CPU in LP1 state mask
228  *      R9  = CPU in LP2 state mask
229  *      R10 = CPU number
230  *      R11 = CPU mask
231  *      R12 = pointer to reset handler data
232  *
233  * NOTE: This code is copied to IRAM. All code and data accesses
234  *       must be position-independent.
235  */
236
237         .align L1_CACHE_SHIFT
238 ENTRY(__tegra_cpu_reset_handler)
239
240 /* DO NOT put any code before the !defined(CONFIG_ARM_SAVE_DEBUG_CONTEXT)
241    block below. It must be the first thing in this subroutine. */
242
243 #if !defined(CONFIG_ARM_SAVE_DEBUG_CONTEXT) || DEBUG_CPU_RESET_HANDLER
244         /* If Debug Architecture v7.1 or later, unlock the OS lock. */
245         mrc     p15, 0, r0, c0, c1, 2           @ ID_DFR0
246         and     r0, r0, #0xF                    @ coprocessor debug model
247         cmp     r0, #5                          @ debug arch >= v7.1?
248         movge   r0, #0                          @ yes, unlock debug
249         mcrge   p14, 0, r0, c1, c0, 4           @ DBGOSLAR
250 #endif
251 #if DEBUG_CPU_RESET_HANDLER
252         b       .
253 #endif
254 #ifndef CONFIG_TRUSTED_FOUNDATIONS
255         cpsid   aif, 0x13                       @ SVC mode, interrupts disabled
256         mrc     p15, 0, r0, c0, c0, 0           @ read main ID register
257         and     r5, r0, #0x00f00000             @ variant
258         and     r6, r0, #0x0000000f             @ revision
259         orr     r6, r6, r5, lsr #20-4           @ combine variant and revision
260 #ifdef CONFIG_ARM_ERRATA_743622
261         teq     r6, #0x20                       @ present in r2p0
262         teqne   r6, #0x21                       @ present in r2p1
263         teqne   r6, #0x22                       @ present in r2p2
264         teqne   r6, #0x27                       @ present in r2p7
265         teqne   r6, #0x29                       @ present in r2p9
266         mrceq   p15, 0, r10, c15, c0, 1         @ read diagnostic register
267         orreq   r10, r10, #1 << 6               @ set bit #6
268         mcreq   p15, 0, r10, c15, c0, 1         @ write diagnostic register
269 #endif
270 #endif
271         mrc     p15, 0, r10, c0, c0, 5          @ MPIDR
272         and     r10, r10, #0x3                  @ R10 = CPU number
273         mov     r11, #1
274         mov     r11, r11, lsl r10               @ R11 = CPU mask
275         adr     r12, __tegra_cpu_reset_handler_data
276
277 #ifdef CONFIG_SMP
278         /* Does the OS know about this CPU? */
279         ldr     r7, [r12, #RESET_DATA(MASK_PRESENT)]
280         tst     r7, r11                         @ if !present
281         bleq    __die                           @ CPU not present (to OS)
282 #endif
283
284 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
285         /* If CPU1, don't let CPU0 reset CPU1 now that CPU1 is coming up. */
286         mov32   r6, TEGRA_PMC_BASE
287         mov     r0, #0
288         cmp     r10, #0
289         strne   r0, [r6, #PMC_SCRATCH41]
290 #endif
291
292 #ifdef CONFIG_PM_SLEEP
293         /* Waking up from LP1? */
294         ldr     r8, [r12, #RESET_DATA(MASK_LP1)]
295         tst     r8, r11                         @ if in_lp1
296         beq     __is_not_lp1
297         cmp     r10, #0
298         bne     __die                           @ only CPU0 can be here
299         ldr     lr, [r12, #RESET_DATA(STARTUP_LP1)]
300         cmp     lr, #0
301         bleq    __die                           @ no LP1 startup handler
302         bx      lr
303 __is_not_lp1:
304 #endif
305
306         /* Waking up from LP2? */
307         ldr     r9, [r12, #RESET_DATA(MASK_LP2)]
308         tst     r9, r11                         @ if in_lp2
309         beq     __is_not_lp2
310         ldr     lr, [r12, #RESET_DATA(STARTUP_LP2)]
311         cmp     lr, #0
312         bleq    __die                           @ no LP2 startup handler
313         bx      lr
314
315 __is_not_lp2:
316
317 #ifdef CONFIG_SMP
318         /* Can only be secondary boot (initial or hotplug) but CPU 0
319            cannot be here. */
320         cmp     r10, #0
321         bleq    __die                           @ CPU0 cannot be here
322         ldr     lr, [r12, #RESET_DATA(STARTUP_SECONDARY)]
323         cmp     lr, #0
324         bleq    __die                           @ no secondary startup handler
325         bx      lr
326 #endif
327
328 /*
329  * We don't know why the CPU reset. Just kill it.
330  * The LR register will contain the address we died at + 4.
331  */
332
333 __die:
334         sub     lr, lr, #4
335         mov32   r7, TEGRA_PMC_BASE
336         str     lr, [r7, #PMC_SCRATCH41]
337
338         mov32   r7, TEGRA_CLK_RESET_BASE
339
340         /* Are we on Tegra20? */
341         mov32   r6, TEGRA_APB_MISC_BASE
342         ldr     r0, [r6, #APB_MISC_GP_HIDREV]
343         and     r0, r0, #0xff00
344         cmp     r0, #(0x20 << 8)
345         bne     1f
346
347 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
348         mov32   r0, 0x1111
349         mov     r1, r0, lsl r10
350         str     r1, [r7, #0x340]                @ CLK_RST_CPU_CMPLX_SET
351 #endif
352 1:
353 #ifdef CONFIG_ARCH_TEGRA_3x_SOC
354         mov32   r6, TEGRA_FLOW_CTRL_BASE
355
356         cmp     r10, #0
357         moveq   r1, #FLOW_CTRL_HALT_CPU0_EVENTS
358         moveq   r2, #FLOW_CTRL_CPU0_CSR
359         movne   r1, r10, lsl #3
360         addne   r2, r1, #(FLOW_CTRL_CPU1_CSR-8)
361         addne   r1, r1, #(FLOW_CTRL_HALT_CPU1_EVENTS-8)
362
363         /* Clear CPU "event" and "interrupt" flags and power gate
364            it when halting but not before it is in the "WFI" state. */
365         ldr     r0, [r6, +r2]
366         orr     r0, r0, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
367         orr     r0, r0, #FLOW_CTRL_CSR_ENABLE
368         str     r0, [r6, +r2]
369
370         /* Unconditionally halt this CPU */
371         mov     r0, #FLOW_CTRL_WAITEVENT
372         str     r0, [r6, +r1]
373         ldr     r0, [r6, +r1]                   @ memory barrier
374
375         dsb
376         isb
377         wfi                                     @ CPU should be power gated here
378
379         /* If the CPU didn't power gate above just kill it's clock. */
380
381         mov     r0, r11, lsl #8
382         str     r0, [r7, #348]                  @ CLK_CPU_CMPLX_SET
383 #endif
384
385         /* If the CPU still isn't dead, just spin here. */
386         b       .
387 ENDPROC(__tegra_cpu_reset_handler)
388
389         .align L1_CACHE_SHIFT
390         .type   __tegra_cpu_reset_handler_data, %object
391         .globl  __tegra_cpu_reset_handler_data
392 __tegra_cpu_reset_handler_data:
393         .rept   TEGRA_RESET_DATA_SIZE
394         .long   0
395         .endr
396         .size   __tegra_cpu_reset_handler_data, . - __tegra_cpu_reset_handler_data
397         .align L1_CACHE_SHIFT
398 ENTRY(__tegra_cpu_reset_handler_end)