aarch32: Implement errata workarounds for Cortex A53

This brings the implementation on par with the software
errata workarounds for AArch64.

Change-Id: Id103602e35b1c0ad3705a5b2b7cdb34dd8a8c5e2
Signed-off-by: Dimitris Papastamos <dimitris.papastamos@arm.com>
diff --git a/include/lib/cpus/aarch32/cortex_a53.h b/include/lib/cpus/aarch32/cortex_a53.h
index 265cb15..24a9c6c 100644
--- a/include/lib/cpus/aarch32/cortex_a53.h
+++ b/include/lib/cpus/aarch32/cortex_a53.h
@@ -42,6 +42,8 @@
  ******************************************************************************/
 #define CORTEX_A53_ACTLR			p15, 0, c15
 
+#define CORTEX_A53_ACTLR_ENDCCASCI_SHIFT	44
+#define CORTEX_A53_ACTLR_ENDCCASCI		(1 << CORTEX_A53_ACTLR_ENDCCASCI_SHIFT)
 #define CORTEX_A53_ACTLR_DTAH			(1 << 24)
 
 /*******************************************************************************
diff --git a/lib/cpus/aarch32/cortex_a53.S b/lib/cpus/aarch32/cortex_a53.S
index 3d5f833..bc2c762 100644
--- a/lib/cpus/aarch32/cortex_a53.S
+++ b/lib/cpus/aarch32/cortex_a53.S
@@ -10,6 +10,11 @@
 #include <cpu_macros.S>
 #include <debug.h>
 
+#if A53_DISABLE_NON_TEMPORAL_HINT
+#undef ERRATA_A53_836870
+#define ERRATA_A53_836870	1
+#endif
+
 	/* ---------------------------------------------
 	 * Disable intra-cluster coherency
 	 * ---------------------------------------------
@@ -23,11 +28,133 @@
 	bx	lr
 endfunc cortex_a53_disable_smp
 
+	/* --------------------------------------------------
+	 * Errata Workaround for Cortex A53 Errata #826319.
+	 * This applies only to revision <= r0p2 of Cortex A53.
+	 * Inputs:
+	 * r0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: r0-r3
+	 * --------------------------------------------------
+	 */
+func errata_a53_826319_wa
+	/*
+	 * Compare r0 against revision r0p2
+	 */
+	mov	r2, lr
+	bl	check_errata_826319
+	mov	lr, r2
+	cmp	r0, #ERRATA_NOT_APPLIES
+	beq	1f
+	ldcopr	r0, CORTEX_A53_L2ACTLR
+	bic	r0, #CORTEX_A53_L2ACTLR_ENABLE_UNIQUECLEAN
+	orr	r0, #CORTEX_A53_L2ACTLR_DISABLE_CLEAN_PUSH
+	stcopr	r0, CORTEX_A53_L2ACTLR
+1:
+	bx	lr
+endfunc errata_a53_826319_wa
+
+func check_errata_826319
+	mov	r1, #0x02
+	b	cpu_rev_var_ls
+endfunc check_errata_826319
+
+	/* ---------------------------------------------------------------------
+	 * Disable the cache non-temporal hint.
+	 *
+	 * This ignores the Transient allocation hint in the MAIR and treats
+	 * allocations the same as non-transient allocation types. As a result,
+	 * the LDNP and STNP instructions in AArch64 behave the same as the
+	 * equivalent LDP and STP instructions.
+	 *
+	 * This is relevant only for revisions <= r0p3 of Cortex-A53.
+	 * From r0p4 and onwards, the bit to disable the hint is enabled by
+	 * default at reset.
+	 *
+	 * Inputs:
+	 * r0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: r0-r3
+	 * ---------------------------------------------------------------------
+	 */
+func a53_disable_non_temporal_hint
+	/*
+	 * Compare r0 against revision r0p3
+	 */
+	mov		r2, lr
+	bl		check_errata_disable_non_temporal_hint
+	mov		lr, r2
+	cmp		r0, #ERRATA_NOT_APPLIES
+	beq		1f
+	ldcopr16	r0, r1, CORTEX_A53_ACTLR
+	orr64_imm	r0, r1, CORTEX_A53_ACTLR_DTAH
+	stcopr16	r0, r1, CORTEX_A53_ACTLR
+1:
+	bx		lr
+endfunc a53_disable_non_temporal_hint
+
+func check_errata_disable_non_temporal_hint
+	mov	r1, #0x03
+	b	cpu_rev_var_ls
+endfunc check_errata_disable_non_temporal_hint
+
+	/* --------------------------------------------------
+	 * Errata Workaround for Cortex A53 Errata #855873.
+	 *
+	 * This applies only to revisions >= r0p3 of Cortex A53.
+	 * Earlier revisions of the core are affected as well, but don't
+	 * have the chicken bit in the CPUACTLR register. It is expected that
+	 * the rich OS takes care of that, especially as the workaround is
+	 * shared with other erratas in those revisions of the CPU.
+	 * Inputs:
+	 * r0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: r0-r3
+	 * --------------------------------------------------
+	 */
+func errata_a53_855873_wa
+	/*
+	 * Compare r0 against revision r0p3 and higher
+	 */
+	mov		r2, lr
+	bl		check_errata_855873
+	mov		lr, r2
+	cmp		r0, #ERRATA_NOT_APPLIES
+	beq		1f
+	ldcopr16	r0, r1, CORTEX_A53_ACTLR
+	orr64_imm	r0, r1, CORTEX_A53_ACTLR_ENDCCASCI
+	stcopr16	r0, r1, CORTEX_A53_ACTLR
+1:
+	bx		lr
+endfunc errata_a53_855873_wa
+
+func check_errata_855873
+	mov	r1, #0x03
+	b	cpu_rev_var_hs
+endfunc check_errata_855873
+
 	/* -------------------------------------------------
 	 * The CPU Ops reset function for Cortex-A53.
+	 * Shall clobber: r0-r6
 	 * -------------------------------------------------
 	 */
 func cortex_a53_reset_func
+	mov	r5, lr
+	bl	cpu_get_rev_var
+	mov	r4, r0
+
+#if ERRATA_A53_826319
+	mov	r0, r4
+	bl	errata_a53_826319_wa
+#endif
+
+#if ERRATA_A53_836870
+	mov	r0, r4
+	bl	a53_disable_non_temporal_hint
+#endif
+
+#if ERRATA_A53_855873
+	mov	r0, r4
+	bl	errata_a53_855873_wa
+#endif
+
 	/* ---------------------------------------------
 	 * Enable the SMP bit.
 	 * ---------------------------------------------
@@ -36,7 +163,7 @@
 	orr64_imm	r0, r1, CORTEX_A53_ECTLR_SMP_BIT
 	stcopr16	r0, r1,	CORTEX_A53_ECTLR
 	isb
-	bx	lr
+	bx	r5
 endfunc cortex_a53_reset_func
 
 	/* ----------------------------------------------------
@@ -111,6 +238,29 @@
 	b	cortex_a53_disable_smp
 endfunc cortex_a53_cluster_pwr_dwn
 
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Cortex A53. Must follow AAPCS.
+ */
+func cortex_a53_errata_report
+	push	{r12, lr}
+
+	bl	cpu_get_rev_var
+	mov	r4, r0
+
+	/*
+	 * Report all errata. The revision-variant information is passed to
+	 * checking functions of each errata.
+	 */
+	report_errata ERRATA_A53_826319, cortex_a53, 826319
+	report_errata ERRATA_A53_836870, cortex_a53, disable_non_temporal_hint
+	report_errata ERRATA_A53_855873, cortex_a53, 855873
+
+	pop	{r12, lr}
+	bx	lr
+endfunc cortex_a53_errata_report
+#endif
+
 declare_cpu_ops cortex_a53, CORTEX_A53_MIDR, \
 	cortex_a53_reset_func, \
 	cortex_a53_core_pwr_dwn, \