From 0e985d708e8f429c1fa1f557d3eea90e32de5228 Mon Sep 17 00:00:00 2001 From: Louis Mayencourt Date: Tue, 9 Apr 2019 16:29:01 +0100 Subject: [PATCH] DSU: Implement workaround for errata 798953 Under certain near idle conditions, DSU may miss response transfers on the ACE master or Peripheral port, leading to deadlock. This workaround disables high-level clock gating of the DSU to prevent this. Change-Id: I820911d61570bacb38dd325b3519bc8d12caa14b Signed-off-by: Louis Mayencourt --- docs/cpu-specific-build-macros.rst | 5 +++ include/lib/cpus/aarch64/dsu_def.h | 2 ++ lib/cpus/aarch64/cortex_a55.S | 5 +++ lib/cpus/aarch64/cortex_a75.S | 5 +++ lib/cpus/aarch64/cortex_a76.S | 8 ++++- lib/cpus/aarch64/dsu_helpers.S | 53 ++++++++++++++++++++++++++++++ lib/cpus/cpu-ops.mk | 8 +++++ 7 files changed, 85 insertions(+), 1 deletion(-) diff --git a/docs/cpu-specific-build-macros.rst b/docs/cpu-specific-build-macros.rst index 0b581692..7b7f4cde 100644 --- a/docs/cpu-specific-build-macros.rst +++ b/docs/cpu-specific-build-macros.rst @@ -233,6 +233,11 @@ of DSU errata workarounds are similar to `CPU errata workarounds`_. For DSU errata, the following build flags are defined: +- ``ERRATA_DSU_798953``: This applies errata 798953 workaround for the + affected DSU configurations. This errata applies only for those DSUs that + revision is r0p0 (on r0p1 it is fixed). However, please note that this + workaround results in increased DSU power consumption on idle. + - ``ERRATA_DSU_936184``: This applies errata 936184 workaround for the affected DSU configurations. This errata applies only for those DSUs that contain the ACP interface **and** the DSU revision is older than r2p0 (on diff --git a/include/lib/cpus/aarch64/dsu_def.h b/include/lib/cpus/aarch64/dsu_def.h index 4ec64eee..0969acf5 100644 --- a/include/lib/cpus/aarch64/dsu_def.h +++ b/include/lib/cpus/aarch64/dsu_def.h @@ -31,6 +31,8 @@ ********************************************************************/ #define CLUSTERACTLR_EL1 S3_0_C15_C3_3 +#define CLUSTERACTLR_EL1_DISABLE_CLOCK_GATING (ULL(1) << 15) + /******************************************************************** * Masks applied for DSU errata workarounds ********************************************************************/ diff --git a/lib/cpus/aarch64/cortex_a55.S b/lib/cpus/aarch64/cortex_a55.S index 1da80efa..b9a3f365 100644 --- a/lib/cpus/aarch64/cortex_a55.S +++ b/lib/cpus/aarch64/cortex_a55.S @@ -173,6 +173,10 @@ endfunc check_errata_903758 func cortex_a55_reset_func mov x19, x30 +#if ERRATA_DSU_798953 + bl errata_dsu_798953_wa +#endif + #if ERRATA_DSU_936184 bl errata_dsu_936184_wa #endif @@ -237,6 +241,7 @@ func cortex_a55_errata_report * Report all errata. The revision variant information is at x8, where * "report_errata" is expecting it and it doesn't corrupt it. */ + report_errata ERRATA_DSU_798953, cortex_a55, dsu_798953 report_errata ERRATA_DSU_936184, cortex_a55, dsu_936184 report_errata ERRATA_A55_768277, cortex_a55, 768277 report_errata ERRATA_A55_778703, cortex_a55, 778703 diff --git a/lib/cpus/aarch64/cortex_a75.S b/lib/cpus/aarch64/cortex_a75.S index 20401889..fda1aecb 100644 --- a/lib/cpus/aarch64/cortex_a75.S +++ b/lib/cpus/aarch64/cortex_a75.S @@ -100,6 +100,10 @@ func cortex_a75_reset_func isb #endif +#if ERRATA_DSU_798953 + bl errata_dsu_798953_wa +#endif + #if ERRATA_DSU_936184 bl errata_dsu_936184_wa #endif @@ -186,6 +190,7 @@ func cortex_a75_errata_report report_errata ERRATA_A75_790748, cortex_a75, 790748 report_errata WORKAROUND_CVE_2017_5715, cortex_a75, cve_2017_5715 report_errata WORKAROUND_CVE_2018_3639, cortex_a75, cve_2018_3639 + report_errata ERRATA_DSU_798953, cortex_a75, dsu_798953 report_errata ERRATA_DSU_936184, cortex_a75, dsu_936184 ldp x8, x30, [sp], #16 diff --git a/lib/cpus/aarch64/cortex_a76.S b/lib/cpus/aarch64/cortex_a76.S index e544018c..4bf6e77a 100644 --- a/lib/cpus/aarch64/cortex_a76.S +++ b/lib/cpus/aarch64/cortex_a76.S @@ -344,9 +344,14 @@ func cortex_a76_reset_func #endif /* DYNAMIC_WORKAROUND_CVE_2018_3639 */ #endif /* WORKAROUND_CVE_2018_3639 */ +#if ERRATA_DSU_798953 + bl errata_dsu_798953_wa +#endif + #if ERRATA_DSU_936184 bl errata_dsu_936184_wa #endif + ret x19 endfunc cortex_a76_reset_func @@ -368,7 +373,7 @@ endfunc cortex_a76_core_pwr_dwn #if REPORT_ERRATA /* - * Errata printing function for Cortex Cortex A76. Must follow AAPCS. + * Errata printing function for Cortex A76. Must follow AAPCS. */ func cortex_a76_errata_report stp x8, x30, [sp, #-16]! @@ -384,6 +389,7 @@ func cortex_a76_errata_report report_errata ERRATA_A76_1130799, cortex_a76, 1130799 report_errata ERRATA_A76_1220197, cortex_a76, 1220197 report_errata WORKAROUND_CVE_2018_3639, cortex_a76, cve_2018_3639 + report_errata ERRATA_DSU_798953, cortex_a76, dsu_798953 report_errata ERRATA_DSU_936184, cortex_a76, dsu_936184 ldp x8, x30, [sp], #16 diff --git a/lib/cpus/aarch64/dsu_helpers.S b/lib/cpus/aarch64/dsu_helpers.S index 29870a4d..100ffaa9 100644 --- a/lib/cpus/aarch64/dsu_helpers.S +++ b/lib/cpus/aarch64/dsu_helpers.S @@ -8,6 +8,59 @@ #include #include + /* ----------------------------------------------------------------------- + * 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 diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index bfee990b..4deb262d 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -214,6 +214,10 @@ ERRATA_A76_1220197 ?=0 # only to r0p0 and r1p0 of the Neoverse N1 cpu. ERRATA_N1_1043202 ?=1 +# Flag to apply DSU erratum 798953. This erratum applies to DSUs revision r0p0. +# Applying the workaround results in higher DSU power consumption on idle. +ERRATA_DSU_798953 ?=0 + # Flag to apply DSU erratum 936184. This erratum applies to DSUs containing # the ACP interface and revision < r2p0. Applying the workaround results in # higher DSU power consumption on idle. @@ -375,6 +379,10 @@ $(eval $(call add_define,ERRATA_A76_1220197)) $(eval $(call assert_boolean,ERRATA_N1_1043202)) $(eval $(call add_define,ERRATA_N1_1043202)) +# Process ERRATA_DSU_798953 flag +$(eval $(call assert_boolean,ERRATA_DSU_798953)) +$(eval $(call add_define,ERRATA_DSU_798953)) + # Process ERRATA_DSU_936184 flag $(eval $(call assert_boolean,ERRATA_DSU_936184)) $(eval $(call add_define,ERRATA_DSU_936184)) -- 2.30.2