1/*
2 * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch.h>
8#include <asm_macros.S>
9#include <assert_macros.S>
10#include <common/debug.h>
11#include <cortex_a53.h>
12#include <cpu_macros.S>
13
14#if A53_DISABLE_NON_TEMPORAL_HINT
15#undef ERRATA_A53_836870
16#define ERRATA_A53_836870	1
17#endif
18
19	/* ---------------------------------------------
20	 * Disable intra-cluster coherency
21	 * ---------------------------------------------
22	 */
23func cortex_a53_disable_smp
24	ldcopr16	r0, r1, CORTEX_A53_ECTLR
25	bic64_imm	r0, r1, CORTEX_A53_ECTLR_SMP_BIT
26	stcopr16	r0, r1, CORTEX_A53_ECTLR
27	isb
28	dsb	sy
29	bx	lr
30endfunc cortex_a53_disable_smp
31
32	/* ---------------------------------------------------
33	 * Errata Workaround for Cortex A53 Errata #819472.
34	 * This applies only to revision <= r0p1 of Cortex A53.
35	 * ---------------------------------------------------
36	 */
37func check_errata_819472
38	/*
39	 * Even though this is only needed for revision <= r0p1, it
40	 * is always applied due to limitations of the current
41	 * errata framework.
42	 */
43	mov	r0, #ERRATA_APPLIES
44	bx	lr
45endfunc check_errata_819472
46
47	/* ---------------------------------------------------
48	 * Errata Workaround for Cortex A53 Errata #824069.
49	 * This applies only to revision <= r0p2 of Cortex A53.
50	 * ---------------------------------------------------
51	 */
52func check_errata_824069
53	/*
54	 * Even though this is only needed for revision <= r0p2, it
55	 * is always applied due to limitations of the current
56	 * errata framework.
57	 */
58	mov	r0, #ERRATA_APPLIES
59	bx	lr
60endfunc check_errata_824069
61
62	/* --------------------------------------------------
63	 * Errata Workaround for Cortex A53 Errata #826319.
64	 * This applies only to revision <= r0p2 of Cortex A53.
65	 * Inputs:
66	 * r0: variant[4:7] and revision[0:3] of current cpu.
67	 * Shall clobber: r0-r3
68	 * --------------------------------------------------
69	 */
70func errata_a53_826319_wa
71	/*
72	 * Compare r0 against revision r0p2
73	 */
74	mov	r2, lr
75	bl	check_errata_826319
76	mov	lr, r2
77	cmp	r0, #ERRATA_NOT_APPLIES
78	beq	1f
79	ldcopr	r0, CORTEX_A53_L2ACTLR
80	bic	r0, #CORTEX_A53_L2ACTLR_ENABLE_UNIQUECLEAN
81	orr	r0, #CORTEX_A53_L2ACTLR_DISABLE_CLEAN_PUSH
82	stcopr	r0, CORTEX_A53_L2ACTLR
831:
84	bx	lr
85endfunc errata_a53_826319_wa
86
87func check_errata_826319
88	mov	r1, #0x02
89	b	cpu_rev_var_ls
90endfunc check_errata_826319
91
92	/* ---------------------------------------------------
93	 * Errata Workaround for Cortex A53 Errata #827319.
94	 * This applies only to revision <= r0p2 of Cortex A53.
95	 * ---------------------------------------------------
96	 */
97func check_errata_827319
98	/*
99	 * Even though this is only needed for revision <= r0p2, it
100	 * is always applied due to limitations of the current
101	 * errata framework.
102	 */
103	mov	r0, #ERRATA_APPLIES
104	bx	lr
105endfunc check_errata_827319
106
107	/* ---------------------------------------------------------------------
108	 * Disable the cache non-temporal hint.
109	 *
110	 * This ignores the Transient allocation hint in the MAIR and treats
111	 * allocations the same as non-transient allocation types. As a result,
112	 * the LDNP and STNP instructions in AArch64 behave the same as the
113	 * equivalent LDP and STP instructions.
114	 *
115	 * This is relevant only for revisions <= r0p3 of Cortex-A53.
116	 * From r0p4 and onwards, the bit to disable the hint is enabled by
117	 * default at reset.
118	 *
119	 * Inputs:
120	 * r0: variant[4:7] and revision[0:3] of current cpu.
121	 * Shall clobber: r0-r3
122	 * ---------------------------------------------------------------------
123	 */
124func a53_disable_non_temporal_hint
125	/*
126	 * Compare r0 against revision r0p3
127	 */
128	mov		r2, lr
129	bl		check_errata_disable_non_temporal_hint
130	mov		lr, r2
131	cmp		r0, #ERRATA_NOT_APPLIES
132	beq		1f
133	ldcopr16	r0, r1, CORTEX_A53_CPUACTLR
134	orr64_imm	r0, r1, CORTEX_A53_CPUACTLR_DTAH
135	stcopr16	r0, r1, CORTEX_A53_CPUACTLR
1361:
137	bx		lr
138endfunc a53_disable_non_temporal_hint
139
140func check_errata_disable_non_temporal_hint
141	mov	r1, #0x03
142	b	cpu_rev_var_ls
143endfunc check_errata_disable_non_temporal_hint
144
145	/* --------------------------------------------------
146	 * Errata Workaround for Cortex A53 Errata #855873.
147	 *
148	 * This applies only to revisions >= r0p3 of Cortex A53.
149	 * Earlier revisions of the core are affected as well, but don't
150	 * have the chicken bit in the CPUACTLR register. It is expected that
151	 * the rich OS takes care of that, especially as the workaround is
152	 * shared with other erratas in those revisions of the CPU.
153	 * Inputs:
154	 * r0: variant[4:7] and revision[0:3] of current cpu.
155	 * Shall clobber: r0-r3
156	 * --------------------------------------------------
157	 */
158func errata_a53_855873_wa
159	/*
160	 * Compare r0 against revision r0p3 and higher
161	 */
162	mov		r2, lr
163	bl		check_errata_855873
164	mov		lr, r2
165	cmp		r0, #ERRATA_NOT_APPLIES
166	beq		1f
167	ldcopr16	r0, r1, CORTEX_A53_CPUACTLR
168	orr64_imm	r0, r1, CORTEX_A53_CPUACTLR_ENDCCASCI
169	stcopr16	r0, r1, CORTEX_A53_CPUACTLR
1701:
171	bx		lr
172endfunc errata_a53_855873_wa
173
174func check_errata_855873
175	mov	r1, #0x03
176	b	cpu_rev_var_hs
177endfunc check_errata_855873
178
179	/* -------------------------------------------------
180	 * The CPU Ops reset function for Cortex-A53.
181	 * Shall clobber: r0-r6
182	 * -------------------------------------------------
183	 */
184func cortex_a53_reset_func
185	mov	r5, lr
186	bl	cpu_get_rev_var
187	mov	r4, r0
188
189#if ERRATA_A53_826319
190	mov	r0, r4
191	bl	errata_a53_826319_wa
192#endif
193
194#if ERRATA_A53_836870
195	mov	r0, r4
196	bl	a53_disable_non_temporal_hint
197#endif
198
199#if ERRATA_A53_855873
200	mov	r0, r4
201	bl	errata_a53_855873_wa
202#endif
203
204	/* ---------------------------------------------
205	 * Enable the SMP bit.
206	 * ---------------------------------------------
207	 */
208	ldcopr16	r0, r1, CORTEX_A53_ECTLR
209	orr64_imm	r0, r1, CORTEX_A53_ECTLR_SMP_BIT
210	stcopr16	r0, r1,	CORTEX_A53_ECTLR
211	isb
212	bx	r5
213endfunc cortex_a53_reset_func
214
215	/* ----------------------------------------------------
216	 * The CPU Ops core power down function for Cortex-A53.
217	 * ----------------------------------------------------
218	 */
219func cortex_a53_core_pwr_dwn
220	push	{r12, lr}
221
222	/* Assert if cache is enabled */
223#if ENABLE_ASSERTIONS
224	ldcopr	r0, SCTLR
225	tst	r0, #SCTLR_C_BIT
226	ASM_ASSERT(eq)
227#endif
228
229	/* ---------------------------------------------
230	 * Flush L1 caches.
231	 * ---------------------------------------------
232	 */
233	mov	r0, #DC_OP_CISW
234	bl	dcsw_op_level1
235
236	/* ---------------------------------------------
237	 * Come out of intra cluster coherency
238	 * ---------------------------------------------
239	 */
240	pop	{r12, lr}
241	b	cortex_a53_disable_smp
242endfunc cortex_a53_core_pwr_dwn
243
244	/* -------------------------------------------------------
245	 * The CPU Ops cluster power down function for Cortex-A53.
246	 * Clobbers: r0-r3
247	 * -------------------------------------------------------
248	 */
249func cortex_a53_cluster_pwr_dwn
250	push	{r12, lr}
251
252	/* Assert if cache is enabled */
253#if ENABLE_ASSERTIONS
254	ldcopr	r0, SCTLR
255	tst	r0, #SCTLR_C_BIT
256	ASM_ASSERT(eq)
257#endif
258
259	/* ---------------------------------------------
260	 * Flush L1 caches.
261	 * ---------------------------------------------
262	 */
263	mov	r0, #DC_OP_CISW
264	bl	dcsw_op_level1
265
266	/* ---------------------------------------------
267	 * Disable the optional ACP.
268	 * ---------------------------------------------
269	 */
270	bl	plat_disable_acp
271
272	/* ---------------------------------------------
273	 * Flush L2 caches.
274	 * ---------------------------------------------
275	 */
276	mov	r0, #DC_OP_CISW
277	bl	dcsw_op_level2
278
279	/* ---------------------------------------------
280	 * Come out of intra cluster coherency
281	 * ---------------------------------------------
282	 */
283	pop	{r12, lr}
284	b	cortex_a53_disable_smp
285endfunc cortex_a53_cluster_pwr_dwn
286
287#if REPORT_ERRATA
288/*
289 * Errata printing function for Cortex A53. Must follow AAPCS.
290 */
291func cortex_a53_errata_report
292	push	{r12, lr}
293
294	bl	cpu_get_rev_var
295	mov	r4, r0
296
297	/*
298	 * Report all errata. The revision-variant information is passed to
299	 * checking functions of each errata.
300	 */
301	report_errata ERRATA_A53_819472, cortex_a53, 819472
302	report_errata ERRATA_A53_824069, cortex_a53, 824069
303	report_errata ERRATA_A53_826319, cortex_a53, 826319
304	report_errata ERRATA_A53_827319, cortex_a53, 827319
305	report_errata ERRATA_A53_836870, cortex_a53, disable_non_temporal_hint
306	report_errata ERRATA_A53_855873, cortex_a53, 855873
307
308	pop	{r12, lr}
309	bx	lr
310endfunc cortex_a53_errata_report
311#endif
312
313declare_cpu_ops cortex_a53, CORTEX_A53_MIDR, \
314	cortex_a53_reset_func, \
315	cortex_a53_core_pwr_dwn, \
316	cortex_a53_cluster_pwr_dwn
317