aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-mvebu
diff options
context:
space:
mode:
authorGregory CLEMENT <gregory.clement@free-electrons.com>2014-04-14 11:10:08 -0400
committerJason Cooper <jason@lakedaemon.net>2014-05-08 12:18:54 -0400
commit2e8a5942f8751c03fdd50228a02909654d13f01d (patch)
treed69f5a3b881817c12064a52c11b9d39426d9f233 /arch/arm/mach-mvebu
parent952f4ca79b4ec7114291aa711add1b36c6ba7515 (diff)
ARM: mvebu: Split low level functions to manipulate HW coherency
Actually enabling coherency and adding a CPU on a SMP group are two different operations which can be done separately. This patch splits this in two functions. Moreover as they use common pattern, this patch also creates local low level functions (ll_get_coherency_base and ll_get_cpuid) to be used by the exposed functions (ll_add_cpu_to_smp_group and ll_enable_coherency) Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com> Link: https://lkml.kernel.org/r/1397488214-20685-6-git-send-email-gregory.clement@free-electrons.com Signed-off-by: Jason Cooper <jason@lakedaemon.net>
Diffstat (limited to 'arch/arm/mach-mvebu')
-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)