diff options
author | Gregory CLEMENT <gregory.clement@free-electrons.com> | 2014-04-14 11:10:08 -0400 |
---|---|---|
committer | Jason Cooper <jason@lakedaemon.net> | 2014-05-08 12:18:54 -0400 |
commit | 2e8a5942f8751c03fdd50228a02909654d13f01d (patch) | |
tree | d69f5a3b881817c12064a52c11b9d39426d9f233 /arch/arm/mach-mvebu | |
parent | 952f4ca79b4ec7114291aa711add1b36c6ba7515 (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.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/coherency_ll.S | 92 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/headsmp.S | 6 |
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 */ |
64 | int ll_set_cpu_coherent(void); | 64 | int ll_enable_coherency(void); |
65 | void ll_add_cpu_to_smp_group(void); | ||
65 | 66 | ||
66 | int set_cpu_coherent(void) | 67 | int 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)*/ | |
28 | ENTRY(ll_set_cpu_coherent) | 28 | ENTRY(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 |
38 | 1: | 38 | 1: |
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] |
42 | 2: | 42 | 2: |
43 | /* Create bit by cpu index */ | 43 | mov pc, lr |
44 | mrc 15, 0, r1, cr0, cr0, 5 | 44 | ENDPROC(ll_get_coherency_base) |
45 | and r1, r1, #15 | 45 | |
46 | /* Returns with the CPU ID in r3 (r0 is untouched)*/ | ||
47 | ENTRY(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 |
48 | ARM_BE8(rev r1, r1) | 52 | ARM_BE8(rev r1, r1) |
53 | mov pc, lr | ||
54 | ENDPROC(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 |
52 | 1: | 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 */ | 63 | ENTRY(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 | ||
61 | 1: | 74 | 1: |
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 | ||
81 | ENDPROC(ll_add_cpu_to_smp_group) | ||
67 | 82 | ||
83 | ENTRY(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 | ||
94 | 1: | ||
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 |
72 | ENDPROC(ll_set_cpu_coherent) | 103 | ENDPROC(ll_enable_coherency) |
104 | |||
73 | 105 | ||
74 | .align 2 | 106 | .align 2 |
75 | 3: | 107 | 3: |
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 @@ | |||
31 | ENTRY(armada_xp_secondary_startup) | 31 | ENTRY(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 | ||
38 | ENDPROC(armada_xp_secondary_startup) | 40 | ENDPROC(armada_xp_secondary_startup) |