Cortex-A55: Implement workaround for erratum 768277

Change-Id: Iebd45ef5e39ee7080235fb85414ce5b2e776f90c
Signed-off-by: Ambroise Vincent <ambroise.vincent@arm.com>
diff --git a/docs/cpu-specific-build-macros.rst b/docs/cpu-specific-build-macros.rst
index 315457a..897c771 100644
--- a/docs/cpu-specific-build-macros.rst
+++ b/docs/cpu-specific-build-macros.rst
@@ -97,6 +97,11 @@
    Earlier revisions of the CPU have other errata which require the same
    workaround in software, so they should be covered anyway.
 
+For Cortex-A55, the following errata build flags are defined :
+
+-  ``ERRATA_A55_768277``: This applies errata 768277 workaround to Cortex-A55
+   CPU. This needs to be enabled only for revision r0p0 of the CPU.
+
 For Cortex-A57, the following errata build flags are defined :
 
 -  ``ERRATA_A57_806969``: This applies errata 806969 workaround to Cortex-A57
diff --git a/include/lib/cpus/aarch64/cortex_a55.h b/include/lib/cpus/aarch64/cortex_a55.h
index 8b21e16..5db0f00 100644
--- a/include/lib/cpus/aarch64/cortex_a55.h
+++ b/include/lib/cpus/aarch64/cortex_a55.h
@@ -18,6 +18,13 @@
 #define CORTEX_A55_CPUPWRCTLR_EL1	S3_0_C15_C2_7
 #define CORTEX_A55_CPUECTLR_EL1		S3_0_C15_C1_4
 
+/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_A55_CPUACTLR_EL1				S3_0_C15_C1_0
+
+#define CORTEX_A55_CPUACTLR_EL1_DISABLE_DUAL_ISSUE	(ULL(1) << 31)
+
 /* Definitions of register field mask in CORTEX_A55_CPUPWRCTLR_EL1 */
 #define CORTEX_A55_CORE_PWRDN_EN_MASK	U(0x1)
 
diff --git a/lib/cpus/aarch64/cortex_a55.S b/lib/cpus/aarch64/cortex_a55.S
index b347e29..018c9db 100644
--- a/lib/cpus/aarch64/cortex_a55.S
+++ b/lib/cpus/aarch64/cortex_a55.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,11 +11,49 @@
 #include <cpu_macros.S>
 #include <plat_macros.S>
 
+	/* --------------------------------------------------
+	 * Errata Workaround for Cortex A55 Errata #768277.
+	 * This applies only to revision r0p0 of Cortex A55.
+	 * Inputs:
+	 * x0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: x0-x17
+	 * --------------------------------------------------
+	 */
+func errata_a55_768277_wa
+	/*
+	 * Compare x0 against revision r0p0
+	 */
+	mov	x17, x30
+	bl	check_errata_768277
+	cbz	x0, 1f
+	mrs	x1, CORTEX_A55_CPUACTLR_EL1
+	orr	x1, x1, #CORTEX_A55_CPUACTLR_EL1_DISABLE_DUAL_ISSUE
+	msr	CORTEX_A55_CPUACTLR_EL1, x1
+	isb
+1:
+	ret	x17
+endfunc errata_a55_768277_wa
+
+func check_errata_768277
+	mov	x1, #0x00
+	b	cpu_rev_var_ls
+endfunc check_errata_768277
+
 func cortex_a55_reset_func
 	mov	x19, x30
+
 #if ERRATA_DSU_936184
 	bl	errata_dsu_936184_wa
 #endif
+
+	bl	cpu_get_rev_var
+	mov	x18, x0
+
+#if ERRATA_A55_768277
+	mov	x0, x18
+	bl	errata_a55_768277_wa
+#endif
+
 	ret	x19
 endfunc cortex_a55_reset_func
 
@@ -49,6 +87,7 @@
 	 * "report_errata" is expecting it and it doesn't corrupt it.
 	 */
 	report_errata ERRATA_DSU_936184, cortex_a55, dsu_936184
+	report_errata ERRATA_A55_768277, cortex_a55, 768277
 
 	ldp	x8, x30, [sp], #16
 	ret
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 7824df2..2ada0be 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -79,6 +79,10 @@
 # of by the rich OS.
 ERRATA_A53_855873	?=0
 
+# Flag to apply erratum 768277 workaround during reset. This erratum applies
+# only to revision r0p0 of the Cortex A55 cpu.
+ERRATA_A55_768277	?=0
+
 # Flag to apply erratum 806969 workaround during reset. This erratum applies
 # only to revision r0p0 of the Cortex A57 cpu.
 ERRATA_A57_806969	?=0
@@ -148,6 +152,10 @@
 $(eval $(call assert_boolean,ERRATA_A53_855873))
 $(eval $(call add_define,ERRATA_A53_855873))
 
+# Process ERRATA_A55_768277 flag
+$(eval $(call assert_boolean,ERRATA_A55_768277))
+$(eval $(call add_define,ERRATA_A55_768277))
+
 # Process ERRATA_A57_806969 flag
 $(eval $(call assert_boolean,ERRATA_A57_806969))
 $(eval $(call add_define,ERRATA_A57_806969))