xref: /aosp_15_r20/external/arm-trusted-firmware/lib/cpus/aarch64/dsu_helpers.S (revision 54fd6939e177f8ff529b10183254802c76df6d08)
1*54fd6939SJiyong Park/*
2*54fd6939SJiyong Park * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
3*54fd6939SJiyong Park *
4*54fd6939SJiyong Park * SPDX-License-Identifier: BSD-3-Clause
5*54fd6939SJiyong Park */
6*54fd6939SJiyong Park
7*54fd6939SJiyong Park#include <asm_macros.S>
8*54fd6939SJiyong Park#include <dsu_def.h>
9*54fd6939SJiyong Park#include <lib/cpus/errata_report.h>
10*54fd6939SJiyong Park
11*54fd6939SJiyong Park	/* -----------------------------------------------------------------------
12*54fd6939SJiyong Park	 * DSU erratum 798953 check function
13*54fd6939SJiyong Park	 * Checks the DSU variant, revision and configuration to determine if
14*54fd6939SJiyong Park	 * the erratum applies. Erratum applies on all configurations of the
15*54fd6939SJiyong Park	 * DSU and if revision-variant is r0p0.
16*54fd6939SJiyong Park	 *
17*54fd6939SJiyong Park	 * The erratum was fixed in r0p1.
18*54fd6939SJiyong Park	 *
19*54fd6939SJiyong Park	 * This function is called from both assembly and C environment. So it
20*54fd6939SJiyong Park	 * follows AAPCS.
21*54fd6939SJiyong Park	 *
22*54fd6939SJiyong Park	 * Clobbers: x0-x3
23*54fd6939SJiyong Park	 * -----------------------------------------------------------------------
24*54fd6939SJiyong Park	 */
25*54fd6939SJiyong Park	.globl	check_errata_dsu_798953
26*54fd6939SJiyong Park	.globl	errata_dsu_798953_wa
27*54fd6939SJiyong Park
28*54fd6939SJiyong Parkfunc check_errata_dsu_798953
29*54fd6939SJiyong Park	mov	x2, #ERRATA_APPLIES
30*54fd6939SJiyong Park	mov	x3, #ERRATA_NOT_APPLIES
31*54fd6939SJiyong Park
32*54fd6939SJiyong Park	/* Check if DSU is equal to r0p0 */
33*54fd6939SJiyong Park	mrs	x1, CLUSTERIDR_EL1
34*54fd6939SJiyong Park
35*54fd6939SJiyong Park	/* DSU variant and revision bitfields in CLUSTERIDR are adjacent */
36*54fd6939SJiyong Park	ubfx	x0, x1, #CLUSTERIDR_REV_SHIFT,\
37*54fd6939SJiyong Park			#(CLUSTERIDR_REV_BITS + CLUSTERIDR_VAR_BITS)
38*54fd6939SJiyong Park	mov	x1, #(0x0 << CLUSTERIDR_REV_SHIFT)
39*54fd6939SJiyong Park	cmp	x0, x1
40*54fd6939SJiyong Park	csel	x0, x2, x3, EQ
41*54fd6939SJiyong Park	ret
42*54fd6939SJiyong Parkendfunc check_errata_dsu_798953
43*54fd6939SJiyong Park
44*54fd6939SJiyong Park	/* --------------------------------------------------
45*54fd6939SJiyong Park	 * Errata Workaround for DSU erratum #798953.
46*54fd6939SJiyong Park	 *
47*54fd6939SJiyong Park	 * Can clobber only: x0-x17
48*54fd6939SJiyong Park	 * --------------------------------------------------
49*54fd6939SJiyong Park	 */
50*54fd6939SJiyong Parkfunc errata_dsu_798953_wa
51*54fd6939SJiyong Park	mov	x17, x30
52*54fd6939SJiyong Park	bl	check_errata_dsu_798953
53*54fd6939SJiyong Park	cbz	x0, 1f
54*54fd6939SJiyong Park
55*54fd6939SJiyong Park	/* If erratum applies, disable high-level clock gating */
56*54fd6939SJiyong Park	mrs	x0, CLUSTERACTLR_EL1
57*54fd6939SJiyong Park	orr	x0, x0, #CLUSTERACTLR_EL1_DISABLE_CLOCK_GATING
58*54fd6939SJiyong Park	msr	CLUSTERACTLR_EL1, x0
59*54fd6939SJiyong Park	isb
60*54fd6939SJiyong Park1:
61*54fd6939SJiyong Park	ret	x17
62*54fd6939SJiyong Parkendfunc errata_dsu_798953_wa
63*54fd6939SJiyong Park
64*54fd6939SJiyong Park	/* -----------------------------------------------------------------------
65*54fd6939SJiyong Park	 * DSU erratum 936184 check function
66*54fd6939SJiyong Park	 * Checks the DSU variant, revision and configuration to determine if
67*54fd6939SJiyong Park	 * the erratum applies. Erratum applies if ACP interface is present
68*54fd6939SJiyong Park	 * in the DSU and revision-variant < r2p0.
69*54fd6939SJiyong Park	 *
70*54fd6939SJiyong Park	 * The erratum was fixed in r2p0.
71*54fd6939SJiyong Park	 *
72*54fd6939SJiyong Park	 * This function is called from both assembly and C environment. So it
73*54fd6939SJiyong Park	 * follows AAPCS.
74*54fd6939SJiyong Park	 *
75*54fd6939SJiyong Park	 * Clobbers: x0-x15
76*54fd6939SJiyong Park	 * -----------------------------------------------------------------------
77*54fd6939SJiyong Park	 */
78*54fd6939SJiyong Park	.globl	check_errata_dsu_936184
79*54fd6939SJiyong Park	.globl	errata_dsu_936184_wa
80*54fd6939SJiyong Park	.weak	is_scu_present_in_dsu
81*54fd6939SJiyong Park
82*54fd6939SJiyong Park	/* --------------------------------------------------------------------
83*54fd6939SJiyong Park	 * Default behaviour respresents SCU is always present with DSU.
84*54fd6939SJiyong Park	 * CPUs can override this definition if required.
85*54fd6939SJiyong Park	 *
86*54fd6939SJiyong Park	 * Can clobber only: x0-x14
87*54fd6939SJiyong Park	 * --------------------------------------------------------------------
88*54fd6939SJiyong Park	 */
89*54fd6939SJiyong Parkfunc is_scu_present_in_dsu
90*54fd6939SJiyong Park	mov	x0, #1
91*54fd6939SJiyong Park	ret
92*54fd6939SJiyong Parkendfunc is_scu_present_in_dsu
93*54fd6939SJiyong Park
94*54fd6939SJiyong Parkfunc check_errata_dsu_936184
95*54fd6939SJiyong Park	mov	x15, x30
96*54fd6939SJiyong Park	bl	is_scu_present_in_dsu
97*54fd6939SJiyong Park	cmp	x0, xzr
98*54fd6939SJiyong Park	/* Default error status */
99*54fd6939SJiyong Park	mov	x0, #ERRATA_NOT_APPLIES
100*54fd6939SJiyong Park
101*54fd6939SJiyong Park	/* If SCU is not present, return without applying patch */
102*54fd6939SJiyong Park	b.eq	1f
103*54fd6939SJiyong Park
104*54fd6939SJiyong Park	/* Erratum applies only if DSU has the ACP interface */
105*54fd6939SJiyong Park	mrs	x1, CLUSTERCFR_EL1
106*54fd6939SJiyong Park	ubfx	x1, x1, #CLUSTERCFR_ACP_SHIFT, #1
107*54fd6939SJiyong Park	cbz	x1, 1f
108*54fd6939SJiyong Park
109*54fd6939SJiyong Park	/* If ACP is present, check if DSU is older than r2p0 */
110*54fd6939SJiyong Park	mrs	x1, CLUSTERIDR_EL1
111*54fd6939SJiyong Park
112*54fd6939SJiyong Park	/* DSU variant and revision bitfields in CLUSTERIDR are adjacent */
113*54fd6939SJiyong Park	ubfx	x2, x1, #CLUSTERIDR_REV_SHIFT,\
114*54fd6939SJiyong Park			#(CLUSTERIDR_REV_BITS + CLUSTERIDR_VAR_BITS)
115*54fd6939SJiyong Park	cmp x2, #(0x2 << CLUSTERIDR_VAR_SHIFT)
116*54fd6939SJiyong Park	b.hs	1f
117*54fd6939SJiyong Park	mov	x0, #ERRATA_APPLIES
118*54fd6939SJiyong Park1:
119*54fd6939SJiyong Park	ret	x15
120*54fd6939SJiyong Parkendfunc check_errata_dsu_936184
121*54fd6939SJiyong Park
122*54fd6939SJiyong Park	/* --------------------------------------------------
123*54fd6939SJiyong Park	 * Errata Workaround for DSU erratum #936184.
124*54fd6939SJiyong Park	 *
125*54fd6939SJiyong Park	 * Can clobber only: x0-x17
126*54fd6939SJiyong Park	 * --------------------------------------------------
127*54fd6939SJiyong Park	 */
128*54fd6939SJiyong Parkfunc errata_dsu_936184_wa
129*54fd6939SJiyong Park	mov	x17, x30
130*54fd6939SJiyong Park	bl	check_errata_dsu_936184
131*54fd6939SJiyong Park	cbz	x0, 1f
132*54fd6939SJiyong Park
133*54fd6939SJiyong Park	/* If erratum applies, we set a mask to a DSU control register */
134*54fd6939SJiyong Park	mrs	x0, CLUSTERACTLR_EL1
135*54fd6939SJiyong Park	ldr	x1, =DSU_ERRATA_936184_MASK
136*54fd6939SJiyong Park	orr	x0, x0, x1
137*54fd6939SJiyong Park	msr	CLUSTERACTLR_EL1, x0
138*54fd6939SJiyong Park	isb
139*54fd6939SJiyong Park1:
140*54fd6939SJiyong Park	ret	x17
141*54fd6939SJiyong Parkendfunc errata_dsu_936184_wa
142