1/*
2 * Copyright (c) 2019-2020, ARM Limited. All rights reserved.
3 * Copyright (c) 2021, NVIDIA Corporation. All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8#include <arch.h>
9#include <asm_macros.S>
10#include <common/bl_common.h>
11#include <cortex_a78_ae.h>
12#include <cpu_macros.S>
13#include <plat_macros.S>
14
15/* Hardware handled coherency */
16#if HW_ASSISTED_COHERENCY == 0
17#error "cortex_a78_ae must be compiled with HW_ASSISTED_COHERENCY enabled"
18#endif
19
20/* --------------------------------------------------
21 * Errata Workaround for A78 AE Erratum 1941500.
22 * This applies to revisions r0p0 and r0p1 of A78 AE.
23 * Inputs:
24 * x0: variant[4:7] and revision[0:3] of current cpu.
25 * Shall clobber: x0-x17
26 * --------------------------------------------------
27 */
28func errata_a78_ae_1941500_wa
29	/* Compare x0 against revisions r0p0 - r0p1 */
30	mov	x17, x30
31	bl	check_errata_1941500
32	cbz	x0, 1f
33
34	/* Set bit 8 in ECTLR_EL1 */
35	mrs	x0, CORTEX_A78_AE_CPUECTLR_EL1
36	bic	x0, x0, #CORTEX_A78_AE_CPUECTLR_EL1_BIT_8
37	msr	CORTEX_A78_AE_CPUECTLR_EL1, x0
38	isb
391:
40	ret	x17
41endfunc errata_a78_ae_1941500_wa
42
43func check_errata_1941500
44	/* Applies to revisions r0p0 and r0p1. */
45	mov	x1, #CPU_REV(0, 0)
46	mov	x2, #CPU_REV(0, 1)
47	b	cpu_rev_var_range
48endfunc check_errata_1941500
49
50/* --------------------------------------------------
51 * Errata Workaround for A78 AE Erratum 1951502.
52 * This applies to revisions r0p0 and r0p1 of A78 AE.
53 * Inputs:
54 * x0: variant[4:7] and revision[0:3] of current cpu.
55 * Shall clobber: x0-x17
56 * --------------------------------------------------
57 */
58func errata_a78_ae_1951502_wa
59	/* Compare x0 against revisions r0p0 - r0p1 */
60	mov	x17, x30
61	bl	check_errata_1951502
62	cbz	x0, 1f
63
64	msr	S3_6_c15_c8_0, xzr
65	ldr	x0, =0x10E3900002
66	msr	S3_6_c15_c8_2, x0
67	ldr	x0, =0x10FFF00083
68	msr	S3_6_c15_c8_3, x0
69	ldr	x0, =0x2001003FF
70	msr	S3_6_c15_c8_1, x0
71
72	mov	x0, #1
73	msr	S3_6_c15_c8_0, x0
74	ldr	x0, =0x10E3800082
75	msr	S3_6_c15_c8_2, x0
76	ldr	x0, =0x10FFF00083
77	msr	S3_6_c15_c8_3, x0
78	ldr	x0, =0x2001003FF
79	msr	S3_6_c15_c8_1, x0
80
81	mov	x0, #2
82	msr	S3_6_c15_c8_0, x0
83	ldr	x0, =0x10E3800200
84	msr	S3_6_c15_c8_2, x0
85	ldr	x0, =0x10FFF003E0
86	msr	S3_6_c15_c8_3, x0
87	ldr	x0, =0x2001003FF
88	msr	S3_6_c15_c8_1, x0
89
90	isb
911:
92	ret	x17
93endfunc errata_a78_ae_1951502_wa
94
95func check_errata_1951502
96	/* Applies to revisions r0p0 and r0p1. */
97	mov	x1, #CPU_REV(0, 0)
98	mov	x2, #CPU_REV(0, 1)
99	b	cpu_rev_var_range
100endfunc check_errata_1951502
101
102	/* -------------------------------------------------
103	 * The CPU Ops reset function for Cortex-A78-AE
104	 * -------------------------------------------------
105	 */
106func cortex_a78_ae_reset_func
107	mov	x19, x30
108	bl	cpu_get_rev_var
109	mov	x18, x0
110
111#if ERRATA_A78_AE_1941500
112	mov	x0, x18
113	bl	errata_a78_ae_1941500_wa
114#endif
115
116#if ERRATA_A78_AE_1951502
117	mov	x0, x18
118	bl	errata_a78_ae_1951502_wa
119#endif
120
121#if ENABLE_AMU
122	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
123	mrs	x0, actlr_el3
124	bic	x0, x0, #CORTEX_A78_ACTLR_TAM_BIT
125	msr	actlr_el3, x0
126
127	/* Make sure accesses from non-secure EL0/EL1 are not trapped to EL2 */
128	mrs	x0, actlr_el2
129	bic	x0, x0, #CORTEX_A78_ACTLR_TAM_BIT
130	msr	actlr_el2, x0
131
132	/* Enable group0 counters */
133	mov	x0, #CORTEX_A78_AMU_GROUP0_MASK
134	msr	CPUAMCNTENSET0_EL0, x0
135
136	/* Enable group1 counters */
137	mov	x0, #CORTEX_A78_AMU_GROUP1_MASK
138	msr	CPUAMCNTENSET1_EL0, x0
139#endif
140
141	isb
142
143	ret	x19
144endfunc cortex_a78_ae_reset_func
145
146	/* -------------------------------------------------------
147	 * HW will do the cache maintenance while powering down
148	 * -------------------------------------------------------
149	 */
150func cortex_a78_ae_core_pwr_dwn
151	/* -------------------------------------------------------
152	 * Enable CPU power down bit in power control register
153	 * -------------------------------------------------------
154	 */
155	mrs	x0, CORTEX_A78_CPUPWRCTLR_EL1
156	orr	x0, x0, #CORTEX_A78_CPUPWRCTLR_EL1_CORE_PWRDN_EN_BIT
157	msr	CORTEX_A78_CPUPWRCTLR_EL1, x0
158	isb
159	ret
160endfunc cortex_a78_ae_core_pwr_dwn
161
162	/*
163	 * Errata printing function for cortex_a78_ae. Must follow AAPCS.
164	 */
165#if REPORT_ERRATA
166func cortex_a78_ae_errata_report
167	stp	x8, x30, [sp, #-16]!
168
169	bl	cpu_get_rev_var
170	mov	x8, x0
171
172	/*
173	 * Report all errata. The revision-variant information is passed to
174	 * checking functions of each errata.
175	 */
176	report_errata ERRATA_A78_AE_1941500, cortex_a78_ae, 1941500
177	report_errata ERRATA_A78_AE_1951502, cortex_a78_ae, 1951502
178
179	ldp	x8, x30, [sp], #16
180	ret
181endfunc cortex_a78_ae_errata_report
182#endif
183
184	/* -------------------------------------------------------
185	 * This function provides cortex_a78_ae specific
186	 * register information for crash reporting.
187	 * It needs to return with x6 pointing to
188	 * a list of register names in ascii and
189	 * x8 - x15 having values of registers to be
190	 * reported.
191	 * -------------------------------------------------------
192	 */
193.section .rodata.cortex_a78_ae_regs, "aS"
194cortex_a78_ae_regs:  /* The ascii list of register names to be reported */
195	.asciz	"cpuectlr_el1", ""
196
197func cortex_a78_ae_cpu_reg_dump
198	adr	x6, cortex_a78_ae_regs
199	mrs	x8, CORTEX_A78_CPUECTLR_EL1
200	ret
201endfunc cortex_a78_ae_cpu_reg_dump
202
203declare_cpu_ops cortex_a78_ae, CORTEX_A78_AE_MIDR, \
204	cortex_a78_ae_reset_func, \
205	cortex_a78_ae_core_pwr_dwn
206