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