1*b62673c6SBoyan Karatotev/* 2*b62673c6SBoyan Karatotev * Copyright (c) 2019-2025, Arm Limited and Contributors. All rights reserved. 3*b62673c6SBoyan Karatotev * 4*b62673c6SBoyan Karatotev * SPDX-License-Identifier: BSD-3-Clause 5*b62673c6SBoyan Karatotev */ 6*b62673c6SBoyan Karatotev 7*b62673c6SBoyan Karatotev#ifndef DSU_MACROS_S 8*b62673c6SBoyan Karatotev#define DSU_MACROS_S 9*b62673c6SBoyan Karatotev 10*b62673c6SBoyan Karatotev#include <asm_macros.S> 11*b62673c6SBoyan Karatotev#include <dsu_def.h> 12*b62673c6SBoyan Karatotev#include <lib/cpus/errata.h> 13*b62673c6SBoyan Karatotev 14*b62673c6SBoyan Karatotev.macro check_errata_dsu_798953_impl 15*b62673c6SBoyan Karatotev mov x2, #ERRATA_APPLIES 16*b62673c6SBoyan Karatotev mov x3, #ERRATA_NOT_APPLIES 17*b62673c6SBoyan Karatotev 18*b62673c6SBoyan Karatotev /* Check if DSU is equal to r0p0 */ 19*b62673c6SBoyan Karatotev mrs x1, CLUSTERIDR_EL1 20*b62673c6SBoyan Karatotev 21*b62673c6SBoyan Karatotev /* DSU variant and revision bitfields in CLUSTERIDR are adjacent */ 22*b62673c6SBoyan Karatotev ubfx x0, x1, #CLUSTERIDR_REV_SHIFT,\ 23*b62673c6SBoyan Karatotev #(CLUSTERIDR_REV_BITS + CLUSTERIDR_VAR_BITS) 24*b62673c6SBoyan Karatotev mov x1, #(0x0 << CLUSTERIDR_REV_SHIFT) 25*b62673c6SBoyan Karatotev cmp x0, x1 26*b62673c6SBoyan Karatotev csel x0, x2, x3, EQ 27*b62673c6SBoyan Karatotev.endm 28*b62673c6SBoyan Karatotev 29*b62673c6SBoyan Karatotev.macro errata_dsu_798953_wa_impl 30*b62673c6SBoyan Karatotev /* If erratum applies, disable high-level clock gating */ 31*b62673c6SBoyan Karatotev mrs x0, CLUSTERACTLR_EL1 32*b62673c6SBoyan Karatotev orr x0, x0, #CLUSTERACTLR_EL1_DISABLE_CLOCK_GATING 33*b62673c6SBoyan Karatotev msr CLUSTERACTLR_EL1, x0 34*b62673c6SBoyan Karatotev.endm 35*b62673c6SBoyan Karatotev 36*b62673c6SBoyan Karatotev.macro branch_if_scu_not_present _target:req 37*b62673c6SBoyan Karatotev /* Check if the SCU L3 Unit is present on the DSU */ 38*b62673c6SBoyan Karatotev mrs x0, CPUCFR_EL1 39*b62673c6SBoyan Karatotev ubfx x0, x0, #SCU_SHIFT, #1 40*b62673c6SBoyan Karatotev eor x0, x0, #1 41*b62673c6SBoyan Karatotev /* If SCU is not present, return without applying patch */ 42*b62673c6SBoyan Karatotev cmp x0, xzr 43*b62673c6SBoyan Karatotev mov x0, #ERRATA_NOT_APPLIES 44*b62673c6SBoyan Karatotev b.eq \_target 45*b62673c6SBoyan Karatotev.endm 46*b62673c6SBoyan Karatotev 47*b62673c6SBoyan Karatotev.macro check_errata_dsu_936184_impl 48*b62673c6SBoyan Karatotev mov x0, #ERRATA_NOT_APPLIES 49*b62673c6SBoyan Karatotev /* Erratum applies only if DSU has the ACP interface */ 50*b62673c6SBoyan Karatotev mrs x1, CLUSTERCFR_EL1 51*b62673c6SBoyan Karatotev ubfx x1, x1, #CLUSTERCFR_ACP_SHIFT, #1 52*b62673c6SBoyan Karatotev cbz x1, 1f 53*b62673c6SBoyan Karatotev 54*b62673c6SBoyan Karatotev /* If ACP is present, check if DSU is older than r2p0 */ 55*b62673c6SBoyan Karatotev mrs x1, CLUSTERIDR_EL1 56*b62673c6SBoyan Karatotev 57*b62673c6SBoyan Karatotev /* DSU variant and revision bitfields in CLUSTERIDR are adjacent */ 58*b62673c6SBoyan Karatotev ubfx x2, x1, #CLUSTERIDR_REV_SHIFT,\ 59*b62673c6SBoyan Karatotev #(CLUSTERIDR_REV_BITS + CLUSTERIDR_VAR_BITS) 60*b62673c6SBoyan Karatotev cmp x2, #(0x2 << CLUSTERIDR_VAR_SHIFT) 61*b62673c6SBoyan Karatotev b.hs 1f 62*b62673c6SBoyan Karatotev mov x0, #ERRATA_APPLIES 63*b62673c6SBoyan Karatotev1: 64*b62673c6SBoyan Karatotev.endm 65*b62673c6SBoyan Karatotev 66*b62673c6SBoyan Karatotev.macro errata_dsu_936184_wa_impl 67*b62673c6SBoyan Karatotev /* If erratum applies, we set a mask to a DSU control register */ 68*b62673c6SBoyan Karatotev mrs x0, CLUSTERACTLR_EL1 69*b62673c6SBoyan Karatotev ldr x1, =DSU_ERRATA_936184_MASK 70*b62673c6SBoyan Karatotev orr x0, x0, x1 71*b62673c6SBoyan Karatotev msr CLUSTERACTLR_EL1, x0 72*b62673c6SBoyan Karatotev.endm 73*b62673c6SBoyan Karatotev 74*b62673c6SBoyan Karatotev.macro check_errata_dsu_2313941_impl 75*b62673c6SBoyan Karatotev mov x2, #ERRATA_APPLIES 76*b62673c6SBoyan Karatotev mov x3, #ERRATA_NOT_APPLIES 77*b62673c6SBoyan Karatotev 78*b62673c6SBoyan Karatotev /* Check if DSU version is less than or equal to r3p1 */ 79*b62673c6SBoyan Karatotev mrs x1, CLUSTERIDR_EL1 80*b62673c6SBoyan Karatotev 81*b62673c6SBoyan Karatotev mov x0, #ERRATA_NOT_APPLIES 82*b62673c6SBoyan Karatotev /* DSU variant and revision bitfields in CLUSTERIDR are adjacent */ 83*b62673c6SBoyan Karatotev ubfx x0, x1, #CLUSTERIDR_REV_SHIFT,\ 84*b62673c6SBoyan Karatotev #(CLUSTERIDR_REV_BITS + CLUSTERIDR_VAR_BITS) 85*b62673c6SBoyan Karatotev mov x1, #(0x31 << CLUSTERIDR_REV_SHIFT) 86*b62673c6SBoyan Karatotev cmp x0, x1 87*b62673c6SBoyan Karatotev csel x0, x2, x3, LS 88*b62673c6SBoyan Karatotev1: 89*b62673c6SBoyan Karatotev.endm 90*b62673c6SBoyan Karatotev 91*b62673c6SBoyan Karatotev.macro errata_dsu_2313941_wa_impl 92*b62673c6SBoyan Karatotev /* If erratum applies, disable high-level clock gating */ 93*b62673c6SBoyan Karatotev mrs x0, CLUSTERACTLR_EL1 94*b62673c6SBoyan Karatotev orr x0, x0, #CLUSTERACTLR_EL1_DISABLE_SCLK_GATING 95*b62673c6SBoyan Karatotev msr CLUSTERACTLR_EL1, x0 96*b62673c6SBoyan Karatotev.endm 97*b62673c6SBoyan Karatotev#endif /* DSU_MACROS_S */ 98