aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-mvebu/coherency.c8
-rw-r--r--arch/arm/mach-mvebu/coherency_ll.S92
-rw-r--r--arch/arm/mach-mvebu/headsmp.S6
3 files changed, 71 insertions, 35 deletions
diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c
index 944372a18ed6..9d5ccd372712 100644
--- a/arch/arm/mach-mvebu/coherency.c
+++ b/arch/arm/mach-mvebu/coherency.c
@@ -60,8 +60,9 @@ static struct of_device_id of_coherency_table[] = {
60 { /* end of list */ }, 60 { /* end of list */ },
61}; 61};
62 62
63/* Function defined in coherency_ll.S */ 63/* Functions defined in coherency_ll.S */
64int ll_set_cpu_coherent(void); 64int ll_enable_coherency(void);
65void ll_add_cpu_to_smp_group(void);
65 66
66int set_cpu_coherent(void) 67int set_cpu_coherent(void)
67{ 68{
@@ -71,7 +72,8 @@ int set_cpu_coherent(void)
71 return 1; 72 return 1;
72 } 73 }
73 74
74 return ll_set_cpu_coherent(); 75 ll_add_cpu_to_smp_group();
76 return ll_enable_coherency();
75} 77}
76 78
77/* 79/*
diff --git a/arch/arm/mach-mvebu/coherency_ll.S b/arch/arm/mach-mvebu/coherency_ll.S
index 98a0b73f909b..f2e2e8677c4b 100644
--- a/arch/arm/mach-mvebu/coherency_ll.S
+++ b/arch/arm/mach-mvebu/coherency_ll.S
@@ -24,52 +24,84 @@
24#include <asm/cp15.h> 24#include <asm/cp15.h>
25 25
26 .text 26 .text
27 27/* Returns with the coherency address in r1 (r0 is untouched)*/
28ENTRY(ll_set_cpu_coherent) 28ENTRY(ll_get_coherency_base)
29 mrc p15, 0, r1, c1, c0, 0 29 mrc p15, 0, r1, c1, c0, 0
30 tst r1, #CR_M @ Check MMU bit enabled 30 tst r1, #CR_M @ Check MMU bit enabled
31 bne 1f 31 bne 1f
32 32
33 /* use physical address of the coherency register*/ 33 /* use physical address of the coherency register */
34 adr r0, 3f 34 adr r1, 3f
35 ldr r3, [r0] 35 ldr r3, [r1]
36 ldr r0, [r0, r3] 36 ldr r1, [r1, r3]
37 b 2f 37 b 2f
381: 381:
39 /* use virtual address of the coherency register*/ 39 /* use virtual address of the coherency register */
40 ldr r0, =coherency_base 40 ldr r1, =coherency_base
41 ldr r0, [r0] 41 ldr r1, [r1]
422: 422:
43 /* Create bit by cpu index */ 43 mov pc, lr
44 mrc 15, 0, r1, cr0, cr0, 5 44ENDPROC(ll_get_coherency_base)
45 and r1, r1, #15 45
46/* Returns with the CPU ID in r3 (r0 is untouched)*/
47ENTRY(ll_get_cpuid)
48 mrc 15, 0, r3, cr0, cr0, 5
49 and r3, r3, #15
46 mov r2, #(1 << 24) 50 mov r2, #(1 << 24)
47 lsl r1, r2, r1 51 lsl r3, r2, r3
48ARM_BE8(rev r1, r1) 52ARM_BE8(rev r1, r1)
53 mov pc, lr
54ENDPROC(ll_get_cpuid)
49 55
50 /* Add CPU to SMP group - Atomic */ 56/* ll_add_cpu_to_smp_group, ll_enable_coherency and
51 add r3, r0, #ARMADA_XP_CFB_CTL_REG_OFFSET 57 * ll_disable_coherency use strex/ldrex whereas MMU can be off. The
521: 58 * Armada XP SoC has an exclusive monitor that can track transactions
53 ldrex r2, [r3] 59 * to Device and/or SO and as such also when MMU is disabled the
54 orr r2, r2, r1 60 * exclusive transactions will be functional
55 strex r0, r2, [r3] 61 */
56 cmp r0, #0
57 bne 1b
58 62
59 /* Enable coherency on CPU - Atomic */ 63ENTRY(ll_add_cpu_to_smp_group)
60 add r3, r3, #ARMADA_XP_CFB_CFG_REG_OFFSET 64 /*
65 * r0 being untouched in ll_get_coherency_base and
66 * ll_get_cpuid, we can use it to save lr modifing it with the
67 * following bl
68 */
69 mov r0, lr
70 bl ll_get_coherency_base
71 bl ll_get_cpuid
72 mov lr, r0
73 add r0, r1, #ARMADA_XP_CFB_CFG_REG_OFFSET
611: 741:
62 ldrex r2, [r3] 75 ldrex r2, [r0]
63 orr r2, r2, r1 76 orr r2, r2, r3
64 strex r0, r2, [r3] 77 strex r1, r2, [r0]
65 cmp r0, #0 78 cmp r1, #0
66 bne 1b 79 bne 1b
80 mov pc, lr
81ENDPROC(ll_add_cpu_to_smp_group)
67 82
83ENTRY(ll_enable_coherency)
84 /*
85 * r0 being untouched in ll_get_coherency_base and
86 * ll_get_cpuid, we can use it to save lr modifing it with the
87 * following bl
88 */
89 mov r0, lr
90 bl ll_get_coherency_base
91 bl ll_get_cpuid
92 mov lr, r0
93 add r0, r1, #ARMADA_XP_CFB_CTL_REG_OFFSET
941:
95 ldrex r2, [r0]
96 orr r2, r2, r3
97 strex r1, r2, [r0]
98 cmp r1, #0
99 bne 1b
68 dsb 100 dsb
69
70 mov r0, #0 101 mov r0, #0
71 mov pc, lr 102 mov pc, lr
72ENDPROC(ll_set_cpu_coherent) 103ENDPROC(ll_enable_coherency)
104
73 105
74 .align 2 106 .align 2
753: 1073:
diff --git a/arch/arm/mach-mvebu/headsmp.S b/arch/arm/mach-mvebu/headsmp.S
index cf7abe6554f7..2c4032e368ba 100644
--- a/arch/arm/mach-mvebu/headsmp.S
+++ b/arch/arm/mach-mvebu/headsmp.S
@@ -31,8 +31,10 @@
31ENTRY(armada_xp_secondary_startup) 31ENTRY(armada_xp_secondary_startup)
32 ARM_BE8(setend be ) @ go BE8 if entered LE 32 ARM_BE8(setend be ) @ go BE8 if entered LE
33 33
34 /* Add CPU to coherency fabric */ 34 bl ll_add_cpu_to_smp_group
35 bl ll_set_cpu_coherent 35
36 bl ll_enable_coherency
37
36 b secondary_startup 38 b secondary_startup
37 39
38ENDPROC(armada_xp_secondary_startup) 40ENDPROC(armada_xp_secondary_startup)