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