1/*
2 * Copyright (c) 2022, ARM Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch.h>
8#include <asm_macros.S>
9#include <common/bl_common.h>
10#include <cortex_a510.h>
11#include <cpu_macros.S>
12#include <plat_macros.S>
13
14/* Hardware handled coherency */
15#if HW_ASSISTED_COHERENCY == 0
16#error "Cortex-A510 must be compiled with HW_ASSISTED_COHERENCY enabled"
17#endif
18
19/* 64-bit only core */
20#if CTX_INCLUDE_AARCH32_REGS == 1
21#error "Cortex-A510 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
22#endif
23
24	/* --------------------------------------------------
25	 * Errata Workaround for Cortex-A510 Errata #1922240.
26	 * This applies only to revision r0p0 (fixed in r0p1)
27	 * x0: variant[4:7] and revision[0:3] of current cpu.
28	 * Shall clobber: x0, x1, x17
29	 * --------------------------------------------------
30	 */
31func errata_cortex_a510_1922240_wa
32	/* Check workaround compatibility. */
33	mov	x17, x30
34	bl	check_errata_1922240
35	cbz	x0, 1f
36
37	/* Apply the workaround by setting IMP_CMPXACTLR_EL1[11:10] = 0b11. */
38	mrs	x0, CORTEX_A510_CMPXACTLR_EL1
39	mov	x1, #3
40	bfi	x0, x1, #10, #2
41	msr	CORTEX_A510_CMPXACTLR_EL1, x0
42
431:
44	ret	x17
45endfunc errata_cortex_a510_1922240_wa
46
47func check_errata_1922240
48	/* Applies to r0p0 only */
49	mov	x1, #0x00
50	b	cpu_rev_var_ls
51endfunc check_errata_1922240
52
53	/* --------------------------------------------------
54	 * Errata Workaround for Cortex-A510 Errata #2288014.
55	 * This applies only to revisions r0p0, r0p1, r0p2,
56	 * r0p3 and r1p0. (fixed in r1p1)
57	 * x0: variant[4:7] and revision[0:3] of current cpu.
58	 * Shall clobber: x0, x1, x17
59	 * --------------------------------------------------
60	 */
61func errata_cortex_a510_2288014_wa
62	/* Check workaround compatibility. */
63	mov	x17, x30
64	bl	check_errata_2288014
65	cbz	x0, 1f
66
67	/* Apply the workaround by setting IMP_CPUACTLR_EL1[18] = 0b1. */
68	mrs	x0, CORTEX_A510_CPUACTLR_EL1
69	mov	x1, #1
70	bfi	x0, x1, #18, #1
71	msr	CORTEX_A510_CPUACTLR_EL1, x0
72
731:
74	ret	x17
75endfunc errata_cortex_a510_2288014_wa
76
77func check_errata_2288014
78	/* Applies to r1p0 and below */
79	mov	x1, #0x10
80	b	cpu_rev_var_ls
81endfunc check_errata_2288014
82
83	/* --------------------------------------------------
84	 * Errata Workaround for Cortex-A510 Errata #2042739.
85	 * This applies only to revisions r0p0, r0p1 and r0p2.
86	 * (fixed in r0p3)
87	 * x0: variant[4:7] and revision[0:3] of current cpu.
88	 * Shall clobber: x0, x1, x17
89	 * --------------------------------------------------
90	 */
91func errata_cortex_a510_2042739_wa
92	/* Check workaround compatibility. */
93	mov	x17, x30
94	bl	check_errata_2042739
95	cbz	x0, 1f
96
97	/* Apply the workaround by disabling ReadPreferUnique. */
98	mrs	x0, CORTEX_A510_CPUECTLR_EL1
99	mov	x1, #CORTEX_A510_CPUECTLR_EL1_READPREFERUNIQUE_DISABLE
100	bfi	x0, x1, #CORTEX_A510_CPUECTLR_EL1_READPREFERUNIQUE_SHIFT, #1
101	msr	CORTEX_A510_CPUECTLR_EL1, x0
102
1031:
104	ret	x17
105endfunc errata_cortex_a510_2042739_wa
106
107func check_errata_2042739
108	/* Applies to revisions r0p0 - r0p2 */
109	mov	x1, #0x02
110	b	cpu_rev_var_ls
111endfunc check_errata_2042739
112
113	/* --------------------------------------------------
114	 * Errata Workaround for Cortex-A510 Errata #2041909.
115	 * This applies only to revision r0p2 and it is fixed in
116	 * r0p3. The issue is also present in r0p0 and r0p1 but
117	 * there is no workaround in those revisions.
118	 * x0: variant[4:7] and revision[0:3] of current cpu.
119	 * Shall clobber: x0, x1, x2, x17
120	 * --------------------------------------------------
121	 */
122func errata_cortex_a510_2041909_wa
123	/* Check workaround compatibility. */
124	mov	x17, x30
125	bl	check_errata_2041909
126	cbz	x0, 1f
127
128	/* Apply workaround */
129	mov	x0, xzr
130	msr	S3_6_C15_C4_0, x0
131	isb
132
133	mov	x0, #0x8500000
134	msr	S3_6_C15_C4_2, x0
135
136	mov	x0, #0x1F700000
137	movk	x0, #0x8, lsl #32
138	msr	S3_6_C15_C4_3, x0
139
140	mov	x0, #0x3F1
141	movk	x0, #0x110, lsl #16
142	msr	S3_6_C15_C4_1, x0
143	isb
144
1451:
146	ret	x17
147endfunc errata_cortex_a510_2041909_wa
148
149func check_errata_2041909
150	/* Applies only to revision r0p2 */
151	mov	x1, #0x02
152	mov	x2, #0x02
153	b	cpu_rev_var_range
154endfunc check_errata_2041909
155
156	/* --------------------------------------------------
157	 * Errata Workaround for Cortex-A510 Errata #2250311.
158	 * This applies only to revisions r0p0, r0p1, r0p2,
159	 * r0p3 and r1p0, and is fixed in r1p1.
160	 * This workaround is not a typical errata fix. MPMM
161	 * is disabled here, but this conflicts with the BL31
162	 * MPMM support. So in addition to simply disabling
163	 * the feature, a flag is set in the MPMM library
164	 * indicating that it should not be enabled even if
165	 * ENABLE_MPMM=1.
166	 * x0: variant[4:7] and revision[0:3] of current cpu.
167	 * Shall clobber: x0, x1, x17
168	 * --------------------------------------------------
169	 */
170func errata_cortex_a510_2250311_wa
171	/* Check workaround compatibility. */
172	mov	x17, x30
173	bl	check_errata_2250311
174	cbz	x0, 1f
175
176	/* Disable MPMM */
177	mrs	x0, CPUMPMMCR_EL3
178	bfm	x0, xzr, #0, #0 /* bfc instruction does not work in GCC */
179	msr	CPUMPMMCR_EL3, x0
180
181#if ENABLE_MPMM && IMAGE_BL31
182	/* If ENABLE_MPMM is set, tell the runtime lib to skip enabling it. */
183	bl mpmm_errata_disable
184#endif
185
1861:
187	ret x17
188endfunc errata_cortex_a510_2250311_wa
189
190func check_errata_2250311
191	/* Applies to r1p0 and lower */
192	mov	x1, #0x10
193	b	cpu_rev_var_ls
194endfunc check_errata_2250311
195
196	/* --------------------------------------------------
197	 * Errata Workaround for Cortex-A510 Errata #2218950.
198	 * This applies only to revisions r0p0, r0p1, r0p2,
199	 * r0p3 and r1p0, and is fixed in r1p1.
200	 * x0: variant[4:7] and revision[0:3] of current cpu.
201	 * Shall clobber: x0, x1, x17
202	 * --------------------------------------------------
203	 */
204func errata_cortex_a510_2218950_wa
205	/* Check workaround compatibility. */
206	mov	x17, x30
207	bl	check_errata_2218950
208	cbz	x0, 1f
209
210	/* Source register for BFI */
211	mov	x1, #1
212
213	/* Set bit 18 in CPUACTLR_EL1 */
214	mrs	x0, CORTEX_A510_CPUACTLR_EL1
215	bfi	x0, x1, #18, #1
216	msr	CORTEX_A510_CPUACTLR_EL1, x0
217
218	/* Set bit 25 in CMPXACTLR_EL1 */
219	mrs	x0, CORTEX_A510_CMPXACTLR_EL1
220	bfi	x0, x1, #25, #1
221	msr	CORTEX_A510_CMPXACTLR_EL1, x0
222
2231:
224	ret x17
225endfunc errata_cortex_a510_2218950_wa
226
227func check_errata_2218950
228	/* Applies to r1p0 and lower */
229	mov	x1, #0x10
230	b	cpu_rev_var_ls
231endfunc check_errata_2218950
232
233	/* --------------------------------------------------
234	 * Errata Workaround for Cortex-A510 Errata #2172148.
235	 * This applies only to revisions r0p0, r0p1, r0p2,
236	 * r0p3 and r1p0, and is fixed in r1p1.
237	 * x0: variant[4:7] and revision[0:3] of current cpu.
238	 * Shall clobber: x0, x1, x17
239	 * --------------------------------------------------
240	 */
241func errata_cortex_a510_2172148_wa
242	/* Check workaround compatibility. */
243	mov	x17, x30
244	bl	check_errata_2172148
245	cbz	x0, 1f
246
247	/*
248	 * Force L2 allocation of transient lines by setting
249	 * CPUECTLR_EL1.RSCTL=0b01 and CPUECTLR_EL1.NTCTL=0b01.
250	 */
251	mrs	x0, CORTEX_A510_CPUECTLR_EL1
252	mov	x1, #1
253	bfi	x0, x1, #CORTEX_A510_CPUECTLR_EL1_RSCTL_SHIFT, #2
254	bfi	x0, x1, #CORTEX_A510_CPUECTLR_EL1_NTCTL_SHIFT, #2
255	msr	CORTEX_A510_CPUECTLR_EL1, x0
256
2571:
258	ret x17
259endfunc errata_cortex_a510_2172148_wa
260
261func check_errata_2172148
262	/* Applies to r1p0 and lower */
263	mov	x1, #0x10
264	b	cpu_rev_var_ls
265endfunc check_errata_2172148
266
267	/* ----------------------------------------------------
268	 * Errata Workaround for Cortex-A510 Errata #2347730.
269	 * This applies to revisions r0p0 - r0p3, r1p0, r1p1.
270	 * It is fixed in r1p2.
271	 * Inputs:
272	 * x0: variant[4:7] and revision[0:3] of current cpu.
273	 * Shall clobber: x0-x1, x17
274	 * ----------------------------------------------------
275	 */
276func errata_cortex_a510_2347730_wa
277	mov	x17, x30
278	bl	check_errata_2347730
279	cbz	x0, 1f
280
281	/*
282	 * Set CPUACTLR_EL1[17] to 1'b1, which disables
283	 * specific microarchitectural clock gating
284	 * behaviour.
285	 */
286	mrs	x1, CORTEX_A510_CPUACTLR_EL1
287	orr	x1, x1, CORTEX_A510_CPUACTLR_EL1_BIT_17
288	msr	CORTEX_A510_CPUACTLR_EL1, x1
2891:
290	ret x17
291endfunc errata_cortex_a510_2347730_wa
292
293func check_errata_2347730
294	/* Applies to revisions r1p1 and lower. */
295	mov	x1, #0x11
296	b	cpu_rev_var_ls
297endfunc check_errata_2347730
298
299	/*---------------------------------------------------
300	 * Errata Workaround for Cortex-A510 Errata #2371937.
301	 * This applies to revisions r1p1 and lower, and is
302	 * fixed in r1p2.
303	 * Inputs:
304	 * x0: variant[4:7] and revision[0:3] of current cpu.
305	 * Shall clobber: x0, x1, x17
306	 *---------------------------------------------------
307	 */
308func errata_cortex_a510_2371937_wa
309	mov	x17, x30
310	bl	check_errata_2371937
311	cbz	x0, 1f
312
313	/*
314	 * Cacheable atomic operations can be forced
315	 * to be executed near by setting
316	 * IMP_CPUECTLR_EL1.ATOM=0b010. ATOM is found
317	 * in [40:38] of CPUECTLR_EL1.
318	 */
319	mrs 	x0, CORTEX_A510_CPUECTLR_EL1
320	mov 	x1, CORTEX_A510_CPUECTLR_EL1_ATOM_EXECALLINSTRNEAR
321	bfi 	x0, x1, CORTEX_A510_CPUECTLR_EL1_ATOM, #3
322	msr 	CORTEX_A510_CPUECTLR_EL1, x0
3231:
324	ret 	x17
325endfunc errata_cortex_a510_2371937_wa
326
327func check_errata_2371937
328	/* Applies to r1p1 and lower */
329	mov 	x1, #0x11
330	b	cpu_rev_var_ls
331endfunc check_errata_2371937
332
333	/* ------------------------------------------------------
334	 * Errata Workaround for Cortex-A510 Errata #2666669
335	 * This applies to revisions r1p1 and lower, and is fixed
336	 * in r1p2.
337	 * Inputs:
338	 * x0: variant[4:7] and revision[0:3] of current cpu.
339	 * Shall clobber: x0, x1, x17
340	 * ------------------------------------------------------
341	 */
342func errata_cortex_a510_2666669_wa
343	mov	x17, x30
344	bl	check_errata_2666669
345	cbz	x0, 1f
346
347	/*
348	 * Workaround will set IMP_CPUACTLR_EL1[38]
349	 * to 0b1.
350	 */
351	mrs	x1, CORTEX_A510_CPUACTLR_EL1
352	orr	x1, x1, CORTEX_A510_CPUACTLR_EL1_BIT_38
353	msr	CORTEX_A510_CPUACTLR_EL1, x1
3541:
355	ret	x17
356endfunc errata_cortex_a510_2666669_wa
357
358func check_errata_2666669
359	/* Applies to r1p1 and lower */
360	mov	x1, #0x11
361	b	cpu_rev_var_ls
362endfunc check_errata_2666669
363
364	/* ----------------------------------------------------
365	 * HW will do the cache maintenance while powering down
366	 * ----------------------------------------------------
367	 */
368func cortex_a510_core_pwr_dwn
369	/* ---------------------------------------------------
370	 * Enable CPU power down bit in power control register
371	 * ---------------------------------------------------
372	 */
373	mrs	x0, CORTEX_A510_CPUPWRCTLR_EL1
374	orr	x0, x0, #CORTEX_A510_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
375	msr	CORTEX_A510_CPUPWRCTLR_EL1, x0
376	isb
377	ret
378endfunc cortex_a510_core_pwr_dwn
379
380	/*
381	 * Errata printing function for Cortex-A510. Must follow AAPCS.
382	 */
383#if REPORT_ERRATA
384func cortex_a510_errata_report
385	stp	x8, x30, [sp, #-16]!
386
387	bl	cpu_get_rev_var
388	mov	x8, x0
389
390	/*
391	 * Report all errata. The revision-variant information is passed to
392	 * checking functions of each errata.
393	 */
394	report_errata ERRATA_A510_1922240, cortex_a510, 1922240
395	report_errata ERRATA_A510_2041909, cortex_a510, 2041909
396	report_errata ERRATA_A510_2042739, cortex_a510, 2042739
397	report_errata ERRATA_A510_2172148, cortex_a510, 2172148
398	report_errata ERRATA_A510_2218950, cortex_a510, 2218950
399	report_errata ERRATA_A510_2250311, cortex_a510, 2250311
400	report_errata ERRATA_A510_2288014, cortex_a510, 2288014
401	report_errata ERRATA_A510_2347730, cortex_a510, 2347730
402	report_errata ERRATA_A510_2371937, cortex_a510, 2371937
403	report_errata ERRATA_A510_2666669, cortex_a510, 2666669
404	report_errata ERRATA_DSU_2313941, cortex_a510, dsu_2313941
405
406	ldp	x8, x30, [sp], #16
407	ret
408endfunc cortex_a510_errata_report
409#endif
410
411func cortex_a510_reset_func
412	mov	x19, x30
413
414	/* Disable speculative loads */
415	msr	SSBS, xzr
416
417	/* Get the CPU revision and stash it in x18. */
418	bl	cpu_get_rev_var
419	mov	x18, x0
420
421#if ERRATA_DSU_2313941
422	bl	errata_dsu_2313941_wa
423#endif
424
425#if ERRATA_A510_1922240
426	mov	x0, x18
427	bl	errata_cortex_a510_1922240_wa
428#endif
429
430#if ERRATA_A510_2288014
431	mov	x0, x18
432	bl	errata_cortex_a510_2288014_wa
433#endif
434
435#if ERRATA_A510_2042739
436	mov	x0, x18
437	bl	errata_cortex_a510_2042739_wa
438#endif
439
440#if ERRATA_A510_2041909
441	mov	x0, x18
442	bl	errata_cortex_a510_2041909_wa
443#endif
444
445#if ERRATA_A510_2250311
446	mov	x0, x18
447	bl	errata_cortex_a510_2250311_wa
448#endif
449
450#if ERRATA_A510_2218950
451	mov	x0, x18
452	bl	errata_cortex_a510_2218950_wa
453#endif
454
455#if ERRATA_A510_2371937
456	mov 	x0, x18
457	bl	errata_cortex_a510_2371937_wa
458#endif
459
460#if ERRATA_A510_2172148
461	mov	x0, x18
462	bl	errata_cortex_a510_2172148_wa
463#endif
464
465#if ERRATA_A510_2347730
466	mov	x0, x18
467	bl	errata_cortex_a510_2347730_wa
468#endif
469
470#if ERRATA_A510_2666669
471	mov	x0, x18
472	bl	errata_cortex_a510_2666669_wa
473#endif
474
475	isb
476	ret	x19
477endfunc cortex_a510_reset_func
478
479	/* ---------------------------------------------
480	 * This function provides Cortex-A510 specific
481	 * register information for crash reporting.
482	 * It needs to return with x6 pointing to
483	 * a list of register names in ascii and
484	 * x8 - x15 having values of registers to be
485	 * reported.
486	 * ---------------------------------------------
487	 */
488.section .rodata.cortex_a510_regs, "aS"
489cortex_a510_regs:  /* The ascii list of register names to be reported */
490	.asciz	"cpuectlr_el1", ""
491
492func cortex_a510_cpu_reg_dump
493	adr	x6, cortex_a510_regs
494	mrs	x8, CORTEX_A510_CPUECTLR_EL1
495	ret
496endfunc cortex_a510_cpu_reg_dump
497
498declare_cpu_ops cortex_a510, CORTEX_A510_MIDR, \
499	cortex_a510_reset_func, \
500	cortex_a510_core_pwr_dwn
501