xref: /rk3399_ARM-atf/lib/cpus/aarch64/cortex_a57.S (revision 54035fc4672aab046f3cf5288ce9870613bd713d)
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 <plat_macros.S>
37
38	/* ---------------------------------------------
39	 * Disable L1 data cache and unified L2 cache
40	 * ---------------------------------------------
41	 */
42func cortex_a57_disable_dcache
43	mrs	x1, sctlr_el3
44	bic	x1, x1, #SCTLR_C_BIT
45	msr	sctlr_el3, x1
46	isb
47	ret
48endfunc cortex_a57_disable_dcache
49
50	/* ---------------------------------------------
51	 * Disable all types of L2 prefetches.
52	 * ---------------------------------------------
53	 */
54func cortex_a57_disable_l2_prefetch
55	mrs	x0, CPUECTLR_EL1
56	orr	x0, x0, #CPUECTLR_DIS_TWD_ACC_PFTCH_BIT
57	mov	x1, #CPUECTLR_L2_IPFTCH_DIST_MASK
58	orr	x1, x1, #CPUECTLR_L2_DPFTCH_DIST_MASK
59	bic	x0, x0, x1
60	msr	CPUECTLR_EL1, x0
61	isb
62	dsb	ish
63	ret
64endfunc cortex_a57_disable_l2_prefetch
65
66	/* ---------------------------------------------
67	 * Disable intra-cluster coherency
68	 * ---------------------------------------------
69	 */
70func cortex_a57_disable_smp
71	mrs	x0, CPUECTLR_EL1
72	bic	x0, x0, #CPUECTLR_SMP_BIT
73	msr	CPUECTLR_EL1, x0
74	ret
75endfunc cortex_a57_disable_smp
76
77	/* ---------------------------------------------
78	 * Disable debug interfaces
79	 * ---------------------------------------------
80	 */
81func cortex_a57_disable_ext_debug
82	mov	x0, #1
83	msr	osdlr_el1, x0
84	isb
85	dsb	sy
86	ret
87endfunc cortex_a57_disable_ext_debug
88
89	/* --------------------------------------------------
90	 * Errata Workaround for Cortex A57 Errata #806969.
91	 * This applies only to revision r0p0 of Cortex A57.
92	 * Inputs:
93	 * x0: variant[4:7] and revision[0:3] of current cpu.
94	 * Clobbers : x0 - x5
95	 * --------------------------------------------------
96	 */
97func errata_a57_806969_wa
98	/*
99	 * Compare x0 against revision r0p0
100	 */
101	cbz	x0, apply_806969
102#if DEBUG
103	b	print_revision_warning
104#else
105	ret
106#endif
107apply_806969:
108	/*
109	 * Test if errata has already been applied in an earlier
110	 * invocation of the reset handler and does not need to
111	 * be applied again.
112	 */
113	mrs	x1, CPUACTLR_EL1
114	tst	x1, #CPUACTLR_NO_ALLOC_WBWA
115	b.ne	skip_806969
116	orr	x1, x1, #CPUACTLR_NO_ALLOC_WBWA
117	msr	CPUACTLR_EL1, x1
118skip_806969:
119	ret
120endfunc errata_a57_806969_wa
121
122
123	/* ---------------------------------------------------
124	 * Errata Workaround for Cortex A57 Errata #813420.
125	 * This applies only to revision r0p0 of Cortex A57.
126	 * Inputs:
127	 * x0: variant[4:7] and revision[0:3] of current cpu.
128	 * Clobbers : x0 - x5
129	 * ---------------------------------------------------
130	 */
131func errata_a57_813420_wa
132	/*
133	 * Compare x0 against revision r0p0
134	 */
135	cbz	x0, apply_813420
136#if DEBUG
137	b	print_revision_warning
138#else
139	ret
140#endif
141apply_813420:
142	/*
143	 * Test if errata has already been applied in an earlier
144	 * invocation of the reset handler and does not need to
145	 * be applied again.
146	 */
147	mrs	x1, CPUACTLR_EL1
148	tst	x1, #CPUACTLR_DCC_AS_DCCI
149	b.ne	skip_813420
150	orr	x1, x1, #CPUACTLR_DCC_AS_DCCI
151	msr	CPUACTLR_EL1, x1
152skip_813420:
153	ret
154endfunc errata_a57_813420_wa
155
156	/* --------------------------------------------------------------------
157	 * Disable the over-read from the LDNP instruction.
158	 *
159	 * This applies to all revisions <= r1p2. The performance degradation
160	 * observed with LDNP/STNP has been fixed on r1p3 and onwards.
161	 *
162	 * Inputs:
163	 * x0: variant[4:7] and revision[0:3] of current cpu.
164	 * Clobbers : x0 - x5, x30
165	 * ---------------------------------------------------------------------
166	 */
167func a57_disable_ldnp_overread
168	/*
169	 * Compare x0 against revision r1p2
170	 */
171	cmp	x0, #0x12
172	b.ls	disable_hint
173#if DEBUG
174	b	print_revision_warning
175#else
176	ret
177#endif
178disable_hint:
179	mrs	x1, CPUACTLR_EL1
180	orr	x1, x1, #CPUACTLR_DIS_OVERREAD
181	msr	CPUACTLR_EL1, x1
182	ret
183endfunc a57_disable_ldnp_overread
184
185	/* -------------------------------------------------
186	 * The CPU Ops reset function for Cortex-A57.
187	 * Clobbers: x0-x5, x15, x19, x30
188	 * -------------------------------------------------
189	 */
190func cortex_a57_reset_func
191	mov	x19, x30
192	mrs	x0, midr_el1
193
194	/*
195	 * Extract the variant[20:23] and revision[0:3] from x0
196	 * and pack it in x15[0:7] as variant[4:7] and revision[0:3].
197	 * First extract x0[16:23] to x15[0:7] and zero fill the rest.
198	 * Then extract x0[0:3] into x15[0:3] retaining other bits.
199	 */
200	ubfx	x15, x0, #(MIDR_VAR_SHIFT - MIDR_REV_BITS), #(MIDR_REV_BITS + MIDR_VAR_BITS)
201	bfxil	x15, x0, #MIDR_REV_SHIFT, #MIDR_REV_BITS
202
203#if ERRATA_A57_806969
204	mov	x0, x15
205	bl	errata_a57_806969_wa
206#endif
207
208#if ERRATA_A57_813420
209	mov	x0, x15
210	bl	errata_a57_813420_wa
211#endif
212
213#if A57_DISABLE_NON_TEMPORAL_HINT
214	mov	x0, x15
215	bl	a57_disable_ldnp_overread
216#endif
217
218	/* ---------------------------------------------
219	 * As a bare minimum enable the SMP bit if it is
220	 * not already set.
221	 * ---------------------------------------------
222	 */
223	mrs	x0, CPUECTLR_EL1
224	tst	x0, #CPUECTLR_SMP_BIT
225	b.ne	skip_smp_setup
226	orr	x0, x0, #CPUECTLR_SMP_BIT
227	msr	CPUECTLR_EL1, x0
228skip_smp_setup:
229	isb
230	ret	x19
231endfunc cortex_a57_reset_func
232
233	/* ----------------------------------------------------
234	 * The CPU Ops core power down function for Cortex-A57.
235	 * ----------------------------------------------------
236	 */
237func cortex_a57_core_pwr_dwn
238	mov	x18, x30
239
240	/* ---------------------------------------------
241	 * Turn off caches.
242	 * ---------------------------------------------
243	 */
244	bl	cortex_a57_disable_dcache
245
246	/* ---------------------------------------------
247	 * Disable the L2 prefetches.
248	 * ---------------------------------------------
249	 */
250	bl	cortex_a57_disable_l2_prefetch
251
252	/* ---------------------------------------------
253	 * Flush L1 caches.
254	 * ---------------------------------------------
255	 */
256	mov	x0, #DCCISW
257	bl	dcsw_op_level1
258
259	/* ---------------------------------------------
260	 * Come out of intra cluster coherency
261	 * ---------------------------------------------
262	 */
263	bl	cortex_a57_disable_smp
264
265	/* ---------------------------------------------
266	 * Force the debug interfaces to be quiescent
267	 * ---------------------------------------------
268	 */
269	mov	x30, x18
270	b	cortex_a57_disable_ext_debug
271endfunc cortex_a57_core_pwr_dwn
272
273	/* -------------------------------------------------------
274	 * The CPU Ops cluster power down function for Cortex-A57.
275	 * -------------------------------------------------------
276	 */
277func cortex_a57_cluster_pwr_dwn
278	mov	x18, x30
279
280	/* ---------------------------------------------
281	 * Turn off caches.
282	 * ---------------------------------------------
283	 */
284	bl	cortex_a57_disable_dcache
285
286	/* ---------------------------------------------
287	 * Disable the L2 prefetches.
288	 * ---------------------------------------------
289	 */
290	bl	cortex_a57_disable_l2_prefetch
291
292#if !SKIP_A57_L1_FLUSH_PWR_DWN
293	/* -------------------------------------------------
294	 * Flush the L1 caches.
295	 * -------------------------------------------------
296	 */
297	mov	x0, #DCCISW
298	bl	dcsw_op_level1
299#endif
300	/* ---------------------------------------------
301	 * Disable the optional ACP.
302	 * ---------------------------------------------
303	 */
304	bl	plat_disable_acp
305
306	/* -------------------------------------------------
307	 * Flush the L2 caches.
308	 * -------------------------------------------------
309	 */
310	mov	x0, #DCCISW
311	bl	dcsw_op_level2
312
313	/* ---------------------------------------------
314	 * Come out of intra cluster coherency
315	 * ---------------------------------------------
316	 */
317	bl	cortex_a57_disable_smp
318
319	/* ---------------------------------------------
320	 * Force the debug interfaces to be quiescent
321	 * ---------------------------------------------
322	 */
323	mov	x30, x18
324	b	cortex_a57_disable_ext_debug
325endfunc cortex_a57_cluster_pwr_dwn
326
327	/* ---------------------------------------------
328	 * This function provides cortex_a57 specific
329	 * register information for crash reporting.
330	 * It needs to return with x6 pointing to
331	 * a list of register names in ascii and
332	 * x8 - x15 having values of registers to be
333	 * reported.
334	 * ---------------------------------------------
335	 */
336.section .rodata.cortex_a57_regs, "aS"
337cortex_a57_regs:  /* The ascii list of register names to be reported */
338	.asciz	"cpuectlr_el1", ""
339
340func cortex_a57_cpu_reg_dump
341	adr	x6, cortex_a57_regs
342	mrs	x8, CPUECTLR_EL1
343	ret
344endfunc cortex_a57_cpu_reg_dump
345
346
347declare_cpu_ops cortex_a57, CORTEX_A57_MIDR
348