summaryrefslogtreecommitdiffstats
path: root/lib/cpus/aarch64/dsu_helpers.S
diff options
context:
space:
mode:
Diffstat (limited to 'lib/cpus/aarch64/dsu_helpers.S')
-rw-r--r--lib/cpus/aarch64/dsu_helpers.S195
1 files changed, 195 insertions, 0 deletions
diff --git a/lib/cpus/aarch64/dsu_helpers.S b/lib/cpus/aarch64/dsu_helpers.S
new file mode 100644
index 0000000..419b6ea
--- /dev/null
+++ b/lib/cpus/aarch64/dsu_helpers.S
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2019-2022, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <dsu_def.h>
+#include <lib/cpus/errata_report.h>
+
+ /* -----------------------------------------------------------------------
+ * DSU erratum 798953 check function
+ * Checks the DSU variant, revision and configuration to determine if
+ * the erratum applies. Erratum applies on all configurations of the
+ * DSU and if revision-variant is r0p0.
+ *
+ * The erratum was fixed in r0p1.
+ *
+ * This function is called from both assembly and C environment. So it
+ * follows AAPCS.
+ *
+ * Clobbers: x0-x3
+ * -----------------------------------------------------------------------
+ */
+ .globl check_errata_dsu_798953
+ .globl errata_dsu_798953_wa
+
+func check_errata_dsu_798953
+ mov x2, #ERRATA_APPLIES
+ mov x3, #ERRATA_NOT_APPLIES
+
+ /* Check if DSU is equal to r0p0 */
+ mrs x1, CLUSTERIDR_EL1
+
+ /* DSU variant and revision bitfields in CLUSTERIDR are adjacent */
+ ubfx x0, x1, #CLUSTERIDR_REV_SHIFT,\
+ #(CLUSTERIDR_REV_BITS + CLUSTERIDR_VAR_BITS)
+ mov x1, #(0x0 << CLUSTERIDR_REV_SHIFT)
+ cmp x0, x1
+ csel x0, x2, x3, EQ
+ ret
+endfunc check_errata_dsu_798953
+
+ /* --------------------------------------------------
+ * Errata Workaround for DSU erratum #798953.
+ *
+ * Can clobber only: x0-x17
+ * --------------------------------------------------
+ */
+func errata_dsu_798953_wa
+ mov x17, x30
+ bl check_errata_dsu_798953
+ cbz x0, 1f
+
+ /* If erratum applies, disable high-level clock gating */
+ mrs x0, CLUSTERACTLR_EL1
+ orr x0, x0, #CLUSTERACTLR_EL1_DISABLE_CLOCK_GATING
+ msr CLUSTERACTLR_EL1, x0
+ isb
+1:
+ ret x17
+endfunc errata_dsu_798953_wa
+
+ /* -----------------------------------------------------------------------
+ * DSU erratum 936184 check function
+ * Checks the DSU variant, revision and configuration to determine if
+ * the erratum applies. Erratum applies if ACP interface is present
+ * in the DSU and revision-variant < r2p0.
+ *
+ * The erratum was fixed in r2p0.
+ *
+ * This function is called from both assembly and C environment. So it
+ * follows AAPCS.
+ *
+ * Clobbers: x0-x15
+ * -----------------------------------------------------------------------
+ */
+ .globl check_errata_dsu_936184
+ .globl errata_dsu_936184_wa
+ .weak is_scu_present_in_dsu
+
+ /* --------------------------------------------------------------------
+ * Default behaviour respresents SCU is always present with DSU.
+ * CPUs can override this definition if required.
+ *
+ * Can clobber only: x0-x14
+ * --------------------------------------------------------------------
+ */
+func is_scu_present_in_dsu
+ mov x0, #1
+ ret
+endfunc is_scu_present_in_dsu
+
+func check_errata_dsu_936184
+ mov x15, x30
+ bl is_scu_present_in_dsu
+ cmp x0, xzr
+ /* Default error status */
+ mov x0, #ERRATA_NOT_APPLIES
+
+ /* If SCU is not present, return without applying patch */
+ b.eq 1f
+
+ /* Erratum applies only if DSU has the ACP interface */
+ mrs x1, CLUSTERCFR_EL1
+ ubfx x1, x1, #CLUSTERCFR_ACP_SHIFT, #1
+ cbz x1, 1f
+
+ /* If ACP is present, check if DSU is older than r2p0 */
+ mrs x1, CLUSTERIDR_EL1
+
+ /* DSU variant and revision bitfields in CLUSTERIDR are adjacent */
+ ubfx x2, x1, #CLUSTERIDR_REV_SHIFT,\
+ #(CLUSTERIDR_REV_BITS + CLUSTERIDR_VAR_BITS)
+ cmp x2, #(0x2 << CLUSTERIDR_VAR_SHIFT)
+ b.hs 1f
+ mov x0, #ERRATA_APPLIES
+1:
+ ret x15
+endfunc check_errata_dsu_936184
+
+ /* --------------------------------------------------
+ * Errata Workaround for DSU erratum #936184.
+ *
+ * Can clobber only: x0-x17
+ * --------------------------------------------------
+ */
+func errata_dsu_936184_wa
+ mov x17, x30
+ bl check_errata_dsu_936184
+ cbz x0, 1f
+
+ /* If erratum applies, we set a mask to a DSU control register */
+ mrs x0, CLUSTERACTLR_EL1
+ ldr x1, =DSU_ERRATA_936184_MASK
+ orr x0, x0, x1
+ msr CLUSTERACTLR_EL1, x0
+ isb
+1:
+ ret x17
+endfunc errata_dsu_936184_wa
+
+ /* -----------------------------------------------------------------------
+ * DSU erratum 2313941 check function
+ * Checks the DSU variant, revision and configuration to determine if
+ * the erratum applies. Erratum applies on all configurations of the
+ * DSU and if revision-variant is r0p0, r1p0, r2p0, r2p1, r3p0, r3p1.
+ *
+ * The erratum is still open.
+ *
+ * This function is called from both assembly and C environment. So it
+ * follows AAPCS.
+ *
+ * Clobbers: x0-x3
+ * -----------------------------------------------------------------------
+ */
+ .globl check_errata_dsu_2313941
+ .globl errata_dsu_2313941_wa
+
+func check_errata_dsu_2313941
+ mov x2, #ERRATA_APPLIES
+ mov x3, #ERRATA_NOT_APPLIES
+
+ /* Check if DSU version is less than or equal to r3p1 */
+ mrs x1, CLUSTERIDR_EL1
+
+ /* DSU variant and revision bitfields in CLUSTERIDR are adjacent */
+ ubfx x0, x1, #CLUSTERIDR_REV_SHIFT,\
+ #(CLUSTERIDR_REV_BITS + CLUSTERIDR_VAR_BITS)
+ mov x1, #(0x31 << CLUSTERIDR_REV_SHIFT)
+ cmp x0, x1
+ csel x0, x2, x3, LS
+ ret
+endfunc check_errata_dsu_2313941
+
+ /* --------------------------------------------------
+ * Errata Workaround for DSU erratum #2313941.
+ *
+ * Can clobber only: x0-x17
+ * --------------------------------------------------
+ */
+func errata_dsu_2313941_wa
+ mov x17, x30
+ bl check_errata_dsu_2313941
+ cbz x0, 1f
+
+ /* If erratum applies, disable high-level clock gating */
+ mrs x0, CLUSTERACTLR_EL1
+ orr x0, x0, #CLUSTERACTLR_EL1_DISABLE_SCLK_GATING
+ msr CLUSTERACTLR_EL1, x0
+ isb
+1:
+ ret x17
+endfunc errata_dsu_2313941_wa
+