aac1d85f9cd940b871579ef4e93b4d5575b0b8eb
[linux-3.10.git] / arch / arm / mm / proc-v7.S
1 /*
2  *  linux/arch/arm/mm/proc-v7.S
3  *
4  *  Copyright (C) 2001 Deep Blue Solutions Ltd.
5  *  Copyright (c) 2001-2014, NVIDIA CORPORATION. All rights reserved.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  *
11  *  This is the "shell" of the ARMv7 processor support.
12  */
13 #include <linux/init.h>
14 #include <linux/linkage.h>
15 #include <asm/assembler.h>
16 #include <asm/asm-offsets.h>
17 #include <asm/hwcap.h>
18 #include <asm/pgtable-hwdef.h>
19 #include <asm/pgtable.h>
20
21 #include "proc-macros.S"
22
23 #ifdef CONFIG_ARM_LPAE
24 #include "proc-v7-3level.S"
25 #else
26 #include "proc-v7-2level.S"
27 #endif
28
29 #define TEGRA_CLK_RESET_BOND_OUT 0x60006070
30
31 ENTRY(cpu_v7_proc_init)
32         mov     pc, lr
33 ENDPROC(cpu_v7_proc_init)
34
35 ENTRY(cpu_v7_proc_fin)
36         mrc     p15, 0, r0, c1, c0, 0           @ ctrl register
37         bic     r0, r0, #0x1000                 @ ...i............
38         bic     r0, r0, #0x0006                 @ .............ca.
39         mcr     p15, 0, r0, c1, c0, 0           @ disable caches
40         mov     pc, lr
41 ENDPROC(cpu_v7_proc_fin)
42
43 /*
44  *      cpu_v7_reset(loc)
45  *
46  *      Perform a soft reset of the system.  Put the CPU into the
47  *      same state as it would be if it had been reset, and branch
48  *      to what would be the reset vector.
49  *
50  *      - loc   - location to jump to for soft reset
51  *
52  *      This code must be executed using a flat identity mapping with
53  *      caches disabled.
54  */
55         .align  5
56         .pushsection    .idmap.text, "ax"
57 ENTRY(cpu_v7_reset)
58         mrc     p15, 0, r1, c1, c0, 0           @ ctrl register
59         bic     r1, r1, #0x1                    @ ...............m
60  THUMB( bic     r1, r1, #1 << 30 )              @ SCTLR.TE (Thumb exceptions)
61         mcr     p15, 0, r1, c1, c0, 0           @ disable MMU
62         isb
63         bx      r0
64 ENDPROC(cpu_v7_reset)
65         .popsection
66
67 /*
68  *      cpu_v7_do_idle()
69  *
70  *      Idle the processor (eg, wait for interrupt).
71  *
72  *      IRQs are already disabled.
73  */
74 ENTRY(cpu_v7_do_idle)
75         dsb                                     @ WFI may enter a low-power mode
76         wfi
77         mov     pc, lr
78 ENDPROC(cpu_v7_do_idle)
79
80 ENTRY(cpu_v7_dcache_clean_area)
81         ALT_SMP(W(nop))                 @ MP extensions imply L1 PTW
82         ALT_UP_B(1f)
83         mov     pc, lr
84 1:      dcache_line_size r2, r3
85 2:      mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
86         add     r0, r0, r2
87         subs    r1, r1, r2
88         bhi     2b
89         dsb
90         mov     pc, lr
91 ENDPROC(cpu_v7_dcache_clean_area)
92
93         string  cpu_v7_name, "ARMv7 Processor"
94         .align
95
96 /* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */
97 .local  cpu_v7_debug_suspend_size
98 #ifdef CONFIG_ARM_SAVE_DEBUG_CONTEXT
99 /*
100  * Debug context:
101  *      8 CP14 registers
102  *      16x2 CP14 breakpoint registers (maximum)
103  *      16x2 CP14 watchpoint registers (maximum)
104  */
105 .equ    cpu_v7_debug_suspend_size, (4 * (8 + (16 * 2) + (16 * 2)))
106
107 .macro  save_brkpt cm
108         mrc     p14, 0, r4, c0, \cm, 4
109         mrc     p14, 0, r5, c0, \cm, 5
110         stmia   r0!, {r4 - r5}
111 .endm
112
113 .macro  restore_brkpt cm
114         ldmia   r0!, {r4 - r5}
115         mcr     p14, 0, r4, c0, \cm, 4
116         mcr     p14, 0, r5, c0, \cm, 5
117 .endm
118
119 .macro  save_wpt cm
120         mrc     p14, 0, r4, c0, \cm, 6
121         mrc     p14, 0, r5, c0, \cm, 7
122         stmia   r0!, {r4 - r5}
123 .endm
124
125 .macro  restore_wpt cm
126         ldmia   r0!, {r4 - r5}
127         mcr     p14, 0, r4, c0, \cm, 6
128         mcr     p14, 0, r5, c0, \cm, 7
129 .endm
130
131 #else
132 .equ    cpu_v7_debug_suspend_size, 0
133 #endif
134
135 .globl  cpu_v7_suspend_size
136 .equ    cpu_v7_suspend_size, (4 * 26) + cpu_v7_debug_suspend_size
137 #ifdef CONFIG_ARM_CPU_SUSPEND
138 ENTRY(cpu_v7_do_suspend)
139         stmfd   sp!, {r3 - r10, lr}
140         mrc     p15, 0, r4, c13, c0, 0  @ FCSE/PID
141         mrc     p15, 0, r5, c13, c0, 3  @ User r/o thread ID
142         mrc     p15, 0, r6, c15, c0, 1  @ diag
143         stmia   r0!, {r4 - r6}
144
145         mrc     p15, 0, r7, c9, c14, 2  @ PMINTENCLR
146         mrc     p15, 0, r8, c9, c14, 0  @ PMUSEREN
147         mrc     p15, 0, r9, c9, c13, 0  @ PMCCNTR, cycle counter
148         mrc     p15, 0, r10, c9, c12, 0 @ PMCR, control register
149         bic     r6, r10, #1             @ disable counters
150         mcr     p15, 0, r6, c9, c12, 0  @ write PMCR
151         mrc     p15, 0, r11, c9, c12, 1 @ PMCNTENSET, counter enable set
152         stmia   r0!, {r7 - r11}
153         mov     r7, r10, lsr #11        @ PMCR/N (number of event counters)
154         and     r7, r7, #0x1f           @ bits 15:11, 5 bits
155         sub     r7, r7, #1              @ start from last
156 1:      mcr     p15, 0, r7, c9, c12, 5  @ set PMSELR
157         mrc     p15, 0, r8, c9, c13, 1  @ read PMXEVTYPER
158         mrc     p15, 0, r9, c9, c13, 2  @ read PMXEVCNTR
159         stmia   r0!, {r8 - r9}
160         subs    r7, #1
161         bpl     1b
162
163         mrc     p15, 0, r6, c3, c0, 0   @ Domain ID
164         mrc     p15, 0, r7, c2, c0, 1   @ TTB 1
165         mrc     p15, 0, r11, c2, c0, 2  @ TTB control register
166         mrc     p15, 0, r8, c1, c0, 0   @ Control register
167         mrc     p15, 0, r9, c1, c0, 1   @ Auxiliary control register
168         mrc     p15, 0, r10, c1, c0, 2  @ Co-processor access control
169         stmia   r0!, {r6 - r11}
170
171 #ifdef CONFIG_ARM_SAVE_DEBUG_CONTEXT
172         /* If Debug Architecture v7.1 or later, set OS lock. */
173         mrc     p15, 0, r11, c0, c1, 2  @ ID_DFR0
174         and     r11, r11, #0xF          @ coprocessor debug model
175         cmp     r11, #5                 @ debug arch >= v7.1?
176 #ifndef CONFIG_ARM_SAVE_DEBUG_CONTEXT_NO_LOCK
177         ldrge   r4, =0xC5ACCE55         @ Lock value
178         mcrge   p14, 0, r4, c1, c0, 4   @ DBGOSLAR
179         isb
180 #endif
181         /* Save CP14 debug controller context */
182
183         mrc     p14, 0, r4, c0, c2, 2   @ DBGDSCRext
184         mrc     p14, 0, r5, c0, c6, 0   @ DBGWFAR
185         mrc     p14, 0, r6, c0, c7, 0   @ DBGVCR
186         mrc     p14, 0, r7, c7, c9, 6   @ DBGCLAIMCLR
187         stmia   r0!, {r4-r7}
188
189         mrclt   p14, 0, r4, c0, c10, 0  @ DBGDSCCR (debug arch v7 only)
190         mrclt   p14, 0, r5, c0, c11, 0  @ DBGDSMCR (debug arch v7 only)
191         stmltia r0!, {r4-r5}            @ (debug arch v7 only)
192
193         tst     r4, #(1 << 29)          @ DBGDSCRext.TXfull
194         mrcne   p14, 0, r4, c0, c3, 2   @ DBGDTRTXext
195         strne   r4, [r0], #4
196
197         tst     r4, #(1 << 30)          @ DBGDSCRext.RXfull
198         mrcne   p14, 0, r4, c0, c0, 2   @ DBGDTRRXext
199         strne   r4, [r0], #4
200
201         mrc     p14, 0, r8, c0, c0, 0   @ read IDR
202         mov     r3, r8, lsr #24
203         and     r3, r3, #0xf            @ r3 has the number of brkpt
204         rsb     r3, r3, #0xf
205
206         /* r3 = (15 - #of brkpt) ;
207            switch offset = r3*12 - 4 = (r3*3 - 1)<<2
208         */
209         add     r3, r3, r3, lsl #1
210         sub     r3, r3, #1
211         add     pc, pc, r3, lsl #2
212
213         save_brkpt      c15
214         save_brkpt      c14
215         save_brkpt      c13
216         save_brkpt      c12
217         save_brkpt      c11
218         save_brkpt      c10
219         save_brkpt      c9
220         save_brkpt      c8
221         save_brkpt      c7
222         save_brkpt      c6
223         save_brkpt      c5
224         save_brkpt      c4
225         save_brkpt      c3
226         save_brkpt      c2
227         save_brkpt      c1
228         save_brkpt      c0
229
230         mov     r3, r8, lsr #28         @ r3 has the number of wpt
231         rsb     r3, r3, #0xf
232
233         /* r3 = (15 - #of wpt) ;
234            switch offset = r3*12 - 4 = (r3*3 - 1)<<2
235         */
236         add     r3, r3, r3, lsl #1
237         sub     r3, r3, #1
238         add     pc, pc, r3, lsl #2
239
240         save_wpt        c15
241         save_wpt        c14
242         save_wpt        c13
243         save_wpt        c12
244         save_wpt        c11
245         save_wpt        c10
246         save_wpt        c9
247         save_wpt        c8
248         save_wpt        c7
249         save_wpt        c6
250         save_wpt        c5
251         save_wpt        c4
252         save_wpt        c3
253         save_wpt        c2
254         save_wpt        c1
255         save_wpt        c0
256 #endif
257         ldmfd   sp!, {r3 - r10, pc}
258 ENDPROC(cpu_v7_do_suspend)
259
260 ENTRY(cpu_v7_do_resume)
261         mov     ip, #0
262         mcr     p15, 0, ip, c8, c7, 0   @ invalidate TLBs
263         mcr     p15, 0, ip, c7, c5, 0   @ invalidate I cache
264         mcr     p15, 0, ip, c13, c0, 1  @ set reserved context ID
265         ldmia   r0!, {r4 - r6}
266         mcr     p15, 0, r4, c13, c0, 0  @ FCSE/PID
267         mcr     p15, 0, r5, c13, c0, 3  @ User r/o thread ID
268         mrc     p14, 0, r7, c0, c1, 0   @ dbgdscr
269         tst     r7, #(1 << 18)          @ dbgdscr.ns
270         mcreq   p15, 0, r6, c15, c0, 1  @ diag only in secure-mode
271
272         ldmia   r0!, {r7 - r11}
273         mcr     p15, 0, r7, c9, c14, 2  @ PMINTENCLR
274         mcr     p15, 0, r8, c9, c14, 0  @ PMUSEREN
275         mcr     p15, 0, r9, c9, c13, 0  @ PMCCNTR, cycle counter
276         mcr     p15, 0, r11, c9, c12, 1 @ PMCNTENSET, counter enable set
277         @ restore PMCR later
278         mov     r7, r10, lsr #11        @ PMCR/N (number of event counters)
279         and     r7, r7, #0x1f           @ bits 15:11, 5 bits
280         sub     r7, r7, #1              @ start from last
281 1:      mcr     p15, 0, r7, c9, c12, 5  @ set PMSELR
282         ldmia   r0!, {r8 - r9}
283         mcr     p15, 0, r8, c9, c13, 1  @ write PMXEVTYPER
284         mcr     p15, 0, r9, c9, c13, 2  @ write PMXEVCNTR
285         subs    r7, #1
286         bpl     1b
287         mcr     p15, 0, r10, c9, c12, 0 @ PMCR, control register
288
289         ldmia   r0!, {r6 - r11}
290         mcr     p15, 0, r6, c3, c0, 0   @ Domain ID
291 #ifndef CONFIG_ARM_LPAE
292         ALT_SMP(orr     r1, r1, #TTB_FLAGS_SMP)
293         ALT_UP(orr      r1, r1, #TTB_FLAGS_UP)
294 #endif
295         mcr     p15, 0, r1, c2, c0, 0   @ TTB 0
296         mcr     p15, 0, r7, c2, c0, 1   @ TTB 1
297         mcr     p15, 0, r11, c2, c0, 2  @ TTB control register
298         mrc     p15, 0, r4, c1, c0, 1   @ Read Auxiliary control register
299         teq     r4, r9                  @ Is it already set?
300 #ifdef CONFIG_ARM_ERRATA_799270
301         ldr     r4, =TEGRA_CLK_RESET_BOND_OUT
302         ldr     r4, [r4]
303         and     r4, r4, #0
304         orr     r9, r9, r4
305 #endif
306         mcrne   p15, 0, r9, c1, c0, 1   @ No, so write it
307         mcr     p15, 0, r10, c1, c0, 2  @ Co-processor access control
308         ldr     r4, =PRRR               @ PRRR
309         ldr     r5, =NMRR               @ NMRR
310         mcr     p15, 0, r4, c10, c2, 0  @ write PRRR
311         mcr     p15, 0, r5, c10, c2, 1  @ write NMRR
312         isb
313
314 #ifdef CONFIG_ARM_SAVE_DEBUG_CONTEXT
315         /* If Debug Architecture v7.1 or later, set OS lock. */
316         mrc     p15, 0, r11, c0, c1, 2  @ ID_DFR0
317         and     r11, r11, #0xF          @ coprocessor debug model
318         cmp     r11, #5                 @ debug arch >= v7.1?
319 #ifndef CONFIG_ARM_SAVE_DEBUG_CONTEXT_NO_LOCK
320         ldrge   r4, =0xC5ACCE55         @ Lock value
321         mcrge   p14, 0, r4, c1, c0, 4   @ DBGOSLAR
322         isb
323 #endif
324
325         /* Restore CP14 debug controller context */
326
327         ldmia   r0!, {r2 - r5}
328         mcr     p14, 0, r3, c0, c6, 0   @ DBGWFAR
329         mcr     p14, 0, r4, c0, c7, 0   @ DBGVCR
330         mcr     p14, 0, r5, c7, c8, 6   @ DBGCLAIMSET
331
332         ldmltia r0!, {r4-r5}            @ (debug arch v7 only)
333         mcrlt   p14, 0, r4, c0, c10, 0  @ DBGDSCCR (debug arch v7 only)
334         mcrlt   p14, 0, r5, c0, c11, 0  @ DBGDSMCR (debug arch v7 only)
335
336         tst     r2, #(1 << 29)          @ DBGDSCRext.TXfull
337         ldrne   r4, [r0], #4
338         mcrne   p14, 0, r4, c0, c3, 2   @ DBGDTRTXext
339
340         tst     r2, #(1 << 30)          @ DBGDSCRext.RXfull
341         ldrne   r4, [r0], #4
342         mcrne   p14, 0, r4, c0, c0, 2   @ DBGDTRRXext
343
344         mrc     p14, 0, r5, c0, c0, 0   @ read IDR
345         mov     r3, r5, lsr #24
346         and     r3, r3, #0xf            @ r3 has the number of brkpt
347         rsb     r3, r3, #0xf
348
349         /* r3 = (15 - #of wpt) ;
350            switch offset = r3*12 - 4 = (r3*3 - 1)<<2
351         */
352         add     r3, r3, r3, lsl #1
353         sub     r3, r3, #1
354         add     pc, pc, r3, lsl #2
355
356         restore_brkpt   c15
357         restore_brkpt   c14
358         restore_brkpt   c13
359         restore_brkpt   c12
360         restore_brkpt   c11
361         restore_brkpt   c10
362         restore_brkpt   c9
363         restore_brkpt   c8
364         restore_brkpt   c7
365         restore_brkpt   c6
366         restore_brkpt   c5
367         restore_brkpt   c4
368         restore_brkpt   c3
369         restore_brkpt   c2
370         restore_brkpt   c1
371         restore_brkpt   c0
372
373         mov     r3, r5, lsr #28         @ r3 has the number of wpt
374         rsb     r3, r3, #0xf
375
376         /* r3 = (15 - #of wpt) ;
377            switch offset = r3*12 - 4 = (r3*3 - 1)<<2
378         */
379         add     r3, r3, r3, lsl #1
380         sub     r3, r3, #1
381         add     pc, pc, r3, lsl #2
382
383 start_restore_wpt:
384         restore_wpt     c15
385         restore_wpt     c14
386         restore_wpt     c13
387         restore_wpt     c12
388         restore_wpt     c11
389         restore_wpt     c10
390         restore_wpt     c9
391         restore_wpt     c8
392         restore_wpt     c7
393         restore_wpt     c6
394         restore_wpt     c5
395         restore_wpt     c4
396         restore_wpt     c3
397         restore_wpt     c2
398         restore_wpt     c1
399         restore_wpt     c0
400         isb
401
402         mcr     p14, 0, r2, c0, c2, 2   @ DSCR
403         isb
404
405 #ifndef CONFIG_ARM_SAVE_DEBUG_CONTEXT_NO_LOCK
406         mov     r4, #0                  @ non-lock value
407         cmp     r11, #5                 @ debug arch >= v7.1?
408         mcrge   p14, 0, r4, c1, c0, 4   @ DBGOSLAR
409         isb
410 #endif
411 #endif
412         dsb
413         mov     r0, r8                  @ control register
414         b       cpu_resume_mmu
415 ENDPROC(cpu_v7_do_resume)
416 #endif
417
418 /*
419  * Cortex-A15
420  */
421         globl_equ       cpu_ca15_proc_init,     cpu_v7_proc_init
422         globl_equ       cpu_ca15_proc_fin,      cpu_v7_proc_fin
423         globl_equ       cpu_ca15_reset,         cpu_v7_reset
424         globl_equ       cpu_ca15_do_idle,       cpu_v7_do_idle
425         globl_equ       cpu_ca15_dcache_clean_area, cpu_v7_dcache_clean_area
426         globl_equ       cpu_ca15_set_pte_ext,   cpu_v7_set_pte_ext
427         globl_equ       cpu_ca15_suspend_size,  cpu_v7_suspend_size
428 #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
429         globl_equ       cpu_ca15_switch_mm,     cpu_v7_icinv_switch_mm
430 #else
431         globl_equ       cpu_ca15_switch_mm,     cpu_v7_switch_mm
432 #endif
433 #ifdef CONFIG_ARM_CPU_SUSPEND
434         globl_equ       cpu_ca15_do_suspend,    cpu_v7_do_suspend
435         globl_equ       cpu_ca15_do_resume,     cpu_v7_do_resume
436 #endif
437
438 #ifdef CONFIG_CPU_PJ4B
439         globl_equ       cpu_pj4b_switch_mm,     cpu_v7_switch_mm
440         globl_equ       cpu_pj4b_set_pte_ext,   cpu_v7_set_pte_ext
441         globl_equ       cpu_pj4b_proc_init,     cpu_v7_proc_init
442         globl_equ       cpu_pj4b_proc_fin,      cpu_v7_proc_fin
443         globl_equ       cpu_pj4b_reset,         cpu_v7_reset
444 #ifdef CONFIG_PJ4B_ERRATA_4742
445 ENTRY(cpu_pj4b_do_idle)
446         dsb                                     @ WFI may enter a low-power mode
447         wfi
448         dsb                                     @barrier
449         mov     pc, lr
450 ENDPROC(cpu_pj4b_do_idle)
451 #else
452         globl_equ       cpu_pj4b_do_idle,       cpu_v7_do_idle
453 #endif
454         globl_equ       cpu_pj4b_dcache_clean_area,     cpu_v7_dcache_clean_area
455         globl_equ       cpu_pj4b_do_suspend,    cpu_v7_do_suspend
456         globl_equ       cpu_pj4b_do_resume,     cpu_v7_do_resume
457         globl_equ       cpu_pj4b_suspend_size,  cpu_v7_suspend_size
458
459 #endif
460
461         __CPUINIT
462
463 /*
464  *      __v7_setup
465  *
466  *      Initialise TLB, Caches, and MMU state ready to switch the MMU
467  *      on.  Return in r0 the new CP15 C1 control register setting.
468  *
469  *      This should be able to cover all ARMv7 cores.
470  *
471  *      It is assumed that:
472  *      - cache type register is implemented
473  */
474 __v7_ca5mp_setup:
475 __v7_ca9mp_setup:
476 #ifdef CONFIG_ARCH_TEGRA_14x_SOC
477         mov     r10, #(5 << 0)                  @ TLB ops broadcasting
478 #else
479         mov     r10, #(1 << 0)                  @ TLB ops broadcasting
480 #endif
481         b       1f
482 __v7_ca15mp_r3_setup:
483         mrc     p15, 1, r0, c15, c0, 4          @ ACTLR2
484         orr     r0, #(1<<31)                    @ Enable regional clock gates
485         mcr     p15, 1, r0, c15, c0, 4
486 __v7_ca15mp_setup:
487 #ifdef CONFIG_ARCH_TEGRA
488         mrc     p15, 0, r0, c1, c0, 1
489         orr     r0, #(1<<24)                    @ Enable NCSE in ACTLR
490         mcr     p15, 0, r0, c1, c0, 1
491
492         mrc     p15, 1, r0, c15, c0, 3          @ L2PCR
493         tst     r0, #0x1000
494         orreq   r0, r0, #0x1000                 @ disable prefetch throttling
495         mcreq   p15, 1, r0, c15, c0, 3
496
497         ALT_SMP(mrc     p15, 0, r0, c1, c0, 1)
498         ALT_UP(mov      r0, #(1 << 6))          @ fake it for UP
499         tst     r0, #(1 << 6)                   @ SMP/nAMP mode enabled?
500         orreq   r0, r0, #(1 << 6)               @ Enable SMP/nAMP mode
501 #ifdef CONFIG_ARM_ERRATA_799270
502         ldr     r10, =TEGRA_CLK_RESET_BOND_OUT
503         ldr     r10, [r10]
504         and     r10, r10, #0
505         orr     r0, r0, r10
506 #endif
507         mcreq   p15, 0, r0, c1, c0, 1
508
509         b       __v7_setup
510 #endif
511 __v7_ca7mp_setup:
512         mov     r10, #0
513 1:
514 #ifdef CONFIG_SMP
515         ALT_SMP(mrc     p15, 0, r0, c1, c0, 1)
516         ALT_UP(mov      r0, #(1 << 6))          @ fake it for UP
517         tst     r0, #(1 << 6)                   @ SMP/nAMP mode enabled?
518         orreq   r0, r0, #(1 << 6)               @ Enable SMP/nAMP mode
519         orreq   r0, r0, r10                     @ Enable CPU-specific SMP bits
520         mcreq   p15, 0, r0, c1, c0, 1
521 #endif
522         b       __v7_setup
523
524 __v7_pj4b_setup:
525 #ifdef CONFIG_CPU_PJ4B
526
527 /* Auxiliary Debug Modes Control 1 Register */
528 #define PJ4B_STATIC_BP (1 << 2) /* Enable Static BP */
529 #define PJ4B_INTER_PARITY (1 << 8) /* Disable Internal Parity Handling */
530 #define PJ4B_BCK_OFF_STREX (1 << 5) /* Enable the back off of STREX instr */
531 #define PJ4B_CLEAN_LINE (1 << 16) /* Disable data transfer for clean line */
532
533 /* Auxiliary Debug Modes Control 2 Register */
534 #define PJ4B_FAST_LDR (1 << 23) /* Disable fast LDR */
535 #define PJ4B_SNOOP_DATA (1 << 25) /* Do not interleave write and snoop data */
536 #define PJ4B_CWF (1 << 27) /* Disable Critical Word First feature */
537 #define PJ4B_OUTSDNG_NC (1 << 29) /* Disable outstanding non cacheable rqst */
538 #define PJ4B_L1_REP_RR (1 << 30) /* L1 replacement - Strict round robin */
539 #define PJ4B_AUX_DBG_CTRL2 (PJ4B_SNOOP_DATA | PJ4B_CWF |\
540                             PJ4B_OUTSDNG_NC | PJ4B_L1_REP_RR)
541
542 /* Auxiliary Functional Modes Control Register 0 */
543 #define PJ4B_SMP_CFB (1 << 1) /* Set SMP mode. Join the coherency fabric */
544 #define PJ4B_L1_PAR_CHK (1 << 2) /* Support L1 parity checking */
545 #define PJ4B_BROADCAST_CACHE (1 << 8) /* Broadcast Cache and TLB maintenance */
546
547 /* Auxiliary Debug Modes Control 0 Register */
548 #define PJ4B_WFI_WFE (1 << 22) /* WFI/WFE - serve the DVM and back to idle */
549
550         /* Auxiliary Debug Modes Control 1 Register */
551         mrc     p15, 1, r0, c15, c1, 1
552         orr     r0, r0, #PJ4B_CLEAN_LINE
553         orr     r0, r0, #PJ4B_BCK_OFF_STREX
554         orr     r0, r0, #PJ4B_INTER_PARITY
555         bic     r0, r0, #PJ4B_STATIC_BP
556         mcr     p15, 1, r0, c15, c1, 1
557
558         /* Auxiliary Debug Modes Control 2 Register */
559         mrc     p15, 1, r0, c15, c1, 2
560         bic     r0, r0, #PJ4B_FAST_LDR
561         orr     r0, r0, #PJ4B_AUX_DBG_CTRL2
562         mcr     p15, 1, r0, c15, c1, 2
563
564         /* Auxiliary Functional Modes Control Register 0 */
565         mrc     p15, 1, r0, c15, c2, 0
566 #ifdef CONFIG_SMP
567         orr     r0, r0, #PJ4B_SMP_CFB
568 #endif
569         orr     r0, r0, #PJ4B_L1_PAR_CHK
570         orr     r0, r0, #PJ4B_BROADCAST_CACHE
571         mcr     p15, 1, r0, c15, c2, 0
572
573         /* Auxiliary Debug Modes Control 0 Register */
574         mrc     p15, 1, r0, c15, c1, 0
575         orr     r0, r0, #PJ4B_WFI_WFE
576         mcr     p15, 1, r0, c15, c1, 0
577
578 #endif /* CONFIG_CPU_PJ4B */
579
580 __v7_setup:
581         adr     r12, __v7_setup_stack           @ the local stack
582         mrc     p15, 0, r0, c0, c0, 0           @ read main ID register
583         ubfx    r10, r0, #4, #28
584         ldr     r6, =0x00f0000
585         bic     r10, r10, r6
586         ldr     r6, =0x410fc0f                  @ ARM cortex A15
587         teq     r10, r6
588         biceq   r10, r10, r10                   @ clear r10 if it's A15
589         beq     4f
590         stmia   r12, {r0-r5, r7, r9, r11, lr}
591         bl      v7_flush_dcache_louis
592         ldmia   r12, {r0-r5, r7, r9, r11, lr}
593
594         and     r10, r0, #0xff000000            @ ARM?
595         teq     r10, #0x41000000
596         bne     3f
597         and     r5, r0, #0x00f00000             @ variant
598         and     r6, r0, #0x0000000f             @ revision
599         orr     r6, r6, r5, lsr #20-4           @ combine variant and revision
600         ubfx    r0, r0, #4, #12                 @ primary part number
601
602         /* Cortex-A8 Errata */
603         ldr     r10, =0x00000c08                @ Cortex-A8 primary part number
604         teq     r0, r10
605         bne     2f
606 #if defined(CONFIG_ARM_ERRATA_430973) && !defined(CONFIG_ARCH_MULTIPLATFORM)
607
608         teq     r5, #0x00100000                 @ only present in r1p*
609         mrceq   p15, 0, r10, c1, c0, 1          @ read aux control register
610         orreq   r10, r10, #(1 << 6)             @ set IBE to 1
611         mcreq   p15, 0, r10, c1, c0, 1          @ write aux control register
612 #endif
613 #ifdef CONFIG_ARM_ERRATA_458693
614         teq     r6, #0x20                       @ only present in r2p0
615         mrceq   p15, 0, r10, c1, c0, 1          @ read aux control register
616         orreq   r10, r10, #(1 << 5)             @ set L1NEON to 1
617         orreq   r10, r10, #(1 << 9)             @ set PLDNOP to 1
618         mcreq   p15, 0, r10, c1, c0, 1          @ write aux control register
619 #endif
620 #ifdef CONFIG_ARM_ERRATA_460075
621         teq     r6, #0x20                       @ only present in r2p0
622         mrceq   p15, 1, r10, c9, c0, 2          @ read L2 cache aux ctrl register
623         tsteq   r10, #1 << 22
624         orreq   r10, r10, #(1 << 22)            @ set the Write Allocate disable bit
625         mcreq   p15, 1, r10, c9, c0, 2          @ write the L2 cache aux ctrl register
626 #endif
627         b       3f
628
629         /* Cortex-A9 Errata */
630 2:      ldr     r10, =0x00000c09                @ Cortex-A9 primary part number
631         teq     r0, r10
632         bne     3f
633         str     r0, [r12]                       @ local stack
634         mrc     p14, 0, r0, c0, c1, 0           @ dbgdscr
635         tst     r0, #(1 << 18)                  @ dbgdscr.ns
636         ldr     r0, [r12]                       @ restore r0
637         bne     3f                              @ skip in non-secure mode
638         cmp     r6, #0x10                       @ power ctrl reg added r1p0
639         mrcge   p15, 0, r10, c15, c0, 0         @ read power control register
640         orrge   r10, r10, #1                    @ enable dynamic clock gating
641         mcrge   p15, 0, r10, c15, c0, 0         @ write power control register
642 #ifdef CONFIG_ARM_ERRATA_716044
643         cmp     r6, #0x12                       @ present in r1p0 - r1p2
644         mrcle   p15, 0, r10, c1, c0, 0
645         orrle   r10, r10, #(1 << 14)            @ set SCTLR.RR
646         mcrle   p15, 0, r10, c1, c0, 0
647 #endif
648 #ifdef CONFIG_ARM_ERRATA_720791
649         teq     r5, #0x00100000                 @ only present in r1p*
650         mrceq   p15, 0, r10, c15, c0, 2         @ read "chicken power ctrl" reg
651         orreq   r10, r10, #0x30                 @ disable core clk gate on
652         mcreq   p15, 0, r10, c15, c0, 2         @ instr-side waits
653 #endif
654 #ifdef CONFIG_ARM_ERRATA_742230
655         cmp     r6, #0x22                       @ only present up to r2p2
656         mrcle   p15, 0, r10, c15, c0, 1         @ read diagnostic register
657         orrle   r10, r10, #1 << 4               @ set bit #4
658         mcrle   p15, 0, r10, c15, c0, 1         @ write diagnostic register
659 #endif
660 #ifdef CONFIG_ARM_ERRATA_742231
661         teq     r6, #0x20                       @ present in r2p0
662         teqne   r6, #0x21                       @ present in r2p1
663         teqne   r6, #0x22                       @ present in r2p2
664         mrceq   p15, 0, r10, c15, c0, 1         @ read diagnostic register
665         orreq   r10, r10, #1 << 12              @ set bit #12
666         orreq   r10, r10, #1 << 22              @ set bit #22
667         mcreq   p15, 0, r10, c15, c0, 1         @ write diagnostic register
668 #endif
669 #ifdef CONFIG_ARM_ERRATA_743622
670         teq     r5, #0x00200000                 @ only present in r2p*
671         mrceq   p15, 0, r10, c15, c0, 1         @ read diagnostic register
672         orreq   r10, r10, #1 << 6               @ set bit #6
673         mcreq   p15, 0, r10, c15, c0, 1         @ write diagnostic register
674 #endif
675 #if defined(CONFIG_ARM_ERRATA_751472) && defined(CONFIG_SMP)
676         ALT_SMP(cmp r6, #0x30)                  @ present prior to r3p0
677         ALT_UP_B(1f)
678         mrclt   p15, 0, r10, c15, c0, 1         @ read diagnostic register
679         orrlt   r10, r10, #1 << 11              @ set bit #11
680         mcrlt   p15, 0, r10, c15, c0, 1         @ write diagnostic register
681 1:
682 #endif
683 #ifdef CONFIG_ARM_ERRATA_752520
684         cmp     r6, #0x28                       @ present prior to r2p9
685         teqlt   r5, #0x00200000                 @ present from r2p0
686         mrceq   p15, 0, r10, c15, c0, 1         @ read diagnostic register
687         orreq   r10, r10, #1 << 20              @ set bit #20
688         mcreq   p15, 0, r10, c15, c0, 1         @ write diagnostic register
689 #endif
690 #ifdef CONFIG_ARM_ERRATA_761320
691         cmp     r6, #0x30                       @ only present up to r3p0
692         mrcle   p15, 0, r10, c15, c0, 1         @ read diagnostic register
693         orrle   r10, r10, #1 << 21              @ set bit #21
694         mcrle   p15, 0, r10, c15, c0, 1         @ write diagnostic register
695 #endif
696
697 3:      mov     r10, #0
698         mcr     p15, 0, r10, c7, c5, 0          @ I+BTB cache invalidate
699 4:
700 #ifdef CONFIG_MMU
701         mcr     p15, 0, r10, c8, c7, 0          @ invalidate I + D TLBs
702         v7_ttb_setup r10, r4, r8, r5            @ TTBCR, TTBRx setup
703         ldr     r5, =PRRR                       @ PRRR
704         ldr     r6, =NMRR                       @ NMRR
705         mcr     p15, 0, r5, c10, c2, 0          @ write PRRR
706         mcr     p15, 0, r6, c10, c2, 1          @ write NMRR
707 #endif
708         dsb                                     @ Complete invalidations
709 #ifndef CONFIG_ARM_THUMBEE
710         mrc     p15, 0, r0, c0, c1, 0           @ read ID_PFR0 for ThumbEE
711         and     r0, r0, #(0xf << 12)            @ ThumbEE enabled field
712         teq     r0, #(1 << 12)                  @ check if ThumbEE is present
713         bne     1f
714         mov     r5, #0
715         mcr     p14, 6, r5, c1, c0, 0           @ Initialize TEEHBR to 0
716         mrc     p14, 6, r0, c0, c0, 0           @ load TEECR
717         orr     r0, r0, #1                      @ set the 1st bit in order to
718         mcr     p14, 6, r0, c0, c0, 0           @ stop userspace TEEHBR access
719 1:
720 #endif
721         adr     r5, v7_crval
722         ldmia   r5, {r5, r6}
723 #ifdef CONFIG_CPU_ENDIAN_BE8
724         orr     r6, r6, #1 << 25                @ big-endian page tables
725 #endif
726 #ifdef CONFIG_SWP_EMULATE
727         orr     r5, r5, #(1 << 10)              @ set SW bit in "clear"
728         bic     r6, r6, #(1 << 10)              @ clear it in "mmuset"
729 #endif
730         mrc     p15, 0, r0, c1, c0, 0           @ read control register
731         bic     r0, r0, r5                      @ clear bits them
732         orr     r0, r0, r6                      @ set them
733  THUMB( orr     r0, r0, #1 << 30        )       @ Thumb exceptions
734         mov     pc, lr                          @ return to head.S:__ret
735 ENDPROC(__v7_setup)
736
737         .align  2
738 __v7_setup_stack:
739         .space  4 * 11                          @ 11 registers
740
741         __INITDATA
742
743         @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
744         define_processor_functions v7, dabort=v7_early_abort, pabort=v7_pabort, suspend=1
745         define_processor_functions ca15, dabort=v7_early_abort, pabort=v7_pabort, suspend=1
746 #ifdef CONFIG_CPU_PJ4B
747         define_processor_functions pj4b, dabort=v7_early_abort, pabort=v7_pabort, suspend=1
748 #endif
749
750         .section ".rodata"
751
752         string  cpu_arch_name, "armv7"
753         string  cpu_elf_name, "v7"
754         .align
755
756         .section ".proc.info.init", #alloc, #execinstr
757
758         /*
759          * Standard v7 proc info content
760          */
761 .macro __v7_proc initfunc, mm_mmuflags = 0, io_mmuflags = 0, hwcaps = 0, proc_fns = v7_processor_functions
762         ALT_SMP(.long   PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \
763                         PMD_SECT_AF | PMD_FLAGS_SMP | \mm_mmuflags)
764         ALT_UP(.long    PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \
765                         PMD_SECT_AF | PMD_FLAGS_UP | \mm_mmuflags)
766         .long   PMD_TYPE_SECT | PMD_SECT_AP_WRITE | \
767                 PMD_SECT_AP_READ | PMD_SECT_AF | \io_mmuflags
768         W(b)    \initfunc
769         .long   cpu_arch_name
770         .long   cpu_elf_name
771         .long   HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_FAST_MULT | \
772                 HWCAP_EDSP | HWCAP_TLS | \hwcaps
773         .long   cpu_v7_name
774         .long   \proc_fns
775         .long   v7wbi_tlb_fns
776         .long   v6_user_fns
777         .long   v7_cache_fns
778 .endm
779
780 #ifndef CONFIG_ARM_LPAE
781         /*
782          * ARM Ltd. Cortex A5 processor.
783          */
784         .type   __v7_ca5mp_proc_info, #object
785 __v7_ca5mp_proc_info:
786         .long   0x410fc050
787         .long   0xff0ffff0
788         __v7_proc __v7_ca5mp_setup
789         .size   __v7_ca5mp_proc_info, . - __v7_ca5mp_proc_info
790
791         /*
792          * ARM Ltd. Cortex A9 processor.
793          */
794         .type   __v7_ca9mp_proc_info, #object
795 __v7_ca9mp_proc_info:
796         .long   0x410fc090
797         .long   0xff0ffff0
798         __v7_proc __v7_ca9mp_setup
799         .size   __v7_ca9mp_proc_info, . - __v7_ca9mp_proc_info
800
801 #endif  /* CONFIG_ARM_LPAE */
802
803         /*
804          * Marvell PJ4B processor.
805          */
806 #ifdef CONFIG_CPU_PJ4B
807         .type   __v7_pj4b_proc_info, #object
808 __v7_pj4b_proc_info:
809         .long   0x560f5800
810         .long   0xff0fff00
811         __v7_proc __v7_pj4b_setup, proc_fns = pj4b_processor_functions
812         .size   __v7_pj4b_proc_info, . - __v7_pj4b_proc_info
813 #endif
814
815         /*
816          * ARM Ltd. Cortex A7 processor.
817          */
818         .type   __v7_ca7mp_proc_info, #object
819 __v7_ca7mp_proc_info:
820         .long   0x410fc070
821         .long   0xff0ffff0
822         __v7_proc __v7_ca7mp_setup
823         .size   __v7_ca7mp_proc_info, . - __v7_ca7mp_proc_info
824
825         /*
826          * ARM Ltd. Cortex A15 r3 processor.
827          */
828         .type   __v7_ca15mp_proc_info, #object
829 __v7_ca15mp_r3_proc_info:
830         .long   0x413fc0f0
831         .long   0xfffffff0
832         __v7_proc __v7_ca15mp_r3_setup, hwcaps = HWCAP_IDIV
833         .size   __v7_ca15mp_proc_info, . - __v7_ca15mp_proc_info
834
835         /*
836          * ARM Ltd. Cortex A15 processor.
837          */
838         .type   __v7_ca15mp_proc_info, #object
839 __v7_ca15mp_proc_info:
840         .long   0x410fc0f0
841         .long   0xff0ffff0
842         __v7_proc __v7_ca15mp_setup, proc_fns = ca15_processor_functions
843         .size   __v7_ca15mp_proc_info, . - __v7_ca15mp_proc_info
844
845         /*
846          * Qualcomm Inc. Krait processors.
847          */
848         .type   __krait_proc_info, #object
849 __krait_proc_info:
850         .long   0x510f0400              @ Required ID value
851         .long   0xff0ffc00              @ Mask for ID
852         /*
853          * Some Krait processors don't indicate support for SDIV and UDIV
854          * instructions in the ARM instruction set, even though they actually
855          * do support them.
856          */
857         __v7_proc __v7_setup, hwcaps = HWCAP_IDIV
858         .size   __krait_proc_info, . - __krait_proc_info
859
860         /*
861          * Match any ARMv7 processor core.
862          */
863         .type   __v7_proc_info, #object
864 __v7_proc_info:
865         .long   0x000f0000              @ Required ID value
866         .long   0x000f0000              @ Mask for ID
867         __v7_proc __v7_setup
868         .size   __v7_proc_info, . - __v7_proc_info