temp revert rk change
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-tegra / cortex-a9.S
1 /*
2  * arch/arm/mach-tegra/cortex-a9.S
3  *
4  * CPU state save & restore routines for CPU hotplug
5  *
6  * Copyright (c) 2010, NVIDIA Corporation.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  * more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21  */
22
23 #include <linux/linkage.h>
24 #include <linux/init.h>
25
26 #include <asm/assembler.h>
27 #include <asm/domain.h>
28 #include <asm/ptrace.h>
29 #include <asm/cache.h>
30 #include <asm/vfpmacros.h>
31 #include <asm/hardware/cache-l2x0.h>
32
33 #include <mach/iomap.h>
34 #include <mach/io.h>
35
36 /*      .section ".cpuinit.text", "ax"*/
37
38 #define TTB_FLAGS 0x6A  @ IRGN_WBWA, OC_RGN_WBWA, S, NOS
39
40 /*
41  * spooled CPU context is 1KB / CPU
42  */
43 #define CTX_SP          0
44 #define CTX_CPSR        4
45 #define CTX_SPSR        8
46 #define CTX_CPACR       12
47 #define CTX_CSSELR      16
48 #define CTX_SCTLR       20
49 #define CTX_ACTLR       24
50 #define CTX_PCTLR       28
51
52 #define CTX_FPEXC       32
53 #define CTX_FPSCR       36
54 #define CTX_DIAGNOSTIC  40
55
56 #define CTX_TTBR0       48
57 #define CTX_TTBR1       52
58 #define CTX_TTBCR       56
59 #define CTX_DACR        60
60 #define CTX_PAR         64
61 #define CTX_PRRR        68
62 #define CTX_NMRR        72
63 #define CTX_VBAR        76
64 #define CTX_CONTEXTIDR  80
65 #define CTX_TPIDRURW    84
66 #define CTX_TPIDRURO    88
67 #define CTX_TPIDRPRW    92
68
69 #define CTX_SVC_SP      0
70 #define CTX_SVC_LR      -1      @ stored on stack
71 #define CTX_SVC_SPSR    8
72
73 #define CTX_SYS_SP      96
74 #define CTX_SYS_LR      100
75
76 #define CTX_ABT_SPSR    112
77 #define CTX_ABT_SP      116
78 #define CTX_ABT_LR      120
79
80 #define CTX_UND_SPSR    128
81 #define CTX_UND_SP      132
82 #define CTX_UND_LR      136
83
84 #define CTX_IRQ_SPSR    144
85 #define CTX_IRQ_SP      148
86 #define CTX_IRQ_LR      152
87
88 #define CTX_FIQ_SPSR    160
89 #define CTX_FIQ_R8      164
90 #define CTX_FIQ_R9      168
91 #define CTX_FIQ_R10     172
92 #define CTX_FIQ_R11     178
93 #define CTX_FIQ_R12     180
94 #define CTX_FIQ_SP      184
95 #define CTX_FIQ_LR      188
96
97 /* context only relevant for master cpu */
98 #ifdef CONFIG_CACHE_L2X0
99 #define CTX_L2_CTRL     224
100 #define CTX_L2_AUX      228
101 #define CTX_L2_TAG_CTRL 232
102 #define CTX_L2_DAT_CTRL 236
103 #define CTX_L2_PREFETCH 240
104 #endif
105
106 #define CTX_VFP_REGS    256
107 #define CTX_VFP_SIZE    (32 * 8)
108
109 #define CTX_CP14_REGS   512
110 #define CTS_CP14_DSCR   512
111 #define CTX_CP14_WFAR   516
112 #define CTX_CP14_VCR    520
113 #define CTX_CP14_CLAIM  524
114
115 /* Each of the folowing is 2 32-bit registers */
116 #define CTS_CP14_BKPT_0 528
117 #define CTS_CP14_BKPT_1 536
118 #define CTS_CP14_BKPT_2 544
119 #define CTS_CP14_BKPT_3 552
120 #define CTS_CP14_BKPT_4 560
121 #define CTS_CP14_BKPT_5 568
122
123 /* Each of the folowing is 2 32-bit registers */
124 #define CTS_CP14_WPT_0  576
125 #define CTS_CP14_WPT_1  584
126 #define CTS_CP14_WPT_2  592
127 #define CTS_CP14_WPT_3  600
128
129 #include "power.h"
130 #include "power-macros.S"
131
132 .macro  ctx_ptr, rd, tmp
133         cpu_id  \tmp
134         mov32   \rd, tegra_context_area
135         ldr     \rd, [\rd]
136         add     \rd, \rd, \tmp, lsl #(CONTEXT_SIZE_BYTES_SHIFT)
137 .endm
138
139 .macro  translate, pa, va, tmp
140         mov     \tmp, #0x1000
141         sub     \tmp, \tmp, #1
142         bic     \pa, \va, \tmp
143         mcr     p15, 0, \pa, c7, c8, 1
144         mrc     p15, 0, \pa, c7, c4, 0
145         bic     \pa, \pa, \tmp
146         and     \tmp, \va, \tmp
147         orr     \pa, \pa, \tmp
148 .endm
149
150 /*
151  *      __cortex_a9_save(unsigned int mode)
152  *
153  *       spools out the volatile processor state to memory, so that
154  *       the CPU may be safely powered down. does not preserve:
155  *       - CP15 c0 registers (except cache size select 2,c0/c0,0)
156  *       - CP15 c1 secure registers (c1/c1, 0-3)
157  *       - CP15 c5 fault status registers (c5/c0 0&1, c5/c1 0&1)
158  *       - CP15 c6 fault address registers (c6/c0 0&2)
159  *       - CP15 c9 performance monitor registers (c9/c12 0-5,
160  *           c9/c13 0-2, c9/c14 0-2)
161  *       - CP15 c10 TLB lockdown register (c10/c0, 0)
162  *       - CP15 c12 MVBAR (c12/c0, 1)
163  *       - CP15 c15 TLB lockdown registers
164  */
165         .align L1_CACHE_SHIFT
166 ENTRY(__cortex_a9_save)
167         mrs     r3, cpsr
168         cps     0x13                    @ save off svc registers
169         mov     r1, sp
170         stmfd   sp!, {r3-r12, lr}
171
172         bic     r2, sp, #(L1_CACHE_BYTES-1)
173
174 1:      mcr     p15, 0, r2, c7, c14, 1  @ clean out dirty stack cachelines
175         add     r2, r2, #L1_CACHE_BYTES
176         cmp     r2, r1
177         ble     1b
178         dsb
179
180         ctx_ptr r8, r9
181         mov     r12, r0
182
183         /* zero-out context area */
184         mov     r9, r8
185         add     r10, r8, #(CONTEXT_SIZE_BYTES)
186         mov     r0, #0
187         mov     r1, #0
188         mov     r2, #0
189         mov     r3, #0
190         mov     r4, #0
191         mov     r5, #0
192         mov     r6, #0
193         mov     r7, #0
194 2:      stmia   r9!, {r0-r7}
195         cmp     r9, r10
196         blo     2b
197
198         mov     r0, sp
199         mov     sp, r12                 @ sp holds the power mode
200         mrs     r1, cpsr
201         mrs     r2, spsr
202
203         mrc     p15, 0, r3, c1, c0, 2   @ cpacr
204         stmia   r8, {r0-r3}
205         mrc     p15, 2, r0, c0, c0, 0   @ csselr
206         mrc     p15, 0, r1, c1, c0, 0   @ sctlr
207         mrc     p15, 0, r2, c1, c0, 1   @ actlr
208         mrc     p15, 0, r4, c15, c0, 0  @ pctlr
209         add     r9, r8, #CTX_CSSELR
210         stmia   r9, {r0-r2, r4}
211
212 #ifdef CONFIG_VFPv3
213         orr     r2, r3, #0xF00000
214         mcr     p15, 0, r2, c1, c0, 2   @ enable access to FPU
215         VFPFMRX r2, FPEXC
216         str     r2, [r8, #CTX_FPEXC]
217         mov     r1, #0x40000000         @ enable access to FPU
218         VFPFMXR FPEXC, r1
219         VFPFMRX r1, FPSCR
220         str     r1, [r8, #CTX_FPSCR]
221         isb
222         add     r9, r8, #CTX_VFP_REGS
223
224         VFPFSTMIA r9, r12       @ save out (16 or 32)*8B of FPU registers
225         VFPFMXR FPEXC, r2
226         mrc     p15, 0, r3, c1, c0, 2   @ restore original FPEXC/CPACR
227 #endif
228         mrc     p15, 0, r0, c15, c0, 1  @ diag
229         str     r0, [r8, #CTX_DIAGNOSTIC]
230
231         add     r9, r8, #CTX_TTBR0
232         mrc     p15, 0, r0, c2, c0, 0   @ TTBR0
233         mrc     p15, 0, r1, c2, c0, 1   @ TTBR1
234         mrc     p15, 0, r2, c2, c0, 2   @ TTBCR
235         mrc     p15, 0, r3, c3, c0, 0   @ domain access control reg
236         mrc     p15, 0, r4, c7, c4, 0   @ PAR
237         mrc     p15, 0, r5, c10, c2, 0  @ PRRR
238         mrc     p15, 0, r6, c10, c2, 1  @ NMRR
239         mrc     p15, 0, r7, c12, c0, 0  @ VBAR
240         stmia   r9!, {r0-r7}
241         mrc     p15, 0, r0, c13, c0, 1  @ CONTEXTIDR
242         mrc     p15, 0, r1, c13, c0, 2  @ TPIDRURW
243         mrc     p15, 0, r2, c13, c0, 3  @ TPIDRURO
244         mrc     p15, 0, r3, c13, c0, 4  @ TPIDRPRW
245         stmia   r9, {r0-r3}
246
247         cps     0x1f                    @ SYS mode
248         add     r9, r8, #CTX_SYS_SP
249         stmia   r9, {sp,lr}
250
251         cps     0x17                    @ Abort mode
252         mrs     r12, spsr
253         add     r9, r8, #CTX_ABT_SPSR
254         stmia   r9, {r12,sp,lr}
255
256         cps     0x12                    @ IRQ mode
257         mrs     r12, spsr
258         add     r9, r8, #CTX_IRQ_SPSR
259         stmia   r9, {r12,sp,lr}
260
261         cps     0x1b                    @ Undefined mode
262         mrs     r12, spsr
263         add     r9, r8, #CTX_UND_SPSR
264         stmia   r9, {r12,sp,lr}
265
266         mov     r0, r8
267         add     r1, r8, #CTX_FIQ_SPSR
268         cps     0x11                    @ FIQ mode
269         mrs     r7, spsr
270         stmia   r1, {r7-r12,sp,lr}
271
272         cps     0x13                    @ back to SVC
273         mov     r8, r0
274
275         /* Save CP14 debug controller context */
276         add     r9, r8, #CTX_CP14_REGS
277         mrc     p14, 0, r0, c0, c1, 0   @ DSCR
278         mrc     p14, 0, r1, c0, c6, 0   @ WFAR
279         mrc     p14, 0, r2, c0, c7, 0   @ VCR
280         mrc     p14, 0, r3, c7, c9, 6   @ CLAIM
281         stmia   r9, {r0-r3}
282
283         add     r9, r8, #CTS_CP14_BKPT_0
284         mrc     p14, 0, r2, c0, c0, 4
285         mrc     p14, 0, r3, c0, c0, 5
286         stmia   r9!, {r2-r3}            @ BRKPT_0
287         mrc     p14, 0, r2, c0, c1, 4
288         mrc     p14, 0, r3, c0, c1, 5
289         stmia   r9!, {r2-r3}            @ BRKPT_0
290         mrc     p14, 0, r2, c0, c2, 4
291         mrc     p14, 0, r3, c0, c2, 5
292         stmia   r9!, {r2-r3}            @ BRKPT_0
293         mrc     p14, 0, r2, c0, c3, 4
294         mrc     p14, 0, r3, c0, c3, 5
295         stmia   r9!, {r2-r3}            @ BRKPT_0
296         mrc     p14, 0, r2, c0, c4, 4
297         mrc     p14, 0, r3, c0, c4, 5
298         stmia   r9!, {r2-r3}            @ BRKPT_0
299         mrc     p14, 0, r2, c0, c5, 4
300         mrc     p14, 0, r3, c0, c5, 5
301         stmia   r9!, {r2-r3}            @ BRKPT_0
302
303         add     r9, r8, #CTS_CP14_WPT_0
304         mrc     p14, 0, r2, c0, c0, 6
305         mrc     p14, 0, r3, c0, c0, 7
306         stmia   r9!, {r2-r3}            @ WPT_0
307         mrc     p14, 0, r2, c0, c1, 6
308         mrc     p14, 0, r3, c0, c1, 7
309         stmia   r9!, {r2-r3}            @ WPT_0
310         mrc     p14, 0, r2, c0, c2, 6
311         mrc     p14, 0, r3, c0, c2, 7
312         stmia   r9!, {r2-r3}            @ WPT_0
313         mrc     p14, 0, r2, c0, c3, 6
314         mrc     p14, 0, r3, c0, c3, 7
315         stmia   r9!, {r2-r3}            @ WPT_0
316
317 #ifdef CONFIG_CACHE_L2X0
318         cpu_id  r4
319         cmp     r4, #0
320         bne     __cortex_a9_save_clean_cache
321         mov32   r4, (TEGRA_ARM_PL310_BASE-IO_CPU_PHYS+IO_CPU_VIRT)
322         add     r9, r8, #CTX_L2_CTRL
323         ldr     r0, [r4, #L2X0_CTRL]
324         ldr     r1, [r4, #L2X0_AUX_CTRL]
325         ldr     r2, [r4, #L2X0_TAG_LATENCY_CTRL]
326         ldr     r3, [r4, #L2X0_DATA_LATENCY_CTRL]
327         ldr     r4, [r4, #L2X0_PREFETCH_OFFSET]
328         stmia   r9, {r0-r4}
329 #endif
330
331
332 __cortex_a9_save_clean_cache:
333         mov     r10, r8
334         add     r9, r10, #(CONTEXT_SIZE_BYTES)
335         add     r9, r9, #(L1_CACHE_BYTES-1)
336         bic     r10, r10, #(L1_CACHE_BYTES-1)
337         bic     r9, r9, #(L1_CACHE_BYTES-1)
338
339 3:      mcr     p15, 0, r10, c7, c10, 1
340         add     r10, r10, #L1_CACHE_BYTES
341         cmp     r10, r9
342         blo     3b
343         dsb
344
345         translate r10, r8, r1
346
347         mov     r0, #0
348         mcr     p15, 0, r0, c1, c0, 1   @ exit coherency
349         isb
350         cpu_id  r0
351         mov32   r1, (TEGRA_ARM_PERIF_BASE-IO_CPU_PHYS+IO_CPU_VIRT+0xC)
352         mov     r3, r0, lsl #2
353         mov     r2, #0xf
354         mov     r2, r2, lsl r3
355         str     r2, [r1]                @ invalidate SCU tags for CPU
356
357         cmp     r0, #0
358         bne     __put_cpu_in_reset
359         mov     r8, r10
360         b       __tear_down_master
361 ENDPROC(__cortex_a9_save)
362
363 /*
364  *      __cortex_a9_restore
365  *
366  *       reloads the volatile CPU state from the context area
367  *       the MMU should already be enabled using the secondary_data
368  *       page tables for cpu_up before this function is called, and the
369  *       CPU should be coherent with the SMP complex
370  */
371         .align L1_CACHE_SHIFT
372 ENTRY(__cortex_a9_restore)
373         cps     0x13
374         ctx_ptr r0, r9
375
376         cps     0x11                    @ FIQ mode
377         add     r1, r0, #CTX_FIQ_SPSR
378         ldmia   r1, {r7-r12,sp,lr}
379         msr     spsr_fsxc, r7
380
381         cps     0x12                    @ IRQ mode
382         add     r1, r0, #CTX_IRQ_SPSR
383         ldmia   r1, {r12, sp, lr}
384         msr     spsr_fsxc, r12
385
386         cps     0x17                    @ abort mode
387         add     r1, r0, #CTX_ABT_SPSR
388         ldmia   r1, {r12, sp, lr}
389         msr     spsr_fsxc, r12
390
391         cps     0x1f                    @ SYS mode
392         add     r1, r0, #CTX_SYS_SP
393         ldmia   r1, {sp, lr}
394
395         cps     0x1b                    @ Undefined mode
396         add     r1, r0, #CTX_UND_SPSR
397         ldmia   r1, {r12, sp, lr}
398         msr     spsr_fsxc, r12
399
400         cps     0x13                    @ back to SVC
401         mov     r8, r0
402
403         add     r9, r8, #CTX_CSSELR
404         ldmia   r9, {r0-r3}
405
406         mcr     p15, 2, r0, c0, c0, 0   @ csselr
407         mcr     p15, 0, r1, c1, c0, 0   @ sctlr
408         mcr     p15, 0, r2, c1, c0, 1   @ actlr
409         mcr     p15, 0, r3, c15, c0, 0  @ pctlr
410
411         add     r9, r8, #CTX_TTBR0
412         ldmia   r9!, {r0-r7}
413
414         mcr     p15, 0, r4, c7, c4, 0   @ PAR
415         mcr     p15, 0, r7, c12, c0, 0  @ VBAR
416         mcr     p15, 0, r3, c3, c0, 0   @ domain access control reg
417         isb
418         mcr     p15, 0, r2, c2, c0, 2   @ TTBCR
419         isb
420         mcr     p15, 0, r5, c10, c2, 0  @ PRRR
421         isb
422         mcr     p15, 0, r6, c10, c2, 1  @ NMRR
423         isb
424
425         ldmia   r9, {r4-r7}
426
427         mcr     p15, 0, r5, c13, c0, 2  @ TPIDRURW
428         mcr     p15, 0, r6, c13, c0, 3  @ TPIDRURO
429         mcr     p15, 0, r7, c13, c0, 4  @ TPIDRPRW
430
431         ldmia   r8, {r5-r7, lr}
432
433         /* perform context switch to previous context */
434         mov     r9, #0
435         mcr     p15, 0, r9, c13, c0, 1  @ set reserved context
436         isb
437         mcr     p15, 0, r0, c2, c0, 0   @ TTBR0
438         isb
439         mcr     p15, 0, r4, c13, c0, 1  @ CONTEXTIDR
440         isb
441         mcr     p15, 0, r1, c2, c0, 1   @ TTBR1
442         isb
443
444         mov     r4, #0
445         mcr     p15, 0, r4, c8, c3, 0   @ invalidate TLB
446         mcr     p15, 0, r4, c7, c5, 6   @ flush BTAC
447         mcr     p15, 0, r4, c7, c5, 0   @ flush instruction cache
448         dsb
449         isb
450
451         mov     sp, r5
452         msr     cpsr_cxsf, r6
453         msr     spsr_cxsf, r7
454
455         /* Restore CP14 debug controller context */
456         add     r9, r8, #CTX_CP14_REGS
457         ldmia   r9, {r0-r3}
458         mcr     p14, 0, r1, c0, c6, 0   @ WFAR
459         mcr     p14, 0, r2, c0, c7, 0   @ VCR
460         mcr     p14, 0, r3, c7, c8, 6   @ CLAIM
461
462         add     r9, r8, #CTS_CP14_BKPT_0
463         ldmia   r9!, {r2-r3}            @ BRKPT_0
464         mcr     p14, 0, r2, c0, c0, 4
465         mcr     p14, 0, r3, c0, c0, 5
466         ldmia   r9!, {r2-r3}            @ BRKPT_0
467         mcr     p14, 0, r2, c0, c1, 4
468         mcr     p14, 0, r3, c0, c1, 5
469         ldmia   r9!, {r2-r3}            @ BRKPT_0
470         mcr     p14, 0, r2, c0, c2, 4
471         mcr     p14, 0, r3, c0, c2, 5
472         ldmia   r9!, {r2-r3}            @ BRKPT_0
473         mcr     p14, 0, r2, c0, c3, 4
474         mcr     p14, 0, r3, c0, c3, 5
475         ldmia   r9!, {r2-r3}            @ BRKPT_0
476         mcr     p14, 0, r2, c0, c4, 4
477         mcr     p14, 0, r3, c0, c4, 5
478         ldmia   r9!, {r2-r3}            @ BRKPT_0
479         mcr     p14, 0, r2, c0, c5, 4
480         mcr     p14, 0, r3, c0, c5, 5
481
482         add     r9, r8, #CTS_CP14_WPT_0
483         ldmia   r9!, {r2-r3}            @ WPT_0
484         mcr     p14, 0, r2, c0, c0, 6
485         mcr     p14, 0, r3, c0, c0, 7
486         ldmia   r9!, {r2-r3}            @ WPT_0
487         mcr     p14, 0, r2, c0, c1, 6
488         mcr     p14, 0, r3, c0, c1, 7
489         ldmia   r9!, {r2-r3}            @ WPT_0
490         mcr     p14, 0, r2, c0, c2, 6
491         mcr     p14, 0, r3, c0, c2, 7
492         ldmia   r9!, {r2-r3}            @ WPT_0
493         mcr     p14, 0, r2, c0, c3, 6
494         mcr     p14, 0, r3, c0, c3, 7
495         isb
496         mcr     p14, 0, r0, c0, c2, 2   @ DSCR
497         isb
498
499 #ifdef CONFIG_VFPv3
500         orr     r4, lr, #0xF00000
501         mcr     p15, 0, r4, c1, c0, 2   @ enable coproc access
502         mov     r5, #0x40000000
503         VFPFMXR FPEXC, r5               @ enable FPU access
504         add     r9, r8, #CTX_VFP_REGS
505         add     r7, r8, #CTX_FPEXC
506         VFPFLDMIA r9, r10
507         ldmia   r7, {r0, r4}
508         VFPFMXR FPSCR, r4
509         VFPFMXR FPEXC, r0
510 #endif
511         mcr     p15, 0, lr, c1, c0, 2   @ cpacr (loaded before VFP)
512
513         ldr     r9, [r8, #CTX_DIAGNOSTIC]
514         mcr     p15, 0, r9, c15, c0, 1  @ diag
515
516         /* finally, restore the stack and return */
517         ldmfd   sp!, {r3-r12, lr}
518         msr     cpsr_fsxc, r3           @ restore original processor mode
519         isb
520         mov     pc, lr
521 ENDPROC(__cortex_a9_restore)
522
523 /*
524  *      __cortex_a9_l2x0_restart(bool invalidate)
525  *
526  *       Reconfigures the L2 cache following a power event.
527  */
528         .align L1_CACHE_SHIFT
529 ENTRY(__cortex_a9_l2x0_restart)
530 #ifdef CONFIG_CACHE_L2X0
531         ctx_ptr r8, r9
532         mov32   r9, (TEGRA_ARM_PL310_BASE-IO_CPU_PHYS+IO_CPU_VIRT)
533         add     r10, r8, #CTX_L2_CTRL
534         ldmia   r10, {r3-r7}
535         str     r5, [r9, #L2X0_TAG_LATENCY_CTRL]
536         str     r6, [r9, #L2X0_DATA_LATENCY_CTRL]
537         str     r7, [r9, #L2X0_PREFETCH_OFFSET]
538         str     r4, [r9, #L2X0_AUX_CTRL]
539         mov     r4, #0x2                @ L2X0_DYNAMIC_CLK_GATING_EN
540         str     r4, [r9, #L2X0_PWR_CTRL]
541         cmp     r0, #0
542
543         beq     __reenable_l2x0
544
545         mov     r0, #0xff
546         str     r0, [r9, #L2X0_INV_WAY]
547 1:      ldr     r1, [r9, #L2X0_INV_WAY]
548         tst     r1, r0
549         bne     1b
550         mov     r0, #0
551         str     r0, [r9, #L2X0_CACHE_SYNC]
552 __reenable_l2x0:
553         mov     r5, #0
554         mcr     p15, 0, r5, c8, c3, 0   @ invalidate TLB
555         mcr     p15, 0, r5, c7, c5, 6   @ flush BTAC
556         mcr     p15, 0, r5, c7, c5, 0   @ flush instruction cache
557         dsb
558         isb
559         str     r3, [r9, #L2X0_CTRL]
560 #endif
561         b       __cortex_a9_restore
562
563
564         .align L1_CACHE_SHIFT
565 ENTRY(__shut_off_mmu)
566         mrc     p15, 0, r3, c1, c0, 0
567         movw    r2, #(1<<12) | (1<<11) | (1<<2) | (1<<0)
568         bic     r3, r3, r2
569         dsb
570         mcr     p15, 0, r3, c1, c0, 0
571         isb
572         bx      r9
573 ENDPROC(__shut_off_mmu)
574
575 /*
576  *      __invalidate_l1
577  *
578  *        Invalidates the L1 data cache (no clean) during initial boot of
579  *        a secondary processor
580  *
581  *        Corrupted registers: r0-r6
582  */
583 __invalidate_l1:
584         mov     r0, #0
585         mcr     p15, 2, r0, c0, c0, 0
586         mrc     p15, 1, r0, c0, c0, 0
587
588         movw    r1, #0x7fff
589         and     r2, r1, r0, lsr #13
590
591         movw    r1, #0x3ff
592
593         and     r3, r1, r0, lsr #3  @ NumWays - 1
594         add     r2, r2, #1      @ NumSets
595
596         and     r0, r0, #0x7
597         add     r0, r0, #4      @ SetShift
598
599         clz     r1, r3          @ WayShift
600         add     r4, r3, #1      @ NumWays
601 1:      sub     r2, r2, #1      @ NumSets--
602         mov     r3, r4          @ Temp = NumWays
603 2:      subs    r3, r3, #1      @ Temp--
604         mov     r5, r3, lsl r1
605         mov     r6, r2, lsl r0
606         orr     r5, r5, r6      @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
607         mcr     p15, 0, r5, c7, c6, 2
608         bgt     2b
609         cmp     r2, #0
610         bgt     1b
611         dsb
612         isb
613         bx      lr
614 ENDPROC(__invalidate_l1)
615
616 /*
617  *      __invalidate_cpu_state
618  *
619  *       Invalidates volatile CPU state (SCU tags, caches, branch address
620  *       arrays, exclusive monitor, etc.) so that they can be safely enabled
621  *       instruction caching and branch predicition enabled as early as
622  *       possible to improve performance
623  */
624 ENTRY(__invalidate_cpu_state)
625         clrex
626         mov     r0, #0
627         mcr     p15, 0, r0, c1, c0, 1   @ disable SMP, prefetch, broadcast
628         isb
629         mcr     p15, 0, r0, c7, c5, 0   @ invalidate BTAC, i-cache
630         mcr     p15, 0, r0, c7, c5, 6   @ invalidate branch pred array
631         mcr     p15, 0, r0, c8, c7, 0   @ invalidate unified TLB
632         dsb
633         isb
634
635         cpu_id  r0
636         cmp     r0, #0
637         mov32   r1, (TEGRA_ARM_PERIF_BASE + 0xC)
638         movne   r0, r0, lsl #2
639         movne   r2, #0xf
640         movne   r2, r2, lsl r0
641         strne   r2, [r1]                @ invalidate SCU tags for CPU
642
643         dsb
644         mov     r0, #0x1800
645         mcr     p15, 0, r0, c1, c0, 0   @ enable branch prediction, i-cache
646         isb
647         b       __invalidate_l1         @ invalidate data cache
648 ENDPROC(__invalidate_cpu_state)
649
650 /*
651  *      __return_to_virtual(unsigned long pgdir, void (*ctx_restore)(void))
652  *
653  *        Restores a CPU to the world of virtual addressing, using the
654  *        specified page tables (which must ensure that a VA=PA mapping
655  *        exists for the __enable_mmu function), and then jumps to
656  *        ctx_restore to restore CPU context and return control to the OS
657  */
658         .align L1_CACHE_SHIFT
659 ENTRY(__return_to_virtual)
660         orr     r8, r0, #TTB_FLAGS
661         mov     lr, r1                  @ "return" to ctx_restore
662         mov     r3, #0
663         mcr     p15, 0, r3, c2, c0, 2   @ TTB control register
664
665         mcr     p15, 0, r8, c2, c0, 1   @ load TTBR1
666
667         mov     r0, #0x1f
668         mcr     p15, 0, r0, c3, c0, 0   @ domain access register
669
670         mov32   r0, 0xff0a89a8
671 #ifdef CONFIG_SMP
672         mov32   r1, 0xc0e0c4e0
673 #else
674         mov32   r1, 0x40e044e0
675 #endif
676         mcr     p15, 0, r0, c10, c2, 0  @ PRRR
677         mcr     p15, 0, r1, c10, c2, 1  @ NMRR
678         mrc     p15, 0, r0, c1, c0, 0
679         mov32   r1, 0x0120c302
680         bic     r0, r0, r1
681         mov32   r1, 0x10c03c7d
682         orr     r0, r0, r1
683
684 #ifdef CONFIG_ALIGNMENT_TRAP
685         orr     r0, r0, #0x2
686 #else
687         bic     r0, r0, #0x2
688 #endif
689         mov     r1, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
690                       domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
691                       domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
692                       domain_val(DOMAIN_IO, DOMAIN_CLIENT))
693         mcr     p15, 0, r1, c3, c0, 0   @ domain access register
694         mcr     p15, 0, r8, c2, c0, 0   @ TTBR0
695         b       __turn_mmu_on_again
696         andeq   r0, r0, r0
697         andeq   r0, r0, r0
698         andeq   r0, r0, r0
699         andeq   r0, r0, r0
700 ENDPROC(__return_to_virtual)
701
702 /*
703  *      __turn_mmu_on_again
704  *
705  *        does exactly what it advertises: turns the MMU on, again
706  *        jumps to the *virtual* address lr after the MMU is enabled.
707  */
708         .align  L1_CACHE_SHIFT
709 __turn_mmu_on_again:
710         mov     r0, r0
711         mcr     p15, 0, r0, c1, c0, 0
712         mrc     p15, 0, r3, c0, c0, 0
713         mov     r3, r3
714         mov     r3, lr
715         bx      lr
716 ENDPROC(__turn_mmu_on_again)