Merge changes from topic "sm/fix_a76_errata" into integration

* changes:
  Workaround for cortex-A76 errata 1286807
  Cortex-A76: workarounds for errata 1257314, 1262606, 1262888, 1275112
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index 2a21bd2..4068c9a 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -534,13 +534,21 @@
 
 -  ``HW_ASSISTED_COHERENCY``: On most Arm systems to-date, platform-specific
    software operations are required for CPUs to enter and exit coherency.
-   However, there exists newer systems where CPUs' entry to and exit from
-   coherency is managed in hardware. Such systems require software to only
-   initiate the operations, and the rest is managed in hardware, minimizing
-   active software management. In such systems, this boolean option enables
-   TF-A to carry out build and run-time optimizations during boot and power
-   management operations. This option defaults to 0 and if it is enabled,
-   then it implies ``WARMBOOT_ENABLE_DCACHE_EARLY`` is also enabled.
+   However, newer systems exist where CPUs' entry to and exit from coherency
+   is managed in hardware. Such systems require software to only initiate these
+   operations, and the rest is managed in hardware, minimizing active software
+   management. In such systems, this boolean option enables TF-A to carry out
+   build and run-time optimizations during boot and power management operations.
+   This option defaults to 0 and if it is enabled, then it implies
+   ``WARMBOOT_ENABLE_DCACHE_EARLY`` is also enabled.
+
+   If this flag is disabled while the platform which TF-A is compiled for
+   includes cores that manage coherency in hardware, then a compilation error is
+   generated. This is based on the fact that a system cannot have, at the same
+   time, cores that manage coherency in hardware and cores that don't. In other
+   words, a platform cannot have, at the same time, cores that require
+   ``HW_ASSISTED_COHERENCY=1`` and cores that require
+   ``HW_ASSISTED_COHERENCY=0``.
 
    Note that, when ``HW_ASSISTED_COHERENCY`` is enabled, version 2 of
    translation library (xlat tables v2) must be used; version 1 of translation
diff --git a/drivers/arm/smmu/smmu_v3.c b/drivers/arm/smmu/smmu_v3.c
index 004e81e..ab2eb2b 100644
--- a/drivers/arm/smmu/smmu_v3.c
+++ b/drivers/arm/smmu/smmu_v3.c
@@ -1,60 +1,55 @@
 /*
- * 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
  */
 
+#include <common/debug.h>
 #include <cdefs.h>
-#include <stdbool.h>
-
 #include <drivers/arm/smmu_v3.h>
 #include <lib/mmio.h>
 
-static inline uint32_t __init smmuv3_read_s_idr1(uintptr_t base)
-{
-	return mmio_read_32(base + SMMU_S_IDR1);
-}
+/* SMMU poll number of retries */
+#define SMMU_POLL_RETRY		1000000
 
-static inline uint32_t __init smmuv3_read_s_init(uintptr_t base)
+static int __init smmuv3_poll(uintptr_t smmu_reg, uint32_t mask,
+				uint32_t value)
 {
-	return mmio_read_32(base + SMMU_S_INIT);
-}
+	uint32_t reg_val, retries = SMMU_POLL_RETRY;
 
-static inline void __init smmuv3_write_s_init(uintptr_t base, uint32_t value)
-{
-	mmio_write_32(base + SMMU_S_INIT, value);
-}
+	do {
+		reg_val = mmio_read_32(smmu_reg);
+		if ((reg_val & mask) == value)
+			return 0;
+	} while (--retries != 0U);
 
-/* Test for pending invalidate */
-static inline bool smmuv3_inval_pending(uintptr_t base)
-{
-	return (smmuv3_read_s_init(base) & SMMU_S_INIT_INV_ALL_MASK) != 0U;
+	ERROR("Failed to poll SMMUv3 register @%p\n", (void *)smmu_reg);
+	ERROR("Read value 0x%x, expected 0x%x\n", reg_val,
+		value == 0U ? reg_val & ~mask : reg_val | mask);
+	return -1;
 }
 
 /*
  * Initialize the SMMU by invalidating all secure caches and TLBs.
- *
- * Returns 0 on success, and -1 on failure.
+ * Abort all incoming transactions in order to implement a default
+ * deny policy on reset
  */
 int __init smmuv3_init(uintptr_t smmu_base)
 {
-	uint32_t idr1_reg;
-
 	/*
 	 * Invalidation of secure caches and TLBs is required only if the SMMU
 	 * supports secure state. If not, it's implementation defined as to how
 	 * SMMU_S_INIT register is accessed.
 	 */
-	idr1_reg = smmuv3_read_s_idr1(smmu_base);
-	if (((idr1_reg >> SMMU_S_IDR1_SECURE_IMPL_SHIFT) &
-			SMMU_S_IDR1_SECURE_IMPL_MASK) == 0U) {
-		return -1;
+	if ((mmio_read_32(smmu_base + SMMU_S_IDR1) &
+			SMMU_S_IDR1_SECURE_IMPL) != 0U) {
+
+		/* Initiate invalidation */
+		mmio_write_32(smmu_base + SMMU_S_INIT, SMMU_S_INIT_INV_ALL);
+
+		/* Wait for global invalidation operation to finish */
+		return smmuv3_poll(smmu_base + SMMU_S_INIT,
+					SMMU_S_INIT_INV_ALL, 0U);
 	}
-
-	/* Initiate invalidation, and wait for it to finish */
-	smmuv3_write_s_init(smmu_base, SMMU_S_INIT_INV_ALL_MASK);
-	while (smmuv3_inval_pending(smmu_base))
-		;
-
 	return 0;
 }
diff --git a/include/drivers/arm/smmu_v3.h b/include/drivers/arm/smmu_v3.h
index 33f3d6f..75c9465 100644
--- a/include/drivers/arm/smmu_v3.h
+++ b/include/drivers/arm/smmu_v3.h
@@ -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
  */
@@ -8,20 +8,27 @@
 #define SMMU_V3_H
 
 #include <stdint.h>
-
 #include <lib/utils_def.h>
 
 /* SMMUv3 register offsets from device base */
+#define SMMU_GBPA	U(0x0044)
 #define SMMU_S_IDR1	U(0x8004)
 #define SMMU_S_INIT	U(0x803c)
+#define SMMU_S_GBPA	U(0x8044)
+
+/* SMMU_GBPA register fields */
+#define SMMU_GBPA_UPDATE		(1UL << 31)
+#define SMMU_GBPA_ABORT			(1UL << 20)
 
 /* SMMU_S_IDR1 register fields */
-#define SMMU_S_IDR1_SECURE_IMPL_SHIFT	31
-#define SMMU_S_IDR1_SECURE_IMPL_MASK	U(0x1)
+#define SMMU_S_IDR1_SECURE_IMPL		(1UL << 31)
 
 /* SMMU_S_INIT register fields */
-#define SMMU_S_INIT_INV_ALL_MASK	U(0x1)
+#define SMMU_S_INIT_INV_ALL		(1UL << 0)
 
+/* SMMU_S_GBPA register fields */
+#define SMMU_S_GBPA_UPDATE		(1UL << 31)
+#define SMMU_S_GBPA_ABORT		(1UL << 20)
 
 int smmuv3_init(uintptr_t smmu_base);
 
diff --git a/lib/cpus/aarch64/cortex_a55.S b/lib/cpus/aarch64/cortex_a55.S
index b9a3f36..0ef373a 100644
--- a/lib/cpus/aarch64/cortex_a55.S
+++ b/lib/cpus/aarch64/cortex_a55.S
@@ -11,6 +11,11 @@
 #include <cpu_macros.S>
 #include <plat_macros.S>
 
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex-A55 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
 	/* --------------------------------------------------
 	 * Errata Workaround for Cortex A55 Errata #768277.
 	 * This applies only to revision r0p0 of Cortex A55.
diff --git a/lib/cpus/aarch64/cortex_a75.S b/lib/cpus/aarch64/cortex_a75.S
index fda1aec..657457e 100644
--- a/lib/cpus/aarch64/cortex_a75.S
+++ b/lib/cpus/aarch64/cortex_a75.S
@@ -10,6 +10,11 @@
 #include <cpuamu.h>
 #include <cpu_macros.S>
 
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex-A75 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
 	/* --------------------------------------------------
 	 * Errata Workaround for Cortex A75 Errata #764081.
 	 * This applies only to revision r0p0 of Cortex A75.
diff --git a/lib/cpus/aarch64/cortex_a76.S b/lib/cpus/aarch64/cortex_a76.S
index aed7970..b48283c 100644
--- a/lib/cpus/aarch64/cortex_a76.S
+++ b/lib/cpus/aarch64/cortex_a76.S
@@ -13,6 +13,11 @@
 #include <plat_macros.S>
 #include <services/arm_arch_svc.h>
 
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex-A76 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
 #define ESR_EL3_A64_SMC0	0x5e000000
 #define ESR_EL3_A32_SMC0	0x4e000000
 
diff --git a/lib/cpus/aarch64/cortex_a76ae.S b/lib/cpus/aarch64/cortex_a76ae.S
index 1ba8e9a..46e9450 100644
--- a/lib/cpus/aarch64/cortex_a76ae.S
+++ b/lib/cpus/aarch64/cortex_a76ae.S
@@ -8,6 +8,11 @@
 #include <cortex_a76ae.h>
 #include <cpu_macros.S>
 
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Cortex-A76AE must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
 	/* ---------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ---------------------------------------------
diff --git a/lib/cpus/aarch64/cortex_deimos.S b/lib/cpus/aarch64/cortex_deimos.S
index 0e72fba..e73e89f 100644
--- a/lib/cpus/aarch64/cortex_deimos.S
+++ b/lib/cpus/aarch64/cortex_deimos.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,6 +11,11 @@
 #include <cpu_macros.S>
 #include <plat_macros.S>
 
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Deimos must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
 	/* ---------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ---------------------------------------------
diff --git a/lib/cpus/aarch64/neoverse_e1.S b/lib/cpus/aarch64/neoverse_e1.S
index 8e40306..71e7b51 100644
--- a/lib/cpus/aarch64/neoverse_e1.S
+++ b/lib/cpus/aarch64/neoverse_e1.S
@@ -11,6 +11,11 @@
 #include <cpu_macros.S>
 #include <plat_macros.S>
 
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Neoverse E1 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
 func neoverse_e1_cpu_pwr_dwn
 	mrs	x0, NEOVERSE_E1_CPUPWRCTLR_EL1
 	orr	x0, x0, #NEOVERSE_E1_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
diff --git a/lib/cpus/aarch64/neoverse_n1.S b/lib/cpus/aarch64/neoverse_n1.S
index ce63899..2038f31 100644
--- a/lib/cpus/aarch64/neoverse_n1.S
+++ b/lib/cpus/aarch64/neoverse_n1.S
@@ -10,6 +10,11 @@
 #include <cpuamu.h>
 #include <cpu_macros.S>
 
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Neoverse N1 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
 /* --------------------------------------------------
  * Errata Workaround for Neoverse N1 Errata
  * This applies to revision r0p0 and r1p0 of Neoverse N1.
diff --git a/lib/cpus/aarch64/neoverse_zeus.S b/lib/cpus/aarch64/neoverse_zeus.S
index 79c8b2f..c5241af 100644
--- a/lib/cpus/aarch64/neoverse_zeus.S
+++ b/lib/cpus/aarch64/neoverse_zeus.S
@@ -11,6 +11,11 @@
 #include <cpu_macros.S>
 #include <plat_macros.S>
 
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Neoverse Zeus must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
 	/* ---------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ---------------------------------------------
diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c
index 7f28b20..3f92d37 100644
--- a/plat/arm/board/fvp/fvp_bl31_setup.c
+++ b/plat/arm/board/fvp/fvp_bl31_setup.c
@@ -34,7 +34,7 @@
 	 */
 	fvp_interconnect_enable();
 
-	/* On FVP RevC, intialize SMMUv3 */
+	/* On FVP RevC, initialize SMMUv3 */
 	if ((arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) != 0U)
 		smmuv3_init(PLAT_FVP_SMMUV3_BASE);
 }
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index c11d848..9b128a5 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -95,18 +95,25 @@
 FVP_CPU_LIBS		:=	lib/cpus/${ARCH}/aem_generic.S
 
 ifeq (${ARCH}, aarch64)
-FVP_CPU_LIBS		+=	lib/cpus/aarch64/cortex_a35.S			\
+
+# select a different set of CPU files, depending on whether we compile with
+# hardware assisted coherency configurations or not
+ifeq (${HW_ASSISTED_COHERENCY}, 0)
+	FVP_CPU_LIBS	+=	lib/cpus/aarch64/cortex_a35.S			\
 				lib/cpus/aarch64/cortex_a53.S			\
-				lib/cpus/aarch64/cortex_a55.S			\
 				lib/cpus/aarch64/cortex_a57.S			\
 				lib/cpus/aarch64/cortex_a72.S			\
-				lib/cpus/aarch64/cortex_a73.S			\
+				lib/cpus/aarch64/cortex_a73.S
+else
+	FVP_CPU_LIBS	+=	lib/cpus/aarch64/cortex_a55.S			\
 				lib/cpus/aarch64/cortex_a75.S			\
 				lib/cpus/aarch64/cortex_a76.S			\
 				lib/cpus/aarch64/cortex_a76ae.S			\
 				lib/cpus/aarch64/neoverse_n1.S			\
+				lib/cpus/aarch64/neoverse_e1.S			\
 				lib/cpus/aarch64/cortex_deimos.S		\
 				lib/cpus/aarch64/neoverse_zeus.S
+endif
 
 else
 FVP_CPU_LIBS		+=	lib/cpus/aarch32/cortex_a32.S
@@ -217,10 +224,13 @@
 endif
 
 ifeq (${ENABLE_AMU},1)
-BL31_SOURCES		+=	lib/cpus/aarch64/cortex_a75_pubsub.c	\
-				lib/cpus/aarch64/neoverse_n1_pubsub.c	\
-				lib/cpus/aarch64/cpuamu.c		\
+BL31_SOURCES		+=	lib/cpus/aarch64/cpuamu.c		\
 				lib/cpus/aarch64/cpuamu_helpers.S
+
+ifeq (${HW_ASSISTED_COHERENCY}, 1)
+BL31_SOURCES		+=	lib/cpus/aarch64/cortex_a75_pubsub.c	\
+				lib/cpus/aarch64/neoverse_n1_pubsub.c
+endif
 endif
 
 ifeq (${RAS_EXTENSION},1)