Merge branch 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszer...
[deliverable/linux.git] / arch / arm / mach-mvebu / coherency_ll.S
CommitLineData
009f1315
GC
1/*
2 * Coherency fabric: low level functions
3 *
4 * Copyright (C) 2012 Marvell
5 *
6 * Gregory CLEMENT <gregory.clement@free-electrons.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 *
12 * This file implements the assembly function to add a CPU to the
13 * coherency fabric. This function is called by each of the secondary
14 * CPUs during their early boot in an SMP kernel, this why this
15 * function have to callable from assembly. It can also be called by a
16 * primary CPU from C code during its boot.
17 */
18
19#include <linux/linkage.h>
20#define ARMADA_XP_CFB_CTL_REG_OFFSET 0x0
21#define ARMADA_XP_CFB_CFG_REG_OFFSET 0x4
22
bca028e7 23#include <asm/assembler.h>
ccd6a131 24#include <asm/cp15.h>
bca028e7 25
009f1315 26 .text
30cdef97
TP
27/*
28 * Returns the coherency base address in r1 (r0 is untouched), or 0 if
29 * the coherency fabric is not enabled.
30 */
2e8a5942 31ENTRY(ll_get_coherency_base)
ccd6a131
GC
32 mrc p15, 0, r1, c1, c0, 0
33 tst r1, #CR_M @ Check MMU bit enabled
34 bne 1f
35
4dd1b7fa
TP
36 /*
37 * MMU is disabled, use the physical address of the coherency
30cdef97
TP
38 * base address. However, if the coherency fabric isn't mapped
39 * (i.e its virtual address is zero), it means coherency is
40 * not enabled, so we return 0.
4dd1b7fa 41 */
30cdef97
TP
42 ldr r1, =coherency_base
43 cmp r1, #0
44 beq 2f
2e8a5942
GC
45 adr r1, 3f
46 ldr r3, [r1]
47 ldr r1, [r1, r3]
ccd6a131
GC
48 b 2f
491:
4dd1b7fa
TP
50 /*
51 * MMU is enabled, use the virtual address of the coherency
52 * base address.
53 */
2e8a5942
GC
54 ldr r1, =coherency_base
55 ldr r1, [r1]
ccd6a131 562:
6ebbf2ce 57 ret lr
2e8a5942
GC
58ENDPROC(ll_get_coherency_base)
59
07ae144b
TP
60/*
61 * Returns the coherency CPU mask in r3 (r0 is untouched). This
62 * coherency CPU mask can be used with the coherency fabric
63 * configuration and control registers. Note that the mask is already
64 * endian-swapped as appropriate so that the calling functions do not
65 * have to care about endianness issues while accessing the coherency
66 * fabric registers
67 */
68ENTRY(ll_get_coherency_cpumask)
2e8a5942
GC
69 mrc 15, 0, r3, cr0, cr0, 5
70 and r3, r3, #15
b41375f7 71 mov r2, #(1 << 24)
2e8a5942 72 lsl r3, r2, r3
4fbe6393 73ARM_BE8(rev r3, r3)
6ebbf2ce 74 ret lr
07ae144b 75ENDPROC(ll_get_coherency_cpumask)
009f1315 76
4dd1b7fa
TP
77/*
78 * ll_add_cpu_to_smp_group(), ll_enable_coherency() and
79 * ll_disable_coherency() use the strex/ldrex instructions while the
80 * MMU can be disabled. The Armada XP SoC has an exclusive monitor
81 * that tracks transactions to Device and/or SO memory and thanks to
82 * that, exclusive transactions are functional even when the MMU is
83 * disabled.
2e8a5942 84 */
009f1315 85
2e8a5942
GC
86ENTRY(ll_add_cpu_to_smp_group)
87 /*
4dd1b7fa 88 * As r0 is not modified by ll_get_coherency_base() and
07ae144b
TP
89 * ll_get_coherency_cpumask(), we use it to temporarly save lr
90 * and avoid it being modified by the branch and link
91 * calls. This function is used very early in the secondary
92 * CPU boot, and no stack is available at this point.
2e8a5942 93 */
90ba76f6 94 mov r0, lr
2e8a5942 95 bl ll_get_coherency_base
30cdef97
TP
96 /* Bail out if the coherency is not enabled */
97 cmp r1, #0
98 reteq r0
07ae144b 99 bl ll_get_coherency_cpumask
90ba76f6 100 mov lr, r0
2e8a5942 101 add r0, r1, #ARMADA_XP_CFB_CFG_REG_OFFSET
b60b61d4 1021:
2e8a5942
GC
103 ldrex r2, [r0]
104 orr r2, r2, r3
105 strex r1, r2, [r0]
106 cmp r1, #0
107 bne 1b
6ebbf2ce 108 ret lr
2e8a5942 109ENDPROC(ll_add_cpu_to_smp_group)
009f1315 110
2e8a5942
GC
111ENTRY(ll_enable_coherency)
112 /*
4dd1b7fa 113 * As r0 is not modified by ll_get_coherency_base() and
07ae144b
TP
114 * ll_get_coherency_cpumask(), we use it to temporarly save lr
115 * and avoid it being modified by the branch and link
116 * calls. This function is used very early in the secondary
117 * CPU boot, and no stack is available at this point.
2e8a5942
GC
118 */
119 mov r0, lr
120 bl ll_get_coherency_base
30cdef97
TP
121 /* Bail out if the coherency is not enabled */
122 cmp r1, #0
123 reteq r0
07ae144b 124 bl ll_get_coherency_cpumask
2e8a5942
GC
125 mov lr, r0
126 add r0, r1, #ARMADA_XP_CFB_CTL_REG_OFFSET
1271:
128 ldrex r2, [r0]
129 orr r2, r2, r3
130 strex r1, r2, [r0]
131 cmp r1, #0
132 bne 1b
009f1315 133 dsb
009f1315 134 mov r0, #0
6ebbf2ce 135 ret lr
2e8a5942
GC
136ENDPROC(ll_enable_coherency)
137
1a6bfbc3
GC
138ENTRY(ll_disable_coherency)
139 /*
4dd1b7fa 140 * As r0 is not modified by ll_get_coherency_base() and
07ae144b
TP
141 * ll_get_coherency_cpumask(), we use it to temporarly save lr
142 * and avoid it being modified by the branch and link
143 * calls. This function is used very early in the secondary
144 * CPU boot, and no stack is available at this point.
1a6bfbc3 145 */
90ba76f6 146 mov r0, lr
1a6bfbc3 147 bl ll_get_coherency_base
30cdef97
TP
148 /* Bail out if the coherency is not enabled */
149 cmp r1, #0
150 reteq r0
07ae144b 151 bl ll_get_coherency_cpumask
90ba76f6 152 mov lr, r0
1a6bfbc3
GC
153 add r0, r1, #ARMADA_XP_CFB_CTL_REG_OFFSET
1541:
155 ldrex r2, [r0]
156 bic r2, r2, r3
157 strex r1, r2, [r0]
158 cmp r1, #0
159 bne 1b
160 dsb
6ebbf2ce 161 ret lr
1a6bfbc3 162ENDPROC(ll_disable_coherency)
ccd6a131
GC
163
164 .align 2
1653:
166 .long coherency_phys_base - .
This page took 0.159896 seconds and 5 git commands to generate.