DSU: Implement workaround for errata 798953
authorLouis Mayencourt <louis.mayencourt@arm.com>
Tue, 9 Apr 2019 15:29:01 +0000 (16:29 +0100)
committerLouis Mayencourt <louis.mayencourt@arm.com>
Wed, 17 Apr 2019 12:46:43 +0000 (13:46 +0100)
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 <louis.mayencourt@arm.com>
docs/cpu-specific-build-macros.rst
include/lib/cpus/aarch64/dsu_def.h
lib/cpus/aarch64/cortex_a55.S
lib/cpus/aarch64/cortex_a75.S
lib/cpus/aarch64/cortex_a76.S
lib/cpus/aarch64/dsu_helpers.S
lib/cpus/cpu-ops.mk

index 0b581692f103130c44ceb85caa652f299983935b..7b7f4cde829b10a07cb469f3dc29666b6ee244c5 100644 (file)
@@ -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
index 4ec64eee3aa4a12d10b918ef792428bc4f5053ab..0969acf53b0e872055babc1d116858308a5bfc7a 100644 (file)
@@ -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
  ********************************************************************/
index 1da80efa28d098168a13fc92c10fa7f0108c482a..b9a3f3653ebcaed489bbb8a274800b6567707e94 100644 (file)
@@ -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
index 20401889074b1a502428129bfd4c437c7a6788e8..fda1aecbecb57b96bee02ddf5d3366187d91772b 100644 (file)
@@ -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
index e544018c85263e54eb895734fda6300e1f5dff03..4bf6e77a9cf060895e65b06e1ad2fe4ed8de4119 100644 (file)
@@ -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
index 29870a4d31e7b65fd3e86b6dd063af55d6a5144c..100ffaa970eaf083d959c8d51780766d6171381b 100644 (file)
@@ -8,6 +8,59 @@
 #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
index bfee990bb2332c5f6fde1142c80266347499fbfa..4deb262d8f5c800673b5bdcf1ab55d3cbd189ae6 100644 (file)
@@ -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))