aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-mvebu/coherency_ll.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-mvebu/coherency_ll.S')
-rw-r--r--arch/arm/mach-mvebu/coherency_ll.S143
1 files changed, 117 insertions, 26 deletions
diff --git a/arch/arm/mach-mvebu/coherency_ll.S b/arch/arm/mach-mvebu/coherency_ll.S
index ee7598fe75db..510c29e079ca 100644
--- a/arch/arm/mach-mvebu/coherency_ll.S
+++ b/arch/arm/mach-mvebu/coherency_ll.S
@@ -21,38 +21,129 @@
21#define ARMADA_XP_CFB_CFG_REG_OFFSET 0x4 21#define ARMADA_XP_CFB_CFG_REG_OFFSET 0x4
22 22
23#include <asm/assembler.h> 23#include <asm/assembler.h>
24#include <asm/cp15.h>
24 25
25 .text 26 .text
27/* Returns the coherency base address in r1 (r0 is untouched) */
28ENTRY(ll_get_coherency_base)
29 mrc p15, 0, r1, c1, c0, 0
30 tst r1, #CR_M @ Check MMU bit enabled
31 bne 1f
32
33 /*
34 * MMU is disabled, use the physical address of the coherency
35 * base address.
36 */
37 adr r1, 3f
38 ldr r3, [r1]
39 ldr r1, [r1, r3]
40 b 2f
411:
42 /*
43 * MMU is enabled, use the virtual address of the coherency
44 * base address.
45 */
46 ldr r1, =coherency_base
47 ldr r1, [r1]
482:
49 mov pc, lr
50ENDPROC(ll_get_coherency_base)
51
26/* 52/*
27 * r0: Coherency fabric base register address 53 * Returns the coherency CPU mask in r3 (r0 is untouched). This
28 * r1: HW CPU id 54 * coherency CPU mask can be used with the coherency fabric
55 * configuration and control registers. Note that the mask is already
56 * endian-swapped as appropriate so that the calling functions do not
57 * have to care about endianness issues while accessing the coherency
58 * fabric registers
29 */ 59 */
30ENTRY(ll_set_cpu_coherent) 60ENTRY(ll_get_coherency_cpumask)
31 /* Create bit by cpu index */ 61 mrc 15, 0, r3, cr0, cr0, 5
32 mov r3, #(1 << 24) 62 and r3, r3, #15
33 lsl r1, r3, r1 63 mov r2, #(1 << 24)
34ARM_BE8(rev r1, r1) 64 lsl r3, r2, r3
35 65ARM_BE8(rev r3, r3)
36 /* Add CPU to SMP group - Atomic */ 66 mov pc, lr
37 add r3, r0, #ARMADA_XP_CFB_CTL_REG_OFFSET 67ENDPROC(ll_get_coherency_cpumask)
381: 68
39 ldrex r2, [r3] 69/*
40 orr r2, r2, r1 70 * ll_add_cpu_to_smp_group(), ll_enable_coherency() and
41 strex r0, r2, [r3] 71 * ll_disable_coherency() use the strex/ldrex instructions while the
42 cmp r0, #0 72 * MMU can be disabled. The Armada XP SoC has an exclusive monitor
43 bne 1b 73 * that tracks transactions to Device and/or SO memory and thanks to
44 74 * that, exclusive transactions are functional even when the MMU is
45 /* Enable coherency on CPU - Atomic */ 75 * disabled.
46 add r3, r3, #ARMADA_XP_CFB_CFG_REG_OFFSET 76 */
77
78ENTRY(ll_add_cpu_to_smp_group)
79 /*
80 * As r0 is not modified by ll_get_coherency_base() and
81 * ll_get_coherency_cpumask(), we use it to temporarly save lr
82 * and avoid it being modified by the branch and link
83 * calls. This function is used very early in the secondary
84 * CPU boot, and no stack is available at this point.
85 */
86 mov r0, lr
87 bl ll_get_coherency_base
88 bl ll_get_coherency_cpumask
89 mov lr, r0
90 add r0, r1, #ARMADA_XP_CFB_CFG_REG_OFFSET
471: 911:
48 ldrex r2, [r3] 92 ldrex r2, [r0]
49 orr r2, r2, r1 93 orr r2, r2, r3
50 strex r0, r2, [r3] 94 strex r1, r2, [r0]
51 cmp r0, #0 95 cmp r1, #0
52 bne 1b 96 bne 1b
97 mov pc, lr
98ENDPROC(ll_add_cpu_to_smp_group)
53 99
100ENTRY(ll_enable_coherency)
101 /*
102 * As r0 is not modified by ll_get_coherency_base() and
103 * ll_get_coherency_cpumask(), we use it to temporarly save lr
104 * and avoid it being modified by the branch and link
105 * calls. This function is used very early in the secondary
106 * CPU boot, and no stack is available at this point.
107 */
108 mov r0, lr
109 bl ll_get_coherency_base
110 bl ll_get_coherency_cpumask
111 mov lr, r0
112 add r0, r1, #ARMADA_XP_CFB_CTL_REG_OFFSET
1131:
114 ldrex r2, [r0]
115 orr r2, r2, r3
116 strex r1, r2, [r0]
117 cmp r1, #0
118 bne 1b
54 dsb 119 dsb
55
56 mov r0, #0 120 mov r0, #0
57 mov pc, lr 121 mov pc, lr
58ENDPROC(ll_set_cpu_coherent) 122ENDPROC(ll_enable_coherency)
123
124ENTRY(ll_disable_coherency)
125 /*
126 * As r0 is not modified by ll_get_coherency_base() and
127 * ll_get_coherency_cpumask(), we use it to temporarly save lr
128 * and avoid it being modified by the branch and link
129 * calls. This function is used very early in the secondary
130 * CPU boot, and no stack is available at this point.
131 */
132 mov r0, lr
133 bl ll_get_coherency_base
134 bl ll_get_coherency_cpumask
135 mov lr, r0
136 add r0, r1, #ARMADA_XP_CFB_CTL_REG_OFFSET
1371:
138 ldrex r2, [r0]
139 bic r2, r2, r3
140 strex r1, r2, [r0]
141 cmp r1, #0
142 bne 1b
143 dsb
144 mov pc, lr
145ENDPROC(ll_disable_coherency)
146
147 .align 2
1483:
149 .long coherency_phys_base - .