1/*
2 * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch.h>
8#include <asm_macros.S>
9#include <common/bl_common.h>
10#include <cortex_a55.h>
11#include <cpu_macros.S>
12#include <plat_macros.S>
13
14/* Hardware handled coherency */
15#if HW_ASSISTED_COHERENCY == 0
16#error "Cortex-A55 must be compiled with HW_ASSISTED_COHERENCY enabled"
17#endif
18
19	.globl cortex_a55_reset_func
20	.globl cortex_a55_core_pwr_dwn
21	/* --------------------------------------------------
22	 * Errata Workaround for Cortex A55 Errata #768277.
23	 * This applies only to revision r0p0 of Cortex A55.
24	 * Inputs:
25	 * x0: variant[4:7] and revision[0:3] of current cpu.
26	 * Shall clobber: x0-x17
27	 * --------------------------------------------------
28	 */
29func errata_a55_768277_wa
30	/*
31	 * Compare x0 against revision r0p0
32	 */
33	mov	x17, x30
34	bl	check_errata_768277
35	cbz	x0, 1f
36	mrs	x1, CORTEX_A55_CPUACTLR_EL1
37	orr	x1, x1, #CORTEX_A55_CPUACTLR_EL1_DISABLE_DUAL_ISSUE
38	msr	CORTEX_A55_CPUACTLR_EL1, x1
39	isb
401:
41	ret	x17
42endfunc errata_a55_768277_wa
43
44func check_errata_768277
45	mov	x1, #0x00
46	b	cpu_rev_var_ls
47endfunc check_errata_768277
48
49	/* ------------------------------------------------------------------
50	 * Errata Workaround for Cortex A55 Errata #778703.
51	 * This applies only to revision r0p0 of Cortex A55 where L2 cache is
52	 * not configured.
53	 * Inputs:
54	 * x0: variant[4:7] and revision[0:3] of current cpu.
55	 * Shall clobber: x0-x17
56	 * ------------------------------------------------------------------
57	 */
58func errata_a55_778703_wa
59	/*
60	 * Compare x0 against revision r0p0 and check that no private L2 cache
61	 * is configured
62	 */
63	mov	x17, x30
64	bl	check_errata_778703
65	cbz	x0, 1f
66	mrs	x1, CORTEX_A55_CPUECTLR_EL1
67	orr	x1, x1, #CORTEX_A55_CPUECTLR_EL1_L1WSCTL
68	msr	CORTEX_A55_CPUECTLR_EL1, x1
69	mrs	x1, CORTEX_A55_CPUACTLR_EL1
70	orr	x1, x1, #CORTEX_A55_CPUACTLR_EL1_DISABLE_WRITE_STREAMING
71	msr	CORTEX_A55_CPUACTLR_EL1, x1
72	isb
731:
74	ret	x17
75endfunc errata_a55_778703_wa
76
77func check_errata_778703
78	mov	x16, x30
79	mov	x1, #0x00
80	bl	cpu_rev_var_ls
81	/*
82	 * Check that no private L2 cache is configured
83	 */
84	mrs	x1, CORTEX_A55_CLIDR_EL1
85	and	x1, x1, CORTEX_A55_CLIDR_EL1_CTYPE3
86	cmp	x1, #0
87	mov	x2, #ERRATA_NOT_APPLIES
88	csel	x0, x0, x2, eq
89	ret	x16
90endfunc check_errata_778703
91
92	/* --------------------------------------------------
93	 * Errata Workaround for Cortex A55 Errata #798797.
94	 * This applies only to revision r0p0 of Cortex A55.
95	 * Inputs:
96	 * x0: variant[4:7] and revision[0:3] of current cpu.
97	 * Shall clobber: x0-x17
98	 * --------------------------------------------------
99	 */
100func errata_a55_798797_wa
101	/*
102	 * Compare x0 against revision r0p0
103	 */
104	mov	x17, x30
105	bl	check_errata_798797
106	cbz	x0, 1f
107	mrs	x1, CORTEX_A55_CPUACTLR_EL1
108	orr	x1, x1, #CORTEX_A55_CPUACTLR_EL1_DISABLE_L1_PAGEWALKS
109	msr	CORTEX_A55_CPUACTLR_EL1, x1
110	isb
1111:
112	ret	x17
113endfunc errata_a55_798797_wa
114
115func check_errata_798797
116	mov	x1, #0x00
117	b	cpu_rev_var_ls
118endfunc check_errata_798797
119
120	/* --------------------------------------------------------------------
121	 * Errata Workaround for Cortex A55 Errata #846532.
122	 * This applies only to revisions <= r0p1 of Cortex A55.
123	 * Disabling dual-issue has a small impact on performance. Disabling a
124	 * power optimization feature is an alternate workaround with no impact
125	 * on performance but with an increase in power consumption (see errata
126	 * notice).
127	 * Inputs:
128	 * x0: variant[4:7] and revision[0:3] of current cpu.
129	 * Shall clobber: x0-x17
130	 * --------------------------------------------------------------------
131	 */
132func errata_a55_846532_wa
133	/*
134	 * Compare x0 against revision r0p1
135	 */
136	mov	x17, x30
137	bl	check_errata_846532
138	cbz	x0, 1f
139	mrs	x1, CORTEX_A55_CPUACTLR_EL1
140	orr	x1, x1, #CORTEX_A55_CPUACTLR_EL1_DISABLE_DUAL_ISSUE
141	msr	CORTEX_A55_CPUACTLR_EL1, x1
142	isb
1431:
144	ret	x17
145endfunc errata_a55_846532_wa
146
147func check_errata_846532
148	mov	x1, #0x01
149	b	cpu_rev_var_ls
150endfunc check_errata_846532
151
152	/* -----------------------------------------------------
153	 * Errata Workaround for Cortex A55 Errata #903758.
154	 * This applies only to revisions <= r0p1 of Cortex A55.
155	 * Inputs:
156	 * x0: variant[4:7] and revision[0:3] of current cpu.
157	 * Shall clobber: x0-x17
158	 * -----------------------------------------------------
159	 */
160func errata_a55_903758_wa
161	/*
162	 * Compare x0 against revision r0p1
163	 */
164	mov	x17, x30
165	bl	check_errata_903758
166	cbz	x0, 1f
167	mrs	x1, CORTEX_A55_CPUACTLR_EL1
168	orr	x1, x1, #CORTEX_A55_CPUACTLR_EL1_DISABLE_L1_PAGEWALKS
169	msr	CORTEX_A55_CPUACTLR_EL1, x1
170	isb
1711:
172	ret	x17
173endfunc errata_a55_903758_wa
174
175func check_errata_903758
176	mov	x1, #0x01
177	b	cpu_rev_var_ls
178endfunc check_errata_903758
179
180	/* -----------------------------------------------------
181	 * Errata Workaround for Cortex A55 Errata #1221012.
182	 * This applies only to revisions <= r1p0 of Cortex A55.
183	 * Inputs:
184	 * x0: variant[4:7] and revision[0:3] of current cpu.
185	 * Shall clobber: x0-x17
186	 * -----------------------------------------------------
187	 */
188func errata_a55_1221012_wa
189	/*
190	 * Compare x0 against revision r1p0
191	 */
192	mov	x17, x30
193	bl	check_errata_1221012
194	cbz	x0, 1f
195	mov	x0, #0x0020
196	movk	x0, #0x0850, lsl #16
197	msr	CPUPOR_EL3, x0
198	mov	x0, #0x0000
199	movk	x0, #0x1FF0, lsl #16
200	movk	x0, #0x2, lsl #32
201	msr	CPUPMR_EL3, x0
202	mov	x0, #0x03fd
203	movk	x0, #0x0110, lsl #16
204	msr	CPUPCR_EL3, x0
205	mov	x0, #0x1
206	msr	CPUPSELR_EL3, x0
207	mov	x0, #0x0040
208	movk	x0, #0x08D0, lsl #16
209	msr	CPUPOR_EL3, x0
210	mov	x0, #0x0040
211	movk	x0, #0x1FF0, lsl #16
212	movk	x0, #0x2, lsl #32
213	msr	CPUPMR_EL3, x0
214	mov	x0, #0x03fd
215	movk	x0, #0x0110, lsl #16
216	msr	CPUPCR_EL3, x0
217	isb
2181:
219	ret	x17
220endfunc errata_a55_1221012_wa
221
222func check_errata_1221012
223	mov	x1, #0x10
224	b	cpu_rev_var_ls
225endfunc check_errata_1221012
226
227	/* --------------------------------------------------
228	 * Errata workaround for Cortex A55 Errata #1530923.
229	 * This applies to all revisions of Cortex A55.
230	 * --------------------------------------------------
231	 */
232func check_errata_1530923
233#if ERRATA_A55_1530923
234	mov	x0, #ERRATA_APPLIES
235#else
236	mov	x0, #ERRATA_MISSING
237#endif
238	ret
239endfunc check_errata_1530923
240
241func cortex_a55_reset_func
242	mov	x19, x30
243
244#if ERRATA_DSU_798953
245	bl	errata_dsu_798953_wa
246#endif
247
248#if ERRATA_DSU_936184
249	bl	errata_dsu_936184_wa
250#endif
251
252	bl	cpu_get_rev_var
253	mov	x18, x0
254
255#if ERRATA_A55_768277
256	mov	x0, x18
257	bl	errata_a55_768277_wa
258#endif
259
260#if ERRATA_A55_778703
261	mov	x0, x18
262	bl	errata_a55_778703_wa
263#endif
264
265#if ERRATA_A55_798797
266	mov	x0, x18
267	bl	errata_a55_798797_wa
268#endif
269
270#if ERRATA_A55_846532
271	mov	x0, x18
272	bl	errata_a55_846532_wa
273#endif
274
275#if ERRATA_A55_903758
276	mov	x0, x18
277	bl	errata_a55_903758_wa
278#endif
279
280#if ERRATA_A55_1221012
281	mov	x0, x18
282	bl	errata_a55_1221012_wa
283#endif
284
285	ret	x19
286endfunc cortex_a55_reset_func
287
288	/* ---------------------------------------------
289	 * HW will do the cache maintenance while powering down
290	 * ---------------------------------------------
291	 */
292func cortex_a55_core_pwr_dwn
293	/* ---------------------------------------------
294	 * Enable CPU power down bit in power control register
295	 * ---------------------------------------------
296	 */
297	mrs	x0, CORTEX_A55_CPUPWRCTLR_EL1
298	orr	x0, x0, #CORTEX_A55_CORE_PWRDN_EN_MASK
299	msr	CORTEX_A55_CPUPWRCTLR_EL1, x0
300	isb
301	ret
302endfunc cortex_a55_core_pwr_dwn
303
304#if REPORT_ERRATA
305/*
306 * Errata printing function for Cortex A55. Must follow AAPCS & can use stack.
307 */
308func cortex_a55_errata_report
309	stp	x8, x30, [sp, #-16]!
310	bl	cpu_get_rev_var
311	mov	x8, x0
312
313	/*
314	 * Report all errata. The revision variant information is at x8, where
315	 * "report_errata" is expecting it and it doesn't corrupt it.
316	 */
317	report_errata ERRATA_DSU_798953, cortex_a55, dsu_798953
318	report_errata ERRATA_DSU_936184, cortex_a55, dsu_936184
319	report_errata ERRATA_A55_768277, cortex_a55, 768277
320	report_errata ERRATA_A55_778703, cortex_a55, 778703
321	report_errata ERRATA_A55_798797, cortex_a55, 798797
322	report_errata ERRATA_A55_846532, cortex_a55, 846532
323	report_errata ERRATA_A55_903758, cortex_a55, 903758
324	report_errata ERRATA_A55_1221012, cortex_a55, 1221012
325	report_errata ERRATA_A55_1530923, cortex_a55, 1530923
326
327	ldp	x8, x30, [sp], #16
328	ret
329endfunc cortex_a55_errata_report
330#endif
331
332	/* ---------------------------------------------
333	 * This function provides cortex_a55 specific
334	 * register information for crash reporting.
335	 * It needs to return with x6 pointing to
336	 * a list of register names in ascii and
337	 * x8 - x15 having values of registers to be
338	 * reported.
339	 * ---------------------------------------------
340	 */
341.section .rodata.cortex_a55_regs, "aS"
342cortex_a55_regs:  /* The ascii list of register names to be reported */
343	.asciz	"cpuectlr_el1", ""
344
345func cortex_a55_cpu_reg_dump
346	adr	x6, cortex_a55_regs
347	mrs	x8, CORTEX_A55_CPUECTLR_EL1
348	ret
349endfunc cortex_a55_cpu_reg_dump
350
351declare_cpu_ops cortex_a55, CORTEX_A55_MIDR, \
352	cortex_a55_reset_func, \
353	cortex_a55_core_pwr_dwn
354