xref: /rk3399_ARM-atf/lib/cpus/aarch64/cortex_a57.S (revision 51faada71a219a8b94cd8d8e423f0f22e9da4d8f)
1/*
2 * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * Neither the name of ARM nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific
16 * prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30#include <arch.h>
31#include <asm_macros.S>
32#include <assert_macros.S>
33#include <bl_common.h>
34#include <cortex_a57.h>
35#include <cpu_macros.S>
36#include <debug.h>
37#include <plat_macros.S>
38
39	/* ---------------------------------------------
40	 * Disable L1 data cache and unified L2 cache
41	 * ---------------------------------------------
42	 */
43func cortex_a57_disable_dcache
44	mrs	x1, sctlr_el3
45	bic	x1, x1, #SCTLR_C_BIT
46	msr	sctlr_el3, x1
47	isb
48	ret
49endfunc cortex_a57_disable_dcache
50
51	/* ---------------------------------------------
52	 * Disable all types of L2 prefetches.
53	 * ---------------------------------------------
54	 */
55func cortex_a57_disable_l2_prefetch
56	mrs	x0, CPUECTLR_EL1
57	orr	x0, x0, #CPUECTLR_DIS_TWD_ACC_PFTCH_BIT
58	mov	x1, #CPUECTLR_L2_IPFTCH_DIST_MASK
59	orr	x1, x1, #CPUECTLR_L2_DPFTCH_DIST_MASK
60	bic	x0, x0, x1
61	msr	CPUECTLR_EL1, x0
62	isb
63	dsb	ish
64	ret
65endfunc cortex_a57_disable_l2_prefetch
66
67	/* ---------------------------------------------
68	 * Disable intra-cluster coherency
69	 * ---------------------------------------------
70	 */
71func cortex_a57_disable_smp
72	mrs	x0, CPUECTLR_EL1
73	bic	x0, x0, #CPUECTLR_SMP_BIT
74	msr	CPUECTLR_EL1, x0
75	ret
76endfunc cortex_a57_disable_smp
77
78	/* ---------------------------------------------
79	 * Disable debug interfaces
80	 * ---------------------------------------------
81	 */
82func cortex_a57_disable_ext_debug
83	mov	x0, #1
84	msr	osdlr_el1, x0
85	isb
86	dsb	sy
87	ret
88endfunc cortex_a57_disable_ext_debug
89
90	/* --------------------------------------------------
91	 * Errata Workaround for Cortex A57 Errata #806969.
92	 * This applies only to revision r0p0 of Cortex A57.
93	 * Inputs:
94	 * x0: variant[4:7] and revision[0:3] of current cpu.
95	 * Shall clobber: x0-x17
96	 * --------------------------------------------------
97	 */
98func errata_a57_806969_wa
99	/*
100	 * Compare x0 against revision r0p0
101	 */
102	mov	x17, x30
103	bl	check_errata_806969
104	cbz	x0, 1f
105	mrs	x1, CPUACTLR_EL1
106	orr	x1, x1, #CPUACTLR_NO_ALLOC_WBWA
107	msr	CPUACTLR_EL1, x1
1081:
109	ret	x17
110endfunc errata_a57_806969_wa
111
112func check_errata_806969
113	mov	x1, #0x00
114	b	cpu_rev_var_ls
115endfunc check_errata_806969
116
117	/* ---------------------------------------------------
118	 * Errata Workaround for Cortex A57 Errata #813419.
119	 * This applies only to revision r0p0 of Cortex A57.
120	 * ---------------------------------------------------
121	 */
122func check_errata_813419
123	/*
124	 * Even though this is only needed for revision r0p0, it
125	 * is always applied due to limitations of the current
126	 * errata framework.
127	 */
128	mov	x0, #ERRATA_APPLIES
129	ret
130endfunc check_errata_813419
131
132	/* ---------------------------------------------------
133	 * Errata Workaround for Cortex A57 Errata #813420.
134	 * This applies only to revision r0p0 of Cortex A57.
135	 * Inputs:
136	 * x0: variant[4:7] and revision[0:3] of current cpu.
137	 * Shall clobber: x0-x17
138	 * ---------------------------------------------------
139	 */
140func errata_a57_813420_wa
141	/*
142	 * Compare x0 against revision r0p0
143	 */
144	mov	x17, x30
145	bl	check_errata_813420
146	cbz	x0, 1f
147	mrs	x1, CPUACTLR_EL1
148	orr	x1, x1, #CPUACTLR_DCC_AS_DCCI
149	msr	CPUACTLR_EL1, x1
1501:
151	ret	x17
152endfunc errata_a57_813420_wa
153
154func check_errata_813420
155	mov	x1, #0x00
156	b	cpu_rev_var_ls
157endfunc check_errata_813420
158
159	/* --------------------------------------------------------------------
160	 * Disable the over-read from the LDNP instruction.
161	 *
162	 * This applies to all revisions <= r1p2. The performance degradation
163	 * observed with LDNP/STNP has been fixed on r1p3 and onwards.
164	 *
165	 * Inputs:
166	 * x0: variant[4:7] and revision[0:3] of current cpu.
167	 * Shall clobber: x0-x17
168	 * ---------------------------------------------------------------------
169	 */
170func a57_disable_ldnp_overread
171	/*
172	 * Compare x0 against revision r1p2
173	 */
174	mov	x17, x30
175	bl	check_errata_disable_ldnp_overread
176	cbz	x0, 1f
177	mrs	x1, CPUACTLR_EL1
178	orr	x1, x1, #CPUACTLR_DIS_OVERREAD
179	msr	CPUACTLR_EL1, x1
1801:
181	ret	x17
182endfunc a57_disable_ldnp_overread
183
184func check_errata_disable_ldnp_overread
185	mov	x1, #0x12
186	b	cpu_rev_var_ls
187endfunc check_errata_disable_ldnp_overread
188
189	/* ---------------------------------------------------
190	 * Errata Workaround for Cortex A57 Errata #826974.
191	 * This applies only to revision <= r1p1 of Cortex A57.
192	 * Inputs:
193	 * x0: variant[4:7] and revision[0:3] of current cpu.
194	 * Shall clobber: x0-x17
195	 * ---------------------------------------------------
196	 */
197func errata_a57_826974_wa
198	/*
199	 * Compare x0 against revision r1p1
200	 */
201	mov	x17, x30
202	bl	check_errata_826974
203	cbz	x0, 1f
204	mrs	x1, CPUACTLR_EL1
205	orr	x1, x1, #CPUACTLR_DIS_LOAD_PASS_DMB
206	msr	CPUACTLR_EL1, x1
2071:
208	ret	x17
209endfunc errata_a57_826974_wa
210
211func check_errata_826974
212	mov	x1, #0x11
213	b	cpu_rev_var_ls
214endfunc check_errata_826974
215
216	/* ---------------------------------------------------
217	 * Errata Workaround for Cortex A57 Errata #826977.
218	 * This applies only to revision <= r1p1 of Cortex A57.
219	 * Inputs:
220	 * x0: variant[4:7] and revision[0:3] of current cpu.
221	 * Shall clobber: x0-x17
222	 * ---------------------------------------------------
223	 */
224func errata_a57_826977_wa
225	/*
226	 * Compare x0 against revision r1p1
227	 */
228	mov	x17, x30
229	bl	check_errata_826977
230	cbz	x0, 1f
231	mrs	x1, CPUACTLR_EL1
232	orr	x1, x1, #CPUACTLR_GRE_NGRE_AS_NGNRE
233	msr	CPUACTLR_EL1, x1
2341:
235	ret	x17
236endfunc errata_a57_826977_wa
237
238func check_errata_826977
239	mov	x1, #0x11
240	b	cpu_rev_var_ls
241endfunc check_errata_826977
242
243	/* ---------------------------------------------------
244	 * Errata Workaround for Cortex A57 Errata #828024.
245	 * This applies only to revision <= r1p1 of Cortex A57.
246	 * Inputs:
247	 * x0: variant[4:7] and revision[0:3] of current cpu.
248	 * Shall clobber: x0-x17
249	 * ---------------------------------------------------
250	 */
251func errata_a57_828024_wa
252	/*
253	 * Compare x0 against revision r1p1
254	 */
255	mov	x17, x30
256	bl	check_errata_828024
257	cbz	x0, 1f
258	mrs	x1, CPUACTLR_EL1
259	/*
260	 * Setting the relevant bits in CPUACTLR_EL1 has to be done in 2
261	 * instructions here because the resulting bitmask doesn't fit in a
262	 * 16-bit value so it cannot be encoded in a single instruction.
263	 */
264	orr	x1, x1, #CPUACTLR_NO_ALLOC_WBWA
265	orr	x1, x1, #(CPUACTLR_DIS_L1_STREAMING | CPUACTLR_DIS_STREAMING)
266	msr	CPUACTLR_EL1, x1
2671:
268	ret	x17
269endfunc errata_a57_828024_wa
270
271func check_errata_828024
272	mov	x1, #0x11
273	b	cpu_rev_var_ls
274endfunc check_errata_828024
275
276	/* ---------------------------------------------------
277	 * Errata Workaround for Cortex A57 Errata #829520.
278	 * This applies only to revision <= r1p2 of Cortex A57.
279	 * Inputs:
280	 * x0: variant[4:7] and revision[0:3] of current cpu.
281	 * Shall clobber: x0-x17
282	 * ---------------------------------------------------
283	 */
284func errata_a57_829520_wa
285	/*
286	 * Compare x0 against revision r1p2
287	 */
288	mov	x17, x30
289	bl	check_errata_829520
290	cbz	x0, 1f
291	mrs	x1, CPUACTLR_EL1
292	orr	x1, x1, #CPUACTLR_DIS_INDIRECT_PREDICTOR
293	msr	CPUACTLR_EL1, x1
2941:
295	ret	x17
296endfunc errata_a57_829520_wa
297
298func check_errata_829520
299	mov	x1, #0x12
300	b	cpu_rev_var_ls
301endfunc check_errata_829520
302
303	/* ---------------------------------------------------
304	 * Errata Workaround for Cortex A57 Errata #833471.
305	 * This applies only to revision <= r1p2 of Cortex A57.
306	 * Inputs:
307	 * x0: variant[4:7] and revision[0:3] of current cpu.
308	 * Shall clobber: x0-x17
309	 * ---------------------------------------------------
310	 */
311func errata_a57_833471_wa
312	/*
313	 * Compare x0 against revision r1p2
314	 */
315	mov	x17, x30
316	bl	check_errata_833471
317	cbz	x0, 1f
318	mrs	x1, CPUACTLR_EL1
319	orr	x1, x1, #CPUACTLR_FORCE_FPSCR_FLUSH
320	msr	CPUACTLR_EL1, x1
3211:
322	ret	x17
323endfunc errata_a57_833471_wa
324
325func check_errata_833471
326	mov	x1, #0x12
327	b	cpu_rev_var_ls
328endfunc check_errata_833471
329
330	/* -------------------------------------------------
331	 * The CPU Ops reset function for Cortex-A57.
332	 * Shall clobber: x0-x19
333	 * -------------------------------------------------
334	 */
335func cortex_a57_reset_func
336	mov	x19, x30
337	bl	cpu_get_rev_var
338	mov	x18, x0
339
340#if ERRATA_A57_806969
341	mov	x0, x18
342	bl	errata_a57_806969_wa
343#endif
344
345#if ERRATA_A57_813420
346	mov	x0, x18
347	bl	errata_a57_813420_wa
348#endif
349
350#if A57_DISABLE_NON_TEMPORAL_HINT
351	mov	x0, x18
352	bl	a57_disable_ldnp_overread
353#endif
354
355#if ERRATA_A57_826974
356	mov	x0, x18
357	bl	errata_a57_826974_wa
358#endif
359
360#if ERRATA_A57_826977
361	mov	x0, x18
362	bl	errata_a57_826977_wa
363#endif
364
365#if ERRATA_A57_828024
366	mov	x0, x18
367	bl	errata_a57_828024_wa
368#endif
369
370#if ERRATA_A57_829520
371	mov	x0, x18
372	bl	errata_a57_829520_wa
373#endif
374
375#if ERRATA_A57_833471
376	mov	x0, x18
377	bl	errata_a57_833471_wa
378#endif
379
380	/* ---------------------------------------------
381	 * Enable the SMP bit.
382	 * ---------------------------------------------
383	 */
384	mrs	x0, CPUECTLR_EL1
385	orr	x0, x0, #CPUECTLR_SMP_BIT
386	msr	CPUECTLR_EL1, x0
387	isb
388	ret	x19
389endfunc cortex_a57_reset_func
390
391	/* ----------------------------------------------------
392	 * The CPU Ops core power down function for Cortex-A57.
393	 * ----------------------------------------------------
394	 */
395func cortex_a57_core_pwr_dwn
396	mov	x18, x30
397
398	/* ---------------------------------------------
399	 * Turn off caches.
400	 * ---------------------------------------------
401	 */
402	bl	cortex_a57_disable_dcache
403
404	/* ---------------------------------------------
405	 * Disable the L2 prefetches.
406	 * ---------------------------------------------
407	 */
408	bl	cortex_a57_disable_l2_prefetch
409
410	/* ---------------------------------------------
411	 * Flush L1 caches.
412	 * ---------------------------------------------
413	 */
414	mov	x0, #DCCISW
415	bl	dcsw_op_level1
416
417	/* ---------------------------------------------
418	 * Come out of intra cluster coherency
419	 * ---------------------------------------------
420	 */
421	bl	cortex_a57_disable_smp
422
423	/* ---------------------------------------------
424	 * Force the debug interfaces to be quiescent
425	 * ---------------------------------------------
426	 */
427	mov	x30, x18
428	b	cortex_a57_disable_ext_debug
429endfunc cortex_a57_core_pwr_dwn
430
431	/* -------------------------------------------------------
432	 * The CPU Ops cluster power down function for Cortex-A57.
433	 * -------------------------------------------------------
434	 */
435func cortex_a57_cluster_pwr_dwn
436	mov	x18, x30
437
438	/* ---------------------------------------------
439	 * Turn off caches.
440	 * ---------------------------------------------
441	 */
442	bl	cortex_a57_disable_dcache
443
444	/* ---------------------------------------------
445	 * Disable the L2 prefetches.
446	 * ---------------------------------------------
447	 */
448	bl	cortex_a57_disable_l2_prefetch
449
450#if !SKIP_A57_L1_FLUSH_PWR_DWN
451	/* -------------------------------------------------
452	 * Flush the L1 caches.
453	 * -------------------------------------------------
454	 */
455	mov	x0, #DCCISW
456	bl	dcsw_op_level1
457#endif
458	/* ---------------------------------------------
459	 * Disable the optional ACP.
460	 * ---------------------------------------------
461	 */
462	bl	plat_disable_acp
463
464	/* -------------------------------------------------
465	 * Flush the L2 caches.
466	 * -------------------------------------------------
467	 */
468	mov	x0, #DCCISW
469	bl	dcsw_op_level2
470
471	/* ---------------------------------------------
472	 * Come out of intra cluster coherency
473	 * ---------------------------------------------
474	 */
475	bl	cortex_a57_disable_smp
476
477	/* ---------------------------------------------
478	 * Force the debug interfaces to be quiescent
479	 * ---------------------------------------------
480	 */
481	mov	x30, x18
482	b	cortex_a57_disable_ext_debug
483endfunc cortex_a57_cluster_pwr_dwn
484
485#if REPORT_ERRATA
486/*
487 * Errata printing function for Cortex A57. Must follow AAPCS.
488 */
489func cortex_a57_errata_report
490	stp	x8, x30, [sp, #-16]!
491
492	bl	cpu_get_rev_var
493	mov	x8, x0
494
495	/*
496	 * Report all errata. The revision-variant information is passed to
497	 * checking functions of each errata.
498	 */
499	report_errata ERRATA_A57_806969, cortex_a57, 806969
500	report_errata ERRATA_A57_813419, cortex_a57, 813419
501	report_errata ERRATA_A57_813420, cortex_a57, 813420
502	report_errata A57_DISABLE_NON_TEMPORAL_HINT, cortex_a57, \
503		disable_ldnp_overread
504	report_errata ERRATA_A57_826974, cortex_a57, 826974
505	report_errata ERRATA_A57_826977, cortex_a57, 826977
506	report_errata ERRATA_A57_828024, cortex_a57, 828024
507	report_errata ERRATA_A57_829520, cortex_a57, 829520
508	report_errata ERRATA_A57_833471, cortex_a57, 833471
509
510	ldp	x8, x30, [sp], #16
511	ret
512endfunc cortex_a57_errata_report
513#endif
514
515	/* ---------------------------------------------
516	 * This function provides cortex_a57 specific
517	 * register information for crash reporting.
518	 * It needs to return with x6 pointing to
519	 * a list of register names in ascii and
520	 * x8 - x15 having values of registers to be
521	 * reported.
522	 * ---------------------------------------------
523	 */
524.section .rodata.cortex_a57_regs, "aS"
525cortex_a57_regs:  /* The ascii list of register names to be reported */
526	.asciz	"cpuectlr_el1", "cpumerrsr_el1", "l2merrsr_el1", ""
527
528func cortex_a57_cpu_reg_dump
529	adr	x6, cortex_a57_regs
530	mrs	x8, CPUECTLR_EL1
531	mrs	x9, CPUMERRSR_EL1
532	mrs	x10, L2MERRSR_EL1
533	ret
534endfunc cortex_a57_cpu_reg_dump
535
536
537declare_cpu_ops cortex_a57, CORTEX_A57_MIDR, \
538	cortex_a57_reset_func, \
539	cortex_a57_core_pwr_dwn, \
540	cortex_a57_cluster_pwr_dwn
541