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