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