]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
0b02b184 DB |
2 | /* |
3 | * armboot - Startup Code for OMAP3530/ARM Cortex CPU-core | |
4 | * | |
5 | * Copyright (c) 2004 Texas Instruments <[email protected]> | |
6 | * | |
7 | * Copyright (c) 2001 Marius Gröger <[email protected]> | |
8 | * Copyright (c) 2002 Alex Züpke <[email protected]> | |
792a09eb | 9 | * Copyright (c) 2002 Gary Jennejohn <[email protected]> |
0b02b184 DB |
10 | * Copyright (c) 2003 Richard Woodruff <[email protected]> |
11 | * Copyright (c) 2003 Kshitij <[email protected]> | |
12 | * Copyright (c) 2006-2008 Syed Mohammed Khasim <[email protected]> | |
0b02b184 DB |
13 | */ |
14 | ||
25ddd1fb | 15 | #include <asm-offsets.h> |
0b02b184 | 16 | #include <config.h> |
a8c68639 | 17 | #include <asm/system.h> |
74236aca | 18 | #include <linux/linkage.h> |
d31d4a2d | 19 | #include <asm/armv7.h> |
0b02b184 | 20 | |
0b02b184 DB |
21 | /************************************************************************* |
22 | * | |
23 | * Startup Code (reset vector) | |
24 | * | |
003b09da PM |
25 | * Do important init only if we don't start from memory! |
26 | * Setup memory and board specific bits prior to relocation. | |
27 | * Relocate armboot to ram. Setup stack. | |
0b02b184 DB |
28 | * |
29 | *************************************************************************/ | |
30 | ||
41623c91 | 31 | .globl reset |
e11c6c27 | 32 | .globl save_boot_params_ret |
ff143d55 | 33 | .type save_boot_params_ret,%function |
d31d4a2d K |
34 | #ifdef CONFIG_ARMV7_LPAE |
35 | .global switch_to_hypervisor_ret | |
36 | #endif | |
561142af HS |
37 | |
38 | reset: | |
e11c6c27 SG |
39 | /* Allow the board to save important registers */ |
40 | b save_boot_params | |
41 | save_boot_params_ret: | |
d31d4a2d K |
42 | #ifdef CONFIG_ARMV7_LPAE |
43 | /* | |
44 | * check for Hypervisor support | |
45 | */ | |
46 | mrc p15, 0, r0, c0, c1, 1 @ read ID_PFR1 | |
47 | and r0, r0, #CPUID_ARM_VIRT_MASK @ mask virtualization bits | |
48 | cmp r0, #(1 << CPUID_ARM_VIRT_SHIFT) | |
49 | beq switch_to_hypervisor | |
50 | switch_to_hypervisor_ret: | |
51 | #endif | |
561142af | 52 | /* |
c4a4e2e2 AP |
53 | * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode, |
54 | * except if in HYP mode already | |
561142af HS |
55 | */ |
56 | mrs r0, cpsr | |
c4a4e2e2 AP |
57 | and r1, r0, #0x1f @ mask mode bits |
58 | teq r1, #0x1a @ test for HYP mode | |
59 | bicne r0, r0, #0x1f @ clear all mode bits | |
60 | orrne r0, r0, #0x13 @ set SVC mode | |
61 | orr r0, r0, #0xc0 @ disable FIQ and IRQ | |
561142af HS |
62 | msr cpsr,r0 |
63 | ||
a8c68639 A |
64 | /* |
65 | * Setup vector: | |
66 | * (OMAP4 spl TEXT_BASE is not 32 byte aligned. | |
67 | * Continue to use ROM code vector only in OMAP4 spl) | |
68 | */ | |
840fe95c | 69 | #if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD)) |
0f274f53 PF |
70 | /* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */ |
71 | mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTLR Register | |
a8c68639 | 72 | bic r0, #CR_V @ V = 0 |
0f274f53 | 73 | mcr p15, 0, r0, c1, c0, 0 @ Write CP15 SCTLR Register |
a8c68639 | 74 | |
2a518053 | 75 | #ifdef CONFIG_HAS_VBAR |
a8c68639 A |
76 | /* Set vector address in CP15 VBAR register */ |
77 | ldr r0, =_start | |
78 | mcr p15, 0, r0, c12, c0, 0 @Set VBAR | |
2a518053 | 79 | #endif |
a8c68639 A |
80 | #endif |
81 | ||
561142af HS |
82 | /* the mask ROM code should have PLL and others stable */ |
83 | #ifndef CONFIG_SKIP_LOWLEVEL_INIT | |
4bbd6b1d | 84 | #ifdef CONFIG_CPU_V7A |
80433c9a | 85 | bl cpu_init_cp15 |
4bbd6b1d | 86 | #endif |
b5bd0982 | 87 | #ifndef CONFIG_SKIP_LOWLEVEL_INIT_ONLY |
561142af | 88 | bl cpu_init_crit |
b5bd0982 | 89 | #endif |
561142af HS |
90 | #endif |
91 | ||
e05e5de7 | 92 | bl _main |
561142af HS |
93 | |
94 | /*------------------------------------------------------------------------------*/ | |
95 | ||
e05e5de7 | 96 | ENTRY(c_runtime_cpu_setup) |
c2dd0d45 A |
97 | /* |
98 | * If I-cache is enabled invalidate it | |
99 | */ | |
100 | #ifndef CONFIG_SYS_ICACHE_OFF | |
101 | mcr p15, 0, r0, c7, c5, 0 @ invalidate icache | |
102 | mcr p15, 0, r0, c7, c10, 4 @ DSB | |
103 | mcr p15, 0, r0, c7, c5, 4 @ ISB | |
104 | #endif | |
f8b9d1d3 | 105 | |
e05e5de7 AA |
106 | bx lr |
107 | ||
108 | ENDPROC(c_runtime_cpu_setup) | |
c3d3a541 | 109 | |
6f0dba85 TK |
110 | /************************************************************************* |
111 | * | |
112 | * void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) | |
113 | * __attribute__((weak)); | |
114 | * | |
115 | * Stack pointer is not yet initialized at this moment | |
116 | * Don't save anything to stack even if compiled with -O0 | |
117 | * | |
118 | *************************************************************************/ | |
119 | ENTRY(save_boot_params) | |
e11c6c27 | 120 | b save_boot_params_ret @ back to my caller |
6f0dba85 TK |
121 | ENDPROC(save_boot_params) |
122 | .weak save_boot_params | |
123 | ||
d31d4a2d K |
124 | #ifdef CONFIG_ARMV7_LPAE |
125 | ENTRY(switch_to_hypervisor) | |
126 | b switch_to_hypervisor_ret | |
127 | ENDPROC(switch_to_hypervisor) | |
128 | .weak switch_to_hypervisor | |
129 | #endif | |
130 | ||
0b02b184 DB |
131 | /************************************************************************* |
132 | * | |
80433c9a | 133 | * cpu_init_cp15 |
0b02b184 | 134 | * |
80433c9a SG |
135 | * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless |
136 | * CONFIG_SYS_ICACHE_OFF is defined. | |
0b02b184 DB |
137 | * |
138 | *************************************************************************/ | |
74236aca | 139 | ENTRY(cpu_init_cp15) |
0b02b184 DB |
140 | /* |
141 | * Invalidate L1 I/D | |
142 | */ | |
143 | mov r0, #0 @ set up for MCR | |
144 | mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs | |
145 | mcr p15, 0, r0, c7, c5, 0 @ invalidate icache | |
c2dd0d45 A |
146 | mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array |
147 | mcr p15, 0, r0, c7, c10, 4 @ DSB | |
148 | mcr p15, 0, r0, c7, c5, 4 @ ISB | |
0b02b184 DB |
149 | |
150 | /* | |
151 | * disable MMU stuff and caches | |
152 | */ | |
153 | mrc p15, 0, r0, c1, c0, 0 | |
154 | bic r0, r0, #0x00002000 @ clear bits 13 (--V-) | |
155 | bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) | |
156 | orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align | |
c2dd0d45 A |
157 | orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB |
158 | #ifdef CONFIG_SYS_ICACHE_OFF | |
159 | bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache | |
160 | #else | |
161 | orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache | |
162 | #endif | |
0b02b184 | 163 | mcr p15, 0, r0, c1, c0, 0 |
0678587f | 164 | |
c5d4752c SW |
165 | #ifdef CONFIG_ARM_ERRATA_716044 |
166 | mrc p15, 0, r0, c1, c0, 0 @ read system control register | |
167 | orr r0, r0, #1 << 11 @ set bit #11 | |
168 | mcr p15, 0, r0, c1, c0, 0 @ write system control register | |
169 | #endif | |
170 | ||
f71cbfe3 | 171 | #if (defined(CONFIG_ARM_ERRATA_742230) || defined(CONFIG_ARM_ERRATA_794072)) |
0678587f SW |
172 | mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register |
173 | orr r0, r0, #1 << 4 @ set bit #4 | |
174 | mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register | |
175 | #endif | |
176 | ||
177 | #ifdef CONFIG_ARM_ERRATA_743622 | |
178 | mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register | |
179 | orr r0, r0, #1 << 6 @ set bit #6 | |
180 | mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register | |
181 | #endif | |
182 | ||
183 | #ifdef CONFIG_ARM_ERRATA_751472 | |
184 | mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register | |
185 | orr r0, r0, #1 << 11 @ set bit #11 | |
186 | mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register | |
187 | #endif | |
b7588e3b NG |
188 | #ifdef CONFIG_ARM_ERRATA_761320 |
189 | mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register | |
190 | orr r0, r0, #1 << 21 @ set bit #21 | |
191 | mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register | |
192 | #endif | |
0678587f | 193 | |
11d94319 PF |
194 | #ifdef CONFIG_ARM_ERRATA_845369 |
195 | mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register | |
196 | orr r0, r0, #1 << 22 @ set bit #22 | |
197 | mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register | |
198 | #endif | |
199 | ||
c616a0df NM |
200 | mov r5, lr @ Store my Caller |
201 | mrc p15, 0, r1, c0, c0, 0 @ r1 has Read Main ID Register (MIDR) | |
202 | mov r3, r1, lsr #20 @ get variant field | |
203 | and r3, r3, #0xf @ r3 has CPU variant | |
204 | and r4, r1, #0xf @ r4 has CPU revision | |
205 | mov r2, r3, lsl #4 @ shift variant field for combined value | |
206 | orr r2, r4, r2 @ r2 has combined CPU variant + revision | |
207 | ||
208 | #ifdef CONFIG_ARM_ERRATA_798870 | |
209 | cmp r2, #0x30 @ Applies to lower than R3p0 | |
210 | bge skip_errata_798870 @ skip if not affected rev | |
211 | cmp r2, #0x20 @ Applies to including and above R2p0 | |
212 | blt skip_errata_798870 @ skip if not affected rev | |
213 | ||
214 | mrc p15, 1, r0, c15, c0, 0 @ read l2 aux ctrl reg | |
215 | orr r0, r0, #1 << 7 @ Enable hazard-detect timeout | |
216 | push {r1-r5} @ Save the cpu info registers | |
217 | bl v7_arch_cp15_set_l2aux_ctrl | |
218 | isb @ Recommended ISB after l2actlr update | |
219 | pop {r1-r5} @ Restore the cpu info - fall through | |
220 | skip_errata_798870: | |
b45c48a7 NM |
221 | #endif |
222 | ||
a615d0be NM |
223 | #ifdef CONFIG_ARM_ERRATA_801819 |
224 | cmp r2, #0x24 @ Applies to lt including R2p4 | |
225 | bgt skip_errata_801819 @ skip if not affected rev | |
226 | cmp r2, #0x20 @ Applies to including and above R2p0 | |
227 | blt skip_errata_801819 @ skip if not affected rev | |
228 | mrc p15, 0, r0, c0, c0, 6 @ pick up REVIDR reg | |
229 | and r0, r0, #1 << 3 @ check REVIDR[3] | |
230 | cmp r0, #1 << 3 | |
231 | beq skip_errata_801819 @ skip erratum if REVIDR[3] is set | |
232 | ||
233 | mrc p15, 0, r0, c1, c0, 1 @ read auxilary control register | |
234 | orr r0, r0, #3 << 27 @ Disables streaming. All write-allocate | |
235 | @ lines allocate in the L1 or L2 cache. | |
236 | orr r0, r0, #3 << 25 @ Disables streaming. All write-allocate | |
237 | @ lines allocate in the L1 cache. | |
238 | push {r1-r5} @ Save the cpu info registers | |
239 | bl v7_arch_cp15_set_acr | |
240 | pop {r1-r5} @ Restore the cpu info - fall through | |
241 | skip_errata_801819: | |
242 | #endif | |
243 | ||
b45c48a7 | 244 | #ifdef CONFIG_ARM_ERRATA_454179 |
d852600e SS |
245 | mrc p15, 0, r0, c1, c0, 1 @ Read ACR |
246 | ||
b45c48a7 | 247 | cmp r2, #0x21 @ Only on < r2p1 |
d852600e | 248 | orrlt r0, r0, #(0x3 << 6) @ Set DBSM(BIT7) and IBE(BIT6) bits |
b45c48a7 | 249 | |
b45c48a7 NM |
250 | push {r1-r5} @ Save the cpu info registers |
251 | bl v7_arch_cp15_set_acr | |
252 | pop {r1-r5} @ Restore the cpu info - fall through | |
5902f4ce NM |
253 | #endif |
254 | ||
7b37a9c7 | 255 | #if defined(CONFIG_ARM_ERRATA_430973) || defined (CONFIG_ARM_CORTEX_A8_CVE_2017_5715) |
d852600e SS |
256 | mrc p15, 0, r0, c1, c0, 1 @ Read ACR |
257 | ||
7b37a9c7 NM |
258 | #ifdef CONFIG_ARM_CORTEX_A8_CVE_2017_5715 |
259 | orr r0, r0, #(0x1 << 6) @ Set IBE bit always to enable OS WA | |
260 | #else | |
5902f4ce | 261 | cmp r2, #0x21 @ Only on < r2p1 |
d852600e | 262 | orrlt r0, r0, #(0x1 << 6) @ Set IBE bit |
7b37a9c7 | 263 | #endif |
5902f4ce NM |
264 | push {r1-r5} @ Save the cpu info registers |
265 | bl v7_arch_cp15_set_acr | |
266 | pop {r1-r5} @ Restore the cpu info - fall through | |
9b4d65f9 NM |
267 | #endif |
268 | ||
269 | #ifdef CONFIG_ARM_ERRATA_621766 | |
d852600e SS |
270 | mrc p15, 0, r0, c1, c0, 1 @ Read ACR |
271 | ||
9b4d65f9 | 272 | cmp r2, #0x21 @ Only on < r2p1 |
d852600e | 273 | orrlt r0, r0, #(0x1 << 5) @ Set L1NEON bit |
9b4d65f9 | 274 | |
9b4d65f9 NM |
275 | push {r1-r5} @ Save the cpu info registers |
276 | bl v7_arch_cp15_set_acr | |
277 | pop {r1-r5} @ Restore the cpu info - fall through | |
19a75b8c SS |
278 | #endif |
279 | ||
280 | #ifdef CONFIG_ARM_ERRATA_725233 | |
d852600e SS |
281 | mrc p15, 1, r0, c9, c0, 2 @ Read L2ACR |
282 | ||
19a75b8c | 283 | cmp r2, #0x21 @ Only on < r2p1 (Cortex A8) |
d852600e | 284 | orrlt r0, r0, #(0x1 << 27) @ L2 PLD data forwarding disable |
19a75b8c | 285 | |
19a75b8c SS |
286 | push {r1-r5} @ Save the cpu info registers |
287 | bl v7_arch_cp15_set_l2aux_ctrl | |
288 | pop {r1-r5} @ Restore the cpu info - fall through | |
c616a0df NM |
289 | #endif |
290 | ||
8776350d NM |
291 | #ifdef CONFIG_ARM_ERRATA_852421 |
292 | mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register | |
293 | orr r0, r0, #1 << 24 @ set bit #24 | |
294 | mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register | |
295 | #endif | |
296 | ||
297 | #ifdef CONFIG_ARM_ERRATA_852423 | |
298 | mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register | |
299 | orr r0, r0, #1 << 12 @ set bit #12 | |
300 | mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register | |
301 | #endif | |
302 | ||
c616a0df | 303 | mov pc, r5 @ back to my caller |
74236aca | 304 | ENDPROC(cpu_init_cp15) |
0b02b184 | 305 | |
b5bd0982 SG |
306 | #if !defined(CONFIG_SKIP_LOWLEVEL_INIT) && \ |
307 | !defined(CONFIG_SKIP_LOWLEVEL_INIT_ONLY) | |
80433c9a SG |
308 | /************************************************************************* |
309 | * | |
310 | * CPU_init_critical registers | |
311 | * | |
312 | * setup important registers | |
313 | * setup memory timing | |
314 | * | |
315 | *************************************************************************/ | |
74236aca | 316 | ENTRY(cpu_init_crit) |
0b02b184 DB |
317 | /* |
318 | * Jump to board specific initialization... | |
319 | * The Mask ROM will have already initialized | |
320 | * basic memory. Go here to bump up clock rate and handle | |
321 | * wake up conditions. | |
322 | */ | |
63ee53a7 | 323 | b lowlevel_init @ go setup pll,mux,memory |
74236aca | 324 | ENDPROC(cpu_init_crit) |
22193540 | 325 | #endif |