Commit | Line | Data |
---|---|---|
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 |
2e8a5942 GC |
27 | /* Returns with the coherency address in r1 (r0 is untouched)*/ |
28 | ENTRY(ll_get_coherency_base) | |
ccd6a131 GC |
29 | mrc p15, 0, r1, c1, c0, 0 |
30 | tst r1, #CR_M @ Check MMU bit enabled | |
31 | bne 1f | |
32 | ||
2e8a5942 GC |
33 | /* use physical address of the coherency register */ |
34 | adr r1, 3f | |
35 | ldr r3, [r1] | |
36 | ldr r1, [r1, r3] | |
ccd6a131 GC |
37 | b 2f |
38 | 1: | |
2e8a5942 GC |
39 | /* use virtual address of the coherency register */ |
40 | ldr r1, =coherency_base | |
41 | ldr r1, [r1] | |
ccd6a131 | 42 | 2: |
2e8a5942 GC |
43 | mov pc, lr |
44 | ENDPROC(ll_get_coherency_base) | |
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 | |
b41375f7 | 50 | mov r2, #(1 << 24) |
2e8a5942 | 51 | lsl r3, r2, r3 |
4fbe6393 | 52 | ARM_BE8(rev r3, r3) |
2e8a5942 GC |
53 | mov pc, lr |
54 | ENDPROC(ll_get_cpuid) | |
009f1315 | 55 | |
2e8a5942 GC |
56 | /* ll_add_cpu_to_smp_group, ll_enable_coherency and |
57 | * ll_disable_coherency use strex/ldrex whereas MMU can be off. The | |
58 | * Armada XP SoC has an exclusive monitor that can track transactions | |
59 | * to Device and/or SO and as such also when MMU is disabled the | |
60 | * exclusive transactions will be functional | |
61 | */ | |
009f1315 | 62 | |
2e8a5942 GC |
63 | ENTRY(ll_add_cpu_to_smp_group) |
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 | |
b60b61d4 | 74 | 1: |
2e8a5942 GC |
75 | ldrex r2, [r0] |
76 | orr r2, r2, r3 | |
77 | strex r1, r2, [r0] | |
78 | cmp r1, #0 | |
79 | bne 1b | |
80 | mov pc, lr | |
81 | ENDPROC(ll_add_cpu_to_smp_group) | |
009f1315 | 82 | |
2e8a5942 GC |
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 | |
009f1315 | 100 | dsb |
009f1315 GC |
101 | mov r0, #0 |
102 | mov pc, lr | |
2e8a5942 GC |
103 | ENDPROC(ll_enable_coherency) |
104 | ||
1a6bfbc3 GC |
105 | ENTRY(ll_disable_coherency) |
106 | /* | |
107 | * r0 being untouched in ll_get_coherency_base and | |
108 | * ll_get_cpuid, we can use it to save lr modifing it with the | |
109 | * following bl | |
110 | */ | |
111 | mov r0, lr | |
112 | bl ll_get_coherency_base | |
113 | bl ll_get_cpuid | |
114 | mov lr, r0 | |
115 | add r0, r1, #ARMADA_XP_CFB_CTL_REG_OFFSET | |
116 | 1: | |
117 | ldrex r2, [r0] | |
118 | bic r2, r2, r3 | |
119 | strex r1, r2, [r0] | |
120 | cmp r1, #0 | |
121 | bne 1b | |
122 | dsb | |
123 | mov pc, lr | |
124 | ENDPROC(ll_disable_coherency) | |
ccd6a131 GC |
125 | |
126 | .align 2 | |
127 | 3: | |
128 | .long coherency_phys_base - . |