DSU erratum 936184 workaround

If the system is in near idle conditions, this erratum could cause a
deadlock or data corruption. This patch applies the workaround that
prevents this.

This DSU erratum affects only the DSUs that contain the ACP interface
and it was fixed in r2p0. The workaround is applied only to the DSUs
that are actually affected.

Link to respective Arm documentation:
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.epm138168/index.html

Change-Id: I033213b3077685130fc1e3f4f79c4d15d7483ec9
Signed-off-by: John Tsichritzis <john.tsichritzis@arm.com>
diff --git a/lib/cpus/aarch64/cortex_a55.S b/lib/cpus/aarch64/cortex_a55.S
index 741c773..4e9bd9f 100644
--- a/lib/cpus/aarch64/cortex_a55.S
+++ b/lib/cpus/aarch64/cortex_a55.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,6 +11,14 @@
 #include <cpu_macros.S>
 #include <plat_macros.S>
 
+func cortex_a55_reset_func
+	mov	x19, x30
+#if ERRATA_DSU_936184
+	bl	errata_dsu_936184_wa
+#endif
+	ret	x19
+endfunc cortex_a55_reset_func
+
 	/* ---------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ---------------------------------------------
@@ -27,6 +35,26 @@
 	ret
 endfunc cortex_a55_core_pwr_dwn
 
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Cortex A55. Must follow AAPCS & can use stack.
+ */
+func cortex_a55_errata_report
+	stp	x8, x30, [sp, #-16]!
+	bl	cpu_get_rev_var
+	mov	x8, x0
+
+	/*
+	 * 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_936184, cortex_a55, dsu_936184
+
+	ldp	x8, x30, [sp], #16
+	ret
+endfunc cortex_a55_errata_report
+#endif
+
 	/* ---------------------------------------------
 	 * This function provides cortex_a55 specific
 	 * register information for crash reporting.
@@ -47,5 +75,5 @@
 endfunc cortex_a55_cpu_reg_dump
 
 declare_cpu_ops cortex_a55, CORTEX_A55_MIDR, \
-	CPU_NO_RESET_FUNC, \
+	cortex_a55_reset_func, \
 	cortex_a55_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_a75.S b/lib/cpus/aarch64/cortex_a75.S
index 73f566f..e121b7d 100644
--- a/lib/cpus/aarch64/cortex_a75.S
+++ b/lib/cpus/aarch64/cortex_a75.S
@@ -11,6 +11,7 @@
 #include <cpu_macros.S>
 
 func cortex_a75_reset_func
+	mov	x19, x30
 #if IMAGE_BL31 && WORKAROUND_CVE_2017_5715
 	cpu_check_csv2	x0, 1f
 	adr	x0, wa_cve_2017_5715_bpiall_vbar
@@ -26,6 +27,10 @@
 	isb
 #endif
 
+#if ERRATA_DSU_936184
+	bl	errata_dsu_936184_wa
+#endif
+
 #if ENABLE_AMU
 	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
 	mrs	x0, actlr_el3
@@ -49,7 +54,7 @@
 	msr	CPUAMCNTENSET_EL0, x0
 	isb
 #endif
-	ret
+	ret	x19
 endfunc cortex_a75_reset_func
 
 func check_errata_cve_2017_5715
@@ -106,6 +111,7 @@
 	 */
 	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_936184, cortex_a75, dsu_936184
 
 	ldp	x8, x30, [sp], #16
 	ret
diff --git a/lib/cpus/aarch64/cortex_a76.S b/lib/cpus/aarch64/cortex_a76.S
index 51d0b15..1697c55 100644
--- a/lib/cpus/aarch64/cortex_a76.S
+++ b/lib/cpus/aarch64/cortex_a76.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -207,6 +207,7 @@
 endfunc cortex_a76_disable_wa_cve_2018_3639
 
 func cortex_a76_reset_func
+	mov	x19, x30
 #if WORKAROUND_CVE_2018_3639
 	mrs	x0, CORTEX_A76_CPUACTLR2_EL1
 	orr	x0, x0, #CORTEX_A76_CPUACTLR2_EL1_DISABLE_LOAD_PASS_STORE
@@ -224,7 +225,11 @@
 	msr	vbar_el3, x0
 	isb
 #endif
-	ret
+
+#if ERRATA_DSU_936184
+	bl	errata_dsu_936184_wa
+#endif
+	ret	x19
 endfunc cortex_a76_reset_func
 
 	/* ---------------------------------------------
@@ -258,6 +263,7 @@
 	 * checking functions of each errata.
 	 */
 	report_errata WORKAROUND_CVE_2018_3639, cortex_a76, cve_2018_3639
+	report_errata ERRATA_DSU_936184, cortex_a76, dsu_936184
 
 	ldp	x8, x30, [sp], #16
 	ret
diff --git a/lib/cpus/aarch64/dsu_helpers.S b/lib/cpus/aarch64/dsu_helpers.S
new file mode 100644
index 0000000..293ed24
--- /dev/null
+++ b/lib/cpus/aarch64/dsu_helpers.S
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <dsu_def.h>
+#include <errata_report.h>
+
+/*
+ * DSU erratum 936184
+ * Check the DSU variant, revision and configuration to determine if the
+ * erratum applies. This erratum was fixed in r2p0.
+ *
+ * This function is called from both assembly and C environment. So it
+ * follows AAPCS.
+ *
+ * Clobbers: x0-x3
+ */
+	.globl	check_errata_dsu_936184
+	.globl	errata_dsu_936184_wa
+
+func check_errata_dsu_936184
+	mov	x2, #ERRATA_NOT_APPLIES
+	mov	x3, #ERRATA_APPLIES
+
+	/* Erratum applies only if ACP interface is present in DSU */
+	mov	x0, x2
+	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	x0, x1, #CLUSTERIDR_REV_SHIFT,\
+			#(CLUSTERIDR_REV_BITS + CLUSTERIDR_VAR_BITS)
+	mov	x1, #(0x2 << CLUSTERIDR_REV_BITS)
+	cmp	x0, x1
+	csel	x0, x2, x3, hs
+1:
+	ret
+endfunc check_errata_dsu_936184
+
+func errata_dsu_936184_wa
+	mov	x20, 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	x20
+endfunc errata_dsu_936184_wa
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 456e3e5..40a8ac7 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -123,6 +123,11 @@
 # only to r0p0 and r1p0 of the Ares cpu.
 ERRATA_ARES_1043202	?=1
 
+# 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.
+ERRATA_DSU_936184	?=0
+
 # Process ERRATA_A53_826319 flag
 $(eval $(call assert_boolean,ERRATA_A53_826319))
 $(eval $(call add_define,ERRATA_A53_826319))
@@ -187,6 +192,10 @@
 $(eval $(call assert_boolean,ERRATA_ARES_1043202))
 $(eval $(call add_define,ERRATA_ARES_1043202))
 
+# Process ERRATA_DSU_936184 flag
+$(eval $(call assert_boolean,ERRATA_DSU_936184))
+$(eval $(call add_define,ERRATA_DSU_936184))
+
 # Errata build flags
 ifneq (${ERRATA_A53_843419},0)
 TF_LDFLAGS_aarch64	+= --fix-cortex-a53-843419