xref: /rk3399_ARM-atf/lib/cpus/aarch64/cortex_a57.S (revision 532ed6183868036e4a4f83cd7a71b93266a3bdb7)
1/*
2 * Copyright (c) 2014-2016, 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	 * Clobbers : x0 - x5
96	 * --------------------------------------------------
97	 */
98func errata_a57_806969_wa
99	/*
100	 * Compare x0 against revision r0p0
101	 */
102	cbz	x0, apply_806969
103#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
104	b	print_revision_warning
105#else
106	ret
107#endif
108apply_806969:
109	mrs	x1, CPUACTLR_EL1
110	orr	x1, x1, #CPUACTLR_NO_ALLOC_WBWA
111	msr	CPUACTLR_EL1, x1
112	ret
113endfunc errata_a57_806969_wa
114
115
116	/* ---------------------------------------------------
117	 * Errata Workaround for Cortex A57 Errata #813420.
118	 * This applies only to revision r0p0 of Cortex A57.
119	 * Inputs:
120	 * x0: variant[4:7] and revision[0:3] of current cpu.
121	 * Clobbers : x0 - x5
122	 * ---------------------------------------------------
123	 */
124func errata_a57_813420_wa
125	/*
126	 * Compare x0 against revision r0p0
127	 */
128	cbz	x0, apply_813420
129#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
130	b	print_revision_warning
131#else
132	ret
133#endif
134apply_813420:
135	mrs	x1, CPUACTLR_EL1
136	orr	x1, x1, #CPUACTLR_DCC_AS_DCCI
137	msr	CPUACTLR_EL1, x1
138	ret
139endfunc errata_a57_813420_wa
140
141	/* --------------------------------------------------------------------
142	 * Disable the over-read from the LDNP instruction.
143	 *
144	 * This applies to all revisions <= r1p2. The performance degradation
145	 * observed with LDNP/STNP has been fixed on r1p3 and onwards.
146	 *
147	 * Inputs:
148	 * x0: variant[4:7] and revision[0:3] of current cpu.
149	 * Clobbers : x0 - x5, x30
150	 * ---------------------------------------------------------------------
151	 */
152func a57_disable_ldnp_overread
153	/*
154	 * Compare x0 against revision r1p2
155	 */
156	cmp	x0, #0x12
157	b.ls	disable_hint
158#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
159	b	print_revision_warning
160#else
161	ret
162#endif
163disable_hint:
164	mrs	x1, CPUACTLR_EL1
165	orr	x1, x1, #CPUACTLR_DIS_OVERREAD
166	msr	CPUACTLR_EL1, x1
167	ret
168endfunc a57_disable_ldnp_overread
169
170	/* ---------------------------------------------------
171	 * Errata Workaround for Cortex A57 Errata #826974.
172	 * This applies only to revision <= r1p1 of Cortex A57.
173	 * Inputs:
174	 * x0: variant[4:7] and revision[0:3] of current cpu.
175	 * Clobbers : x0 - x5
176	 * ---------------------------------------------------
177	 */
178func errata_a57_826974_wa
179	/*
180	 * Compare x0 against revision r1p1
181	 */
182	cmp	x0, #0x11
183	b.ls	apply_826974
184#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
185	b	print_revision_warning
186#else
187	ret
188#endif
189apply_826974:
190	mrs	x1, CPUACTLR_EL1
191	orr	x1, x1, #CPUACTLR_DIS_LOAD_PASS_DMB
192	msr	CPUACTLR_EL1, x1
193	ret
194endfunc errata_a57_826974_wa
195
196	/* ---------------------------------------------------
197	 * Errata Workaround for Cortex A57 Errata #826977.
198	 * This applies only to revision <= r1p1 of Cortex A57.
199	 * Inputs:
200	 * x0: variant[4:7] and revision[0:3] of current cpu.
201	 * Clobbers : x0 - x5
202	 * ---------------------------------------------------
203	 */
204func errata_a57_826977_wa
205	/*
206	 * Compare x0 against revision r1p1
207	 */
208	cmp	x0, #0x11
209	b.ls	apply_826977
210#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
211	b	print_revision_warning
212#else
213	ret
214#endif
215apply_826977:
216	mrs	x1, CPUACTLR_EL1
217	orr	x1, x1, #CPUACTLR_GRE_NGRE_AS_NGNRE
218	msr	CPUACTLR_EL1, x1
219	ret
220endfunc errata_a57_826977_wa
221
222	/* ---------------------------------------------------
223	 * Errata Workaround for Cortex A57 Errata #828024.
224	 * This applies only to revision <= r1p1 of Cortex A57.
225	 * Inputs:
226	 * x0: variant[4:7] and revision[0:3] of current cpu.
227	 * Clobbers : x0 - x5
228	 * ---------------------------------------------------
229	 */
230func errata_a57_828024_wa
231	/*
232	 * Compare x0 against revision r1p1
233	 */
234	cmp	x0, #0x11
235	b.ls	apply_828024
236#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
237	b	print_revision_warning
238#else
239	ret
240#endif
241apply_828024:
242	mrs	x1, CPUACTLR_EL1
243	/*
244	 * Setting the relevant bits in CPUACTLR_EL1 has to be done in 2
245	 * instructions here because the resulting bitmask doesn't fit in a
246	 * 16-bit value so it cannot be encoded in a single instruction.
247	 */
248	orr	x1, x1, #CPUACTLR_NO_ALLOC_WBWA
249	orr	x1, x1, #(CPUACTLR_DIS_L1_STREAMING | CPUACTLR_DIS_STREAMING)
250	msr	CPUACTLR_EL1, x1
251	ret
252endfunc errata_a57_828024_wa
253
254	/* ---------------------------------------------------
255	 * Errata Workaround for Cortex A57 Errata #829520.
256	 * This applies only to revision <= r1p2 of Cortex A57.
257	 * Inputs:
258	 * x0: variant[4:7] and revision[0:3] of current cpu.
259	 * Clobbers : x0 - x5
260	 * ---------------------------------------------------
261	 */
262func errata_a57_829520_wa
263	/*
264	 * Compare x0 against revision r1p2
265	 */
266	cmp	x0, #0x12
267	b.ls	apply_829520
268#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
269	b	print_revision_warning
270#else
271	ret
272#endif
273apply_829520:
274	mrs	x1, CPUACTLR_EL1
275	orr	x1, x1, #CPUACTLR_DIS_INDIRECT_PREDICTOR
276	msr	CPUACTLR_EL1, x1
277	ret
278endfunc errata_a57_829520_wa
279
280	/* ---------------------------------------------------
281	 * Errata Workaround for Cortex A57 Errata #833471.
282	 * This applies only to revision <= r1p2 of Cortex A57.
283	 * Inputs:
284	 * x0: variant[4:7] and revision[0:3] of current cpu.
285	 * Clobbers : x0 - x5
286	 * ---------------------------------------------------
287	 */
288func errata_a57_833471_wa
289	/*
290	 * Compare x0 against revision r1p2
291	 */
292	cmp	x0, #0x12
293	b.ls	apply_833471
294#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
295	b	print_revision_warning
296#else
297	ret
298#endif
299apply_833471:
300	mrs	x1, CPUACTLR_EL1
301	orr	x1, x1, #CPUACTLR_FORCE_FPSCR_FLUSH
302	msr	CPUACTLR_EL1, x1
303	ret
304endfunc errata_a57_833471_wa
305
306	/* -------------------------------------------------
307	 * The CPU Ops reset function for Cortex-A57.
308	 * Clobbers: x0-x5, x15, x19, x30
309	 * -------------------------------------------------
310	 */
311func cortex_a57_reset_func
312	mov	x19, x30
313	mrs	x0, midr_el1
314
315	/*
316	 * Extract the variant[20:23] and revision[0:3] from x0
317	 * and pack it in x15[0:7] as variant[4:7] and revision[0:3].
318	 * First extract x0[16:23] to x15[0:7] and zero fill the rest.
319	 * Then extract x0[0:3] into x15[0:3] retaining other bits.
320	 */
321	ubfx	x15, x0, #(MIDR_VAR_SHIFT - MIDR_REV_BITS), #(MIDR_REV_BITS + MIDR_VAR_BITS)
322	bfxil	x15, x0, #MIDR_REV_SHIFT, #MIDR_REV_BITS
323
324#if ERRATA_A57_806969
325	mov	x0, x15
326	bl	errata_a57_806969_wa
327#endif
328
329#if ERRATA_A57_813420
330	mov	x0, x15
331	bl	errata_a57_813420_wa
332#endif
333
334#if A57_DISABLE_NON_TEMPORAL_HINT
335	mov	x0, x15
336	bl	a57_disable_ldnp_overread
337#endif
338
339#if ERRATA_A57_826974
340	mov	x0, x15
341	bl	errata_a57_826974_wa
342#endif
343
344#if ERRATA_A57_826977
345	mov	x0, x15
346	bl	errata_a57_826977_wa
347#endif
348
349#if ERRATA_A57_828024
350	mov	x0, x15
351	bl	errata_a57_828024_wa
352#endif
353
354#if ERRATA_A57_829520
355	mov	x0, x15
356	bl	errata_a57_829520_wa
357#endif
358
359#if ERRATA_A57_833471
360	mov	x0, x15
361	bl	errata_a57_833471_wa
362#endif
363
364	/* ---------------------------------------------
365	 * Enable the SMP bit.
366	 * ---------------------------------------------
367	 */
368	mrs	x0, CPUECTLR_EL1
369	orr	x0, x0, #CPUECTLR_SMP_BIT
370	msr	CPUECTLR_EL1, x0
371	isb
372	ret	x19
373endfunc cortex_a57_reset_func
374
375	/* ----------------------------------------------------
376	 * The CPU Ops core power down function for Cortex-A57.
377	 * ----------------------------------------------------
378	 */
379func cortex_a57_core_pwr_dwn
380	mov	x18, x30
381
382	/* ---------------------------------------------
383	 * Turn off caches.
384	 * ---------------------------------------------
385	 */
386	bl	cortex_a57_disable_dcache
387
388	/* ---------------------------------------------
389	 * Disable the L2 prefetches.
390	 * ---------------------------------------------
391	 */
392	bl	cortex_a57_disable_l2_prefetch
393
394	/* ---------------------------------------------
395	 * Flush L1 caches.
396	 * ---------------------------------------------
397	 */
398	mov	x0, #DCCISW
399	bl	dcsw_op_level1
400
401	/* ---------------------------------------------
402	 * Come out of intra cluster coherency
403	 * ---------------------------------------------
404	 */
405	bl	cortex_a57_disable_smp
406
407	/* ---------------------------------------------
408	 * Force the debug interfaces to be quiescent
409	 * ---------------------------------------------
410	 */
411	mov	x30, x18
412	b	cortex_a57_disable_ext_debug
413endfunc cortex_a57_core_pwr_dwn
414
415	/* -------------------------------------------------------
416	 * The CPU Ops cluster power down function for Cortex-A57.
417	 * -------------------------------------------------------
418	 */
419func cortex_a57_cluster_pwr_dwn
420	mov	x18, x30
421
422	/* ---------------------------------------------
423	 * Turn off caches.
424	 * ---------------------------------------------
425	 */
426	bl	cortex_a57_disable_dcache
427
428	/* ---------------------------------------------
429	 * Disable the L2 prefetches.
430	 * ---------------------------------------------
431	 */
432	bl	cortex_a57_disable_l2_prefetch
433
434#if !SKIP_A57_L1_FLUSH_PWR_DWN
435	/* -------------------------------------------------
436	 * Flush the L1 caches.
437	 * -------------------------------------------------
438	 */
439	mov	x0, #DCCISW
440	bl	dcsw_op_level1
441#endif
442	/* ---------------------------------------------
443	 * Disable the optional ACP.
444	 * ---------------------------------------------
445	 */
446	bl	plat_disable_acp
447
448	/* -------------------------------------------------
449	 * Flush the L2 caches.
450	 * -------------------------------------------------
451	 */
452	mov	x0, #DCCISW
453	bl	dcsw_op_level2
454
455	/* ---------------------------------------------
456	 * Come out of intra cluster coherency
457	 * ---------------------------------------------
458	 */
459	bl	cortex_a57_disable_smp
460
461	/* ---------------------------------------------
462	 * Force the debug interfaces to be quiescent
463	 * ---------------------------------------------
464	 */
465	mov	x30, x18
466	b	cortex_a57_disable_ext_debug
467endfunc cortex_a57_cluster_pwr_dwn
468
469	/* ---------------------------------------------
470	 * This function provides cortex_a57 specific
471	 * register information for crash reporting.
472	 * It needs to return with x6 pointing to
473	 * a list of register names in ascii and
474	 * x8 - x15 having values of registers to be
475	 * reported.
476	 * ---------------------------------------------
477	 */
478.section .rodata.cortex_a57_regs, "aS"
479cortex_a57_regs:  /* The ascii list of register names to be reported */
480	.asciz	"cpuectlr_el1", "cpumerrsr_el1", "l2merrsr_el1", ""
481
482func cortex_a57_cpu_reg_dump
483	adr	x6, cortex_a57_regs
484	mrs	x8, CPUECTLR_EL1
485	mrs	x9, CPUMERRSR_EL1
486	mrs	x10, L2MERRSR_EL1
487	ret
488endfunc cortex_a57_cpu_reg_dump
489
490
491declare_cpu_ops cortex_a57, CORTEX_A57_MIDR
492