1/*
2 * Copyright (c) 2019-2023, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <asm_macros.S>
8#include <dsu_def.h>
9#include <lib/cpus/errata.h>
10
11	/* -----------------------------------------------------------------------
12	 * DSU erratum 798953 check function
13	 * Checks the DSU variant, revision and configuration to determine if
14	 * the erratum applies. Erratum applies on all configurations of the
15	 * DSU and if revision-variant is r0p0.
16	 *
17	 * The erratum was fixed in r0p1.
18	 *
19	 * This function is called from both assembly and C environment. So it
20	 * follows AAPCS.
21	 *
22	 * Clobbers: x0-x3
23	 * -----------------------------------------------------------------------
24	 */
25	.globl	check_errata_dsu_798953
26	.globl	errata_dsu_798953_wa
27
28func check_errata_dsu_798953
29	mov	x2, #ERRATA_APPLIES
30	mov	x3, #ERRATA_NOT_APPLIES
31
32	/* Check if DSU is equal to r0p0 */
33	mrs	x1, CLUSTERIDR_EL1
34
35	/* DSU variant and revision bitfields in CLUSTERIDR are adjacent */
36	ubfx	x0, x1, #CLUSTERIDR_REV_SHIFT,\
37			#(CLUSTERIDR_REV_BITS + CLUSTERIDR_VAR_BITS)
38	mov	x1, #(0x0 << CLUSTERIDR_REV_SHIFT)
39	cmp	x0, x1
40	csel	x0, x2, x3, EQ
41	ret
42endfunc check_errata_dsu_798953
43
44	/* --------------------------------------------------
45	 * Errata Workaround for DSU erratum #798953.
46	 *
47	 * Can clobber only: x0-x8
48	 * --------------------------------------------------
49	 */
50func errata_dsu_798953_wa
51	mov	x8, x30
52	bl	check_errata_dsu_798953
53	cbz	x0, 1f
54
55	/* If erratum applies, disable high-level clock gating */
56	mrs	x0, CLUSTERACTLR_EL1
57	orr	x0, x0, #CLUSTERACTLR_EL1_DISABLE_CLOCK_GATING
58	msr	CLUSTERACTLR_EL1, x0
59	isb
601:
61	ret	x8
62endfunc errata_dsu_798953_wa
63
64	/* -----------------------------------------------------------------------
65	 * DSU erratum 936184 check function
66	 * Checks the DSU variant, revision and configuration to determine if
67	 * the erratum applies. Erratum applies if ACP interface is present
68	 * in the DSU and revision-variant < r2p0.
69	 *
70	 * The erratum was fixed in r2p0.
71	 *
72	 * This function is called from both assembly and C environment. So it
73	 * follows AAPCS.
74	 *
75	 * Clobbers: x0-x4
76	 * -----------------------------------------------------------------------
77	 */
78	.globl	check_errata_dsu_936184
79	.globl	errata_dsu_936184_wa
80	.weak	is_scu_present_in_dsu
81
82	/* --------------------------------------------------------------------
83	 * Default behaviour respresents SCU is always present with DSU.
84	 * CPUs can override this definition if required.
85	 *
86	 * Can clobber only: x0-x3
87	 * --------------------------------------------------------------------
88	 */
89func is_scu_present_in_dsu
90	mov	x0, #1
91	ret
92endfunc is_scu_present_in_dsu
93
94func check_errata_dsu_936184
95	mov	x4, x30
96	bl	is_scu_present_in_dsu
97	cmp	x0, xzr
98	/* Default error status */
99	mov	x0, #ERRATA_NOT_APPLIES
100
101	/* If SCU is not present, return without applying patch */
102	b.eq	1f
103
104	/* Erratum applies only if DSU has the ACP interface */
105	mrs	x1, CLUSTERCFR_EL1
106	ubfx	x1, x1, #CLUSTERCFR_ACP_SHIFT, #1
107	cbz	x1, 1f
108
109	/* If ACP is present, check if DSU is older than r2p0 */
110	mrs	x1, CLUSTERIDR_EL1
111
112	/* DSU variant and revision bitfields in CLUSTERIDR are adjacent */
113	ubfx	x2, x1, #CLUSTERIDR_REV_SHIFT,\
114			#(CLUSTERIDR_REV_BITS + CLUSTERIDR_VAR_BITS)
115	cmp x2, #(0x2 << CLUSTERIDR_VAR_SHIFT)
116	b.hs	1f
117	mov	x0, #ERRATA_APPLIES
1181:
119	ret	x4
120endfunc check_errata_dsu_936184
121
122	/* --------------------------------------------------
123	 * Errata Workaround for DSU erratum #936184.
124	 *
125	 * Can clobber only: x0-x8
126	 * --------------------------------------------------
127	 */
128func errata_dsu_936184_wa
129	mov	x8, x30
130	bl	check_errata_dsu_936184
131	cbz	x0, 1f
132
133	/* If erratum applies, we set a mask to a DSU control register */
134	mrs	x0, CLUSTERACTLR_EL1
135	ldr	x1, =DSU_ERRATA_936184_MASK
136	orr	x0, x0, x1
137	msr	CLUSTERACTLR_EL1, x0
138	isb
1391:
140	ret	x8
141endfunc errata_dsu_936184_wa
142
143	/* -----------------------------------------------------------------------
144	 * DSU erratum 2313941 check function
145	 * Checks the DSU variant, revision and configuration to determine if
146	 * the erratum applies. Erratum applies on all configurations of the
147	 * DSU and if revision-variant is r0p0, r1p0, r2p0, r2p1, r3p0, r3p1.
148	 *
149	 * The erratum is still open.
150	 *
151	 * This function is called from both assembly and C environment. So it
152	 * follows AAPCS.
153	 *
154	 * Clobbers: x0-x4
155	 * -----------------------------------------------------------------------
156	 */
157	.globl	check_errata_dsu_2313941
158	.globl	errata_dsu_2313941_wa
159
160func check_errata_dsu_2313941
161	mov	x4, x30
162	bl	is_scu_present_in_dsu
163	cmp	x0, xzr
164	/* Default error status */
165	mov	x0, #ERRATA_NOT_APPLIES
166
167	/* If SCU is not present, return without applying patch */
168	b.eq	1f
169
170	mov	x2, #ERRATA_APPLIES
171	mov	x3, #ERRATA_NOT_APPLIES
172
173	/* Check if DSU version is less than or equal to r3p1 */
174	mrs	x1, CLUSTERIDR_EL1
175
176	/* DSU variant and revision bitfields in CLUSTERIDR are adjacent */
177	ubfx	x0, x1, #CLUSTERIDR_REV_SHIFT,\
178			#(CLUSTERIDR_REV_BITS + CLUSTERIDR_VAR_BITS)
179	mov	x1, #(0x31 << CLUSTERIDR_REV_SHIFT)
180	cmp	x0, x1
181	csel	x0, x2, x3, LS
1821:
183	ret	x4
184endfunc check_errata_dsu_2313941
185
186	/* --------------------------------------------------
187	 * Errata Workaround for DSU erratum #2313941.
188	 *
189	 * Can clobber only: x0-x8
190	 * --------------------------------------------------
191	 */
192func errata_dsu_2313941_wa
193	mov	x8, x30
194	bl	check_errata_dsu_2313941
195	cbz	x0, 1f
196
197	/* If erratum applies, disable high-level clock gating */
198	mrs	x0, CLUSTERACTLR_EL1
199	orr	x0, x0, #CLUSTERACTLR_EL1_DISABLE_SCLK_GATING
200	msr	CLUSTERACTLR_EL1, x0
201	isb
2021:
203	ret	x8
204endfunc errata_dsu_2313941_wa
205