Merge changes Ib1ed9786,I6c4855c8 into integration

* changes:
  plat: imx: Correct the SGIs that used for secure interrupt
  plat: imx8mm: Add the support for opteed spd on imx8mq/imx8mm
diff --git a/Makefile b/Makefile
index 721246d..42fdb73 100644
--- a/Makefile
+++ b/Makefile
@@ -150,6 +150,15 @@
 endif
 endif
 
+# USE_DEBUGFS experimental feature recommended only in debug builds
+ifeq (${USE_DEBUGFS},1)
+ifeq (${DEBUG},1)
+        $(warning DEBUGFS experimental feature is enabled.)
+else
+        $(warning DEBUGFS experimental, recommended in DEBUG builds ONLY)
+endif
+endif
+
 ################################################################################
 # Toolchain
 ################################################################################
@@ -204,6 +213,18 @@
 AS			=	$(CC) -c -x assembler-with-cpp $(TF_CFLAGS_$(ARCH))
 CPP			=	$(CC) -E
 PP			=	$(CC) -E
+else ifneq ($(findstring gcc,$(notdir $(CC))),)
+TF_CFLAGS_aarch32	=	$(march32-directive)
+TF_CFLAGS_aarch64	=	$(march64-directive)
+ifeq ($(ENABLE_LTO),1)
+	# Enable LTO only for aarch64
+	ifeq (${ARCH},aarch64)
+		LTO_CFLAGS	=	-flto
+		# Use gcc as a wrapper for the ld, recommended for LTO
+		LINKER		:=	${CROSS_COMPILE}gcc
+	endif
+endif
+LD			=	$(LINKER)
 else
 TF_CFLAGS_aarch32	=	$(march32-directive)
 TF_CFLAGS_aarch64	=	$(march64-directive)
@@ -228,64 +249,63 @@
 ASFLAGS_aarch32		=	$(march32-directive)
 ASFLAGS_aarch64		=	$(march64-directive)
 
+# General warnings
+WARNINGS		:=	-Wall -Wmissing-include-dirs -Wunused	\
+				-Wdisabled-optimization	-Wvla -Wshadow	\
+				-Wno-unused-parameter
+
+# Additional warnings
+# Level 1
 WARNING1 := -Wextra
-WARNING1 += -Wmissing-declarations
 WARNING1 += -Wmissing-format-attribute
 WARNING1 += -Wmissing-prototypes
 WARNING1 += -Wold-style-definition
-WARNING1 += -Wunused-const-variable
 
+# Level 2
 WARNING2 := -Waggregate-return
 WARNING2 += -Wcast-align
 WARNING2 += -Wnested-externs
-WARNING2 += -Wshadow
-WARNING2 += -Wlogical-op
-WARNING2 += -Wmissing-field-initializers
-WARNING2 += -Wsign-compare
 
 WARNING3 := -Wbad-function-cast
 WARNING3 += -Wcast-qual
 WARNING3 += -Wconversion
 WARNING3 += -Wpacked
-WARNING3 += -Wpadded
 WARNING3 += -Wpointer-arith
 WARNING3 += -Wredundant-decls
 WARNING3 += -Wswitch-default
 
 ifeq (${W},1)
-WARNINGS := $(WARNING1)
+WARNINGS += $(WARNING1)
 else ifeq (${W},2)
-WARNINGS := $(WARNING1) $(WARNING2)
+WARNINGS += $(WARNING1) $(WARNING2)
 else ifeq (${W},3)
-WARNINGS := $(WARNING1) $(WARNING2) $(WARNING3)
+WARNINGS += $(WARNING1) $(WARNING2) $(WARNING3)
 endif
 
-WARNINGS	+=		-Wunused -Wno-unused-parameter	\
-				-Wdisabled-optimization		\
-				-Wvla
-
+# Compiler specific warnings
 ifeq ($(findstring clang,$(notdir $(CC))),)
 # not using clang
-WARNINGS	+=		-Wunused-but-set-variable	\
-				-Wmaybe-uninitialized		\
-				-Wpacked-bitfield-compat	\
-				-Wshift-overflow=2
+WARNINGS	+=		-Wunused-but-set-variable -Wmaybe-uninitialized	\
+				-Wpacked-bitfield-compat -Wshift-overflow=2 \
+				-Wlogical-op
 else
 # using clang
-WARNINGS	+=		-Wshift-overflow -Wshift-sign-overflow
+WARNINGS	+=		-Wshift-overflow -Wshift-sign-overflow \
+				-Wlogical-op-parentheses
 endif
 
 ifneq (${E},0)
 ERRORS := -Werror
 endif
 
-CPPFLAGS		=	${DEFINES} ${INCLUDES} ${MBEDTLS_INC} -nostdinc		\
-				-Wmissing-include-dirs $(ERRORS) $(WARNINGS)
+CPPFLAGS		=	${DEFINES} ${INCLUDES} ${MBEDTLS_INC} -nostdinc	\
+				$(ERRORS) $(WARNINGS)
 ASFLAGS			+=	$(CPPFLAGS) $(ASFLAGS_$(ARCH))			\
 				-ffreestanding -Wa,--fatal-warnings
 TF_CFLAGS		+=	$(CPPFLAGS) $(TF_CFLAGS_$(ARCH))		\
-				-ffreestanding -fno-builtin -Wall -std=gnu99	\
-				-Os -ffunction-sections -fdata-sections
+				-ffunction-sections -fdata-sections		\
+				-ffreestanding -fno-builtin -fno-common		\
+				-Os -std=gnu99
 
 ifeq (${SANITIZE_UB},on)
 TF_CFLAGS		+=	-fsanitize=undefined -fno-sanitize-recover
@@ -300,11 +320,28 @@
 ifneq ($(findstring armlink,$(notdir $(LD))),)
 TF_LDFLAGS		+=	--diag_error=warning --lto_level=O1
 TF_LDFLAGS		+=	--remove --info=unused,unusedsymbols
+TF_LDFLAGS		+=	$(TF_LDFLAGS_$(ARCH))
+else ifneq ($(findstring gcc,$(notdir $(LD))),)
+# Pass ld options with Wl or Xlinker switches
+TF_LDFLAGS		+=	-Wl,--fatal-warnings -O1
+TF_LDFLAGS		+=	-Wl,--gc-sections
+ifeq ($(ENABLE_LTO),1)
+	ifeq (${ARCH},aarch64)
+		TF_LDFLAGS	+=	-flto -fuse-linker-plugin
+	endif
+endif
+# GCC automatically adds fix-cortex-a53-843419 flag when used to link
+# which breaks some builds, so disable if errata fix is not explicitly enabled
+ifneq (${ERRATA_A53_843419},1)
+	TF_LDFLAGS	+= 	-mno-fix-cortex-a53-843419
+endif
+TF_LDFLAGS		+= 	-nostdlib
+TF_LDFLAGS		+=	$(subst --,-Xlinker --,$(TF_LDFLAGS_$(ARCH)))
 else
 TF_LDFLAGS		+=	--fatal-warnings -O1
 TF_LDFLAGS		+=	--gc-sections
-endif
 TF_LDFLAGS		+=	$(TF_LDFLAGS_$(ARCH))
+endif
 
 DTC_FLAGS		+=	-I dts -O dtb
 DTC_CPPFLAGS		+=	-nostdinc -Iinclude -undef -x assembler-with-cpp
@@ -405,7 +442,11 @@
 
 ifeq ($(ENABLE_PIE),1)
     TF_CFLAGS		+=	-fpie
-    TF_LDFLAGS		+=	-pie --no-dynamic-linker
+	ifneq ($(findstring gcc,$(notdir $(LD))),)
+		TF_LDFLAGS	+=	-Wl,-pie -Wl,--no-dynamic-linker
+	else
+		TF_LDFLAGS	+=	-pie --no-dynamic-linker
+	endif
 else
     PIE_FOUND		:=	$(findstring --enable-default-pie,${GCC_V_OUTPUT})
     ifneq ($(PIE_FOUND),)
@@ -623,6 +664,13 @@
 # Variables for use with ROMLIB
 ROMLIBPATH		?=	lib/romlib
 
+# Variable for use with Python
+PYTHON			?=	python3
+
+# Variables for use with PRINT_MEMORY_MAP
+PRINT_MEMORY_MAP_PATH		?=	tools/memory
+PRINT_MEMORY_MAP		?=	${PRINT_MEMORY_MAP_PATH}/print_memory_map.py
+
 ################################################################################
 # Include BL specific makefiles
 ################################################################################
@@ -672,7 +720,6 @@
 $(eval $(call assert_boolean,ENABLE_PSCI_STAT))
 $(eval $(call assert_boolean,ENABLE_RUNTIME_INSTRUMENTATION))
 $(eval $(call assert_boolean,ENABLE_SPE_FOR_LOWER_ELS))
-$(eval $(call assert_boolean,ENABLE_SPM))
 $(eval $(call assert_boolean,ENABLE_SVE_FOR_NS))
 $(eval $(call assert_boolean,ERROR_DEPRECATED))
 $(eval $(call assert_boolean,FAULT_INJECTION_SUPPORT))
@@ -689,10 +736,12 @@
 $(eval $(call assert_boolean,RESET_TO_BL31))
 $(eval $(call assert_boolean,SAVE_KEYS))
 $(eval $(call assert_boolean,SEPARATE_CODE_AND_RODATA))
+$(eval $(call assert_boolean,SEPARATE_NOBITS_REGION))
 $(eval $(call assert_boolean,SPIN_ON_BL1_EXIT))
 $(eval $(call assert_boolean,SPM_MM))
 $(eval $(call assert_boolean,TRUSTED_BOARD_BOOT))
 $(eval $(call assert_boolean,USE_COHERENT_MEM))
+$(eval $(call assert_boolean,USE_DEBUGFS))
 $(eval $(call assert_boolean,USE_ROMLIB))
 $(eval $(call assert_boolean,USE_TBBR_DEFS))
 $(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY))
@@ -737,7 +786,6 @@
 $(eval $(call add_define,ENABLE_PSCI_STAT))
 $(eval $(call add_define,ENABLE_RUNTIME_INSTRUMENTATION))
 $(eval $(call add_define,ENABLE_SPE_FOR_LOWER_ELS))
-$(eval $(call add_define,ENABLE_SPM))
 $(eval $(call add_define,ENABLE_SVE_FOR_NS))
 $(eval $(call add_define,ERROR_DEPRECATED))
 $(eval $(call add_define,FAULT_INJECTION_SUPPORT))
@@ -753,12 +801,14 @@
 $(eval $(call add_define,RAS_EXTENSION))
 $(eval $(call add_define,RESET_TO_BL31))
 $(eval $(call add_define,SEPARATE_CODE_AND_RODATA))
+$(eval $(call add_define,SEPARATE_NOBITS_REGION))
 $(eval $(call add_define,RECLAIM_INIT_CODE))
 $(eval $(call add_define,SPD_${SPD}))
 $(eval $(call add_define,SPIN_ON_BL1_EXIT))
 $(eval $(call add_define,SPM_MM))
 $(eval $(call add_define,TRUSTED_BOARD_BOOT))
 $(eval $(call add_define,USE_COHERENT_MEM))
+$(eval $(call add_define,USE_DEBUGFS))
 $(eval $(call add_define,USE_ROMLIB))
 $(eval $(call add_define,USE_TBBR_DEFS))
 $(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY))
@@ -795,7 +845,7 @@
 # Build targets
 ################################################################################
 
-.PHONY:	all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch fiptool sptool fip fwu_fip certtool dtbs
+.PHONY:	all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch fiptool sptool fip fwu_fip certtool dtbs memmap
 .SUFFIXES:
 
 all: msg_start
@@ -989,6 +1039,10 @@
 romlib.bin: libraries
 	${Q}${MAKE} PLAT_DIR=${PLAT_DIR} BUILD_PLAT=${BUILD_PLAT} ENABLE_BTI=${ENABLE_BTI} ARM_ARCH_MINOR=${ARM_ARCH_MINOR} INCLUDES='${INCLUDES}' DEFINES='${DEFINES}' --no-print-directory -C ${ROMLIBPATH} all
 
+# Call print_memory_map tool
+memmap: all
+	${Q}${PYTHON} $(PRINT_MEMORY_MAP) $(BUILD_PLAT)
+
 cscope:
 	@echo "  CSCOPE"
 	${Q}find ${CURDIR} -name "*.[chsS]" > cscope.files
@@ -1028,6 +1082,7 @@
 	@echo "  fiptool        Build the Firmware Image Package (FIP) creation tool"
 	@echo "  sptool         Build the Secure Partition Package creation tool"
 	@echo "  dtbs           Build the Device Tree Blobs (if required for the platform)"
+	@echo "  memmap         Print the memory map of the built binaries"
 	@echo ""
 	@echo "Note: most build targets require PLAT to be set to a specific platform."
 	@echo ""
diff --git a/bl1/aarch64/bl1_entrypoint.S b/bl1/aarch64/bl1_entrypoint.S
index 855add3..00f2718 100644
--- a/bl1/aarch64/bl1_entrypoint.S
+++ b/bl1/aarch64/bl1_entrypoint.S
@@ -30,7 +30,8 @@
 		_secondary_cold_boot=!COLD_BOOT_SINGLE_CPU	\
 		_init_memory=1					\
 		_init_c_runtime=1				\
-		_exception_vectors=bl1_exceptions
+		_exception_vectors=bl1_exceptions		\
+		_pie_fixup_size=0
 
 	/* --------------------------------------------------------------------
 	 * Perform BL1 setup
diff --git a/bl1/bl1.ld.S b/bl1/bl1.ld.S
index c4f6b99..877af8e 100644
--- a/bl1/bl1.ld.S
+++ b/bl1/bl1.ld.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,7 +27,7 @@
     .text . : {
         __TEXT_START__ = .;
         *bl1_entrypoint.o(.text*)
-        *(.text*)
+        *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
         . = ALIGN(PAGE_SIZE);
         __TEXT_END__ = .;
@@ -44,7 +44,7 @@
 
     .rodata . : {
         __RODATA_START__ = .;
-        *(.rodata*)
+        *(SORT_BY_ALIGNMENT(.rodata*))
 
         /* Ensure 8-byte alignment for descriptors and ensure inclusion */
         . = ALIGN(8);
@@ -72,8 +72,8 @@
     ro . : {
         __RO_START__ = .;
         *bl1_entrypoint.o(.text*)
-        *(.text*)
-        *(.rodata*)
+        *(SORT_BY_ALIGNMENT(.text*))
+        *(SORT_BY_ALIGNMENT(.rodata*))
 
         /* Ensure 8-byte alignment for descriptors and ensure inclusion */
         . = ALIGN(8);
@@ -114,7 +114,7 @@
      */
     .data . : ALIGN(16) {
         __DATA_RAM_START__ = .;
-        *(.data*)
+        *(SORT_BY_ALIGNMENT(.data*))
         __DATA_RAM_END__ = .;
     } >RAM AT>ROM
 
@@ -131,7 +131,7 @@
      */
     .bss : ALIGN(16) {
         __BSS_START__ = .;
-        *(.bss*)
+        *(SORT_BY_ALIGNMENT(.bss*))
         *(COMMON)
         __BSS_END__ = .;
     } >RAM
diff --git a/bl2/aarch64/bl2_el3_entrypoint.S b/bl2/aarch64/bl2_el3_entrypoint.S
index 6fe2dd9..f97121e 100644
--- a/bl2/aarch64/bl2_el3_entrypoint.S
+++ b/bl2/aarch64/bl2_el3_entrypoint.S
@@ -26,7 +26,8 @@
 		_secondary_cold_boot=!COLD_BOOT_SINGLE_CPU      \
 		_init_memory=1                                  \
 		_init_c_runtime=1                               \
-		_exception_vectors=bl2_el3_exceptions
+		_exception_vectors=bl2_el3_exceptions		\
+		_pie_fixup_size=0
 
 	/* ---------------------------------------------
 	 * Restore parameters of boot rom
diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S
index 30cdf7d..6230562 100644
--- a/bl2/bl2.ld.S
+++ b/bl2/bl2.ld.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,7 +27,7 @@
     .text . : {
         __TEXT_START__ = .;
         *bl2_entrypoint.o(.text*)
-        *(.text*)
+        *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
         . = ALIGN(PAGE_SIZE);
         __TEXT_END__ = .;
@@ -44,7 +44,7 @@
 
     .rodata . : {
         __RODATA_START__ = .;
-        *(.rodata*)
+        *(SORT_BY_ALIGNMENT(.rodata*))
 
         /* Ensure 8-byte alignment for descriptors and ensure inclusion */
         . = ALIGN(8);
@@ -59,8 +59,8 @@
     ro . : {
         __RO_START__ = .;
         *bl2_entrypoint.o(.text*)
-        *(.text*)
-        *(.rodata*)
+        *(SORT_BY_ALIGNMENT(.text*))
+        *(SORT_BY_ALIGNMENT(.rodata*))
 
         /* Ensure 8-byte alignment for descriptors and ensure inclusion */
         . = ALIGN(8);
@@ -93,7 +93,7 @@
      */
     .data . : {
         __DATA_START__ = .;
-        *(.data*)
+        *(SORT_BY_ALIGNMENT(.data*))
         __DATA_END__ = .;
     } >RAM
 
diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S
index 82b51a8..dc398eb 100644
--- a/bl2/bl2_el3.ld.S
+++ b/bl2/bl2_el3.ld.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
  */
@@ -44,7 +44,7 @@
 	*bl2_el3_entrypoint.o(.text*)
 	*(.text.asm.*)
 	__TEXT_RESIDENT_END__ = .;
-        *(.text*)
+        *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
         . = ALIGN(PAGE_SIZE);
         __TEXT_END__ = .;
@@ -52,7 +52,7 @@
 
     .rodata . : {
         __RODATA_START__ = .;
-        *(.rodata*)
+        *(SORT_BY_ALIGNMENT(.rodata*))
 
         /* Ensure 8-byte alignment for descriptors and ensure inclusion */
         . = ALIGN(8);
@@ -82,8 +82,8 @@
 	*bl2_el3_entrypoint.o(.text*)
 	*(.text.asm.*)
 	__TEXT_RESIDENT_END__ = .;
-        *(.text*)
-        *(.rodata*)
+        *(SORT_BY_ALIGNMENT(.text*))
+        *(SORT_BY_ALIGNMENT(.rodata*))
 
         /*
          * Ensure 8-byte alignment for cpu_ops so that its fields are also
@@ -135,7 +135,7 @@
      */
     .data . : {
         __DATA_RAM_START__ = .;
-        *(.data*)
+        *(SORT_BY_ALIGNMENT(.data*))
         __DATA_RAM_END__ = .;
     } >RAM AT>ROM
 
diff --git a/bl2u/bl2u.ld.S b/bl2u/bl2u.ld.S
index 8d4984f..8d257ce 100644
--- a/bl2u/bl2u.ld.S
+++ b/bl2u/bl2u.ld.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,7 +27,7 @@
     .text . : {
         __TEXT_START__ = .;
         *bl2u_entrypoint.o(.text*)
-        *(.text*)
+        *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
         . = ALIGN(PAGE_SIZE);
         __TEXT_END__ = .;
@@ -44,7 +44,7 @@
 
     .rodata . : {
         __RODATA_START__ = .;
-        *(.rodata*)
+        *(SORT_BY_ALIGNMENT(.rodata*))
         . = ALIGN(PAGE_SIZE);
         __RODATA_END__ = .;
     } >RAM
@@ -52,8 +52,8 @@
     ro . : {
         __RO_START__ = .;
         *bl2u_entrypoint.o(.text*)
-        *(.text*)
-        *(.rodata*)
+        *(SORT_BY_ALIGNMENT(.text*))
+        *(SORT_BY_ALIGNMENT(.rodata*))
 
         *(.vectors)
         __RO_END_UNALIGNED__ = .;
@@ -80,7 +80,7 @@
      */
     .data . : {
         __DATA_START__ = .;
-        *(.data*)
+        *(SORT_BY_ALIGNMENT(.data*))
         __DATA_END__ = .;
     } >RAM
 
diff --git a/bl31/aarch64/bl31_entrypoint.S b/bl31/aarch64/bl31_entrypoint.S
index 1ad26e4..665a05e 100644
--- a/bl31/aarch64/bl31_entrypoint.S
+++ b/bl31/aarch64/bl31_entrypoint.S
@@ -9,7 +9,7 @@
 #include <arch.h>
 #include <common/bl_common.h>
 #include <el3_common_macros.S>
-#include <lib/pmf/pmf_asm_macros.S>
+#include <lib/pmf/aarch64/pmf_asm_macros.S>
 #include <lib/runtime_instr.h>
 #include <lib/xlat_tables/xlat_mmu_helpers.h>
 
@@ -32,17 +32,6 @@
 	mov	x22, x2
 	mov	x23, x3
 
-	/* --------------------------------------------------------------------
-	 * If PIE is enabled, fixup the Global descriptor Table and dynamic
-	 * relocations
-	 * --------------------------------------------------------------------
-	 */
-#if ENABLE_PIE
-	mov_imm	x0, BL31_BASE
-	mov_imm	x1, BL31_LIMIT
-	bl	fixup_gdt_reloc
-#endif /* ENABLE_PIE */
-
 #if !RESET_TO_BL31
 	/* ---------------------------------------------------------------------
 	 * For !RESET_TO_BL31 systems, only the primary CPU ever reaches
@@ -59,7 +48,8 @@
 		_secondary_cold_boot=0				\
 		_init_memory=0					\
 		_init_c_runtime=1				\
-		_exception_vectors=runtime_exceptions
+		_exception_vectors=runtime_exceptions		\
+		_pie_fixup_size=BL31_LIMIT - BL31_BASE
 #else
 
 	/* ---------------------------------------------------------------------
@@ -74,7 +64,8 @@
 		_secondary_cold_boot=!COLD_BOOT_SINGLE_CPU	\
 		_init_memory=1					\
 		_init_c_runtime=1				\
-		_exception_vectors=runtime_exceptions
+		_exception_vectors=runtime_exceptions		\
+		_pie_fixup_size=BL31_LIMIT - BL31_BASE
 
 	/* ---------------------------------------------------------------------
 	 * For RESET_TO_BL31 systems, BL31 is the first bootloader to run so
@@ -174,7 +165,8 @@
 		_secondary_cold_boot=0				\
 		_init_memory=0					\
 		_init_c_runtime=0				\
-		_exception_vectors=runtime_exceptions
+		_exception_vectors=runtime_exceptions		\
+		_pie_fixup_size=0
 
 	/*
 	 * We're about to enable MMU and participate in PSCI state coordination.
diff --git a/bl31/aarch64/ea_delegate.S b/bl31/aarch64/ea_delegate.S
index 3cc4d56..1d28d5e 100644
--- a/bl31/aarch64/ea_delegate.S
+++ b/bl31/aarch64/ea_delegate.S
@@ -102,9 +102,11 @@
 	/* Setup exception class and syndrome arguments for platform handler */
 	mov	x0, #ERROR_EA_SYNC
 	mrs	x1, esr_el3
-	adr	x30, el3_exit
-	b	delegate_sync_ea
+	bl	delegate_sync_ea
 
+	/* el3_exit assumes SP_EL0 on entry */
+	msr	spsel, #MODE_SP_EL0
+	b	el3_exit
 2:
 	ldp	x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
 	ldp	x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
@@ -146,8 +148,11 @@
 	/* Setup exception class and syndrome arguments for platform handler */
 	mov	x0, #ERROR_EA_ASYNC
 	mrs	x1, esr_el3
-	adr	x30, el3_exit
-	b	delegate_async_ea
+	bl	delegate_async_ea
+
+	/* el3_exit assumes SP_EL0 on entry */
+	msr	spsel, #MODE_SP_EL0
+	b	el3_exit
 endfunc enter_lower_el_async_ea
 
 
diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S
index c7d587c..42227f0 100644
--- a/bl31/bl31.ld.S
+++ b/bl31/bl31.ld.S
@@ -15,6 +15,11 @@
 
 MEMORY {
     RAM (rwx): ORIGIN = BL31_BASE, LENGTH = BL31_LIMIT - BL31_BASE
+#if SEPARATE_NOBITS_REGION
+    NOBITS (rw!a): ORIGIN = BL31_NOBITS_BASE, LENGTH = BL31_NOBITS_LIMIT - BL31_NOBITS_BASE
+#else
+#define NOBITS RAM
+#endif
 }
 
 #ifdef PLAT_EXTRA_LD_SCRIPT
@@ -33,7 +38,7 @@
     .text . : {
         __TEXT_START__ = .;
         *bl31_entrypoint.o(.text*)
-        *(.text*)
+        *(SORT_BY_ALIGNMENT(.text*))
         *(.vectors)
         . = ALIGN(PAGE_SIZE);
         __TEXT_END__ = .;
@@ -41,7 +46,7 @@
 
     .rodata . : {
         __RODATA_START__ = .;
-        *(.rodata*)
+        *(SORT_BY_ALIGNMENT(.rodata*))
 
         /* Ensure 8-byte alignment for descriptors and ensure inclusion */
         . = ALIGN(8);
@@ -87,8 +92,8 @@
     ro . : {
         __RO_START__ = .;
         *bl31_entrypoint.o(.text*)
-        *(.text*)
-        *(.rodata*)
+        *(SORT_BY_ALIGNMENT(.text*))
+        *(SORT_BY_ALIGNMENT(.rodata*))
 
         /* Ensure 8-byte alignment for descriptors and ensure inclusion */
         . = ALIGN(8);
@@ -142,7 +147,7 @@
     ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
            "cpu_ops not defined for this platform.")
 
-#if ENABLE_SPM
+#if SPM_MM
 #ifndef SPM_SHIM_EXCEPTIONS_VMA
 #define SPM_SHIM_EXCEPTIONS_VMA         RAM
 #endif
@@ -179,7 +184,7 @@
      */
    .data . : {
         __DATA_START__ = .;
-        *(.data*)
+        *(SORT_BY_ALIGNMENT(.data*))
         __DATA_END__ = .;
     } >RAM
 
@@ -198,11 +203,28 @@
     ASSERT(. <= BL31_PROGBITS_LIMIT, "BL31 progbits has exceeded its limit.")
 #endif
 
+#if SEPARATE_NOBITS_REGION
+    /*
+     * Define a linker symbol to mark end of the RW memory area for this
+     * image.
+     */
+    __RW_END__ = .;
+    __BL31_END__ = .;
+
+    ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.")
+
+    . = BL31_NOBITS_BASE;
+    ASSERT(. == ALIGN(PAGE_SIZE),
+           "BL31 NOBITS base address is not aligned on a page boundary.")
+
+    __NOBITS_START__ = .;
+#endif
+
     stacks (NOLOAD) : {
         __STACKS_START__ = .;
         *(tzfw_normal_stacks)
         __STACKS_END__ = .;
-    } >RAM
+    } >NOBITS
 
     /*
      * The .bss section gets initialised to 0 at runtime.
@@ -211,7 +233,7 @@
      */
     .bss (NOLOAD) : ALIGN(16) {
         __BSS_START__ = .;
-        *(.bss*)
+        *(SORT_BY_ALIGNMENT(.bss*))
         *(COMMON)
 #if !USE_COHERENT_MEM
         /*
@@ -262,7 +284,7 @@
         __PMF_TIMESTAMP_END__ = .;
 #endif /* ENABLE_PMF */
         __BSS_END__ = .;
-    } >RAM
+    } >NOBITS
 
     /*
      * The xlat_table section is for full, aligned page tables (4K).
@@ -272,7 +294,7 @@
      */
     xlat_table (NOLOAD) : {
         *(xlat_table)
-    } >RAM
+    } >NOBITS
 
 #if USE_COHERENT_MEM
     /*
@@ -298,9 +320,18 @@
          */
         . = ALIGN(PAGE_SIZE);
         __COHERENT_RAM_END__ = .;
-    } >RAM
+    } >NOBITS
 #endif
 
+#if SEPARATE_NOBITS_REGION
+    /*
+     * Define a linker symbol to mark end of the NOBITS memory area for this
+     * image.
+     */
+    __NOBITS_END__ = .;
+
+    ASSERT(. <= BL31_NOBITS_LIMIT, "BL31 NOBITS region has exceeded its limit.")
+#else
     /*
      * Define a linker symbol to mark end of the RW memory area for this
      * image.
@@ -309,4 +340,5 @@
     __BL31_END__ = .;
 
     ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.")
+#endif
 }
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index c9ba926..58909e8 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -5,22 +5,17 @@
 #
 
 ################################################################################
-# Include SPM Makefile
+# Include Makefile for the SPM-MM implementation
 ################################################################################
-ifeq (${ENABLE_SPM},1)
-  ifeq (${SPM_MM},1)
-    ifeq (${EL3_EXCEPTION_HANDLING},0)
-      $(error EL3_EXCEPTION_HANDLING must be 1 for SPM support)
-    endif
-    $(info Including makefile of SPM based on MM)
-    include services/std_svc/spm_mm/spm.mk
+ifeq (${SPM_MM},1)
+  ifeq (${EL3_EXCEPTION_HANDLING},0)
+    $(error EL3_EXCEPTION_HANDLING must be 1 for SPM-MM support)
   else
-    $(info Including SPM makefile)
-    include services/std_svc/spm/spm.mk
+    $(info Including SPM Management Mode (MM) makefile)
+    include services/std_svc/spm_mm/spm_mm.mk
   endif
 endif
 
-
 include lib/psci/psci_lib.mk
 
 BL31_SOURCES		+=	bl31/bl31_main.c				\
@@ -43,6 +38,11 @@
 BL31_SOURCES		+=	lib/pmf/pmf_main.c
 endif
 
+include lib/debugfs/debugfs.mk
+ifeq (${USE_DEBUGFS},1)
+	BL31_SOURCES	+= $(DEBUGFS_SRCS)
+endif
+
 ifeq (${EL3_EXCEPTION_HANDLING},1)
 BL31_SOURCES		+=	bl31/ehf.c
 endif
diff --git a/bl32/sp_min/aarch32/entrypoint.S b/bl32/sp_min/aarch32/entrypoint.S
index 0a68475..f3a1e44 100644
--- a/bl32/sp_min/aarch32/entrypoint.S
+++ b/bl32/sp_min/aarch32/entrypoint.S
@@ -10,6 +10,9 @@
 #include <common/runtime_svc.h>
 #include <context.h>
 #include <el3_common_macros.S>
+#include <lib/el3_runtime/cpu_data.h>
+#include <lib/pmf/aarch32/pmf_asm_macros.S>
+#include <lib/runtime_instr.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
 #include <smccc_helpers.h>
 #include <smccc_macros.S>
@@ -164,6 +167,20 @@
 	/* On SMC entry, `sp` points to `smc_ctx_t`. Save `lr`. */
 	str	lr, [sp, #SMC_CTX_LR_MON]
 
+#if ENABLE_RUNTIME_INSTRUMENTATION
+	/*
+	 * Read the timestamp value and store it on top of the C runtime stack.
+	 * The value will be saved to the per-cpu data once the C stack is
+	 * available, as a valid stack is needed to call _cpu_data()
+	 */
+	strd	r0, r1, [sp, #SMC_CTX_GPREG_R0]
+	ldcopr16 r0, r1, CNTPCT_64
+	ldr	lr, [sp, #SMC_CTX_SP_MON]
+	strd	r0, r1, [lr, #-8]!
+	str	lr, [sp, #SMC_CTX_SP_MON]
+	ldrd	r0, r1, [sp, #SMC_CTX_GPREG_R0]
+#endif
+
 	smccc_save_gp_mode_regs
 
 	clrex_on_monitor_entry
@@ -175,6 +192,23 @@
 	mov	r2, sp				/* handle */
 	ldr	sp, [r2, #SMC_CTX_SP_MON]
 
+#if ENABLE_RUNTIME_INSTRUMENTATION
+	/* Save handle to a callee saved register */
+	mov	r6, r2
+
+	/*
+	 * Restore the timestamp value and store it in per-cpu data. The value
+	 * will be extracted from per-cpu data by the C level SMC handler and
+	 * saved to the PMF timestamp region.
+	 */
+	ldrd	r4, r5, [sp], #8
+	bl	_cpu_data
+	strd	r4, r5, [r0, #CPU_DATA_PMF_TS0_OFFSET]
+
+	/* Restore handle */
+	mov	r2, r6
+#endif
+
 	ldr	r0, [r2, #SMC_CTX_SCR]
 	and	r3, r0, #SCR_NS_BIT		/* flags */
 
@@ -239,6 +273,16 @@
  * The Warm boot entrypoint for SP_MIN.
  */
 func sp_min_warm_entrypoint
+#if ENABLE_RUNTIME_INSTRUMENTATION
+	/*
+	 * This timestamp update happens with cache off.  The next
+	 * timestamp collection will need to do cache maintenance prior
+	 * to timestamp update.
+	 */
+	pmf_calc_timestamp_addr rt_instr_svc, RT_INSTR_EXIT_HW_LOW_PWR
+	ldcopr16 r2, r3, CNTPCT_64
+	strd	r2, r3, [r0]
+#endif
 	/*
 	 * On the warm boot path, most of the EL3 initialisations performed by
 	 * 'el3_entrypoint_common' must be skipped:
@@ -295,6 +339,30 @@
 	bl	smc_get_next_ctx
 	/* r0 points to `smc_ctx_t` */
 	/* The PSCI cpu_context registers have been copied to `smc_ctx_t` */
+
+#if ENABLE_RUNTIME_INSTRUMENTATION
+	/* Save smc_ctx_t */
+	mov	r5, r0
+
+	pmf_calc_timestamp_addr rt_instr_svc, RT_INSTR_EXIT_PSCI
+	mov	r4, r0
+
+	/*
+	 * Invalidate before updating timestamp to ensure previous timestamp
+	 * updates on the same cache line with caches disabled are properly
+	 * seen by the same core. Without the cache invalidate, the core might
+	 * write into a stale cache line.
+	 */
+	mov	r1, #PMF_TS_SIZE
+	bl	inv_dcache_range
+
+	ldcopr16 r0, r1, CNTPCT_64
+	strd	r0, r1, [r4]
+
+	/* Restore smc_ctx_t */
+	mov	r0, r5
+#endif
+
 	b	sp_min_exit
 endfunc sp_min_warm_entrypoint
 
diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S
index 4559903..6997a7f 100644
--- a/bl32/sp_min/sp_min.ld.S
+++ b/bl32/sp_min/sp_min.ld.S
@@ -55,6 +55,14 @@
         KEEP(*(rt_svc_descs))
         __RT_SVC_DESCS_END__ = .;
 
+#if ENABLE_PMF
+        /* Ensure 4-byte alignment for descriptors and ensure inclusion */
+        . = ALIGN(4);
+        __PMF_SVC_DESCS_START__ = .;
+        KEEP(*(pmf_svc_descs))
+        __PMF_SVC_DESCS_END__ = .;
+#endif /* ENABLE_PMF */
+
         /*
          * Ensure 4-byte alignment for cpu_ops so that its fields are also
          * aligned. Also ensure cpu_ops inclusion.
diff --git a/bl32/sp_min/sp_min_main.c b/bl32/sp_min/sp_min_main.c
index f39e33b..f050160 100644
--- a/bl32/sp_min/sp_min_main.c
+++ b/bl32/sp_min/sp_min_main.c
@@ -19,7 +19,9 @@
 #include <context.h>
 #include <drivers/console.h>
 #include <lib/el3_runtime/context_mgmt.h>
+#include <lib/pmf/pmf.h>
 #include <lib/psci/psci.h>
+#include <lib/runtime_instr.h>
 #include <lib/utils.h>
 #include <plat/common/platform.h>
 #include <platform_sp_min.h>
@@ -28,6 +30,11 @@
 
 #include "sp_min_private.h"
 
+#if ENABLE_RUNTIME_INSTRUMENTATION
+PMF_REGISTER_SERVICE_SMC(rt_instr_svc, PMF_RT_INSTR_SVC_ID,
+	RT_INSTR_TOTAL_IDS, PMF_STORE_ENABLE)
+#endif
+
 /* Pointers to per-core cpu contexts */
 static void *sp_min_cpu_ctx_ptr[PLATFORM_CORE_COUNT];
 
diff --git a/common/bl_common.c b/common/bl_common.c
index e6f9802..b74225b 100644
--- a/common/bl_common.c
+++ b/common/bl_common.c
@@ -143,26 +143,45 @@
 	return io_result;
 }
 
-static int load_auth_image_internal(unsigned int image_id,
-				    image_info_t *image_data,
-				    int is_parent_image)
+/*
+ * Load an image and flush it out to main memory so that it can be executed
+ * later by any CPU, regardless of cache and MMU state.
+ */
+static int load_image_flush(unsigned int image_id,
+			    image_info_t *image_data)
 {
 	int rc;
 
+	rc = load_image(image_id, image_data);
+	if (rc == 0) {
+		flush_dcache_range(image_data->image_base,
+				   image_data->image_size);
+	}
+
+	return rc;
+}
+
+
 #if TRUSTED_BOARD_BOOT
-	if (dyn_is_auth_disabled() == 0) {
-		unsigned int parent_id;
+/*
+ * This function uses recursion to authenticate the parent images up to the root
+ * of trust.
+ */
+static int load_auth_image_recursive(unsigned int image_id,
+				    image_info_t *image_data,
+				    int is_parent_image)
+{
+	int rc;
+	unsigned int parent_id;
 
-		/* Use recursion to authenticate parent images */
-		rc = auth_mod_get_parent_id(image_id, &parent_id);
-		if (rc == 0) {
-			rc = load_auth_image_internal(parent_id, image_data, 1);
-			if (rc != 0) {
-				return rc;
-			}
+	/* Use recursion to authenticate parent images */
+	rc = auth_mod_get_parent_id(image_id, &parent_id);
+	if (rc == 0) {
+		rc = load_auth_image_recursive(parent_id, image_data, 1);
+		if (rc != 0) {
+			return rc;
 		}
 	}
-#endif /* TRUSTED_BOARD_BOOT */
 
 	/* Load the image */
 	rc = load_image(image_id, image_data);
@@ -170,51 +189,58 @@
 		return rc;
 	}
 
-#if TRUSTED_BOARD_BOOT
-	if (dyn_is_auth_disabled() == 0) {
-		/* Authenticate it */
-		rc = auth_mod_verify_img(image_id,
-					 (void *)image_data->image_base,
-					 image_data->image_size);
-		if (rc != 0) {
-			/* Authentication error, zero memory and flush it right away. */
-			zero_normalmem((void *)image_data->image_base,
+	/* Authenticate it */
+	rc = auth_mod_verify_img(image_id,
+				 (void *)image_data->image_base,
+				 image_data->image_size);
+	if (rc != 0) {
+		/* Authentication error, zero memory and flush it right away. */
+		zero_normalmem((void *)image_data->image_base,
 			       image_data->image_size);
-			flush_dcache_range(image_data->image_base,
-					   image_data->image_size);
-			return -EAUTH;
-		}
+		flush_dcache_range(image_data->image_base,
+				   image_data->image_size);
+		return -EAUTH;
 	}
-#endif /* TRUSTED_BOARD_BOOT */
 
 	/*
 	 * Flush the image to main memory so that it can be executed later by
-	 * any CPU, regardless of cache and MMU state. If TBB is enabled, then
-	 * the file has been successfully loaded and authenticated and flush
-	 * only for child images, not for the parents (certificates).
+	 * any CPU, regardless of cache and MMU state. This is only needed for
+	 * child images, not for the parents (certificates).
 	 */
 	if (is_parent_image == 0) {
 		flush_dcache_range(image_data->image_base,
 				   image_data->image_size);
 	}
 
-
 	return 0;
 }
+#endif /* TRUSTED_BOARD_BOOT */
+
+static int load_auth_image_internal(unsigned int image_id,
+				    image_info_t *image_data)
+{
+#if TRUSTED_BOARD_BOOT
+	if (dyn_is_auth_disabled() == 0) {
+		return load_auth_image_recursive(image_id, image_data, 0);
+	}
+#endif
+
+	return load_image_flush(image_id, image_data);
+}
 
 /*******************************************************************************
  * Generic function to load and authenticate an image. The image is actually
  * loaded by calling the 'load_image()' function. Therefore, it returns the
  * same error codes if the loading operation failed, or -EAUTH if the
  * authentication failed. In addition, this function uses recursion to
- * authenticate the parent images up to the root of trust.
+ * authenticate the parent images up to the root of trust (if TBB is enabled).
  ******************************************************************************/
 int load_auth_image(unsigned int image_id, image_info_t *image_data)
 {
 	int err;
 
 	do {
-		err = load_auth_image_internal(image_id, image_data, 0);
+		err = load_auth_image_internal(image_id, image_data);
 	} while ((err != 0) && (plat_try_next_boot_source() != 0));
 
 	return err;
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 68f84ea..d9d7f84 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -17,10 +17,18 @@
 :G: `sandrine-bailleux-arm`_
 :M: Alexei Fedorov <alexei.fedorov@arm.com>
 :G: `AlexeiFedorov`_
-:M: Paul Beesley <paul.beesley@arm.com>
-:G: `pbeesley-arm`_
 :M: György Szing <gyorgy.szing@arm.com>
 :G: `gyuri-szing`_
+:M: Manish Pandey <manish.pandey2@arm.com>
+:G: `manish-pandey-arm`_
+:M: Mark Dykes <mark.dykes@arm.com>
+:G: `mardyk01`_
+:M: Olivier Deprez <olivier.deprez@arm.com>
+:G: `odeprez`_
+:M: Bipin Ravi <bipin.ravi@arm.com>
+:G: `bipinravi-arm`_
+:M: Joanna Farley <joanna.farley@arm.com>
+:G: `joannafarley-arm`_
 
 Allwinner ARMv8 platform port
 -----------------------------
@@ -300,7 +308,6 @@
 .. _mtk09422: https://github.com/mtk09422
 .. _niej: https://github.com/niej
 .. _npoushin: https://github.com/npoushin
-.. _pbeesley-arm: https://github.com/pbeesley-arm
 .. _qoriq-open-source: https://github.com/qoriq-open-source
 .. _remi-triplefault: https://github.com/repk
 .. _rockchip-linux: https://github.com/rockchip-linux
@@ -314,3 +321,8 @@
 .. _TonyXie06: https://github.com/TonyXie06
 .. _vwadekar: https://github.com/vwadekar
 .. _Yann-lms: https://github.com/Yann-lms
+.. _manish-pandey-arm: https://github.com/manish-pandey-arm
+.. _mardyk01: https://github.com/mardyk01
+.. _odeprez: https://github.com/odeprez
+.. _bipinravi-arm: https://github.com/bipinravi-arm
+.. _joannafarley-arm: https://github.com/joannafarley-arm
diff --git a/docs/change-log-upcoming.rst b/docs/change-log-upcoming.rst
new file mode 100644
index 0000000..3d7d509
--- /dev/null
+++ b/docs/change-log-upcoming.rst
@@ -0,0 +1,145 @@
+Change Log for Upcoming Release
+===============================
+
+This document contains a summary of the new features, changes, fixes and known
+issues to be included in the upcoming release of Trusted Firmware-A. The contents
+of this file will be moved to the collective change-log.rst file at the time of
+release code freeze.
+
+
+Upcoming Release Version 2.3
+----------------------------
+
+**Trusted Firmware-A Contributors,
+Please log all relevant new features, changes, fixes, and known issues for the
+upcoming release.  For the CPU support, drivers, and tools sections please preface
+the log description with the relevant key word, example: "<CPU>: <CPU Support
+addition>".  Use the RST format convention already used in the Change Log.**
+
+New Features
+^^^^^^^^^^^^
+
+- Arm Architecture
+   - Example: "Add support for Branch Target Identification (BTI)"
+
+- Build System
+   - Example: "Add support for default stack-protector flag"
+
+- CPU Support
+   - Example: "cortex-a55: Workaround for erratum 1221012"
+
+- Drivers
+   - Example: "console: Allow the console to register multiple times"
+
+- Libraries
+   - Example: "Introduce BTI support in Library at ROM (romlib)"
+
+- New Platforms Support
+   - Example: "qemu/qemu_sbsa: New platform support added for QEMU SBSA platform"
+
+- Platforms
+   - Example: "arm/common: Introduce wrapper functions to setup secure watchdog"
+
+- PSCI
+   - Example: "Adding new optional PSCI hook ``pwr_domain_on_finish_late``"
+
+- Security
+   - Example: "UBSAN support and handlers"
+
+- Tools
+   - Example: "fiptool: Add support to build fiptool on Windows."
+
+
+Changed
+^^^^^^^
+
+- Arm Architecture
+   - Example: "Refactor ARMv8.3 Pointer Authentication support code"
+
+- BL-Specific
+   - Example: "BL2: Invalidate dcache build option for BL2 entry at EL3"
+
+- Boot Flow
+   - Example: "Add helper to parse BL31 parameters (both versions)"
+
+- Drivers
+   - Example: "gicv3: Prevent pending G1S interrupt from becoming G0 interrupt"
+
+- Platforms
+   - Example: "arm/common: Shorten the Firmware Update (FWU) process"
+
+- PSCI
+   - Example: "PSCI: Lookup list of parent nodes to lock only once"
+
+- Secure Partition Manager (SPM)
+   - Example: "Move shim layer to TTBR1_EL1"
+
+- Security
+   - Example: "Refactor SPSR initialisation code"
+
+- Tools
+   - Example: "cert_create: Remove RSA PKCS#1 v1.5 support"
+
+
+Resolved Issues
+^^^^^^^^^^^^^^^
+
+- Arm Architecture
+   - Example: "Fix restoration of PAuth context"
+
+- BL-Specific
+   - Example: "Fix BL31 crash reporting on AArch64 only platforms"
+
+- Build System
+   - Example: "Remove several warnings reported with W=2 and W=1"
+
+- Code Quality
+   - Example: "Unify type of "cpu_idx" across PSCI module"
+
+- CPU Support
+   - Example: "cortex-a12: Fix MIDR mask"
+
+- Drivers
+   - Example: "scmi: Fix wrong payload length"
+
+- Library Code
+   - Example: "libc: Fix memchr implementation"
+
+- Platforms
+   - Example: "rpi: rpi3: Fix compilation error when stack protector is enabled"
+
+- Security
+   - Example: "AArch32: Disable Secure Cycle Counter"
+
+Deprecations
+^^^^^^^^^^^^
+
+- Common Code
+   - Example: "Remove MULTI_CONSOLE_API flag and references to it"
+
+- Drivers
+   - Example: "console: Remove deprecated finish_console_register"
+
+- Secure Partition Manager (SPM):
+   - Example: "Prototype SPCI-based SPM (services/std_svc/spm) will be replaced
+     with alternative methods of secure partitioning support."
+
+Known Issues
+^^^^^^^^^^^^
+
+- Build System
+   - dtb: DTB creation not supported when building on a Windows host.
+
+     This step in the build process is skipped when running on a Windows host. A
+     known issue from the 1.6 release.
+
+- Platforms
+   - arm/juno: System suspend from Linux does not function as documented in the
+     user guide
+
+     Following the instructions provided in the user guide document does not
+     result in the platform entering system suspend state as expected. A message
+     relating to the hdlcd driver failing to suspend will be emitted on the
+     Linux terminal.
+
+   - mediatek/mt6795: This platform does not build in this release
diff --git a/docs/change-log.rst b/docs/change-log.rst
index a0db2a9..cf5b57a 100644
--- a/docs/change-log.rst
+++ b/docs/change-log.rst
@@ -60,6 +60,10 @@
 
    - Neoverse Zeus: Apply the MSR SSBS instruction
 
+   - cortex-Hercules/HerculesAE: Support added for Cortex-Hercules and
+     Cortex-HerculesAE CPUs
+   - cortex-Hercules/HerculesAE: Enable AMU for Cortex-Hercules and Cortex-HerculesAE
+
    - cortex-a76AE: Support added for Cortex-A76AE CPU
    - cortex-a76: Workaround for erratum 1257314, 1262606, 1262888, 1275112,
      1286807
diff --git a/docs/components/arm-sip-service.rst b/docs/components/arm-sip-service.rst
index 2d58586..01bc04d 100644
--- a/docs/components/arm-sip-service.rst
+++ b/docs/components/arm-sip-service.rst
@@ -17,6 +17,7 @@
 
 -  Performance Measurement Framework (PMF)
 -  Execution State Switching service
+-  DebugFS interface
 
 Source definitions for Arm SiP service are located in the ``arm_sip_svc.h`` header
 file.
@@ -87,6 +88,346 @@
 and 1 populated with the supplied *Cookie hi* and *Cookie lo* values,
 respectively.
 
+DebugFS interface
+-----------------
+
+The optional DebugFS interface is accessed through an SMC SiP service. Refer
+to the component documentation for details.
+
+String parameters are passed through a shared buffer using a specific union:
+
+.. code:: c
+
+    union debugfs_parms {
+        struct {
+            char fname[MAX_PATH_LEN];
+        } open;
+
+        struct mount {
+            char srv[MAX_PATH_LEN];
+            char where[MAX_PATH_LEN];
+            char spec[MAX_PATH_LEN];
+        } mount;
+
+        struct {
+            char path[MAX_PATH_LEN];
+            dir_t dir;
+        } stat;
+
+        struct {
+            char oldpath[MAX_PATH_LEN];
+            char newpath[MAX_PATH_LEN];
+        } bind;
+    };
+
+Format of the dir_t structure as such:
+
+.. code:: c
+
+    typedef struct {
+        char		name[NAMELEN];
+        long		length;
+        unsigned char	mode;
+        unsigned char	index;
+        unsigned char	dev;
+        qid_t		qid;
+    } dir_t;
+
+
+* Identifiers
+
+======================== =============================================
+SMC_OK                   0
+SMC_UNK                  -1
+DEBUGFS_E_INVALID_PARAMS -2
+======================== =============================================
+
+======================== =============================================
+MOUNT                    0
+CREATE                   1
+OPEN                     2
+CLOSE                    3
+READ                     4
+WRITE                    5
+SEEK                     6
+BIND                     7
+STAT                     8
+INIT                     10
+VERSION                  11
+======================== =============================================
+
+MOUNT
+~~~~~
+
+Description
+^^^^^^^^^^^
+This operation mounts a blob of data pointed to by path stored in `src`, at
+filesystem location pointed to by path stored in `where`, using driver pointed
+to by path in `spec`.
+
+Parameters
+^^^^^^^^^^
+======== ============================================================
+uint32_t FunctionID (0x82000030 / 0xC2000030)
+uint32_t ``MOUNT``
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ==========================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == DEBUGFS_E_INVALID_PARAMS if mount operation failed
+=============== ==========================================================
+
+OPEN
+~~~~
+
+Description
+^^^^^^^^^^^
+This operation opens the file path pointed to by `fname`.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x82000030 / 0xC2000030)
+uint32_t ``OPEN``
+uint32_t mode
+======== ============================================================
+
+mode can be one of:
+
+.. code:: c
+
+    enum mode {
+        O_READ   = 1 << 0,
+        O_WRITE  = 1 << 1,
+        O_RDWR   = 1 << 2,
+        O_BIND   = 1 << 3,
+        O_DIR    = 1 << 4,
+        O_STAT   = 1 << 5
+    };
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ==========================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == DEBUGFS_E_INVALID_PARAMS if open operation failed
+
+uint32_t        w1: file descriptor id on success.
+=============== ==========================================================
+
+CLOSE
+~~~~~
+
+Description
+^^^^^^^^^^^
+
+This operation closes a file described by a file descriptor obtained by a
+previous call to OPEN.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x82000030 / 0xC2000030)
+uint32_t ``CLOSE``
+uint32_t File descriptor id returned by OPEN
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+=============== ==========================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == DEBUGFS_E_INVALID_PARAMS if close operation failed
+=============== ==========================================================
+
+READ
+~~~~
+
+Description
+^^^^^^^^^^^
+
+This operation reads a number of bytes from a file descriptor obtained by
+a previous call to OPEN.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x82000030 / 0xC2000030)
+uint32_t ``READ``
+uint32_t File descriptor id returned by OPEN
+uint32_t Number of bytes to read
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+On success, the read data is retrieved from the shared buffer after the
+operation.
+
+=============== ==========================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == DEBUGFS_E_INVALID_PARAMS if read operation failed
+
+uint32_t        w1: number of bytes read on success.
+=============== ==========================================================
+
+SEEK
+~~~~
+
+Description
+^^^^^^^^^^^
+
+Move file pointer for file described by given `file descriptor` of given
+`offset` related to `whence`.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x82000030 / 0xC2000030)
+uint32_t ``SEEK``
+uint32_t File descriptor id returned by OPEN
+sint32_t offset in the file relative to whence
+uint32_t whence
+======== ============================================================
+
+whence can be one of:
+
+========= ============================================================
+KSEEK_SET 0
+KSEEK_CUR 1
+KSEEK_END 2
+========= ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ==========================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == DEBUGFS_E_INVALID_PARAMS if seek operation failed
+=============== ==========================================================
+
+BIND
+~~~~
+
+Description
+^^^^^^^^^^^
+
+Create a link from `oldpath` to `newpath`.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x82000030 / 0xC2000030)
+uint32_t ``BIND``
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ==========================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == DEBUGFS_E_INVALID_PARAMS if bind operation failed
+=============== ==========================================================
+
+STAT
+~~~~
+
+Description
+^^^^^^^^^^^
+
+Perform a stat operation on provided file `name` and returns the directory
+entry statistics into `dir`.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x82000030 / 0xC2000030)
+uint32_t ``STAT``
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ==========================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == DEBUGFS_E_INVALID_PARAMS if stat operation failed
+=============== ==========================================================
+
+INIT
+~~~~
+
+Description
+^^^^^^^^^^^
+Initial call to setup the shared exchange buffer. Notice if successful once,
+subsequent calls fail after a first initialization. The caller maps the same
+page frame in its virtual space and uses this buffer to exchange string
+parameters with filesystem primitives.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x82000030 / 0xC2000030)
+uint32_t ``INIT``
+uint64_t Physical address of the shared buffer.
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ======================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == DEBUGFS_E_INVALID_PARAMS if already initialized,
+                or internal error occurred.
+=============== ======================================================
+
+VERSION
+~~~~~~~
+
+Description
+^^^^^^^^^^^
+Returns the debugfs interface version if implemented in TF-A.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x82000030 / 0xC2000030)
+uint32_t ``VERSION``
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ======================================================
+int32_t         w0 == SMC_OK on success
+
+                w0 == SMC_UNK if interface is not implemented
+
+uint32_t        w1: On success, debugfs interface version, 32 bits
+                value with major version number in upper 16 bits and
+                minor version in lower 16 bits.
+=============== ======================================================
+
+* CREATE(1) and WRITE (5) command identifiers are unimplemented and
+  return `SMC_UNK`.
+
 --------------
 
 *Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/components/debugfs-design.rst b/docs/components/debugfs-design.rst
new file mode 100644
index 0000000..06916f3
--- /dev/null
+++ b/docs/components/debugfs-design.rst
@@ -0,0 +1,132 @@
+========
+Debug FS
+========
+
+.. contents::
+
+Overview
+--------
+
+The *DebugFS* feature is primarily aimed at exposing firmware debug data to
+higher SW layers such as a non-secure component. Such component can be the
+TFTF test payload or a Linux kernel module.
+
+Virtual filesystem
+------------------
+
+The core functionality lies in a virtual file system based on a 9p file server
+interface (`Notes on the Plan 9 Kernel Source`_). The implementation permits
+exposing virtual files, firmware drivers, and file blobs.
+
+Namespace
+~~~~~~~~~
+
+Two namespaces are exposed:
+
+  - # is used as root for drivers (e.g. #t0 is the first uart)
+  - / is used as root for virtual "files" (e.g. /fip, or /dev/uart)
+
+9p interface
+~~~~~~~~~~~~
+
+The associated primitives are:
+
+- Unix-like:
+
+  - open(): create a file descriptor that acts as a handle to the file passed as
+    an argument.
+  - close(): close the file descriptor created by open().
+  - read(): read from a file to a buffer.
+  - write(): write from a buffer to a file.
+  - seek(): set the file position indicator of a file descriptor either to a
+    relative or an absolute offset.
+  - stat(): get information about a file (type, mode, size, ...).
+
+.. code:: c
+
+    int open(const char *name, int flags);
+    int close(int fd);
+    int read(int fd, void *buf, int n);
+    int write(int fd, void *buf, int n);
+    int seek(int fd, long off, int whence);
+    int stat(char *path, dir_t *dir);
+
+- Specific primitives :
+
+  - mount(): create a link between a driver and spec.
+  - create(): create a file in a specific location.
+  - bind(): expose the content of a directory to another directory.
+
+.. code:: c
+
+    int mount(char *srv, char *mnt, char *spec);
+    int create(const char *name, int flags);
+    int bind(char *path, char *where);
+
+This interface is embedded into the BL31 run-time payload when selected by build
+options. The interface multiplexes drivers or emulated "files":
+
+- Debug data can be partitioned into different virtual files e.g. expose PMF
+  measurements through a file, and internal firmware state counters through
+  another file.
+- This permits direct access to a firmware driver, mainly for test purposes
+  (e.g. a hardware device that may not be accessible to non-privileged/
+  non-secure layers, or for which no support exists in the NS side).
+
+SMC interface
+-------------
+
+The communication with the 9p layer in BL31 is made through an SMC conduit
+(`SMC Calling Convention PDD`_), using a specific SiP Function Id. An NS shared
+buffer is used to pass path string parameters, or e.g. to exchange data on a
+read operation. Refer to `ARM SiP Services`_ for a description of the SMC
+interface.
+
+Security considerations
+-----------------------
+
+- Due to the nature of the exposed data, the feature is considered experimental
+  and importantly **shall only be used in debug builds**.
+- Several primitive imply string manipulations and usage of string formats.
+- Special care is taken with the shared buffer to avoid TOCTOU attacks.
+
+Limitations
+-----------
+
+- In order to setup the shared buffer, the component consuming the interface
+  needs to allocate a physical page frame and transmit its address.
+- In order to map the shared buffer, BL31 requires enabling the dynamic xlat
+  table option.
+- Data exchange is limited by the shared buffer length. A large read operation
+  might be split into multiple read operations of smaller chunks.
+- On concurrent access, a spinlock is implemented in the BL31 service to protect
+  the internal work buffer, and re-entrancy into the filesystem layers.
+- Notice, a physical device driver if exposed by the firmware may conflict with
+  the higher level OS if the latter implements its own driver for the same
+  physical device.
+
+Applications
+------------
+
+The SMC interface is accessible from an NS environment, that is:
+
+- a test payload, bootloader or hypervisor running at NS-EL2
+- a Linux kernel driver running at NS-EL1
+- a Linux userspace application through the kernel driver
+
+References
+----------
+
+.. [#] `SMC Calling Convention PDD`_
+.. [#] `Notes on the Plan 9 Kernel Source`_
+.. [#] `Linux 9p remote filesystem protocol`_
+.. [#] `ARM SiP Services`_
+
+--------------
+
+*Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.*
+
+.. _SMC Calling Convention PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/
+.. _Notes on the Plan 9 Kernel Source: http://lsub.org/who/nemo/9.pdf
+.. _Linux 9p remote filesystem protocol: https://www.kernel.org/doc/Documentation/filesystems/9p.txt
+.. _ARM SiP Services: arm-sip-service.rst
diff --git a/docs/components/romlib-design.rst b/docs/components/romlib-design.rst
index d8bc89c..d34b3cc 100644
--- a/docs/components/romlib-design.rst
+++ b/docs/components/romlib-design.rst
@@ -111,10 +111,31 @@
 
 BL image --> function
 
+Memory impact
+~~~~~~~~~~~~~
+
+Using library at ROM will modify the memory layout of the BL images:
+
+- The ROM library needs a page aligned RAM section to hold the RW data. This
+  section is defined by the ROMLIB_RW_BASE and ROMLIB_RW_END macros.
+  On Arm platforms a section of 1 page (0x1000) is allocated at the top of SRAM.
+  This will have for effect to shift down all the BL images by 1 page.
+
+- Depending on the functions moved to the ROM library, the size of the BL images
+  will be reduced.
+  For example: moving MbedTLS function into the ROM library reduces BL1 and
+  BL2, but not BL31.
+
+- This change in BL images size can be taken into consideration to optimize the
+  memory layout when defining the BLx_BASE macros.
+
 Build library at ROM
 ~~~~~~~~~~~~~~~~~~~~~
 
-The environment variable ``CROSS_COMPILE`` must be set as per the user guide.
+The environment variable ``CROSS_COMPILE`` must be set appropriately. Refer to
+:ref:`Performing an Initial Build` for more information about setting this
+variable.
+
 In the below example the usage of ROMLIB together with mbed TLS is demonstrated
 to showcase the benefits of library at ROM - it's not mandatory.
 
diff --git a/docs/components/secure-partition-manager-design.rst b/docs/components/secure-partition-manager-design.rst
index de0792d..9aba954 100644
--- a/docs/components/secure-partition-manager-design.rst
+++ b/docs/components/secure-partition-manager-design.rst
@@ -160,7 +160,7 @@
     Partition.
 
   - ``plat_get_secure_partition_boot_info()`` returns a
-    ``secure_partition_boot_info_t`` struct that is populated by the platform
+    ``spm_mm_boot_info_t`` struct that is populated by the platform
     with information about the memory map of the Secure Partition.
 
 For an example of all the changes in context, you may refer to commit
@@ -308,8 +308,8 @@
 Miscellaneous interfaces
 ------------------------
 
-``SPM_VERSION_AARCH32``
-^^^^^^^^^^^^^^^^^^^^^^^
+``SPM_MM_VERSION_AARCH32``
+^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 - Description
 
@@ -369,7 +369,7 @@
 The SPM is responsible for initialising the architectural execution context to
 enable initialisation of a service in S-EL0. The responsibilities of the SPM are
 listed below. At the end of initialisation, the partition issues a
-``SP_EVENT_COMPLETE_AARCH64`` call (described later) to signal readiness for
+``MM_SP_EVENT_COMPLETE_AARCH64`` call (described later) to signal readiness for
 handling requests for services implemented by the Secure Partition. The
 initialisation event is executed as a Fast Call.
 
@@ -488,12 +488,12 @@
 The SPM receives requests for Secure Partition services through a synchronous
 invocation (i.e. a SMC from the Non-secure world). These requests are delegated
 to the partition by programming a return from the last
-``SP_EVENT_COMPLETE_AARCH64`` call received from the partition. The last call
+``MM_SP_EVENT_COMPLETE_AARCH64`` call received from the partition. The last call
 was made to signal either completion of Secure Partition initialisation or
 completion of a partition service request.
 
-``SP_EVENT_COMPLETE_AARCH64``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+``MM_SP_EVENT_COMPLETE_AARCH64``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 - Description
 
@@ -569,7 +569,7 @@
 
 - Caller responsibilities
 
-  A Secure Partition must only call ``SP_EVENT_COMPLETE_AARCH64`` to signal
+  A Secure Partition must only call ``MM_SP_EVENT_COMPLETE_AARCH64`` to signal
   completion of a request that was delegated to it by the SPM.
 
 - Callee responsibilities
@@ -613,18 +613,19 @@
 
 In this case, the Secure Partition needs a way to change the access permissions
 of its memory regions. The SPM provides this feature through the
-``SP_MEMORY_ATTRIBUTES_SET_AARCH64`` SVC interface. This interface is available
-to the Secure Partition during a specific time window: from the first entry into
-the Secure Partition up to the first ``SP_EVENT_COMPLETE`` call that signals the
-Secure Partition has finished its initialisation. Once the initialisation is
-complete, the SPM does not allow changes to the memory attributes.
+``MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64`` SVC interface. This interface is
+available to the Secure Partition during a specific time window: from the first
+entry into the Secure Partition up to the first ``SP_EVENT_COMPLETE`` call that
+signals the Secure Partition has finished its initialisation. Once the
+initialisation is complete, the SPM does not allow changes to the memory
+attributes.
 
 This section describes the standard SVC interface that is implemented by the SPM
 to determine and change permission attributes of memory regions that belong to a
 Secure Partition.
 
-``SP_MEMORY_ATTRIBUTES_GET_AARCH64``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+``MM_SP_MEMORY_ATTRIBUTES_GET_AARCH64``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 - Description
 
@@ -673,7 +674,7 @@
     - ``NOT_SUPPORTED`` : The SPM does not support retrieval of attributes of
       any memory page that is accessible by the Secure Partition, or the
       function was called from the Non-secure world. Also returned if it is
-      used after ``SP_EVENT_COMPLETE_AARCH64``.
+      used after ``MM_SP_EVENT_COMPLETE_AARCH64``.
 
     See `Error Codes`_ for integer values that are associated with each return
     code.
@@ -696,8 +697,8 @@
   The SPM must not return the memory access controls for a page of memory that
   is not accessible from a Secure Partition.
 
-``SP_MEMORY_ATTRIBUTES_SET_AARCH64``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+``MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 - Description
 
@@ -762,7 +763,7 @@
     - ``NOT_SUPPORTED``: The SPM does not permit change of attributes of any
       memory region that is accessible by the Secure Partition. Function was
       called from the Non-secure world. Also returned if it is used after
-      ``SP_EVENT_COMPLETE_AARCH64``.
+      ``MM_SP_EVENT_COMPLETE_AARCH64``.
 
     See `Error Codes`_ for integer values that are associated with each return
     code.
@@ -776,8 +777,8 @@
   currently supported.
 
   This function is only available at boot time. This interface is revoked after
-  the Secure Partition sends the first ``SP_EVENT_COMPLETE_AARCH64`` to signal
-  that it is initialised and ready to receive run-time requests.
+  the Secure Partition sends the first ``MM_SP_EVENT_COMPLETE_AARCH64`` to
+  signal that it is initialised and ready to receive run-time requests.
 
 - Caller responsibilities
 
diff --git a/docs/design/alt-boot-flows.rst b/docs/design/alt-boot-flows.rst
new file mode 100644
index 0000000..b44c061
--- /dev/null
+++ b/docs/design/alt-boot-flows.rst
@@ -0,0 +1,84 @@
+Alternative Boot Flows
+======================
+
+EL3 payloads alternative boot flow
+----------------------------------
+
+On a pre-production system, the ability to execute arbitrary, bare-metal code at
+the highest exception level is required. It allows full, direct access to the
+hardware, for example to run silicon soak tests.
+
+Although it is possible to implement some baremetal secure firmware from
+scratch, this is a complex task on some platforms, depending on the level of
+configuration required to put the system in the expected state.
+
+Rather than booting a baremetal application, a possible compromise is to boot
+``EL3 payloads`` through TF-A instead. This is implemented as an alternative
+boot flow, where a modified BL2 boots an EL3 payload, instead of loading the
+other BL images and passing control to BL31. It reduces the complexity of
+developing EL3 baremetal code by:
+
+-  putting the system into a known architectural state;
+-  taking care of platform secure world initialization;
+-  loading the SCP_BL2 image if required by the platform.
+
+When booting an EL3 payload on Arm standard platforms, the configuration of the
+TrustZone controller is simplified such that only region 0 is enabled and is
+configured to permit secure access only. This gives full access to the whole
+DRAM to the EL3 payload.
+
+The system is left in the same state as when entering BL31 in the default boot
+flow. In particular:
+
+-  Running in EL3;
+-  Current state is AArch64;
+-  Little-endian data access;
+-  All exceptions disabled;
+-  MMU disabled;
+-  Caches disabled.
+
+.. _alt_boot_flows_el3_payload:
+
+Booting an EL3 payload
+~~~~~~~~~~~~~~~~~~~~~~
+
+The EL3 payload image is a standalone image and is not part of the FIP. It is
+not loaded by TF-A. Therefore, there are 2 possible scenarios:
+
+-  The EL3 payload may reside in non-volatile memory (NVM) and execute in
+   place. In this case, booting it is just a matter of specifying the right
+   address in NVM through ``EL3_PAYLOAD_BASE`` when building TF-A.
+
+-  The EL3 payload needs to be loaded in volatile memory (e.g. DRAM) at
+   run-time.
+
+To help in the latter scenario, the ``SPIN_ON_BL1_EXIT=1`` build option can be
+used. The infinite loop that it introduces in BL1 stops execution at the right
+moment for a debugger to take control of the target and load the payload (for
+example, over JTAG).
+
+It is expected that this loading method will work in most cases, as a debugger
+connection is usually available in a pre-production system. The user is free to
+use any other platform-specific mechanism to load the EL3 payload, though.
+
+
+Preloaded BL33 alternative boot flow
+------------------------------------
+
+Some platforms have the ability to preload BL33 into memory instead of relying
+on TF-A to load it. This may simplify packaging of the normal world code and
+improve performance in a development environment. When secure world cold boot
+is complete, TF-A simply jumps to a BL33 base address provided at build time.
+
+For this option to be used, the ``PRELOADED_BL33_BASE`` build option has to be
+used when compiling TF-A. For example, the following command will create a FIP
+without a BL33 and prepare to jump to a BL33 image loaded at address
+0x80000000:
+
+.. code:: shell
+
+    make PRELOADED_BL33_BASE=0x80000000 PLAT=fvp all fip
+
+--------------
+
+*Copyright (c) 2019, Arm Limited. All rights reserved.*
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 891703b..7fa027f 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -227,6 +227,12 @@
 -  ``ERRATA_A76_1275112``: This applies errata 1275112 workaround to Cortex-A76
    CPU. This needs to be enabled only for revision <= r3p0 of the CPU.
 
+For Hercules, the following errata build flags are defined :
+
+-  ``ERRATA_HERCULES_1688305``: This applies errata 1688305 workaround to
+   Hercules CPU. This needs to be enabled only for revision r0p0 - r1p0 of
+   the CPU.
+
 For Neoverse N1, the following errata build flags are defined :
 
 -  ``ERRATA_N1_1073348``: This applies errata 1073348 workaround to Neoverse-N1
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index 4958fc0..5fc1335 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -597,7 +597,7 @@
 is not necessary for AArch32 SPs.
 
 Details on BL32 initialization and the SPD's role are described in the
-"Secure-EL1 Payloads and Dispatchers" section below.
+:ref:`firmware_design_sel1_spd` section below.
 
 BL33 (Non-trusted Firmware) execution
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -868,7 +868,7 @@
 
    TF-A provides a Test Secure-EL1 Payload (TSP) and its associated Dispatcher
    (TSPD). Details of SPD design and TSP/TSPD operation are described in the
-   "Secure-EL1 Payloads and Dispatchers" section below.
+   :ref:`firmware_design_sel1_spd` section below.
 
 #. CPU implementation service
 
@@ -978,8 +978,8 @@
 framework finally sets up the execution stack for the handler, and invokes the
 services ``handle()`` function.
 
-On return from the handler the result registers are populated in X0-X3 before
-restoring the stack and CPU state and returning from the original SMC.
+On return from the handler the result registers are populated in X0-X7 as needed
+before restoring the stack and CPU state and returning from the original SMC.
 
 Exception Handling Framework
 ----------------------------
@@ -1500,6 +1500,11 @@
 this NOBITS section, making the image unnecessarily bigger. Smaller images
 allow faster loading from the FIP to the main memory.
 
+For BL31, a platform can specify an alternate location for NOBITS sections
+(other than immediately following PROGBITS sections) by setting
+``SEPARATE_NOBITS_REGION`` to 1 and defining ``BL31_NOBITS_BASE`` and
+``BL31_NOBITS_LIMIT``.
+
 Linker scripts and symbols
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -1875,10 +1880,7 @@
                |   MHU    |
     0x04000000 +----------+
 
-Library at ROM
----------------
-
-Please refer to the :ref:`Library at ROM` document.
+.. _firmware_design_fip:
 
 Firmware Image Package (FIP)
 ----------------------------
@@ -2543,7 +2545,7 @@
 targets the base Armv8.0-A architecture; i.e. as if ``ARM_ARCH_MAJOR`` == 8
 and ``ARM_ARCH_MINOR`` == 0, which are also their respective default values.
 
-See also the *Summary of build options* in :ref:`User Guide`.
+.. seealso:: :ref:`Build Options`
 
 For details on the Architecture Extension and available features, please refer
 to the respective Architecture Extension Supplement.
diff --git a/docs/design/index.rst b/docs/design/index.rst
index a51a4eb..e3b8f74 100644
--- a/docs/design/index.rst
+++ b/docs/design/index.rst
@@ -6,6 +6,7 @@
    :caption: Contents
    :numbered:
 
+   alt-boot-flows
    auth-framework
    cpu-specific-build-macros
    firmware-design
@@ -13,3 +14,8 @@
    psci-pd-tree
    reset-design
    trusted-board-boot
+   trusted-board-boot-build
+
+--------------
+
+*Copyright (c) 2019, Arm Limited. All rights reserved.*
diff --git a/docs/design/reset-design.rst b/docs/design/reset-design.rst
index a92ceeb..7b10c95 100644
--- a/docs/design/reset-design.rst
+++ b/docs/design/reset-design.rst
@@ -115,8 +115,8 @@
 It allows the Arm FVP port to support the ``RESET_TO_BL31`` configuration, in
 which case the ``bl31.bin`` image must be loaded to its run address in Trusted
 SRAM and all CPU reset vectors be changed from the default ``0x0`` to this run
-address. See the :ref:`User Guide` for details of running the FVP models in this
-way.
+address. See the :ref:`Arm Fixed Virtual Platforms (FVP)` for details of running
+the FVP models in this way.
 
 Although technically it would be possible to program the reset base address with
 the right support in the SCP firmware, this is currently not implemented so the
diff --git a/docs/design/trusted-board-boot-build.rst b/docs/design/trusted-board-boot-build.rst
new file mode 100644
index 0000000..2025243
--- /dev/null
+++ b/docs/design/trusted-board-boot-build.rst
@@ -0,0 +1,114 @@
+Building FIP images with support for Trusted Board Boot
+=======================================================
+
+Trusted Board Boot primarily consists of the following two features:
+
+-  Image Authentication, described in :ref:`Trusted Board Boot`, and
+-  Firmware Update, described in :ref:`Firmware Update (FWU)`
+
+The following steps should be followed to build FIP and (optionally) FWU_FIP
+images with support for these features:
+
+#. Fulfill the dependencies of the ``mbedtls`` cryptographic and image parser
+   modules by checking out a recent version of the `mbed TLS Repository`_. It
+   is important to use a version that is compatible with TF-A and fixes any
+   known security vulnerabilities. See `mbed TLS Security Center`_ for more
+   information. See the :ref:`Prerequisites` document for the appropriate
+   version of mbed TLS to use.
+
+   The ``drivers/auth/mbedtls/mbedtls_*.mk`` files contain the list of mbed TLS
+   source files the modules depend upon.
+   ``include/drivers/auth/mbedtls/mbedtls_config.h`` contains the configuration
+   options required to build the mbed TLS sources.
+
+   Note that the mbed TLS library is licensed under the Apache version 2.0
+   license. Using mbed TLS source code will affect the licensing of TF-A
+   binaries that are built using this library.
+
+#. To build the FIP image, ensure the following command line variables are set
+   while invoking ``make`` to build TF-A:
+
+   -  ``MBEDTLS_DIR=<path of the directory containing mbed TLS sources>``
+   -  ``TRUSTED_BOARD_BOOT=1``
+   -  ``GENERATE_COT=1``
+
+   In the case of Arm platforms, the location of the ROTPK hash must also be
+   specified at build time. Two locations are currently supported (see
+   ``ARM_ROTPK_LOCATION`` build option):
+
+   -  ``ARM_ROTPK_LOCATION=regs``: the ROTPK hash is obtained from the Trusted
+      root-key storage registers present in the platform. On Juno, this
+      registers are read-only. On FVP Base and Cortex models, the registers
+      are read-only, but the value can be specified using the command line
+      option ``bp.trusted_key_storage.public_key`` when launching the model.
+      On both Juno and FVP models, the default value corresponds to an
+      ECDSA-SECP256R1 public key hash, whose private part is not currently
+      available.
+
+   -  ``ARM_ROTPK_LOCATION=devel_rsa``: use the ROTPK hash that is hardcoded
+      in the Arm platform port. The private/public RSA key pair may be
+      found in ``plat/arm/board/common/rotpk``.
+
+   -  ``ARM_ROTPK_LOCATION=devel_ecdsa``: use the ROTPK hash that is hardcoded
+      in the Arm platform port. The private/public ECDSA key pair may be
+      found in ``plat/arm/board/common/rotpk``.
+
+   Example of command line using RSA development keys:
+
+   .. code:: shell
+
+       MBEDTLS_DIR=<path of the directory containing mbed TLS sources> \
+       make PLAT=<platform> TRUSTED_BOARD_BOOT=1 GENERATE_COT=1        \
+       ARM_ROTPK_LOCATION=devel_rsa                                    \
+       ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem        \
+       BL33=<path-to>/<bl33_image>                                     \
+       all fip
+
+   The result of this build will be the bl1.bin and the fip.bin binaries. This
+   FIP will include the certificates corresponding to the Chain of Trust
+   described in the TBBR-client document. These certificates can also be found
+   in the output build directory.
+
+#. The optional FWU_FIP contains any additional images to be loaded from
+   Non-Volatile storage during the :ref:`Firmware Update (FWU)` process. To build the
+   FWU_FIP, any FWU images required by the platform must be specified on the
+   command line. On Arm development platforms like Juno, these are:
+
+   -  NS_BL2U. The AP non-secure Firmware Updater image.
+   -  SCP_BL2U. The SCP Firmware Update Configuration image.
+
+   Example of Juno command line for generating both ``fwu`` and ``fwu_fip``
+   targets using RSA development:
+
+   ::
+
+       MBEDTLS_DIR=<path of the directory containing mbed TLS sources> \
+       make PLAT=juno TRUSTED_BOARD_BOOT=1 GENERATE_COT=1              \
+       ARM_ROTPK_LOCATION=devel_rsa                                    \
+       ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem        \
+       BL33=<path-to>/<bl33_image>                                     \
+       SCP_BL2=<path-to>/<scp_bl2_image>                               \
+       SCP_BL2U=<path-to>/<scp_bl2u_image>                             \
+       NS_BL2U=<path-to>/<ns_bl2u_image>                               \
+       all fip fwu_fip
+
+   .. note::
+      The BL2U image will be built by default and added to the FWU_FIP.
+      The user may override this by adding ``BL2U=<path-to>/<bl2u_image>``
+      to the command line above.
+
+   .. note::
+      Building and installing the non-secure and SCP FWU images (NS_BL1U,
+      NS_BL2U and SCP_BL2U) is outside the scope of this document.
+
+   The result of this build will be bl1.bin, fip.bin and fwu_fip.bin binaries.
+   Both the FIP and FWU_FIP will include the certificates corresponding to the
+   Chain of Trust described in the TBBR-client document. These certificates
+   can also be found in the output build directory.
+
+--------------
+
+*Copyright (c) 2019, Arm Limited. All rights reserved.*
+
+.. _mbed TLS Repository: https://github.com/ARMmbed/mbedtls.git
+.. _mbed TLS Security Center: https://tls.mbed.org/security
diff --git a/docs/design/trusted-board-boot.rst b/docs/design/trusted-board-boot.rst
index f3b1c36..49e8adb 100644
--- a/docs/design/trusted-board-boot.rst
+++ b/docs/design/trusted-board-boot.rst
@@ -187,8 +187,8 @@
 
 The Trusted Board Boot implementation spans both generic and platform-specific
 BL1 and BL2 code, and in tool code on the host build machine. The feature is
-enabled through use of specific build flags as described in the
-:ref:`User Guide`.
+enabled through use of specific build flags as described in
+:ref:`Build Options`.
 
 On the host machine, a tool generates the certificates, which are included in
 the FIP along with the boot loader images. These certificates are loaded in
@@ -222,9 +222,12 @@
 The certificates are also stored individually in the in the output build
 directory.
 
-The tool resides in the ``tools/cert_create`` directory. It uses OpenSSL SSL
-library version 1.0.1 or later to generate the X.509 certificates. Instructions
-for building and using the tool can be found in the :ref:`User Guide`.
+The tool resides in the ``tools/cert_create`` directory. It uses the OpenSSL SSL
+library version to generate the X.509 certificates. The specific version of the
+library that is required is given in the :ref:`Prerequisites` document.
+
+Instructions for building and using the tool can be found at
+:ref:`tools_build_cert_create`.
 
 --------------
 
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
new file mode 100644
index 0000000..d7bb044
--- /dev/null
+++ b/docs/getting_started/build-options.rst
@@ -0,0 +1,652 @@
+Build Options
+=============
+
+The TF-A build system supports the following build options. Unless mentioned
+otherwise, these options are expected to be specified at the build command
+line and are not to be modified in any component makefiles. Note that the
+build system doesn't track dependency for build options. Therefore, if any of
+the build options are changed from a previous build, a clean build must be
+performed.
+
+.. _build_options_common:
+
+Common build options
+--------------------
+
+-  ``AARCH32_INSTRUCTION_SET``: Choose the AArch32 instruction set that the
+   compiler should use. Valid values are T32 and A32. It defaults to T32 due to
+   code having a smaller resulting size.
+
+-  ``AARCH32_SP`` : Choose the AArch32 Secure Payload component to be built as
+   as the BL32 image when ``ARCH=aarch32``. The value should be the path to the
+   directory containing the SP source, relative to the ``bl32/``; the directory
+   is expected to contain a makefile called ``<aarch32_sp-value>.mk``.
+
+-  ``ARCH`` : Choose the target build architecture for TF-A. It can take either
+   ``aarch64`` or ``aarch32`` as values. By default, it is defined to
+   ``aarch64``.
+
+-  ``ARM_ARCH_MAJOR``: The major version of Arm Architecture to target when
+   compiling TF-A. Its value must be numeric, and defaults to 8 . See also,
+   *Armv8 Architecture Extensions* and *Armv7 Architecture Extensions* in
+   :ref:`Firmware Design`.
+
+-  ``ARM_ARCH_MINOR``: The minor version of Arm Architecture to target when
+   compiling TF-A. Its value must be a numeric, and defaults to 0. See also,
+   *Armv8 Architecture Extensions* in :ref:`Firmware Design`.
+
+-  ``BL2``: This is an optional build option which specifies the path to BL2
+   image for the ``fip`` target. In this case, the BL2 in the TF-A will not be
+   built.
+
+-  ``BL2U``: This is an optional build option which specifies the path to
+   BL2U image. In this case, the BL2U in TF-A will not be built.
+
+-  ``BL2_AT_EL3``: This is an optional build option that enables the use of
+   BL2 at EL3 execution level.
+
+-  ``BL2_IN_XIP_MEM``: In some use-cases BL2 will be stored in eXecute In Place
+   (XIP) memory, like BL1. In these use-cases, it is necessary to initialize
+   the RW sections in RAM, while leaving the RO sections in place. This option
+   enable this use-case. For now, this option is only supported when BL2_AT_EL3
+   is set to '1'.
+
+-  ``BL31``: This is an optional build option which specifies the path to
+   BL31 image for the ``fip`` target. In this case, the BL31 in TF-A will not
+   be built.
+
+-  ``BL31_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
+   file that contains the BL31 private key in PEM format. If ``SAVE_KEYS=1``,
+   this file name will be used to save the key.
+
+-  ``BL32``: This is an optional build option which specifies the path to
+   BL32 image for the ``fip`` target. In this case, the BL32 in TF-A will not
+   be built.
+
+-  ``BL32_EXTRA1``: This is an optional build option which specifies the path to
+   Trusted OS Extra1 image for the  ``fip`` target.
+
+-  ``BL32_EXTRA2``: This is an optional build option which specifies the path to
+   Trusted OS Extra2 image for the ``fip`` target.
+
+-  ``BL32_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
+   file that contains the BL32 private key in PEM format. If ``SAVE_KEYS=1``,
+   this file name will be used to save the key.
+
+-  ``BL33``: Path to BL33 image in the host file system. This is mandatory for
+   ``fip`` target in case TF-A BL2 is used.
+
+-  ``BL33_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
+   file that contains the BL33 private key in PEM format. If ``SAVE_KEYS=1``,
+   this file name will be used to save the key.
+
+-  ``BRANCH_PROTECTION``: Numeric value to enable ARMv8.3 Pointer Authentication
+   and ARMv8.5 Branch Target Identification support for TF-A BL images themselves.
+   If enabled, it is needed to use a compiler that supports the option
+   ``-mbranch-protection``. Selects the branch protection features to use:
+-  0: Default value turns off all types of branch protection
+-  1: Enables all types of branch protection features
+-  2: Return address signing to its standard level
+-  3: Extend the signing to include leaf functions
+
+   The table below summarizes ``BRANCH_PROTECTION`` values, GCC compilation options
+   and resulting PAuth/BTI features.
+
+   +-------+--------------+-------+-----+
+   | Value |  GCC option  | PAuth | BTI |
+   +=======+==============+=======+=====+
+   |   0   |     none     |   N   |  N  |
+   +-------+--------------+-------+-----+
+   |   1   |   standard   |   Y   |  Y  |
+   +-------+--------------+-------+-----+
+   |   2   |   pac-ret    |   Y   |  N  |
+   +-------+--------------+-------+-----+
+   |   3   | pac-ret+leaf |   Y   |  N  |
+   +-------+--------------+-------+-----+
+
+   This option defaults to 0 and this is an experimental feature.
+   Note that Pointer Authentication is enabled for Non-secure world
+   irrespective of the value of this option if the CPU supports it.
+
+-  ``BUILD_MESSAGE_TIMESTAMP``: String used to identify the time and date of the
+   compilation of each build. It must be set to a C string (including quotes
+   where applicable). Defaults to a string that contains the time and date of
+   the compilation.
+
+-  ``BUILD_STRING``: Input string for VERSION_STRING, which allows the TF-A
+   build to be uniquely identified. Defaults to the current git commit id.
+
+-  ``CFLAGS``: Extra user options appended on the compiler's command line in
+   addition to the options set by the build system.
+
+-  ``COLD_BOOT_SINGLE_CPU``: This option indicates whether the platform may
+   release several CPUs out of reset. It can take either 0 (several CPUs may be
+   brought up) or 1 (only one CPU will ever be brought up during cold reset).
+   Default is 0. If the platform always brings up a single CPU, there is no
+   need to distinguish between primary and secondary CPUs and the boot path can
+   be optimised. The ``plat_is_my_cpu_primary()`` and
+   ``plat_secondary_cold_boot_setup()`` platform porting interfaces do not need
+   to be implemented in this case.
+
+-  ``CRASH_REPORTING``: A non-zero value enables a console dump of processor
+   register state when an unexpected exception occurs during execution of
+   BL31. This option defaults to the value of ``DEBUG`` - i.e. by default
+   this is only enabled for a debug build of the firmware.
+
+-  ``CREATE_KEYS``: This option is used when ``GENERATE_COT=1``. It tells the
+   certificate generation tool to create new keys in case no valid keys are
+   present or specified. Allowed options are '0' or '1'. Default is '1'.
+
+-  ``CTX_INCLUDE_AARCH32_REGS`` : Boolean option that, when set to 1, will cause
+   the AArch32 system registers to be included when saving and restoring the
+   CPU context. The option must be set to 0 for AArch64-only platforms (that
+   is on hardware that does not implement AArch32, or at least not at EL1 and
+   higher ELs). Default value is 1.
+
+-  ``CTX_INCLUDE_FPREGS``: Boolean option that, when set to 1, will cause the FP
+   registers to be included when saving and restoring the CPU context. Default
+   is 0.
+
+-  ``CTX_INCLUDE_PAUTH_REGS``: Boolean option that, when set to 1, enables
+   Pointer Authentication for Secure world. This will cause the ARMv8.3-PAuth
+   registers to be included when saving and restoring the CPU context as
+   part of world switch. Default value is 0 and this is an experimental feature.
+   Note that Pointer Authentication is enabled for Non-secure world irrespective
+   of the value of this flag if the CPU supports it.
+
+-  ``DEBUG``: Chooses between a debug and release build. It can take either 0
+   (release) or 1 (debug) as values. 0 is the default.
+
+-  ``DISABLE_BIN_GENERATION``: Boolean option to disable the generation
+   of the binary image. If set to 1, then only the ELF image is built.
+   0 is the default.
+
+-  ``DYN_DISABLE_AUTH``: Provides the capability to dynamically disable Trusted
+   Board Boot authentication at runtime. This option is meant to be enabled only
+   for development platforms. ``TRUSTED_BOARD_BOOT`` flag must be set if this
+   flag has to be enabled. 0 is the default.
+
+-  ``E``: Boolean option to make warnings into errors. Default is 1.
+
+-  ``EL3_PAYLOAD_BASE``: This option enables booting an EL3 payload instead of
+   the normal boot flow. It must specify the entry point address of the EL3
+   payload. Please refer to the "Booting an EL3 payload" section for more
+   details.
+
+-  ``ENABLE_AMU``: Boolean option to enable Activity Monitor Unit extensions.
+   This is an optional architectural feature available on v8.4 onwards. Some
+   v8.2 implementations also implement an AMU and this option can be used to
+   enable this feature on those systems as well. Default is 0.
+
+-  ``ENABLE_ASSERTIONS``: This option controls whether or not calls to ``assert()``
+   are compiled out. For debug builds, this option defaults to 1, and calls to
+   ``assert()`` are left in place. For release builds, this option defaults to 0
+   and calls to ``assert()`` function are compiled out. This option can be set
+   independently of ``DEBUG``. It can also be used to hide any auxiliary code
+   that is only required for the assertion and does not fit in the assertion
+   itself.
+
+-  ``ENABLE_BACKTRACE``: This option controls whether to enables backtrace
+   dumps or not. It is supported in both AArch64 and AArch32. However, in
+   AArch32 the format of the frame records are not defined in the AAPCS and they
+   are defined by the implementation. This implementation of backtrace only
+   supports the format used by GCC when T32 interworking is disabled. For this
+   reason enabling this option in AArch32 will force the compiler to only
+   generate A32 code. This option is enabled by default only in AArch64 debug
+   builds, but this behaviour can be overridden in each platform's Makefile or
+   in the build command line.
+
+-  ``ENABLE_LTO``: Boolean option to enable Link Time Optimization (LTO)
+   support in GCC for TF-A. This option is currently only supported for
+   AArch64. Default is 0.
+
+-  ``ENABLE_MPAM_FOR_LOWER_ELS``: Boolean option to enable lower ELs to use MPAM
+   feature. MPAM is an optional Armv8.4 extension that enables various memory
+   system components and resources to define partitions; software running at
+   various ELs can assign themselves to desired partition to control their
+   performance aspects.
+
+   When this option is set to ``1``, EL3 allows lower ELs to access their own
+   MPAM registers without trapping into EL3. This option doesn't make use of
+   partitioning in EL3, however. Platform initialisation code should configure
+   and use partitions in EL3 as required. This option defaults to ``0``.
+
+-  ``ENABLE_PIE``: Boolean option to enable Position Independent Executable(PIE)
+   support within generic code in TF-A. This option is currently only supported
+   in BL31. Default is 0.
+
+-  ``ENABLE_PMF``: Boolean option to enable support for optional Performance
+   Measurement Framework(PMF). Default is 0.
+
+-  ``ENABLE_PSCI_STAT``: Boolean option to enable support for optional PSCI
+   functions ``PSCI_STAT_RESIDENCY`` and ``PSCI_STAT_COUNT``. Default is 0.
+   In the absence of an alternate stat collection backend, ``ENABLE_PMF`` must
+   be enabled. If ``ENABLE_PMF`` is set, the residency statistics are tracked in
+   software.
+
+-  ``ENABLE_RUNTIME_INSTRUMENTATION``: Boolean option to enable runtime
+   instrumentation which injects timestamp collection points into TF-A to
+   allow runtime performance to be measured. Currently, only PSCI is
+   instrumented. Enabling this option enables the ``ENABLE_PMF`` build option
+   as well. Default is 0.
+
+-  ``ENABLE_SPE_FOR_LOWER_ELS`` : Boolean option to enable Statistical Profiling
+   extensions. This is an optional architectural feature for AArch64.
+   The default is 1 but is automatically disabled when the target architecture
+   is AArch32.
+
+-  ``ENABLE_SVE_FOR_NS``: Boolean option to enable Scalable Vector Extension
+   (SVE) for the Non-secure world only. SVE is an optional architectural feature
+   for AArch64. Note that when SVE is enabled for the Non-secure world, access
+   to SIMD and floating-point functionality from the Secure world is disabled.
+   This is to avoid corruption of the Non-secure world data in the Z-registers
+   which are aliased by the SIMD and FP registers. The build option is not
+   compatible with the ``CTX_INCLUDE_FPREGS`` build option, and will raise an
+   assert on platforms where SVE is implemented and ``ENABLE_SVE_FOR_NS`` set to
+   1. The default is 1 but is automatically disabled when the target
+   architecture is AArch32.
+
+-  ``ENABLE_STACK_PROTECTOR``: String option to enable the stack protection
+   checks in GCC. Allowed values are "all", "strong", "default" and "none". The
+   default value is set to "none". "strong" is the recommended stack protection
+   level if this feature is desired. "none" disables the stack protection. For
+   all values other than "none", the ``plat_get_stack_protector_canary()``
+   platform hook needs to be implemented. The value is passed as the last
+   component of the option ``-fstack-protector-$ENABLE_STACK_PROTECTOR``.
+
+-  ``ERROR_DEPRECATED``: This option decides whether to treat the usage of
+   deprecated platform APIs, helper functions or drivers within Trusted
+   Firmware as error. It can take the value 1 (flag the use of deprecated
+   APIs as error) or 0. The default is 0.
+
+-  ``EL3_EXCEPTION_HANDLING``: When set to ``1``, enable handling of exceptions
+   targeted at EL3. When set ``0`` (default), no exceptions are expected or
+   handled at EL3, and a panic will result. This is supported only for AArch64
+   builds.
+
+-  ``FAULT_INJECTION_SUPPORT``: ARMv8.4 extensions introduced support for fault
+   injection from lower ELs, and this build option enables lower ELs to use
+   Error Records accessed via System Registers to inject faults. This is
+   applicable only to AArch64 builds.
+
+   This feature is intended for testing purposes only, and is advisable to keep
+   disabled for production images.
+
+-  ``FIP_NAME``: This is an optional build option which specifies the FIP
+   filename for the ``fip`` target. Default is ``fip.bin``.
+
+-  ``FWU_FIP_NAME``: This is an optional build option which specifies the FWU
+   FIP filename for the ``fwu_fip`` target. Default is ``fwu_fip.bin``.
+
+-  ``GENERATE_COT``: Boolean flag used to build and execute the ``cert_create``
+   tool to create certificates as per the Chain of Trust described in
+   :ref:`Trusted Board Boot`. The build system then calls ``fiptool`` to
+   include the certificates in the FIP and FWU_FIP. Default value is '0'.
+
+   Specify both ``TRUSTED_BOARD_BOOT=1`` and ``GENERATE_COT=1`` to include support
+   for the Trusted Board Boot feature in the BL1 and BL2 images, to generate
+   the corresponding certificates, and to include those certificates in the
+   FIP and FWU_FIP.
+
+   Note that if ``TRUSTED_BOARD_BOOT=0`` and ``GENERATE_COT=1``, the BL1 and BL2
+   images will not include support for Trusted Board Boot. The FIP will still
+   include the corresponding certificates. This FIP can be used to verify the
+   Chain of Trust on the host machine through other mechanisms.
+
+   Note that if ``TRUSTED_BOARD_BOOT=1`` and ``GENERATE_COT=0``, the BL1 and BL2
+   images will include support for Trusted Board Boot, but the FIP and FWU_FIP
+   will not include the corresponding certificates, causing a boot failure.
+
+-  ``GICV2_G0_FOR_EL3``: Unlike GICv3, the GICv2 architecture doesn't have
+   inherent support for specific EL3 type interrupts. Setting this build option
+   to ``1`` assumes GICv2 *Group 0* interrupts are expected to target EL3, both
+   by `platform abstraction layer`__ and `Interrupt Management Framework`__.
+   This allows GICv2 platforms to enable features requiring EL3 interrupt type.
+   This also means that all GICv2 Group 0 interrupts are delivered to EL3, and
+   the Secure Payload interrupts needs to be synchronously handed over to Secure
+   EL1 for handling. The default value of this option is ``0``, which means the
+   Group 0 interrupts are assumed to be handled by Secure EL1.
+
+   .. __: `platform-interrupt-controller-API.rst`
+   .. __: `interrupt-framework-design.rst`
+
+-  ``HANDLE_EA_EL3_FIRST``: When set to ``1``, External Aborts and SError
+   Interrupts will be always trapped in EL3 i.e. in BL31 at runtime. When set to
+   ``0`` (default), these exceptions will be trapped in the current exception
+   level (or in EL1 if the current exception level is EL0).
+
+-  ``HW_ASSISTED_COHERENCY``: On most Arm systems to-date, platform-specific
+   software operations are required for CPUs to enter and exit coherency.
+   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
+   library is not supported.
+
+-  ``JUNO_AARCH32_EL3_RUNTIME``: This build flag enables you to execute EL3
+   runtime software in AArch32 mode, which is required to run AArch32 on Juno.
+   By default this flag is set to '0'. Enabling this flag builds BL1 and BL2 in
+   AArch64 and facilitates the loading of ``SP_MIN`` and BL33 as AArch32 executable
+   images.
+
+-  ``KEY_ALG``: This build flag enables the user to select the algorithm to be
+   used for generating the PKCS keys and subsequent signing of the certificate.
+   It accepts 3 values: ``rsa``, ``rsa_1_5`` and ``ecdsa``. The option
+   ``rsa_1_5`` is the legacy PKCS#1 RSA 1.5 algorithm which is not TBBR
+   compliant and is retained only for compatibility. The default value of this
+   flag is ``rsa`` which is the TBBR compliant PKCS#1 RSA 2.1 scheme.
+
+-  ``KEY_SIZE``: This build flag enables the user to select the key size for
+   the algorithm specified by ``KEY_ALG``. The valid values for ``KEY_SIZE``
+   depend on the chosen algorithm and the cryptographic module.
+
+   +-----------+------------------------------------+
+   |  KEY_ALG  |        Possible key sizes          |
+   +===========+====================================+
+   |    rsa    | 1024 , 2048 (default), 3072, 4096* |
+   +-----------+------------------------------------+
+   |   ecdsa   |            unavailable             |
+   +-----------+------------------------------------+
+
+   * Only 2048 bits size is available with CryptoCell 712 SBROM release 1.
+     Only 3072 bits size is available with CryptoCell 712 SBROM release 2.
+
+-  ``HASH_ALG``: This build flag enables the user to select the secure hash
+   algorithm. It accepts 3 values: ``sha256``, ``sha384`` and ``sha512``.
+   The default value of this flag is ``sha256``.
+
+-  ``LDFLAGS``: Extra user options appended to the linkers' command line in
+   addition to the one set by the build system.
+
+-  ``LOG_LEVEL``: Chooses the log level, which controls the amount of console log
+   output compiled into the build. This should be one of the following:
+
+   ::
+
+       0  (LOG_LEVEL_NONE)
+       10 (LOG_LEVEL_ERROR)
+       20 (LOG_LEVEL_NOTICE)
+       30 (LOG_LEVEL_WARNING)
+       40 (LOG_LEVEL_INFO)
+       50 (LOG_LEVEL_VERBOSE)
+
+   All log output up to and including the selected log level is compiled into
+   the build. The default value is 40 in debug builds and 20 in release builds.
+
+-  ``NON_TRUSTED_WORLD_KEY``: This option is used when ``GENERATE_COT=1``. It
+   specifies the file that contains the Non-Trusted World private key in PEM
+   format. If ``SAVE_KEYS=1``, this file name will be used to save the key.
+
+-  ``NS_BL2U``: Path to NS_BL2U image in the host file system. This image is
+   optional. It is only needed if the platform makefile specifies that it
+   is required in order to build the ``fwu_fip`` target.
+
+-  ``NS_TIMER_SWITCH``: Enable save and restore for non-secure timer register
+   contents upon world switch. It can take either 0 (don't save and restore) or
+   1 (do save and restore). 0 is the default. An SPD may set this to 1 if it
+   wants the timer registers to be saved and restored.
+
+-  ``OVERRIDE_LIBC``: This option allows platforms to override the default libc
+   for the BL image. It can be either 0 (include) or 1 (remove). The default
+   value is 0.
+
+-  ``PL011_GENERIC_UART``: Boolean option to indicate the PL011 driver that
+   the underlying hardware is not a full PL011 UART but a minimally compliant
+   generic UART, which is a subset of the PL011. The driver will not access
+   any register that is not part of the SBSA generic UART specification.
+   Default value is 0 (a full PL011 compliant UART is present).
+
+-  ``PLAT``: Choose a platform to build TF-A for. The chosen platform name
+   must be subdirectory of any depth under ``plat/``, and must contain a
+   platform makefile named ``platform.mk``. For example, to build TF-A for the
+   Arm Juno board, select PLAT=juno.
+
+-  ``PRELOADED_BL33_BASE``: This option enables booting a preloaded BL33 image
+   instead of the normal boot flow. When defined, it must specify the entry
+   point address for the preloaded BL33 image. This option is incompatible with
+   ``EL3_PAYLOAD_BASE``. If both are defined, ``EL3_PAYLOAD_BASE`` has priority
+   over ``PRELOADED_BL33_BASE``.
+
+-  ``PROGRAMMABLE_RESET_ADDRESS``: This option indicates whether the reset
+   vector address can be programmed or is fixed on the platform. It can take
+   either 0 (fixed) or 1 (programmable). Default is 0. If the platform has a
+   programmable reset address, it is expected that a CPU will start executing
+   code directly at the right address, both on a cold and warm reset. In this
+   case, there is no need to identify the entrypoint on boot and the boot path
+   can be optimised. The ``plat_get_my_entrypoint()`` platform porting interface
+   does not need to be implemented in this case.
+
+-  ``PSCI_EXTENDED_STATE_ID``: As per PSCI1.0 Specification, there are 2 formats
+   possible for the PSCI power-state parameter: original and extended State-ID
+   formats. This flag if set to 1, configures the generic PSCI layer to use the
+   extended format. The default value of this flag is 0, which means by default
+   the original power-state format is used by the PSCI implementation. This flag
+   should be specified by the platform makefile and it governs the return value
+   of PSCI_FEATURES API for CPU_SUSPEND smc function id. When this option is
+   enabled on Arm platforms, the option ``ARM_RECOM_STATE_ID_ENC`` needs to be
+   set to 1 as well.
+
+-  ``RAS_EXTENSION``: When set to ``1``, enable Armv8.2 RAS features. RAS features
+   are an optional extension for pre-Armv8.2 CPUs, but are mandatory for Armv8.2
+   or later CPUs.
+
+   When ``RAS_EXTENSION`` is set to ``1``, ``HANDLE_EA_EL3_FIRST`` must also be
+   set to ``1``.
+
+   This option is disabled by default.
+
+-  ``RESET_TO_BL31``: Enable BL31 entrypoint as the CPU reset vector instead
+   of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1
+   entrypoint) or 1 (CPU reset to BL31 entrypoint).
+   The default value is 0.
+
+-  ``RESET_TO_SP_MIN``: SP_MIN is the minimal AArch32 Secure Payload provided
+   in TF-A. This flag configures SP_MIN entrypoint as the CPU reset vector
+   instead of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1
+   entrypoint) or 1 (CPU reset to SP_MIN entrypoint). The default value is 0.
+
+-  ``ROT_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
+   file that contains the ROT private key in PEM format. If ``SAVE_KEYS=1``, this
+   file name will be used to save the key.
+
+-  ``SAVE_KEYS``: This option is used when ``GENERATE_COT=1``. It tells the
+   certificate generation tool to save the keys used to establish the Chain of
+   Trust. Allowed options are '0' or '1'. Default is '0' (do not save).
+
+-  ``SCP_BL2``: Path to SCP_BL2 image in the host file system. This image is optional.
+   If a SCP_BL2 image is present then this option must be passed for the ``fip``
+   target.
+
+-  ``SCP_BL2_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
+   file that contains the SCP_BL2 private key in PEM format. If ``SAVE_KEYS=1``,
+   this file name will be used to save the key.
+
+-  ``SCP_BL2U``: Path to SCP_BL2U image in the host file system. This image is
+   optional. It is only needed if the platform makefile specifies that it
+   is required in order to build the ``fwu_fip`` target.
+
+-  ``SDEI_SUPPORT``: Setting this to ``1`` enables support for Software
+   Delegated Exception Interface to BL31 image. This defaults to ``0``.
+
+   When set to ``1``, the build option ``EL3_EXCEPTION_HANDLING`` must also be
+   set to ``1``.
+
+-  ``SEPARATE_CODE_AND_RODATA``: Whether code and read-only data should be
+   isolated on separate memory pages. This is a trade-off between security and
+   memory usage. See "Isolating code and read-only data on separate memory
+   pages" section in :ref:`Firmware Design`. This flag is disabled by default and
+   affects all BL images.
+
+-  ``SEPARATE_NOBITS_REGION``: Setting this option to ``1`` allows the NOBITS
+   sections of BL31 (.bss, stacks, page tables, and coherent memory) to be
+   allocated in RAM discontiguous from the loaded firmware image. When set, the
+   platform is expected to provide definitons for ``BL31_NOBITS_BASE`` and
+   ``BL31_NOBITS_LIMIT``. When the option is ``0`` (the default), NOBITS
+   sections are placed in RAM immediately following the loaded firmware image.
+
+-  ``SPD``: Choose a Secure Payload Dispatcher component to be built into TF-A.
+   This build option is only valid if ``ARCH=aarch64``. The value should be
+   the path to the directory containing the SPD source, relative to
+   ``services/spd/``; the directory is expected to contain a makefile called
+   ``<spd-value>.mk``.
+
+-  ``SPIN_ON_BL1_EXIT``: This option introduces an infinite loop in BL1. It can
+   take either 0 (no loop) or 1 (add a loop). 0 is the default. This loop stops
+   execution in BL1 just before handing over to BL31. At this point, all
+   firmware images have been loaded in memory, and the MMU and caches are
+   turned off. Refer to the "Debugging options" section for more details.
+
+-  ``SPM_MM`` : Boolean option to enable the Management Mode (MM)-based Secure
+   Partition Manager (SPM) implementation. The default value is ``0``.
+
+-  ``SP_MIN_WITH_SECURE_FIQ``: Boolean flag to indicate the SP_MIN handles
+   secure interrupts (caught through the FIQ line). Platforms can enable
+   this directive if they need to handle such interruption. When enabled,
+   the FIQ are handled in monitor mode and non secure world is not allowed
+   to mask these events. Platforms that enable FIQ handling in SP_MIN shall
+   implement the api ``sp_min_plat_fiq_handler()``. The default value is 0.
+
+-  ``TRUSTED_BOARD_BOOT``: Boolean flag to include support for the Trusted Board
+   Boot feature. When set to '1', BL1 and BL2 images include support to load
+   and verify the certificates and images in a FIP, and BL1 includes support
+   for the Firmware Update. The default value is '0'. Generation and inclusion
+   of certificates in the FIP and FWU_FIP depends upon the value of the
+   ``GENERATE_COT`` option.
+
+   .. warning::
+      This option depends on ``CREATE_KEYS`` to be enabled. If the keys
+      already exist in disk, they will be overwritten without further notice.
+
+-  ``TRUSTED_WORLD_KEY``: This option is used when ``GENERATE_COT=1``. It
+   specifies the file that contains the Trusted World private key in PEM
+   format. If ``SAVE_KEYS=1``, this file name will be used to save the key.
+
+-  ``TSP_INIT_ASYNC``: Choose BL32 initialization method as asynchronous or
+   synchronous, (see "Initializing a BL32 Image" section in
+   :ref:`Firmware Design`). It can take the value 0 (BL32 is initialized using
+   synchronous method) or 1 (BL32 is initialized using asynchronous method).
+   Default is 0.
+
+-  ``TSP_NS_INTR_ASYNC_PREEMPT``: A non zero value enables the interrupt
+   routing model which routes non-secure interrupts asynchronously from TSP
+   to EL3 causing immediate preemption of TSP. The EL3 is responsible
+   for saving and restoring the TSP context in this routing model. The
+   default routing model (when the value is 0) is to route non-secure
+   interrupts to TSP allowing it to save its context and hand over
+   synchronously to EL3 via an SMC.
+
+   .. note::
+      When ``EL3_EXCEPTION_HANDLING`` is ``1``, ``TSP_NS_INTR_ASYNC_PREEMPT``
+      must also be set to ``1``.
+
+-  ``USE_ARM_LINK``: This flag determines whether to enable support for ARM
+   linker. When the ``LINKER`` build variable points to the armlink linker,
+   this flag is enabled automatically. To enable support for armlink, platforms
+   will have to provide a scatter file for the BL image. Currently, Tegra
+   platforms use the armlink support to compile BL3-1 images.
+
+-  ``USE_COHERENT_MEM``: This flag determines whether to include the coherent
+   memory region in the BL memory map or not (see "Use of Coherent memory in
+   TF-A" section in :ref:`Firmware Design`). It can take the value 1
+   (Coherent memory region is included) or 0 (Coherent memory region is
+   excluded). Default is 1.
+
+-  ``USE_DEBUGFS``: When set to 1 this option activates an EXPERIMENTAL feature
+   exposing a virtual filesystem interface through BL31 as a SiP SMC function.
+   Default is 0.
+
+-  ``USE_ROMLIB``: This flag determines whether library at ROM will be used.
+   This feature creates a library of functions to be placed in ROM and thus
+   reduces SRAM usage. Refer to :ref:`Library at ROM` for further details. Default
+   is 0.
+
+-  ``V``: Verbose build. If assigned anything other than 0, the build commands
+   are printed. Default is 0.
+
+-  ``VERSION_STRING``: String used in the log output for each TF-A image.
+   Defaults to a string formed by concatenating the version number, build type
+   and build string.
+
+-  ``W``: Warning level. Some compiler warning options of interest have been
+   regrouped and put in the root Makefile. This flag can take the values 0 to 3,
+   each level enabling more warning options. Default is 0.
+
+-  ``WARMBOOT_ENABLE_DCACHE_EARLY`` : Boolean option to enable D-cache early on
+   the CPU after warm boot. This is applicable for platforms which do not
+   require interconnect programming to enable cache coherency (eg: single
+   cluster platforms). If this option is enabled, then warm boot path
+   enables D-caches immediately after enabling MMU. This option defaults to 0.
+
+Debugging options
+-----------------
+
+To compile a debug version and make the build more verbose use
+
+.. code:: shell
+
+    make PLAT=<platform> DEBUG=1 V=1 all
+
+AArch64 GCC uses DWARF version 4 debugging symbols by default. Some tools (for
+example DS-5) might not support this and may need an older version of DWARF
+symbols to be emitted by GCC. This can be achieved by using the
+``-gdwarf-<version>`` flag, with the version being set to 2 or 3. Setting the
+version to 2 is recommended for DS-5 versions older than 5.16.
+
+When debugging logic problems it might also be useful to disable all compiler
+optimizations by using ``-O0``.
+
+.. warning::
+   Using ``-O0`` could cause output images to be larger and base addresses
+   might need to be recalculated (see the **Memory layout on Arm development
+   platforms** section in the :ref:`Firmware Design`).
+
+Extra debug options can be passed to the build system by setting ``CFLAGS`` or
+``LDFLAGS``:
+
+.. code:: shell
+
+    CFLAGS='-O0 -gdwarf-2'                                     \
+    make PLAT=<platform> DEBUG=1 V=1 all
+
+Note that using ``-Wl,`` style compilation driver options in ``CFLAGS`` will be
+ignored as the linker is called directly.
+
+It is also possible to introduce an infinite loop to help in debugging the
+post-BL2 phase of TF-A. This can be done by rebuilding BL1 with the
+``SPIN_ON_BL1_EXIT=1`` build flag. Refer to the :ref:`build_options_common`
+section. In this case, the developer may take control of the target using a
+debugger when indicated by the console output. When using DS-5, the following
+commands can be used:
+
+::
+
+    # Stop target execution
+    interrupt
+
+    #
+    # Prepare your debugging environment, e.g. set breakpoints
+    #
+
+    # Jump over the debug loop
+    set var $AARCH64::$Core::$PC = $AARCH64::$Core::$PC + 4
+
+    # Resume execution
+    continue
+
+--------------
+
+*Copyright (c) 2019, Arm Limited. All rights reserved.*
diff --git a/docs/getting_started/docs-build.rst b/docs/getting_started/docs-build.rst
index fa07642..c5625e9 100644
--- a/docs/getting_started/docs-build.rst
+++ b/docs/getting_started/docs-build.rst
@@ -22,6 +22,9 @@
 - Python 3 (3.5 or later)
 - PlantUML (1.2017.15 or later)
 
+Optionally, the `Dia`_ application can be installed if you need to edit
+existing ``.dia`` diagram files, or create new ones.
+
 You must also install the Python modules that are specified in the
 ``requirements.txt`` file in the root of the ``docs`` directory. These modules
 can be installed using ``pip3`` (the Python Package Installer). Passing this
@@ -33,7 +36,7 @@
 
 .. code:: shell
 
-    sudo apt install python3 python3-pip plantuml
+    sudo apt install python3 python3-pip plantuml [dia]
     pip3 install [--user] -r requirements.txt
 
 .. note::
@@ -75,3 +78,4 @@
 
 .. _Sphinx: http://www.sphinx-doc.org/en/master/
 .. _pip homepage: https://pip.pypa.io/en/stable/
+.. _Dia: https://wiki.gnome.org/Apps/Dia
diff --git a/docs/getting_started/index.rst b/docs/getting_started/index.rst
index 07e3753..817beaf 100644
--- a/docs/getting_started/index.rst
+++ b/docs/getting_started/index.rst
@@ -6,9 +6,16 @@
    :caption: Contents
    :numbered:
 
-   user-guide
+   prerequisites
    docs-build
+   tools-build
+   initial-build
+   build-options
    image-terminology
    porting-guide
    psci-lib-integration-guide
    rt-svc-writers-guide
+
+--------------
+
+*Copyright (c) 2019, Arm Limited. All rights reserved.*
diff --git a/docs/getting_started/initial-build.rst b/docs/getting_started/initial-build.rst
new file mode 100644
index 0000000..893aba2
--- /dev/null
+++ b/docs/getting_started/initial-build.rst
@@ -0,0 +1,117 @@
+Performing an Initial Build
+===========================
+
+-  Before building TF-A, the environment variable ``CROSS_COMPILE`` must point
+   to the Linaro cross compiler.
+
+   For AArch64:
+
+   .. code:: shell
+
+       export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf-
+
+   For AArch32:
+
+   .. code:: shell
+
+       export CROSS_COMPILE=<path-to-aarch32-gcc>/bin/arm-none-eabi-
+
+   It is possible to build TF-A using Clang or Arm Compiler 6. To do so
+   ``CC`` needs to point to the clang or armclang binary, which will
+   also select the clang or armclang assembler. Be aware that the
+   GNU linker is used by default.  In case of being needed the linker
+   can be overridden using the ``LD`` variable. Clang linker version 6 is
+   known to work with TF-A.
+
+   In both cases ``CROSS_COMPILE`` should be set as described above.
+
+   Arm Compiler 6 will be selected when the base name of the path assigned
+   to ``CC`` matches the string 'armclang'.
+
+   For AArch64 using Arm Compiler 6:
+
+   .. code:: shell
+
+       export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf-
+       make CC=<path-to-armclang>/bin/armclang PLAT=<platform> all
+
+   Clang will be selected when the base name of the path assigned to ``CC``
+   contains the string 'clang'. This is to allow both clang and clang-X.Y
+   to work.
+
+   For AArch64 using clang:
+
+   .. code:: shell
+
+       export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf-
+       make CC=<path-to-clang>/bin/clang PLAT=<platform> all
+
+-  Change to the root directory of the TF-A source tree and build.
+
+   For AArch64:
+
+   .. code:: shell
+
+       make PLAT=<platform> all
+
+   For AArch32:
+
+   .. code:: shell
+
+       make PLAT=<platform> ARCH=aarch32 AARCH32_SP=sp_min all
+
+   Notes:
+
+   -  If ``PLAT`` is not specified, ``fvp`` is assumed by default. See the
+      :ref:`Build Options` document for more information on available build
+      options.
+
+   -  (AArch32 only) Currently only ``PLAT=fvp`` is supported.
+
+   -  (AArch32 only) ``AARCH32_SP`` is the AArch32 EL3 Runtime Software and it
+      corresponds to the BL32 image. A minimal ``AARCH32_SP``, sp_min, is
+      provided by TF-A to demonstrate how PSCI Library can be integrated with
+      an AArch32 EL3 Runtime Software. Some AArch32 EL3 Runtime Software may
+      include other runtime services, for example Trusted OS services. A guide
+      to integrate PSCI library with AArch32 EL3 Runtime Software can be found
+      at :ref:`PSCI Library Integration guide for Armv8-A AArch32 systems`.
+
+   -  (AArch64 only) The TSP (Test Secure Payload), corresponding to the BL32
+      image, is not compiled in by default. Refer to the
+      :ref:`Test Secure Payload (TSP) and Dispatcher (TSPD)` document for
+      details on building the TSP.
+
+   -  By default this produces a release version of the build. To produce a
+      debug version instead, refer to the "Debugging options" section below.
+
+   -  The build process creates products in a ``build`` directory tree, building
+      the objects and binaries for each boot loader stage in separate
+      sub-directories. The following boot loader binary files are created
+      from the corresponding ELF files:
+
+      -  ``build/<platform>/<build-type>/bl1.bin``
+      -  ``build/<platform>/<build-type>/bl2.bin``
+      -  ``build/<platform>/<build-type>/bl31.bin`` (AArch64 only)
+      -  ``build/<platform>/<build-type>/bl32.bin`` (mandatory for AArch32)
+
+      where ``<platform>`` is the name of the chosen platform and ``<build-type>``
+      is either ``debug`` or ``release``. The actual number of images might differ
+      depending on the platform.
+
+-  Build products for a specific build variant can be removed using:
+
+   .. code:: shell
+
+       make DEBUG=<D> PLAT=<platform> clean
+
+   ... where ``<D>`` is ``0`` or ``1``, as specified when building.
+
+   The build tree can be removed completely using:
+
+   .. code:: shell
+
+       make realclean
+
+--------------
+
+*Copyright (c) 2019, Arm Limited. All rights reserved.*
diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst
index 9cca75e..bb14717 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/getting_started/porting-guide.rst
@@ -23,8 +23,6 @@
 discusses these in detail. The subsequent sections discuss the remaining
 modifications for each BL stage in detail.
 
-This document should be read in conjunction with the TF-A :ref:`User Guide`.
-
 Please refer to the :ref:`Platform Compatibility Policy` for the policy
 regarding compatibility and deprecation of these porting interfaces.
 
@@ -2001,7 +1999,7 @@
 
 ::
 
-    Argument : unsigned int, const psci_power_state_t *, int
+    Argument : unsigned int, const psci_power_state_t *, unsigned int
     Return   : u_register_t
 
 This is an optional interface that is is invoked after resuming from a low power
@@ -2387,8 +2385,8 @@
 `Arm Generic Interrupt Controller version 2.0 (GICv2)`_
 and `3.0 (GICv3)`_. Juno builds the Arm platform layer to use GICv2 and the
 FVP can be configured to use either GICv2 or GICv3 depending on the build flag
-``FVP_USE_GIC_DRIVER`` (See FVP platform specific build options in
-:ref:`User Guide` for more details).
+``FVP_USE_GIC_DRIVER`` (See :ref:`build_options_arm_fvp_platform` for more
+details).
 
 See also: `Interrupt Controller Abstraction APIs`__.
 
@@ -2796,10 +2794,10 @@
 
 It is mandatory to implement at least one storage driver. For the Arm
 development platforms the Firmware Image Package (FIP) driver is provided as
-the default means to load data from storage (see the "Firmware Image Package"
-section in the :ref:`User Guide`). The storage layer is described in the header file
-``include/drivers/io/io_storage.h``. The implementation of the common library
-is in ``drivers/io/io_storage.c`` and the driver files are located in
+the default means to load data from storage (see :ref:`firmware_design_fip`).
+The storage layer is described in the header file
+``include/drivers/io/io_storage.h``. The implementation of the common library is
+in ``drivers/io/io_storage.c`` and the driver files are located in
 ``drivers/io/``.
 
 .. uml:: ../resources/diagrams/plantuml/io_arm_class_diagram.puml
diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst
new file mode 100644
index 0000000..3e0c8ff
--- /dev/null
+++ b/docs/getting_started/prerequisites.rst
@@ -0,0 +1,136 @@
+Prerequisites
+=============
+
+This document describes the software requirements for building |TF-A| for
+AArch32 and AArch64 target platforms.
+
+It may possible to build |TF-A| with combinations of software packages that are
+different from those listed below, however only the software described in this
+document can be officially supported.
+
+Build Host
+----------
+
+|TF-A| can be built using either a Linux or a Windows machine as the build host.
+
+A relatively recent Linux distribution is recommended for building |TF-A|. We
+have performed tests using Ubuntu 16.04 LTS (64-bit) but other distributions
+should also work fine as a base, provided that the necessary tools and libraries
+can be installed.
+
+.. _prerequisites_toolchain:
+
+Toolchain
+---------
+
+|TF-A| can be built with any of the following *cross-compiler* toolchains that
+target the Armv7-A or Armv8-A architectures:
+
+- GCC >= 9.2-2019.12 (from the `Arm Developer website`_)
+- Clang >= 4.0
+- Arm Compiler >= 6.0
+
+In addition, a native compiler is required to build the supporting tools.
+
+.. note::
+   The software has also been built on Windows 7 Enterprise SP1, using CMD.EXE,
+   Cygwin, and Msys (MinGW) shells, using version 5.3.1 of the GNU toolchain.
+
+.. note::
+   For instructions on how to select the cross compiler refer to
+   :ref:`Performing an Initial Build`.
+
+.. _prerequisites_software_and_libraries:
+
+Software and Libraries
+----------------------
+
+The following tools are required to obtain and build |TF-A|:
+
+- An appropriate toolchain (see :ref:`prerequisites_toolchain`)
+- GNU Make
+- Git
+
+The following libraries must be available to build one or more components or
+supporting tools:
+
+- OpenSSL >= 1.0.1
+
+   Required to build the cert_create tool.
+
+The following libraries are required for Trusted Board Boot support:
+
+- mbed TLS == 2.16.2 (tag: ``mbedtls-2.16.2``)
+
+These tools are optional:
+
+- Device Tree Compiler (DTC) >= 1.4.6
+
+   Needed if you want to rebuild the provided Flattened Device Tree (FDT)
+   source files (``.dts`` files). DTC is available for Linux through the package
+   repositories of most distributions.
+
+- Arm `Development Studio 5 (DS-5)`_
+
+   The standard software package used for debugging software on Arm development
+   platforms and |FVP| models.
+
+Package Installation (Linux)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If you are using the recommended Ubuntu distribution then you can install the
+required packages with the following command:
+
+.. code:: shell
+
+    sudo apt install build-essential git libssl-dev
+
+The optional packages can be installed using:
+
+.. code:: shell
+
+    sudo apt install device-tree-compiler
+
+Supporting Files
+----------------
+
+TF-A has been tested with pre-built binaries and file systems from `Linaro
+Release 19.06`_. Alternatively, you can build the binaries from source using
+instructions in :ref:`Performing an Initial Build`.
+
+.. _prerequisites_get_source:
+
+Getting the TF-A Source
+-----------------------
+
+Source code for |TF-A| is maintained in a Git repository hosted on
+TrustedFirmware.org. To clone this repository from the server, run the following
+in your shell:
+
+.. code:: shell
+
+    git clone "https://review.trustedfirmware.org/TF-A/trusted-firmware-a" && (cd "trusted-firmware-a" && mkdir -p .git/hooks && curl -Lo `git rev-parse --git-dir`/hooks/commit-msg https://review.trustedfirmware.org/tools/hooks/commit-msg; chmod +x `git rev-parse --git-dir`/hooks/commit-msg)
+
+This will clone the Git repository also install a *commit hook* that
+automatically inserts appropriate *Change-Id:* lines at the end of your
+commit messages. These change IDs are required when committing changes that you
+intend to push for review via our Gerrit system.
+
+You can read more about Git hooks in the *githooks* page of the Git documentation,
+available at: https://git-scm.com/docs/githooks
+
+Alternatively, you can clone without the commit hook using:
+
+.. code:: shell
+
+    git clone "https://review.trustedfirmware.org/TF-A/trusted-firmware-a"
+
+--------------
+
+*Copyright (c) 2019, Arm Limited. All rights reserved.*
+
+.. _Arm Developer website: https://developer.arm.com/open-source/gnu-toolchain/gnu-a/downloads
+.. _Linaro Release Notes: https://community.arm.com/dev-platforms/w/docs/226/old-release-notes
+.. _Linaro instructions: https://community.arm.com/dev-platforms/w/docs/304/arm-reference-platforms-deliverables
+.. _Development Studio 5 (DS-5): https://developer.arm.com/products/software-development-tools/ds-5-development-studio
+.. _Linaro Release 19.06: http://releases.linaro.org/members/arm/platforms/19.06
diff --git a/docs/getting_started/rt-svc-writers-guide.rst b/docs/getting_started/rt-svc-writers-guide.rst
index 6a06025..5375b65 100644
--- a/docs/getting_started/rt-svc-writers-guide.rst
+++ b/docs/getting_started/rt-svc-writers-guide.rst
@@ -244,17 +244,35 @@
 
    TF-A expects owning entities to follow this recommendation.
 
-#. Returning the result to the caller. The `SMCCC`_ allows for up to 256 bits
-   of return value in SMC64 using X0-X3 and 128 bits in SMC32 using W0-W3. The
-   framework provides a family of macros to set the multi-register return
-   value and complete the handler:
+#. Returning the result to the caller. Based on `SMCCC`_ spec, results are
+   returned in W0-W7(X0-X7) registers for SMC32(SMC64) calls from AArch64
+   state. Results are returned in R0-R7 registers for SMC32 calls from AArch32
+   state. The framework provides a family of macros to set the multi-register
+   return value and complete the handler:
 
    .. code:: c
 
+       AArch64 state:
+
        SMC_RET1(handle, x0);
        SMC_RET2(handle, x0, x1);
        SMC_RET3(handle, x0, x1, x2);
        SMC_RET4(handle, x0, x1, x2, x3);
+       SMC_RET5(handle, x0, x1, x2, x3, x4);
+       SMC_RET6(handle, x0, x1, x2, x3, x4, x5);
+       SMC_RET7(handle, x0, x1, x2, x3, x4, x5, x6);
+       SMC_RET8(handle, x0, x1, x2, x3, x4, x5, x6, x7);
+
+       AArch32 state:
+
+       SMC_RET1(handle, r0);
+       SMC_RET2(handle, r0, r1);
+       SMC_RET3(handle, r0, r1, r2);
+       SMC_RET4(handle, r0, r1, r2, r3);
+       SMC_RET5(handle, r0, r1, r2, r3, r4);
+       SMC_RET6(handle, r0, r1, r2, r3, r4, r5);
+       SMC_RET7(handle, r0, r1, r2, r3, r4, r5, r6);
+       SMC_RET8(handle, r0, r1, r2, r3, r4, r5, r6, r7);
 
 The ``cookie`` parameter to the handler is reserved for future use and can be
 ignored. The ``handle`` is returned by the SMC handler - completion of the
diff --git a/docs/getting_started/tools-build.rst b/docs/getting_started/tools-build.rst
new file mode 100644
index 0000000..bb707cb
--- /dev/null
+++ b/docs/getting_started/tools-build.rst
@@ -0,0 +1,140 @@
+Building Supporting Tools
+=========================
+
+Building and using the FIP tool
+-------------------------------
+
+Firmware Image Package (FIP) is a packaging format used by TF-A to package
+firmware images in a single binary. The number and type of images that should
+be packed in a FIP is platform specific and may include TF-A images and other
+firmware images required by the platform. For example, most platforms require
+a BL33 image which corresponds to the normal world bootloader (e.g. UEFI or
+U-Boot).
+
+The TF-A build system provides the make target ``fip`` to create a FIP file
+for the specified platform using the FIP creation tool included in the TF-A
+project. Examples below show how to build a FIP file for FVP, packaging TF-A
+and BL33 images.
+
+For AArch64:
+
+.. code:: shell
+
+    make PLAT=fvp BL33=<path-to>/bl33.bin fip
+
+For AArch32:
+
+.. code:: shell
+
+    make PLAT=fvp ARCH=aarch32 AARCH32_SP=sp_min BL33=<path-to>/bl33.bin fip
+
+The resulting FIP may be found in:
+
+::
+
+    build/fvp/<build-type>/fip.bin
+
+For advanced operations on FIP files, it is also possible to independently build
+the tool and create or modify FIPs using this tool. To do this, follow these
+steps:
+
+It is recommended to remove old artifacts before building the tool:
+
+.. code:: shell
+
+    make -C tools/fiptool clean
+
+Build the tool:
+
+.. code:: shell
+
+    make [DEBUG=1] [V=1] fiptool
+
+The tool binary can be located in:
+
+::
+
+    ./tools/fiptool/fiptool
+
+Invoking the tool with ``help`` will print a help message with all available
+options.
+
+Example 1: create a new Firmware package ``fip.bin`` that contains BL2 and BL31:
+
+.. code:: shell
+
+    ./tools/fiptool/fiptool create \
+        --tb-fw build/<platform>/<build-type>/bl2.bin \
+        --soc-fw build/<platform>/<build-type>/bl31.bin \
+        fip.bin
+
+Example 2: view the contents of an existing Firmware package:
+
+.. code:: shell
+
+    ./tools/fiptool/fiptool info <path-to>/fip.bin
+
+Example 3: update the entries of an existing Firmware package:
+
+.. code:: shell
+
+    # Change the BL2 from Debug to Release version
+    ./tools/fiptool/fiptool update \
+        --tb-fw build/<platform>/release/bl2.bin \
+        build/<platform>/debug/fip.bin
+
+Example 4: unpack all entries from an existing Firmware package:
+
+.. code:: shell
+
+    # Images will be unpacked to the working directory
+    ./tools/fiptool/fiptool unpack <path-to>/fip.bin
+
+Example 5: remove an entry from an existing Firmware package:
+
+.. code:: shell
+
+    ./tools/fiptool/fiptool remove \
+        --tb-fw build/<platform>/debug/fip.bin
+
+Note that if the destination FIP file exists, the create, update and
+remove operations will automatically overwrite it.
+
+The unpack operation will fail if the images already exist at the
+destination. In that case, use -f or --force to continue.
+
+More information about FIP can be found in the :ref:`Firmware Design` document.
+
+.. _tools_build_cert_create:
+
+Building the Certificate Generation Tool
+----------------------------------------
+
+The ``cert_create`` tool is built as part of the TF-A build process when the
+``fip`` make target is specified and TBB is enabled (as described in the
+previous section), but it can also be built separately with the following
+command:
+
+.. code:: shell
+
+    make PLAT=<platform> [DEBUG=1] [V=1] certtool
+
+For platforms that require their own IDs in certificate files, the generic
+'cert_create' tool can be built with the following command. Note that the target
+platform must define its IDs within a ``platform_oid.h`` header file for the
+build to succeed.
+
+.. code:: shell
+
+    make PLAT=<platform> USE_TBBR_DEFS=0 [DEBUG=1] [V=1] certtool
+
+``DEBUG=1`` builds the tool in debug mode. ``V=1`` makes the build process more
+verbose. The following command should be used to obtain help about the tool:
+
+.. code:: shell
+
+    ./tools/cert_create/cert_create -h
+
+--------------
+
+*Copyright (c) 2019, Arm Limited. All rights reserved.*
diff --git a/docs/getting_started/user-guide.rst b/docs/getting_started/user-guide.rst
deleted file mode 100644
index 9876531..0000000
--- a/docs/getting_started/user-guide.rst
+++ /dev/null
@@ -1,2214 +0,0 @@
-User Guide
-==========
-
-This document describes how to build Trusted Firmware-A (TF-A) and run it with a
-tested set of other software components using defined configurations on the Juno
-Arm development platform and Arm Fixed Virtual Platform (FVP) models. It is
-possible to use other software components, configurations and platforms but that
-is outside the scope of this document.
-
-This document assumes that the reader has previous experience running a fully
-bootable Linux software stack on Juno or FVP using the prebuilt binaries and
-filesystems provided by Linaro. Further information may be found in the
-`Linaro instructions`_. It also assumes that the user understands the role of
-the different software components required to boot a Linux system:
-
--  Specific firmware images required by the platform (e.g. SCP firmware on Juno)
--  Normal world bootloader (e.g. UEFI or U-Boot)
--  Device tree
--  Linux kernel image
--  Root filesystem
-
-This document also assumes that the user is familiar with the `FVP models`_ and
-the different command line options available to launch the model.
-
-This document should be used in conjunction with the :ref:`Firmware Design`.
-
-Host machine requirements
--------------------------
-
-The minimum recommended machine specification for building the software and
-running the FVP models is a dual-core processor running at 2GHz with 12GB of
-RAM. For best performance, use a machine with a quad-core processor running at
-2.6GHz with 16GB of RAM.
-
-The software has been tested on Ubuntu 16.04 LTS (64-bit). Packages used for
-building the software were installed from that distribution unless otherwise
-specified.
-
-The software has also been built on Windows 7 Enterprise SP1, using CMD.EXE,
-Cygwin, and Msys (MinGW) shells, using version 5.3.1 of the GNU toolchain.
-
-Tools
------
-
-Install the required packages to build TF-A with the following command:
-
-.. code:: shell
-
-    sudo apt-get install device-tree-compiler build-essential gcc make git libssl-dev
-
-Download and install the AArch32 (arm-eabi) or AArch64 little-endian
-(aarch64-linux-gnu) GCC 8.3-2019.03 cross compiler from `Arm Developer page`_.
-
-Optionally, TF-A can be built using clang version 4.0 or newer or Arm
-Compiler 6. See instructions below on how to switch the default compiler.
-
-In addition, the following optional packages and tools may be needed:
-
--  ``device-tree-compiler`` (dtc) package if you need to rebuild the Flattened Device
-   Tree (FDT) source files (``.dts`` files) provided with this software. The
-   version of dtc must be 1.4.6 or above.
-
--  For debugging, Arm `Development Studio 5 (DS-5)`_.
-
--  To create and modify the diagram files included in the documentation, `Dia`_.
-   This tool can be found in most Linux distributions. Inkscape is needed to
-   generate the actual \*.png files.
-
-TF-A has been tested with pre-built binaries and file systems from
-`Linaro Release 19.06`_. Alternatively, you can build the binaries from
-source using instructions provided at the `Arm Platforms User guide`_.
-
-Getting the TF-A source code
-----------------------------
-
-Clone the repository from the Gerrit server. The project details may be found
-on the `arm-trusted-firmware-a project page`_. We recommend the "`Clone with
-commit-msg hook`" clone method, which will setup the git commit hook that
-automatically generates and inserts appropriate `Change-Id:` lines in your
-commit messages.
-
-Checking source code style
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Trusted Firmware follows the `Linux Coding Style`_ . When making changes to the
-source, for submission to the project, the source must be in compliance with
-this style guide.
-
-Additional, project-specific guidelines are defined in the
-:ref:`Coding Style & Guidelines` document.
-
-To assist with coding style compliance, the project Makefile contains two
-targets which both utilise the `checkpatch.pl` script that ships with the Linux
-source tree. The project also defines certain *checkpatch* options in the
-``.checkpatch.conf`` file in the top-level directory.
-
-.. note::
-   Checkpatch errors will gate upstream merging of pull requests.
-   Checkpatch warnings will not gate merging but should be reviewed and fixed if
-   possible.
-
-To check the entire source tree, you must first download copies of
-``checkpatch.pl``, ``spelling.txt`` and ``const_structs.checkpatch`` available
-in the `Linux master tree`_ *scripts* directory, then set the ``CHECKPATCH``
-environment variable to point to ``checkpatch.pl`` (with the other 2 files in
-the same directory) and build the `checkcodebase` target:
-
-.. code:: shell
-
-    make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkcodebase
-
-To just check the style on the files that differ between your local branch and
-the remote master, use:
-
-.. code:: shell
-
-    make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkpatch
-
-If you wish to check your patch against something other than the remote master,
-set the ``BASE_COMMIT`` variable to your desired branch. By default, ``BASE_COMMIT``
-is set to ``origin/master``.
-
-Building TF-A
--------------
-
--  Before building TF-A, the environment variable ``CROSS_COMPILE`` must point
-   to the cross compiler.
-
-   For AArch64:
-
-   .. code:: shell
-
-       export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
-
-   For AArch32:
-
-   .. code:: shell
-
-       export CROSS_COMPILE=<path-to-aarch32-gcc>/bin/arm-eabi-
-
-   It is possible to build TF-A using Clang or Arm Compiler 6. To do so
-   ``CC`` needs to point to the clang or armclang binary, which will
-   also select the clang or armclang assembler. Be aware that the
-   GNU linker is used by default.  In case of being needed the linker
-   can be overridden using the ``LD`` variable. Clang linker version 6 is
-   known to work with TF-A.
-
-   In both cases ``CROSS_COMPILE`` should be set as described above.
-
-   Arm Compiler 6 will be selected when the base name of the path assigned
-   to ``CC`` matches the string 'armclang'.
-
-   For AArch64 using Arm Compiler 6:
-
-   .. code:: shell
-
-       export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
-       make CC=<path-to-armclang>/bin/armclang PLAT=<platform> all
-
-   Clang will be selected when the base name of the path assigned to ``CC``
-   contains the string 'clang'. This is to allow both clang and clang-X.Y
-   to work.
-
-   For AArch64 using clang:
-
-   .. code:: shell
-
-       export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
-       make CC=<path-to-clang>/bin/clang PLAT=<platform> all
-
--  Change to the root directory of the TF-A source tree and build.
-
-   For AArch64:
-
-   .. code:: shell
-
-       make PLAT=<platform> all
-
-   For AArch32:
-
-   .. code:: shell
-
-       make PLAT=<platform> ARCH=aarch32 AARCH32_SP=sp_min all
-
-   Notes:
-
-   -  If ``PLAT`` is not specified, ``fvp`` is assumed by default. See the
-      `Summary of build options`_ for more information on available build
-      options.
-
-   -  (AArch32 only) ``AARCH32_SP`` is the AArch32 EL3 Runtime Software and it
-      corresponds to the BL32 image. A minimal ``AARCH32_SP``, sp_min, is
-      provided by TF-A to demonstrate how PSCI Library can be integrated with
-      an AArch32 EL3 Runtime Software. Some AArch32 EL3 Runtime Software may
-      include other runtime services, for example Trusted OS services. A guide
-      to integrate PSCI library with AArch32 EL3 Runtime Software can be found
-      at :ref:`PSCI Library Integration guide for Armv8-A AArch32 systems`.
-
-   -  (AArch64 only) The TSP (Test Secure Payload), corresponding to the BL32
-      image, is not compiled in by default. Refer to the
-      `Building the Test Secure Payload`_ section below.
-
-   -  By default this produces a release version of the build. To produce a
-      debug version instead, refer to the "Debugging options" section below.
-
-   -  The build process creates products in a ``build`` directory tree, building
-      the objects and binaries for each boot loader stage in separate
-      sub-directories. The following boot loader binary files are created
-      from the corresponding ELF files:
-
-      -  ``build/<platform>/<build-type>/bl1.bin``
-      -  ``build/<platform>/<build-type>/bl2.bin``
-      -  ``build/<platform>/<build-type>/bl31.bin`` (AArch64 only)
-      -  ``build/<platform>/<build-type>/bl32.bin`` (mandatory for AArch32)
-
-      where ``<platform>`` is the name of the chosen platform and ``<build-type>``
-      is either ``debug`` or ``release``. The actual number of images might differ
-      depending on the platform.
-
--  Build products for a specific build variant can be removed using:
-
-   .. code:: shell
-
-       make DEBUG=<D> PLAT=<platform> clean
-
-   ... where ``<D>`` is ``0`` or ``1``, as specified when building.
-
-   The build tree can be removed completely using:
-
-   .. code:: shell
-
-       make realclean
-
-Summary of build options
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-The TF-A build system supports the following build options. Unless mentioned
-otherwise, these options are expected to be specified at the build command
-line and are not to be modified in any component makefiles. Note that the
-build system doesn't track dependency for build options. Therefore, if any of
-the build options are changed from a previous build, a clean build must be
-performed.
-
-Common build options
-^^^^^^^^^^^^^^^^^^^^
-
--  ``AARCH32_INSTRUCTION_SET``: Choose the AArch32 instruction set that the
-   compiler should use. Valid values are T32 and A32. It defaults to T32 due to
-   code having a smaller resulting size.
-
--  ``AARCH32_SP`` : Choose the AArch32 Secure Payload component to be built as
-   as the BL32 image when ``ARCH=aarch32``. The value should be the path to the
-   directory containing the SP source, relative to the ``bl32/``; the directory
-   is expected to contain a makefile called ``<aarch32_sp-value>.mk``.
-
--  ``ARCH`` : Choose the target build architecture for TF-A. It can take either
-   ``aarch64`` or ``aarch32`` as values. By default, it is defined to
-   ``aarch64``.
-
--  ``ARM_ARCH_MAJOR``: The major version of Arm Architecture to target when
-   compiling TF-A. Its value must be numeric, and defaults to 8 . See also,
-   *Armv8 Architecture Extensions* and *Armv7 Architecture Extensions* in
-   :ref:`Firmware Design`.
-
--  ``ARM_ARCH_MINOR``: The minor version of Arm Architecture to target when
-   compiling TF-A. Its value must be a numeric, and defaults to 0. See also,
-   *Armv8 Architecture Extensions* in :ref:`Firmware Design`.
-
--  ``BL2``: This is an optional build option which specifies the path to BL2
-   image for the ``fip`` target. In this case, the BL2 in the TF-A will not be
-   built.
-
--  ``BL2U``: This is an optional build option which specifies the path to
-   BL2U image. In this case, the BL2U in TF-A will not be built.
-
--  ``BL2_AT_EL3``: This is an optional build option that enables the use of
-   BL2 at EL3 execution level.
-
--  ``BL2_IN_XIP_MEM``: In some use-cases BL2 will be stored in eXecute In Place
-   (XIP) memory, like BL1. In these use-cases, it is necessary to initialize
-   the RW sections in RAM, while leaving the RO sections in place. This option
-   enable this use-case. For now, this option is only supported when BL2_AT_EL3
-   is set to '1'.
-
--  ``BL2_INV_DCACHE``: This is an optional build option which control dcache
-   invalidation upon BL2 entry. Some platform cannot handle cache operations
-   during entry as the coherency unit is not yet initialized. This may cause
-   crashing. Leaving this option to '1' (default) will allow the operation.
-   This option is only relevant when BL2_AT_EL3 is set to '1'.
-
--  ``BL31``: This is an optional build option which specifies the path to
-   BL31 image for the ``fip`` target. In this case, the BL31 in TF-A will not
-   be built.
-
--  ``BL31_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
-   file that contains the BL31 private key in PEM format. If ``SAVE_KEYS=1``,
-   this file name will be used to save the key.
-
--  ``BL32``: This is an optional build option which specifies the path to
-   BL32 image for the ``fip`` target. In this case, the BL32 in TF-A will not
-   be built.
-
--  ``BL32_EXTRA1``: This is an optional build option which specifies the path to
-   Trusted OS Extra1 image for the  ``fip`` target.
-
--  ``BL32_EXTRA2``: This is an optional build option which specifies the path to
-   Trusted OS Extra2 image for the ``fip`` target.
-
--  ``BL32_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
-   file that contains the BL32 private key in PEM format. If ``SAVE_KEYS=1``,
-   this file name will be used to save the key.
-
--  ``BL33``: Path to BL33 image in the host file system. This is mandatory for
-   ``fip`` target in case TF-A BL2 is used.
-
--  ``BL33_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
-   file that contains the BL33 private key in PEM format. If ``SAVE_KEYS=1``,
-   this file name will be used to save the key.
-
--  ``BRANCH_PROTECTION``: Numeric value to enable ARMv8.3 Pointer Authentication
-   and ARMv8.5 Branch Target Identification support for TF-A BL images themselves.
-   If enabled, it is needed to use a compiler (e.g GCC 9.1 and later versions) that
-   supports the option ``-mbranch-protection``.
-   Selects the branch protection features to use:
--  0: Default value turns off all types of branch protection
--  1: Enables all types of branch protection features
--  2: Return address signing to its standard level
--  3: Extend the signing to include leaf functions
-
-   The table below summarizes ``BRANCH_PROTECTION`` values, GCC compilation options
-   and resulting PAuth/BTI features.
-
-   +-------+--------------+-------+-----+
-   | Value |  GCC option  | PAuth | BTI |
-   +=======+==============+=======+=====+
-   |   0   |     none     |   N   |  N  |
-   +-------+--------------+-------+-----+
-   |   1   |   standard   |   Y   |  Y  |
-   +-------+--------------+-------+-----+
-   |   2   |   pac-ret    |   Y   |  N  |
-   +-------+--------------+-------+-----+
-   |   3   | pac-ret+leaf |   Y   |  N  |
-   +-------+--------------+-------+-----+
-
-   This option defaults to 0 and this is an experimental feature.
-   Note that Pointer Authentication is enabled for Non-secure world
-   irrespective of the value of this option if the CPU supports it.
-
--  ``BUILD_MESSAGE_TIMESTAMP``: String used to identify the time and date of the
-   compilation of each build. It must be set to a C string (including quotes
-   where applicable). Defaults to a string that contains the time and date of
-   the compilation.
-
--  ``BUILD_STRING``: Input string for VERSION_STRING, which allows the TF-A
-   build to be uniquely identified. Defaults to the current git commit id.
-
--  ``CFLAGS``: Extra user options appended on the compiler's command line in
-   addition to the options set by the build system.
-
--  ``COLD_BOOT_SINGLE_CPU``: This option indicates whether the platform may
-   release several CPUs out of reset. It can take either 0 (several CPUs may be
-   brought up) or 1 (only one CPU will ever be brought up during cold reset).
-   Default is 0. If the platform always brings up a single CPU, there is no
-   need to distinguish between primary and secondary CPUs and the boot path can
-   be optimised. The ``plat_is_my_cpu_primary()`` and
-   ``plat_secondary_cold_boot_setup()`` platform porting interfaces do not need
-   to be implemented in this case.
-
--  ``CRASH_REPORTING``: A non-zero value enables a console dump of processor
-   register state when an unexpected exception occurs during execution of
-   BL31. This option defaults to the value of ``DEBUG`` - i.e. by default
-   this is only enabled for a debug build of the firmware.
-
--  ``CREATE_KEYS``: This option is used when ``GENERATE_COT=1``. It tells the
-   certificate generation tool to create new keys in case no valid keys are
-   present or specified. Allowed options are '0' or '1'. Default is '1'.
-
--  ``CTX_INCLUDE_AARCH32_REGS`` : Boolean option that, when set to 1, will cause
-   the AArch32 system registers to be included when saving and restoring the
-   CPU context. The option must be set to 0 for AArch64-only platforms (that
-   is on hardware that does not implement AArch32, or at least not at EL1 and
-   higher ELs). Default value is 1.
-
--  ``CTX_INCLUDE_FPREGS``: Boolean option that, when set to 1, will cause the FP
-   registers to be included when saving and restoring the CPU context. Default
-   is 0.
-
--  ``CTX_INCLUDE_MTE_REGS``: Enables register saving/reloading support for
-   ARMv8.5 Memory Tagging Extension. A value of 0 will disable
-   saving/reloading and restrict the use of MTE to the normal world if the
-   CPU has support, while a value of 1 enables the saving/reloading, allowing
-   the use of MTE in both the secure and non-secure worlds. Default is 0
-   (disabled) and this feature is experimental.
-
--  ``CTX_INCLUDE_PAUTH_REGS``: Boolean option that, when set to 1, enables
-   Pointer Authentication for Secure world. This will cause the ARMv8.3-PAuth
-   registers to be included when saving and restoring the CPU context as
-   part of world switch. Default value is 0 and this is an experimental feature.
-   Note that Pointer Authentication is enabled for Non-secure world irrespective
-   of the value of this flag if the CPU supports it.
-
--  ``DEBUG``: Chooses between a debug and release build. It can take either 0
-   (release) or 1 (debug) as values. 0 is the default.
-
--  ``DISABLE_BIN_GENERATION``: Boolean option to disable the generation
-   of the binary image. If set to 1, then only the ELF image is built.
-   0 is the default.
-
--  ``DYN_DISABLE_AUTH``: Provides the capability to dynamically disable Trusted
-   Board Boot authentication at runtime. This option is meant to be enabled only
-   for development platforms. ``TRUSTED_BOARD_BOOT`` flag must be set if this
-   flag has to be enabled. 0 is the default.
-
--  ``E``: Boolean option to make warnings into errors. Default is 1.
-
--  ``EL3_PAYLOAD_BASE``: This option enables booting an EL3 payload instead of
-   the normal boot flow. It must specify the entry point address of the EL3
-   payload. Please refer to the "Booting an EL3 payload" section for more
-   details.
-
--  ``ENABLE_AMU``: Boolean option to enable Activity Monitor Unit extensions.
-   This is an optional architectural feature available on v8.4 onwards. Some
-   v8.2 implementations also implement an AMU and this option can be used to
-   enable this feature on those systems as well. Default is 0.
-
--  ``ENABLE_ASSERTIONS``: This option controls whether or not calls to ``assert()``
-   are compiled out. For debug builds, this option defaults to 1, and calls to
-   ``assert()`` are left in place. For release builds, this option defaults to 0
-   and calls to ``assert()`` function are compiled out. This option can be set
-   independently of ``DEBUG``. It can also be used to hide any auxiliary code
-   that is only required for the assertion and does not fit in the assertion
-   itself.
-
--  ``ENABLE_BACKTRACE``: This option controls whether to enables backtrace
-   dumps or not. It is supported in both AArch64 and AArch32. However, in
-   AArch32 the format of the frame records are not defined in the AAPCS and they
-   are defined by the implementation. This implementation of backtrace only
-   supports the format used by GCC when T32 interworking is disabled. For this
-   reason enabling this option in AArch32 will force the compiler to only
-   generate A32 code. This option is enabled by default only in AArch64 debug
-   builds, but this behaviour can be overridden in each platform's Makefile or
-   in the build command line.
-
--  ``ENABLE_MPAM_FOR_LOWER_ELS``: Boolean option to enable lower ELs to use MPAM
-   feature. MPAM is an optional Armv8.4 extension that enables various memory
-   system components and resources to define partitions; software running at
-   various ELs can assign themselves to desired partition to control their
-   performance aspects.
-
-   When this option is set to ``1``, EL3 allows lower ELs to access their own
-   MPAM registers without trapping into EL3. This option doesn't make use of
-   partitioning in EL3, however. Platform initialisation code should configure
-   and use partitions in EL3 as required. This option defaults to ``0``.
-
--  ``ENABLE_PIE``: Boolean option to enable Position Independent Executable(PIE)
-   support within generic code in TF-A. This option is currently only supported
-   in BL31. Default is 0.
-
--  ``ENABLE_PMF``: Boolean option to enable support for optional Performance
-   Measurement Framework(PMF). Default is 0.
-
--  ``ENABLE_PSCI_STAT``: Boolean option to enable support for optional PSCI
-   functions ``PSCI_STAT_RESIDENCY`` and ``PSCI_STAT_COUNT``. Default is 0.
-   In the absence of an alternate stat collection backend, ``ENABLE_PMF`` must
-   be enabled. If ``ENABLE_PMF`` is set, the residency statistics are tracked in
-   software.
-
--  ``ENABLE_RUNTIME_INSTRUMENTATION``: Boolean option to enable runtime
-   instrumentation which injects timestamp collection points into TF-A to
-   allow runtime performance to be measured. Currently, only PSCI is
-   instrumented. Enabling this option enables the ``ENABLE_PMF`` build option
-   as well. Default is 0.
-
--  ``ENABLE_SPE_FOR_LOWER_ELS`` : Boolean option to enable Statistical Profiling
-   extensions. This is an optional architectural feature for AArch64.
-   The default is 1 but is automatically disabled when the target architecture
-   is AArch32.
-
--  ``ENABLE_SPM`` : Boolean option to enable the Secure Partition Manager (SPM).
-   Refer to :ref:`Secure Partition Manager` for more details about
-   this feature. Default is 0.
-
--  ``ENABLE_SVE_FOR_NS``: Boolean option to enable Scalable Vector Extension
-   (SVE) for the Non-secure world only. SVE is an optional architectural feature
-   for AArch64. Note that when SVE is enabled for the Non-secure world, access
-   to SIMD and floating-point functionality from the Secure world is disabled.
-   This is to avoid corruption of the Non-secure world data in the Z-registers
-   which are aliased by the SIMD and FP registers. The build option is not
-   compatible with the ``CTX_INCLUDE_FPREGS`` build option, and will raise an
-   assert on platforms where SVE is implemented and ``ENABLE_SVE_FOR_NS`` set to
-   1. The default is 1 but is automatically disabled when the target
-   architecture is AArch32.
-
--  ``ENABLE_STACK_PROTECTOR``: String option to enable the stack protection
-   checks in GCC. Allowed values are "all", "strong", "default" and "none". The
-   default value is set to "none". "strong" is the recommended stack protection
-   level if this feature is desired. "none" disables the stack protection. For
-   all values other than "none", the ``plat_get_stack_protector_canary()``
-   platform hook needs to be implemented. The value is passed as the last
-   component of the option ``-fstack-protector-$ENABLE_STACK_PROTECTOR``.
-
--  ``ERROR_DEPRECATED``: This option decides whether to treat the usage of
-   deprecated platform APIs, helper functions or drivers within Trusted
-   Firmware as error. It can take the value 1 (flag the use of deprecated
-   APIs as error) or 0. The default is 0.
-
--  ``EL3_EXCEPTION_HANDLING``: When set to ``1``, enable handling of exceptions
-   targeted at EL3. When set ``0`` (default), no exceptions are expected or
-   handled at EL3, and a panic will result. This is supported only for AArch64
-   builds.
-
--  ``FAULT_INJECTION_SUPPORT``: ARMv8.4 extensions introduced support for fault
-   injection from lower ELs, and this build option enables lower ELs to use
-   Error Records accessed via System Registers to inject faults. This is
-   applicable only to AArch64 builds.
-
-   This feature is intended for testing purposes only, and is advisable to keep
-   disabled for production images.
-
--  ``FIP_NAME``: This is an optional build option which specifies the FIP
-   filename for the ``fip`` target. Default is ``fip.bin``.
-
--  ``FWU_FIP_NAME``: This is an optional build option which specifies the FWU
-   FIP filename for the ``fwu_fip`` target. Default is ``fwu_fip.bin``.
-
--  ``GENERATE_COT``: Boolean flag used to build and execute the ``cert_create``
-   tool to create certificates as per the Chain of Trust described in
-   :ref:`Trusted Board Boot`. The build system then calls ``fiptool`` to
-   include the certificates in the FIP and FWU_FIP. Default value is '0'.
-
-   Specify both ``TRUSTED_BOARD_BOOT=1`` and ``GENERATE_COT=1`` to include support
-   for the Trusted Board Boot feature in the BL1 and BL2 images, to generate
-   the corresponding certificates, and to include those certificates in the
-   FIP and FWU_FIP.
-
-   Note that if ``TRUSTED_BOARD_BOOT=0`` and ``GENERATE_COT=1``, the BL1 and BL2
-   images will not include support for Trusted Board Boot. The FIP will still
-   include the corresponding certificates. This FIP can be used to verify the
-   Chain of Trust on the host machine through other mechanisms.
-
-   Note that if ``TRUSTED_BOARD_BOOT=1`` and ``GENERATE_COT=0``, the BL1 and BL2
-   images will include support for Trusted Board Boot, but the FIP and FWU_FIP
-   will not include the corresponding certificates, causing a boot failure.
-
--  ``GICV2_G0_FOR_EL3``: Unlike GICv3, the GICv2 architecture doesn't have
-   inherent support for specific EL3 type interrupts. Setting this build option
-   to ``1`` assumes GICv2 *Group 0* interrupts are expected to target EL3, both
-   by `platform abstraction layer`__ and `Interrupt Management Framework`__.
-   This allows GICv2 platforms to enable features requiring EL3 interrupt type.
-   This also means that all GICv2 Group 0 interrupts are delivered to EL3, and
-   the Secure Payload interrupts needs to be synchronously handed over to Secure
-   EL1 for handling. The default value of this option is ``0``, which means the
-   Group 0 interrupts are assumed to be handled by Secure EL1.
-
-   .. __: `platform-interrupt-controller-API.rst`
-   .. __: `interrupt-framework-design.rst`
-
--  ``HANDLE_EA_EL3_FIRST``: When set to ``1``, External Aborts and SError
-   Interrupts will be always trapped in EL3 i.e. in BL31 at runtime. When set to
-   ``0`` (default), these exceptions will be trapped in the current exception
-   level (or in EL1 if the current exception level is EL0).
-
--  ``HW_ASSISTED_COHERENCY``: On most Arm systems to-date, platform-specific
-   software operations are required for CPUs to enter and exit coherency.
-   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
-   library is not supported.
-
--  ``JUNO_AARCH32_EL3_RUNTIME``: This build flag enables you to execute EL3
-   runtime software in AArch32 mode, which is required to run AArch32 on Juno.
-   By default this flag is set to '0'. Enabling this flag builds BL1 and BL2 in
-   AArch64 and facilitates the loading of ``SP_MIN`` and BL33 as AArch32 executable
-   images.
-
--  ``KEY_ALG``: This build flag enables the user to select the algorithm to be
-   used for generating the PKCS keys and subsequent signing of the certificate.
-   It accepts 2 values: ``rsa`` and ``ecdsa``. The default value of this flag
-   is ``rsa`` which is the TBBR compliant PKCS#1 RSA 2.1 scheme.
-
--  ``KEY_SIZE``: This build flag enables the user to select the key size for
-   the algorithm specified by ``KEY_ALG``. The valid values for ``KEY_SIZE``
-   depend on the chosen algorithm.
-
-   +-----------+------------------------------------+
-   |  KEY_ALG  |        Possible key sizes          |
-   +===========+====================================+
-   |    rsa    |  1024, 2048 (default), 3072, 4096  |
-   +-----------+------------------------------------+
-   |   ecdsa   |            unavailable             |
-   +-----------+------------------------------------+
-
--  ``HASH_ALG``: This build flag enables the user to select the secure hash
-   algorithm. It accepts 3 values: ``sha256``, ``sha384`` and ``sha512``.
-   The default value of this flag is ``sha256``.
-
--  ``LDFLAGS``: Extra user options appended to the linkers' command line in
-   addition to the one set by the build system.
-
--  ``LOG_LEVEL``: Chooses the log level, which controls the amount of console log
-   output compiled into the build. This should be one of the following:
-
-   ::
-
-       0  (LOG_LEVEL_NONE)
-       10 (LOG_LEVEL_ERROR)
-       20 (LOG_LEVEL_NOTICE)
-       30 (LOG_LEVEL_WARNING)
-       40 (LOG_LEVEL_INFO)
-       50 (LOG_LEVEL_VERBOSE)
-
-   All log output up to and including the selected log level is compiled into
-   the build. The default value is 40 in debug builds and 20 in release builds.
-
--  ``NON_TRUSTED_WORLD_KEY``: This option is used when ``GENERATE_COT=1``. It
-   specifies the file that contains the Non-Trusted World private key in PEM
-   format. If ``SAVE_KEYS=1``, this file name will be used to save the key.
-
--  ``NS_BL2U``: Path to NS_BL2U image in the host file system. This image is
-   optional. It is only needed if the platform makefile specifies that it
-   is required in order to build the ``fwu_fip`` target.
-
--  ``NS_TIMER_SWITCH``: Enable save and restore for non-secure timer register
-   contents upon world switch. It can take either 0 (don't save and restore) or
-   1 (do save and restore). 0 is the default. An SPD may set this to 1 if it
-   wants the timer registers to be saved and restored.
-
--  ``OVERRIDE_LIBC``: This option allows platforms to override the default libc
-   for the BL image. It can be either 0 (include) or 1 (remove). The default
-   value is 0.
-
--  ``PL011_GENERIC_UART``: Boolean option to indicate the PL011 driver that
-   the underlying hardware is not a full PL011 UART but a minimally compliant
-   generic UART, which is a subset of the PL011. The driver will not access
-   any register that is not part of the SBSA generic UART specification.
-   Default value is 0 (a full PL011 compliant UART is present).
-
--  ``PLAT``: Choose a platform to build TF-A for. The chosen platform name
-   must be subdirectory of any depth under ``plat/``, and must contain a
-   platform makefile named ``platform.mk``. For example, to build TF-A for the
-   Arm Juno board, select PLAT=juno.
-
--  ``PRELOADED_BL33_BASE``: This option enables booting a preloaded BL33 image
-   instead of the normal boot flow. When defined, it must specify the entry
-   point address for the preloaded BL33 image. This option is incompatible with
-   ``EL3_PAYLOAD_BASE``. If both are defined, ``EL3_PAYLOAD_BASE`` has priority
-   over ``PRELOADED_BL33_BASE``.
-
--  ``PROGRAMMABLE_RESET_ADDRESS``: This option indicates whether the reset
-   vector address can be programmed or is fixed on the platform. It can take
-   either 0 (fixed) or 1 (programmable). Default is 0. If the platform has a
-   programmable reset address, it is expected that a CPU will start executing
-   code directly at the right address, both on a cold and warm reset. In this
-   case, there is no need to identify the entrypoint on boot and the boot path
-   can be optimised. The ``plat_get_my_entrypoint()`` platform porting interface
-   does not need to be implemented in this case.
-
--  ``PSCI_EXTENDED_STATE_ID``: As per PSCI1.0 Specification, there are 2 formats
-   possible for the PSCI power-state parameter: original and extended State-ID
-   formats. This flag if set to 1, configures the generic PSCI layer to use the
-   extended format. The default value of this flag is 0, which means by default
-   the original power-state format is used by the PSCI implementation. This flag
-   should be specified by the platform makefile and it governs the return value
-   of PSCI_FEATURES API for CPU_SUSPEND smc function id. When this option is
-   enabled on Arm platforms, the option ``ARM_RECOM_STATE_ID_ENC`` needs to be
-   set to 1 as well.
-
--  ``RAS_EXTENSION``: When set to ``1``, enable Armv8.2 RAS features. RAS features
-   are an optional extension for pre-Armv8.2 CPUs, but are mandatory for Armv8.2
-   or later CPUs.
-
-   When ``RAS_EXTENSION`` is set to ``1``, ``HANDLE_EA_EL3_FIRST`` must also be
-   set to ``1``.
-
-   This option is disabled by default.
-
--  ``RESET_TO_BL31``: Enable BL31 entrypoint as the CPU reset vector instead
-   of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1
-   entrypoint) or 1 (CPU reset to BL31 entrypoint).
-   The default value is 0.
-
--  ``RESET_TO_SP_MIN``: SP_MIN is the minimal AArch32 Secure Payload provided
-   in TF-A. This flag configures SP_MIN entrypoint as the CPU reset vector
-   instead of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1
-   entrypoint) or 1 (CPU reset to SP_MIN entrypoint). The default value is 0.
-
--  ``ROT_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
-   file that contains the ROT private key in PEM format. If ``SAVE_KEYS=1``, this
-   file name will be used to save the key.
-
--  ``SANITIZE_UB``: This option enables the Undefined Behaviour sanitizer. It
-   can take 3 values: 'off' (default), 'on' and 'trap'. When using 'trap',
-   gcc and clang will insert calls to ``__builtin_trap`` on detected
-   undefined behaviour, which defaults to a ``brk`` instruction. When using
-   'on', undefined behaviour is translated to a call to special handlers which
-   prints the exact location of the problem and its cause and then panics.
-
-    .. note::
-        Because of the space penalty of the Undefined Behaviour sanitizer,
-        this option will increase the size of the binary. Depending on the
-        memory constraints of the target platform, it may not be possible to
-        enable the sanitizer for all images (BL1 and BL2 are especially
-        likely to be memory constrained). We recommend that the
-        sanitizer is enabled only in debug builds.
-
--  ``SAVE_KEYS``: This option is used when ``GENERATE_COT=1``. It tells the
-   certificate generation tool to save the keys used to establish the Chain of
-   Trust. Allowed options are '0' or '1'. Default is '0' (do not save).
-
--  ``SCP_BL2``: Path to SCP_BL2 image in the host file system. This image is optional.
-   If a SCP_BL2 image is present then this option must be passed for the ``fip``
-   target.
-
--  ``SCP_BL2_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
-   file that contains the SCP_BL2 private key in PEM format. If ``SAVE_KEYS=1``,
-   this file name will be used to save the key.
-
--  ``SCP_BL2U``: Path to SCP_BL2U image in the host file system. This image is
-   optional. It is only needed if the platform makefile specifies that it
-   is required in order to build the ``fwu_fip`` target.
-
--  ``SDEI_SUPPORT``: Setting this to ``1`` enables support for Software
-   Delegated Exception Interface to BL31 image. This defaults to ``0``.
-
-   When set to ``1``, the build option ``EL3_EXCEPTION_HANDLING`` must also be
-   set to ``1``.
-
--  ``SEPARATE_CODE_AND_RODATA``: Whether code and read-only data should be
-   isolated on separate memory pages. This is a trade-off between security and
-   memory usage. See "Isolating code and read-only data on separate memory
-   pages" section in :ref:`Firmware Design`. This flag is disabled by default
-   and affects all BL images.
-
--  ``SPD``: Choose a Secure Payload Dispatcher component to be built into TF-A.
-   This build option is only valid if ``ARCH=aarch64``. The value should be
-   the path to the directory containing the SPD source, relative to
-   ``services/spd/``; the directory is expected to contain a makefile called
-   ``<spd-value>.mk``.
-
--  ``SPIN_ON_BL1_EXIT``: This option introduces an infinite loop in BL1. It can
-   take either 0 (no loop) or 1 (add a loop). 0 is the default. This loop stops
-   execution in BL1 just before handing over to BL31. At this point, all
-   firmware images have been loaded in memory, and the MMU and caches are
-   turned off. Refer to the "Debugging options" section for more details.
-
--  ``SP_MIN_WITH_SECURE_FIQ``: Boolean flag to indicate the SP_MIN handles
-   secure interrupts (caught through the FIQ line). Platforms can enable
-   this directive if they need to handle such interruption. When enabled,
-   the FIQ are handled in monitor mode and non secure world is not allowed
-   to mask these events. Platforms that enable FIQ handling in SP_MIN shall
-   implement the api ``sp_min_plat_fiq_handler()``. The default value is 0.
-
--  ``TRUSTED_BOARD_BOOT``: Boolean flag to include support for the Trusted Board
-   Boot feature. When set to '1', BL1 and BL2 images include support to load
-   and verify the certificates and images in a FIP, and BL1 includes support
-   for the Firmware Update. The default value is '0'. Generation and inclusion
-   of certificates in the FIP and FWU_FIP depends upon the value of the
-   ``GENERATE_COT`` option.
-
-   .. warning::
-      This option depends on ``CREATE_KEYS`` to be enabled. If the keys
-      already exist in disk, they will be overwritten without further notice.
-
--  ``TRUSTED_WORLD_KEY``: This option is used when ``GENERATE_COT=1``. It
-   specifies the file that contains the Trusted World private key in PEM
-   format. If ``SAVE_KEYS=1``, this file name will be used to save the key.
-
--  ``TSP_INIT_ASYNC``: Choose BL32 initialization method as asynchronous or
-   synchronous, (see "Initializing a BL32 Image" section in
-   :ref:`Firmware Design`). It can take the value 0 (BL32 is initialized using
-   synchronous method) or 1 (BL32 is initialized using asynchronous method).
-   Default is 0.
-
--  ``TSP_NS_INTR_ASYNC_PREEMPT``: A non zero value enables the interrupt
-   routing model which routes non-secure interrupts asynchronously from TSP
-   to EL3 causing immediate preemption of TSP. The EL3 is responsible
-   for saving and restoring the TSP context in this routing model. The
-   default routing model (when the value is 0) is to route non-secure
-   interrupts to TSP allowing it to save its context and hand over
-   synchronously to EL3 via an SMC.
-
-   .. note::
-      When ``EL3_EXCEPTION_HANDLING`` is ``1``, ``TSP_NS_INTR_ASYNC_PREEMPT``
-      must also be set to ``1``.
-
--  ``USE_ARM_LINK``: This flag determines whether to enable support for ARM
-   linker. When the ``LINKER`` build variable points to the armlink linker,
-   this flag is enabled automatically. To enable support for armlink, platforms
-   will have to provide a scatter file for the BL image. Currently, Tegra
-   platforms use the armlink support to compile BL3-1 images.
-
--  ``USE_COHERENT_MEM``: This flag determines whether to include the coherent
-   memory region in the BL memory map or not (see "Use of Coherent memory in
-   TF-A" section in :ref:`Firmware Design`). It can take the value 1
-   (Coherent memory region is included) or 0 (Coherent memory region is
-   excluded). Default is 1.
-
--  ``USE_ROMLIB``: This flag determines whether library at ROM will be used.
-   This feature creates a library of functions to be placed in ROM and thus
-   reduces SRAM usage. Refer to :ref:`Library at ROM` for further details.
-   Default is 0.
-
--  ``USE_SPINLOCK_CAS``: Setting this build flag to 1 selects the spinlock
-    implementation variant using the ARMv8.1-LSE compare-and-swap instruction.
-    Notice this option is experimental and only available to AArch64 builds.
-
--  ``V``: Verbose build. If assigned anything other than 0, the build commands
-   are printed. Default is 0.
-
--  ``VERSION_STRING``: String used in the log output for each TF-A image.
-   Defaults to a string formed by concatenating the version number, build type
-   and build string.
-
--  ``W``: Warning level. Some compiler warning options of interest have been
-   regrouped and put in the root Makefile. This flag can take the values 0 to 3,
-   each level enabling more warning options. Default is 0.
-
--  ``WARMBOOT_ENABLE_DCACHE_EARLY`` : Boolean option to enable D-cache early on
-   the CPU after warm boot. This is applicable for platforms which do not
-   require interconnect programming to enable cache coherency (eg: single
-   cluster platforms). If this option is enabled, then warm boot path
-   enables D-caches immediately after enabling MMU. This option defaults to 0.
-
-Arm development platform specific build options
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
--  ``ARM_BL31_IN_DRAM``: Boolean option to select loading of BL31 in TZC secured
-   DRAM. By default, BL31 is in the secure SRAM. Set this flag to 1 to load
-   BL31 in TZC secured DRAM. If TSP is present, then setting this option also
-   sets the TSP location to DRAM and ignores the ``ARM_TSP_RAM_LOCATION`` build
-   flag.
-
--  ``ARM_CONFIG_CNTACR``: boolean option to unlock access to the ``CNTBase<N>``
-   frame registers by setting the ``CNTCTLBase.CNTACR<N>`` register bits. The
-   frame number ``<N>`` is defined by ``PLAT_ARM_NSTIMER_FRAME_ID``, which should
-   match the frame used by the Non-Secure image (normally the Linux kernel).
-   Default is true (access to the frame is allowed).
-
--  ``ARM_DISABLE_TRUSTED_WDOG``: boolean option to disable the Trusted Watchdog.
-   By default, Arm platforms use a watchdog to trigger a system reset in case
-   an error is encountered during the boot process (for example, when an image
-   could not be loaded or authenticated). The watchdog is enabled in the early
-   platform setup hook at BL1 and disabled in the BL1 prepare exit hook. The
-   Trusted Watchdog may be disabled at build time for testing or development
-   purposes.
-
--  ``ARM_LINUX_KERNEL_AS_BL33``: The Linux kernel expects registers x0-x3 to
-   have specific values at boot. This boolean option allows the Trusted Firmware
-   to have a Linux kernel image as BL33 by preparing the registers to these
-   values before jumping to BL33. This option defaults to 0 (disabled). For
-   AArch64 ``RESET_TO_BL31`` and for AArch32 ``RESET_TO_SP_MIN`` must be 1 when
-   using it. If this option is set to 1, ``ARM_PRELOADED_DTB_BASE`` must be set
-   to the location of a device tree blob (DTB) already loaded in memory. The
-   Linux Image address must be specified using the ``PRELOADED_BL33_BASE``
-   option.
-
--  ``ARM_PLAT_MT``: This flag determines whether the Arm platform layer has to
-   cater for the multi-threading ``MT`` bit when accessing MPIDR. When this flag
-   is set, the functions which deal with MPIDR assume that the ``MT`` bit in
-   MPIDR is set and access the bit-fields in MPIDR accordingly. Default value of
-   this flag is 0. Note that this option is not used on FVP platforms.
-
--  ``ARM_RECOM_STATE_ID_ENC``: The PSCI1.0 specification recommends an encoding
-   for the construction of composite state-ID in the power-state parameter.
-   The existing PSCI clients currently do not support this encoding of
-   State-ID yet. Hence this flag is used to configure whether to use the
-   recommended State-ID encoding or not. The default value of this flag is 0,
-   in which case the platform is configured to expect NULL in the State-ID
-   field of power-state parameter.
-
--  ``ARM_ROTPK_LOCATION``: used when ``TRUSTED_BOARD_BOOT=1``. It specifies the
-   location of the ROTPK hash returned by the function ``plat_get_rotpk_info()``
-   for Arm platforms. Depending on the selected option, the proper private key
-   must be specified using the ``ROT_KEY`` option when building the Trusted
-   Firmware. This private key will be used by the certificate generation tool
-   to sign the BL2 and Trusted Key certificates. Available options for
-   ``ARM_ROTPK_LOCATION`` are:
-
-   -  ``regs`` : return the ROTPK hash stored in the Trusted root-key storage
-      registers. The private key corresponding to this ROTPK hash is not
-      currently available.
-   -  ``devel_rsa`` : return a development public key hash embedded in the BL1
-      and BL2 binaries. This hash has been obtained from the RSA public key
-      ``arm_rotpk_rsa.der``, located in ``plat/arm/board/common/rotpk``. To use
-      this option, ``arm_rotprivk_rsa.pem`` must be specified as ``ROT_KEY`` when
-      creating the certificates.
-   -  ``devel_ecdsa`` : return a development public key hash embedded in the BL1
-      and BL2 binaries. This hash has been obtained from the ECDSA public key
-      ``arm_rotpk_ecdsa.der``, located in ``plat/arm/board/common/rotpk``. To use
-      this option, ``arm_rotprivk_ecdsa.pem`` must be specified as ``ROT_KEY``
-      when creating the certificates.
-
--  ``ARM_TSP_RAM_LOCATION``: location of the TSP binary. Options:
-
-   -  ``tsram`` : Trusted SRAM (default option when TBB is not enabled)
-   -  ``tdram`` : Trusted DRAM (if available)
-   -  ``dram`` : Secure region in DRAM (default option when TBB is enabled,
-      configured by the TrustZone controller)
-
--  ``ARM_XLAT_TABLES_LIB_V1``: boolean option to compile TF-A with version 1
-   of the translation tables library instead of version 2. It is set to 0 by
-   default, which selects version 2.
-
--  ``ARM_CRYPTOCELL_INTEG`` : bool option to enable TF-A to invoke Arm®
-   TrustZone® CryptoCell functionality for Trusted Board Boot on capable Arm
-   platforms. If this option is specified, then the path to the CryptoCell
-   SBROM library must be specified via ``CCSBROM_LIB_PATH`` flag.
-
-For a better understanding of these options, the Arm development platform memory
-map is explained in the :ref:`Firmware Design`.
-
-Arm CSS platform specific build options
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
--  ``CSS_DETECT_PRE_1_7_0_SCP``: Boolean flag to detect SCP version
-   incompatibility. Version 1.7.0 of the SCP firmware made a non-backwards
-   compatible change to the MTL protocol, used for AP/SCP communication.
-   TF-A no longer supports earlier SCP versions. If this option is set to 1
-   then TF-A will detect if an earlier version is in use. Default is 1.
-
--  ``CSS_LOAD_SCP_IMAGES``: Boolean flag, which when set, adds SCP_BL2 and
-   SCP_BL2U to the FIP and FWU_FIP respectively, and enables them to be loaded
-   during boot. Default is 1.
-
--  ``CSS_USE_SCMI_SDS_DRIVER``: Boolean flag which selects SCMI/SDS drivers
-   instead of SCPI/BOM driver for communicating with the SCP during power
-   management operations and for SCP RAM Firmware transfer. If this option
-   is set to 1, then SCMI/SDS drivers will be used. Default is 0.
-
-Arm FVP platform specific build options
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
--  ``FVP_CLUSTER_COUNT`` : Configures the cluster count to be used to
-   build the topology tree within TF-A. By default TF-A is configured for dual
-   cluster topology and this option can be used to override the default value.
-
--  ``FVP_INTERCONNECT_DRIVER``: Selects the interconnect driver to be built. The
-   default interconnect driver depends on the value of ``FVP_CLUSTER_COUNT`` as
-   explained in the options below:
-
-   -  ``FVP_CCI`` : The CCI driver is selected. This is the default
-      if 0 < ``FVP_CLUSTER_COUNT`` <= 2.
-   -  ``FVP_CCN`` : The CCN driver is selected. This is the default
-      if ``FVP_CLUSTER_COUNT`` > 2.
-
--  ``FVP_MAX_CPUS_PER_CLUSTER``: Sets the maximum number of CPUs implemented in
-   a single cluster.  This option defaults to 4.
-
--  ``FVP_MAX_PE_PER_CPU``: Sets the maximum number of PEs implemented on any CPU
-   in the system. This option defaults to 1. Note that the build option
-   ``ARM_PLAT_MT`` doesn't have any effect on FVP platforms.
-
--  ``FVP_USE_GIC_DRIVER`` : Selects the GIC driver to be built. Options:
-
-   -  ``FVP_GIC600`` : The GIC600 implementation of GICv3 is selected
-   -  ``FVP_GICV2`` : The GICv2 only driver is selected
-   -  ``FVP_GICV3`` : The GICv3 only driver is selected (default option)
-
--  ``FVP_USE_SP804_TIMER`` : Use the SP804 timer instead of the Generic Timer
-   for functions that wait for an arbitrary time length (udelay and mdelay).
-   The default value is 0.
-
--  ``FVP_HW_CONFIG_DTS`` : Specify the path to the DTS file to be compiled
-   to DTB and packaged in FIP as the HW_CONFIG. See :ref:`Firmware Design` for
-   details on HW_CONFIG. By default, this is initialized to a sensible DTS
-   file in ``fdts/`` folder depending on other build options. But some cases,
-   like shifted affinity format for MPIDR, cannot be detected at build time
-   and this option is needed to specify the appropriate DTS file.
-
--  ``FVP_HW_CONFIG`` : Specify the path to the HW_CONFIG blob to be packaged in
-   FIP. See :ref:`Firmware Design` for details on HW_CONFIG. This option is
-   similar to the ``FVP_HW_CONFIG_DTS`` option, but it directly specifies the
-   HW_CONFIG blob instead of the DTS file. This option is useful to override
-   the default HW_CONFIG selected by the build system.
-
-ARM JUNO platform specific build options
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
--  ``JUNO_TZMP1`` : Boolean option to configure Juno to be used for TrustZone
-   Media Protection (TZ-MP1). Default value of this flag is 0.
-
-Debugging options
-~~~~~~~~~~~~~~~~~
-
-To compile a debug version and make the build more verbose use
-
-.. code:: shell
-
-    make PLAT=<platform> DEBUG=1 V=1 all
-
-AArch64 GCC uses DWARF version 4 debugging symbols by default. Some tools (for
-example DS-5) might not support this and may need an older version of DWARF
-symbols to be emitted by GCC. This can be achieved by using the
-``-gdwarf-<version>`` flag, with the version being set to 2 or 3. Setting the
-version to 2 is recommended for DS-5 versions older than 5.16.
-
-When debugging logic problems it might also be useful to disable all compiler
-optimizations by using ``-O0``.
-
-.. warning::
-   Using ``-O0`` could cause output images to be larger and base addresses
-   might need to be recalculated (see the **Memory layout on Arm development
-   platforms** section in the :ref:`Firmware Design`).
-
-Extra debug options can be passed to the build system by setting ``CFLAGS`` or
-``LDFLAGS``:
-
-.. code:: shell
-
-    CFLAGS='-O0 -gdwarf-2'                                     \
-    make PLAT=<platform> DEBUG=1 V=1 all
-
-Note that using ``-Wl,`` style compilation driver options in ``CFLAGS`` will be
-ignored as the linker is called directly.
-
-It is also possible to introduce an infinite loop to help in debugging the
-post-BL2 phase of TF-A. This can be done by rebuilding BL1 with the
-``SPIN_ON_BL1_EXIT=1`` build flag. Refer to the `Summary of build options`_
-section. In this case, the developer may take control of the target using a
-debugger when indicated by the console output. When using DS-5, the following
-commands can be used:
-
-::
-
-    # Stop target execution
-    interrupt
-
-    #
-    # Prepare your debugging environment, e.g. set breakpoints
-    #
-
-    # Jump over the debug loop
-    set var $AARCH64::$Core::$PC = $AARCH64::$Core::$PC + 4
-
-    # Resume execution
-    continue
-
-Building the Test Secure Payload
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The TSP is coupled with a companion runtime service in the BL31 firmware,
-called the TSPD. Therefore, if you intend to use the TSP, the BL31 image
-must be recompiled as well. For more information on SPs and SPDs, see the
-:ref:`Secure-EL1 Payloads and Dispatchers <firmware_design_sel1_spd>` section
-in the :ref:`Firmware Design` document.
-
-First clean the TF-A build directory to get rid of any previous BL31 binary.
-Then to build the TSP image use:
-
-.. code:: shell
-
-    make PLAT=<platform> SPD=tspd all
-
-An additional boot loader binary file is created in the ``build`` directory:
-
-::
-
-    build/<platform>/<build-type>/bl32.bin
-
-
-Building and using the FIP tool
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Firmware Image Package (FIP) is a packaging format used by TF-A to package
-firmware images in a single binary. The number and type of images that should
-be packed in a FIP is platform specific and may include TF-A images and other
-firmware images required by the platform. For example, most platforms require
-a BL33 image which corresponds to the normal world bootloader (e.g. UEFI or
-U-Boot).
-
-The TF-A build system provides the make target ``fip`` to create a FIP file
-for the specified platform using the FIP creation tool included in the TF-A
-project. Examples below show how to build a FIP file for FVP, packaging TF-A
-and BL33 images.
-
-For AArch64:
-
-.. code:: shell
-
-    make PLAT=fvp BL33=<path-to>/bl33.bin fip
-
-For AArch32:
-
-.. code:: shell
-
-    make PLAT=fvp ARCH=aarch32 AARCH32_SP=sp_min BL33=<path-to>/bl33.bin fip
-
-The resulting FIP may be found in:
-
-::
-
-    build/fvp/<build-type>/fip.bin
-
-For advanced operations on FIP files, it is also possible to independently build
-the tool and create or modify FIPs using this tool. To do this, follow these
-steps:
-
-It is recommended to remove old artifacts before building the tool:
-
-.. code:: shell
-
-    make -C tools/fiptool clean
-
-Build the tool:
-
-.. code:: shell
-
-    make [DEBUG=1] [V=1] fiptool
-
-The tool binary can be located in:
-
-::
-
-    ./tools/fiptool/fiptool
-
-Invoking the tool with ``help`` will print a help message with all available
-options.
-
-Example 1: create a new Firmware package ``fip.bin`` that contains BL2 and BL31:
-
-.. code:: shell
-
-    ./tools/fiptool/fiptool create \
-        --tb-fw build/<platform>/<build-type>/bl2.bin \
-        --soc-fw build/<platform>/<build-type>/bl31.bin \
-        fip.bin
-
-Example 2: view the contents of an existing Firmware package:
-
-.. code:: shell
-
-    ./tools/fiptool/fiptool info <path-to>/fip.bin
-
-Example 3: update the entries of an existing Firmware package:
-
-.. code:: shell
-
-    # Change the BL2 from Debug to Release version
-    ./tools/fiptool/fiptool update \
-        --tb-fw build/<platform>/release/bl2.bin \
-        build/<platform>/debug/fip.bin
-
-Example 4: unpack all entries from an existing Firmware package:
-
-.. code:: shell
-
-    # Images will be unpacked to the working directory
-    ./tools/fiptool/fiptool unpack <path-to>/fip.bin
-
-Example 5: remove an entry from an existing Firmware package:
-
-.. code:: shell
-
-    ./tools/fiptool/fiptool remove \
-        --tb-fw build/<platform>/debug/fip.bin
-
-Note that if the destination FIP file exists, the create, update and
-remove operations will automatically overwrite it.
-
-The unpack operation will fail if the images already exist at the
-destination. In that case, use -f or --force to continue.
-
-More information about FIP can be found in the :ref:`Firmware Design` document.
-
-Building FIP images with support for Trusted Board Boot
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Trusted Board Boot primarily consists of the following two features:
-
--  Image Authentication, described in :ref:`Trusted Board Boot`, and
--  Firmware Update, described in :ref:`Firmware Update (FWU)`
-
-The following steps should be followed to build FIP and (optionally) FWU_FIP
-images with support for these features:
-
-#. Fulfill the dependencies of the ``mbedtls`` cryptographic and image parser
-   modules by checking out a recent version of the `mbed TLS Repository`_. It
-   is important to use a version that is compatible with TF-A and fixes any
-   known security vulnerabilities. See `mbed TLS Security Center`_ for more
-   information. The latest version of TF-A is tested with tag
-   ``mbedtls-2.16.2``.
-
-   The ``drivers/auth/mbedtls/mbedtls_*.mk`` files contain the list of mbed TLS
-   source files the modules depend upon.
-   ``include/drivers/auth/mbedtls/mbedtls_config.h`` contains the configuration
-   options required to build the mbed TLS sources.
-
-   Note that the mbed TLS library is licensed under the Apache version 2.0
-   license. Using mbed TLS source code will affect the licensing of TF-A
-   binaries that are built using this library.
-
-#. To build the FIP image, ensure the following command line variables are set
-   while invoking ``make`` to build TF-A:
-
-   -  ``MBEDTLS_DIR=<path of the directory containing mbed TLS sources>``
-   -  ``TRUSTED_BOARD_BOOT=1``
-   -  ``GENERATE_COT=1``
-
-   In the case of Arm platforms, the location of the ROTPK hash must also be
-   specified at build time. Two locations are currently supported (see
-   ``ARM_ROTPK_LOCATION`` build option):
-
-   -  ``ARM_ROTPK_LOCATION=regs``: the ROTPK hash is obtained from the Trusted
-      root-key storage registers present in the platform. On Juno, this
-      registers are read-only. On FVP Base and Cortex models, the registers
-      are read-only, but the value can be specified using the command line
-      option ``bp.trusted_key_storage.public_key`` when launching the model.
-      On both Juno and FVP models, the default value corresponds to an
-      ECDSA-SECP256R1 public key hash, whose private part is not currently
-      available.
-
-   -  ``ARM_ROTPK_LOCATION=devel_rsa``: use the ROTPK hash that is hardcoded
-      in the Arm platform port. The private/public RSA key pair may be
-      found in ``plat/arm/board/common/rotpk``.
-
-   -  ``ARM_ROTPK_LOCATION=devel_ecdsa``: use the ROTPK hash that is hardcoded
-      in the Arm platform port. The private/public ECDSA key pair may be
-      found in ``plat/arm/board/common/rotpk``.
-
-   Example of command line using RSA development keys:
-
-   .. code:: shell
-
-       MBEDTLS_DIR=<path of the directory containing mbed TLS sources> \
-       make PLAT=<platform> TRUSTED_BOARD_BOOT=1 GENERATE_COT=1        \
-       ARM_ROTPK_LOCATION=devel_rsa                                    \
-       ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem        \
-       BL33=<path-to>/<bl33_image>                                     \
-       all fip
-
-   The result of this build will be the bl1.bin and the fip.bin binaries. This
-   FIP will include the certificates corresponding to the Chain of Trust
-   described in the TBBR-client document. These certificates can also be found
-   in the output build directory.
-
-#. The optional FWU_FIP contains any additional images to be loaded from
-   Non-Volatile storage during the :ref:`Firmware Update (FWU)` process. To
-   build the FWU_FIP, any FWU images required by the platform must be specified
-   on the command line. On Arm development platforms like Juno, these are:
-
-   -  NS_BL2U. The AP non-secure Firmware Updater image.
-   -  SCP_BL2U. The SCP Firmware Update Configuration image.
-
-   Example of Juno command line for generating both ``fwu`` and ``fwu_fip``
-   targets using RSA development:
-
-   ::
-
-       MBEDTLS_DIR=<path of the directory containing mbed TLS sources> \
-       make PLAT=juno TRUSTED_BOARD_BOOT=1 GENERATE_COT=1              \
-       ARM_ROTPK_LOCATION=devel_rsa                                    \
-       ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem        \
-       BL33=<path-to>/<bl33_image>                                     \
-       SCP_BL2=<path-to>/<scp_bl2_image>                               \
-       SCP_BL2U=<path-to>/<scp_bl2u_image>                             \
-       NS_BL2U=<path-to>/<ns_bl2u_image>                               \
-       all fip fwu_fip
-
-   .. note::
-      The BL2U image will be built by default and added to the FWU_FIP.
-      The user may override this by adding ``BL2U=<path-to>/<bl2u_image>``
-      to the command line above.
-
-   .. note::
-      Building and installing the non-secure and SCP FWU images (NS_BL1U,
-      NS_BL2U and SCP_BL2U) is outside the scope of this document.
-
-   The result of this build will be bl1.bin, fip.bin and fwu_fip.bin binaries.
-   Both the FIP and FWU_FIP will include the certificates corresponding to the
-   Chain of Trust described in the TBBR-client document. These certificates
-   can also be found in the output build directory.
-
-Building the Certificate Generation Tool
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The ``cert_create`` tool is built as part of the TF-A build process when the
-``fip`` make target is specified and TBB is enabled (as described in the
-previous section), but it can also be built separately with the following
-command:
-
-.. code:: shell
-
-    make PLAT=<platform> [DEBUG=1] [V=1] certtool
-
-For platforms that require their own IDs in certificate files, the generic
-'cert_create' tool can be built with the following command. Note that the target
-platform must define its IDs within a ``platform_oid.h`` header file for the
-build to succeed.
-
-.. code:: shell
-
-    make PLAT=<platform> USE_TBBR_DEFS=0 [DEBUG=1] [V=1] certtool
-
-``DEBUG=1`` builds the tool in debug mode. ``V=1`` makes the build process more
-verbose. The following command should be used to obtain help about the tool:
-
-.. code:: shell
-
-    ./tools/cert_create/cert_create -h
-
-Building a FIP for Juno and FVP
--------------------------------
-
-This section provides Juno and FVP specific instructions to build Trusted
-Firmware, obtain the additional required firmware, and pack it all together in
-a single FIP binary. It assumes that a `Linaro Release`_ has been installed.
-
-.. note::
-   Pre-built binaries for AArch32 are available from Linaro Release 16.12
-   onwards. Before that release, pre-built binaries are only available for
-   AArch64.
-
-.. warning::
-   Follow the full instructions for one platform before switching to a
-   different one. Mixing instructions for different platforms may result in
-   corrupted binaries.
-
-.. warning::
-   The uboot image downloaded by the Linaro workspace script does not always
-   match the uboot image packaged as BL33 in the corresponding fip file. It is
-   recommended to use the version that is packaged in the fip file using the
-   instructions below.
-
-.. note::
-   For the FVP, the kernel FDT is packaged in FIP during build and loaded
-   by the firmware at runtime. See `Obtaining the Flattened Device Trees`_
-   section for more info on selecting the right FDT to use.
-
-#. Clean the working directory
-
-   .. code:: shell
-
-       make realclean
-
-#. Obtain SCP_BL2 (Juno) and BL33 (all platforms)
-
-   Use the fiptool to extract the SCP_BL2 and BL33 images from the FIP
-   package included in the Linaro release:
-
-   .. code:: shell
-
-       # Build the fiptool
-       make [DEBUG=1] [V=1] fiptool
-
-       # Unpack firmware images from Linaro FIP
-       ./tools/fiptool/fiptool unpack <path-to-linaro-release>/[SOFTWARE]/fip.bin
-
-   The unpack operation will result in a set of binary images extracted to the
-   current working directory. The SCP_BL2 image corresponds to
-   ``scp-fw.bin`` and BL33 corresponds to ``nt-fw.bin``.
-
-   .. note::
-      The fiptool will complain if the images to be unpacked already
-      exist in the current directory. If that is the case, either delete those
-      files or use the ``--force`` option to overwrite.
-
-   .. note::
-      For AArch32, the instructions below assume that nt-fw.bin is a
-      normal world boot loader that supports AArch32.
-
-#. Build TF-A images and create a new FIP for FVP
-
-   .. code:: shell
-
-       # AArch64
-       make PLAT=fvp BL33=nt-fw.bin all fip
-
-       # AArch32
-       make PLAT=fvp ARCH=aarch32 AARCH32_SP=sp_min BL33=nt-fw.bin all fip
-
-#. Build TF-A images and create a new FIP for Juno
-
-   For AArch64:
-
-   Building for AArch64 on Juno simply requires the addition of ``SCP_BL2``
-   as a build parameter.
-
-   .. code:: shell
-
-       make PLAT=juno BL33=nt-fw.bin SCP_BL2=scp-fw.bin all fip
-
-   For AArch32:
-
-   Hardware restrictions on Juno prevent cold reset into AArch32 execution mode,
-   therefore BL1 and BL2 must be compiled for AArch64, and BL32 is compiled
-   separately for AArch32.
-
-   -  Before building BL32, the environment variable ``CROSS_COMPILE`` must point
-      to the AArch32 cross compiler.
-
-      .. code:: shell
-
-          export CROSS_COMPILE=<path-to-aarch32-gcc>/bin/arm-eabi-
-
-   -  Build BL32 in AArch32.
-
-      .. code:: shell
-
-          make ARCH=aarch32 PLAT=juno AARCH32_SP=sp_min \
-          RESET_TO_SP_MIN=1 JUNO_AARCH32_EL3_RUNTIME=1 bl32
-
-   -  Save ``bl32.bin`` to a temporary location and clean the build products.
-
-      ::
-
-          cp <path-to-build>/bl32.bin <path-to-temporary>
-          make realclean
-
-   -  Before building BL1 and BL2, the environment variable ``CROSS_COMPILE``
-      must point to the AArch64 cross compiler.
-
-      .. code:: shell
-
-          export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
-
-   -  The following parameters should be used to build BL1 and BL2 in AArch64
-      and point to the BL32 file.
-
-      .. code:: shell
-
-          make ARCH=aarch64 PLAT=juno JUNO_AARCH32_EL3_RUNTIME=1 \
-          BL33=nt-fw.bin SCP_BL2=scp-fw.bin \
-          BL32=<path-to-temporary>/bl32.bin all fip
-
-The resulting BL1 and FIP images may be found in:
-
-::
-
-    # Juno
-    ./build/juno/release/bl1.bin
-    ./build/juno/release/fip.bin
-
-    # FVP
-    ./build/fvp/release/bl1.bin
-    ./build/fvp/release/fip.bin
-
-
-Booting Firmware Update images
--------------------------------------
-
-When Firmware Update (FWU) is enabled there are at least 2 new images
-that have to be loaded, the Non-Secure FWU ROM (NS-BL1U), and the
-FWU FIP.
-
-Juno
-~~~~
-
-The new images must be programmed in flash memory by adding
-an entry in the ``SITE1/HBI0262x/images.txt`` configuration file
-on the Juno SD card (where ``x`` depends on the revision of the Juno board).
-Refer to the `Juno Getting Started Guide`_, section 2.3 "Flash memory
-programming" for more information. User should ensure these do not
-overlap with any other entries in the file.
-
-::
-
-	NOR10UPDATE: AUTO                       ;Image Update:NONE/AUTO/FORCE
-	NOR10ADDRESS: 0x00400000                ;Image Flash Address [ns_bl2u_base_address]
-	NOR10FILE: \SOFTWARE\fwu_fip.bin        ;Image File Name
-	NOR10LOAD: 00000000                     ;Image Load Address
-	NOR10ENTRY: 00000000                    ;Image Entry Point
-
-	NOR11UPDATE: AUTO                       ;Image Update:NONE/AUTO/FORCE
-	NOR11ADDRESS: 0x03EB8000                ;Image Flash Address [ns_bl1u_base_address]
-	NOR11FILE: \SOFTWARE\ns_bl1u.bin        ;Image File Name
-	NOR11LOAD: 00000000                     ;Image Load Address
-
-The address ns_bl1u_base_address is the value of NS_BL1U_BASE - 0x8000000.
-In the same way, the address ns_bl2u_base_address is the value of
-NS_BL2U_BASE - 0x8000000.
-
-FVP
-~~~
-
-The additional fip images must be loaded with:
-
-::
-
-    --data cluster0.cpu0="<path_to>/ns_bl1u.bin"@0x0beb8000	[ns_bl1u_base_address]
-    --data cluster0.cpu0="<path_to>/fwu_fip.bin"@0x08400000	[ns_bl2u_base_address]
-
-The address ns_bl1u_base_address is the value of NS_BL1U_BASE.
-In the same way, the address ns_bl2u_base_address is the value of
-NS_BL2U_BASE.
-
-
-EL3 payloads alternative boot flow
-----------------------------------
-
-On a pre-production system, the ability to execute arbitrary, bare-metal code at
-the highest exception level is required. It allows full, direct access to the
-hardware, for example to run silicon soak tests.
-
-Although it is possible to implement some baremetal secure firmware from
-scratch, this is a complex task on some platforms, depending on the level of
-configuration required to put the system in the expected state.
-
-Rather than booting a baremetal application, a possible compromise is to boot
-``EL3 payloads`` through TF-A instead. This is implemented as an alternative
-boot flow, where a modified BL2 boots an EL3 payload, instead of loading the
-other BL images and passing control to BL31. It reduces the complexity of
-developing EL3 baremetal code by:
-
--  putting the system into a known architectural state;
--  taking care of platform secure world initialization;
--  loading the SCP_BL2 image if required by the platform.
-
-When booting an EL3 payload on Arm standard platforms, the configuration of the
-TrustZone controller is simplified such that only region 0 is enabled and is
-configured to permit secure access only. This gives full access to the whole
-DRAM to the EL3 payload.
-
-The system is left in the same state as when entering BL31 in the default boot
-flow. In particular:
-
--  Running in EL3;
--  Current state is AArch64;
--  Little-endian data access;
--  All exceptions disabled;
--  MMU disabled;
--  Caches disabled.
-
-Booting an EL3 payload
-~~~~~~~~~~~~~~~~~~~~~~
-
-The EL3 payload image is a standalone image and is not part of the FIP. It is
-not loaded by TF-A. Therefore, there are 2 possible scenarios:
-
--  The EL3 payload may reside in non-volatile memory (NVM) and execute in
-   place. In this case, booting it is just a matter of specifying the right
-   address in NVM through ``EL3_PAYLOAD_BASE`` when building TF-A.
-
--  The EL3 payload needs to be loaded in volatile memory (e.g. DRAM) at
-   run-time.
-
-To help in the latter scenario, the ``SPIN_ON_BL1_EXIT=1`` build option can be
-used. The infinite loop that it introduces in BL1 stops execution at the right
-moment for a debugger to take control of the target and load the payload (for
-example, over JTAG).
-
-It is expected that this loading method will work in most cases, as a debugger
-connection is usually available in a pre-production system. The user is free to
-use any other platform-specific mechanism to load the EL3 payload, though.
-
-Booting an EL3 payload on FVP
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The EL3 payloads boot flow requires the CPU's mailbox to be cleared at reset for
-the secondary CPUs holding pen to work properly. Unfortunately, its reset value
-is undefined on the FVP platform and the FVP platform code doesn't clear it.
-Therefore, one must modify the way the model is normally invoked in order to
-clear the mailbox at start-up.
-
-One way to do that is to create an 8-byte file containing all zero bytes using
-the following command:
-
-.. code:: shell
-
-    dd if=/dev/zero of=mailbox.dat bs=1 count=8
-
-and pre-load it into the FVP memory at the mailbox address (i.e. ``0x04000000``)
-using the following model parameters:
-
-::
-
-    --data cluster0.cpu0=mailbox.dat@0x04000000   [Base FVPs]
-    --data=mailbox.dat@0x04000000                 [Foundation FVP]
-
-To provide the model with the EL3 payload image, the following methods may be
-used:
-
-#. If the EL3 payload is able to execute in place, it may be programmed into
-   flash memory. On Base Cortex and AEM FVPs, the following model parameter
-   loads it at the base address of the NOR FLASH1 (the NOR FLASH0 is already
-   used for the FIP):
-
-   ::
-
-       -C bp.flashloader1.fname="<path-to>/<el3-payload>"
-
-   On Foundation FVP, there is no flash loader component and the EL3 payload
-   may be programmed anywhere in flash using method 3 below.
-
-#. When using the ``SPIN_ON_BL1_EXIT=1`` loading method, the following DS-5
-   command may be used to load the EL3 payload ELF image over JTAG:
-
-   ::
-
-       load <path-to>/el3-payload.elf
-
-#. The EL3 payload may be pre-loaded in volatile memory using the following
-   model parameters:
-
-   ::
-
-       --data cluster0.cpu0="<path-to>/el3-payload>"@address   [Base FVPs]
-       --data="<path-to>/<el3-payload>"@address                [Foundation FVP]
-
-   The address provided to the FVP must match the ``EL3_PAYLOAD_BASE`` address
-   used when building TF-A.
-
-Booting an EL3 payload on Juno
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-If the EL3 payload is able to execute in place, it may be programmed in flash
-memory by adding an entry in the ``SITE1/HBI0262x/images.txt`` configuration file
-on the Juno SD card (where ``x`` depends on the revision of the Juno board).
-Refer to the `Juno Getting Started Guide`_, section 2.3 "Flash memory
-programming" for more information.
-
-Alternatively, the same DS-5 command mentioned in the FVP section above can
-be used to load the EL3 payload's ELF file over JTAG on Juno.
-
-Preloaded BL33 alternative boot flow
-------------------------------------
-
-Some platforms have the ability to preload BL33 into memory instead of relying
-on TF-A to load it. This may simplify packaging of the normal world code and
-improve performance in a development environment. When secure world cold boot
-is complete, TF-A simply jumps to a BL33 base address provided at build time.
-
-For this option to be used, the ``PRELOADED_BL33_BASE`` build option has to be
-used when compiling TF-A. For example, the following command will create a FIP
-without a BL33 and prepare to jump to a BL33 image loaded at address
-0x80000000:
-
-.. code:: shell
-
-    make PRELOADED_BL33_BASE=0x80000000 PLAT=fvp all fip
-
-Boot of a preloaded kernel image on Base FVP
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following example uses a simplified boot flow by directly jumping from the
-TF-A to the Linux kernel, which will use a ramdisk as filesystem. This can be
-useful if both the kernel and the device tree blob (DTB) are already present in
-memory (like in FVP).
-
-For example, if the kernel is loaded at ``0x80080000`` and the DTB is loaded at
-address ``0x82000000``, the firmware can be built like this:
-
-.. code:: shell
-
-    CROSS_COMPILE=aarch64-linux-gnu-  \
-    make PLAT=fvp DEBUG=1             \
-    RESET_TO_BL31=1                   \
-    ARM_LINUX_KERNEL_AS_BL33=1        \
-    PRELOADED_BL33_BASE=0x80080000    \
-    ARM_PRELOADED_DTB_BASE=0x82000000 \
-    all fip
-
-Now, it is needed to modify the DTB so that the kernel knows the address of the
-ramdisk. The following script generates a patched DTB from the provided one,
-assuming that the ramdisk is loaded at address ``0x84000000``. Note that this
-script assumes that the user is using a ramdisk image prepared for U-Boot, like
-the ones provided by Linaro. If using a ramdisk without this header,the ``0x40``
-offset in ``INITRD_START`` has to be removed.
-
-.. code:: bash
-
-    #!/bin/bash
-
-    # Path to the input DTB
-    KERNEL_DTB=<path-to>/<fdt>
-    # Path to the output DTB
-    PATCHED_KERNEL_DTB=<path-to>/<patched-fdt>
-    # Base address of the ramdisk
-    INITRD_BASE=0x84000000
-    # Path to the ramdisk
-    INITRD=<path-to>/<ramdisk.img>
-
-    # Skip uboot header (64 bytes)
-    INITRD_START=$(printf "0x%x" $((${INITRD_BASE} + 0x40)) )
-    INITRD_SIZE=$(stat -Lc %s ${INITRD})
-    INITRD_END=$(printf "0x%x" $((${INITRD_BASE} + ${INITRD_SIZE})) )
-
-    CHOSEN_NODE=$(echo                                        \
-    "/ {                                                      \
-            chosen {                                          \
-                    linux,initrd-start = <${INITRD_START}>;   \
-                    linux,initrd-end = <${INITRD_END}>;       \
-            };                                                \
-    };")
-
-    echo $(dtc -O dts -I dtb ${KERNEL_DTB}) ${CHOSEN_NODE} |  \
-            dtc -O dtb -o ${PATCHED_KERNEL_DTB} -
-
-And the FVP binary can be run with the following command:
-
-.. code:: shell
-
-    <path-to>/FVP_Base_AEMv8A-AEMv8A                            \
-    -C pctl.startup=0.0.0.0                                     \
-    -C bp.secure_memory=1                                       \
-    -C cluster0.NUM_CORES=4                                     \
-    -C cluster1.NUM_CORES=4                                     \
-    -C cache_state_modelled=1                                   \
-    -C cluster0.cpu0.RVBAR=0x04020000                           \
-    -C cluster0.cpu1.RVBAR=0x04020000                           \
-    -C cluster0.cpu2.RVBAR=0x04020000                           \
-    -C cluster0.cpu3.RVBAR=0x04020000                           \
-    -C cluster1.cpu0.RVBAR=0x04020000                           \
-    -C cluster1.cpu1.RVBAR=0x04020000                           \
-    -C cluster1.cpu2.RVBAR=0x04020000                           \
-    -C cluster1.cpu3.RVBAR=0x04020000                           \
-    --data cluster0.cpu0="<path-to>/bl31.bin"@0x04020000        \
-    --data cluster0.cpu0="<path-to>/<patched-fdt>"@0x82000000   \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
-    --data cluster0.cpu0="<path-to>/<ramdisk.img>"@0x84000000
-
-Boot of a preloaded kernel image on Juno
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The Trusted Firmware must be compiled in a similar way as for FVP explained
-above. The process to load binaries to memory is the one explained in
-`Booting an EL3 payload on Juno`_.
-
-.. _user_guide_run_fvp:
-
-Running the software on FVP
----------------------------
-
-The latest version of the AArch64 build of TF-A has been tested on the following
-Arm FVPs without shifted affinities, and that do not support threaded CPU cores
-(64-bit host machine only).
-
-.. note::
-   The FVP models used are Version 11.6 Build 45, unless otherwise stated.
-
--  ``FVP_Base_AEMv8A-AEMv8A``
--  ``FVP_Base_AEMv8A-AEMv8A-AEMv8A-AEMv8A-CCN502``
--  ``FVP_Base_RevC-2xAEMv8A``
--  ``FVP_Base_Cortex-A32x4``
--  ``FVP_Base_Cortex-A35x4``
--  ``FVP_Base_Cortex-A53x4``
--  ``FVP_Base_Cortex-A55x4+Cortex-A75x4``
--  ``FVP_Base_Cortex-A55x4``
--  ``FVP_Base_Cortex-A57x1-A53x1``
--  ``FVP_Base_Cortex-A57x2-A53x4``
--  ``FVP_Base_Cortex-A57x4-A53x4``
--  ``FVP_Base_Cortex-A57x4``
--  ``FVP_Base_Cortex-A72x4-A53x4``
--  ``FVP_Base_Cortex-A72x4``
--  ``FVP_Base_Cortex-A73x4-A53x4``
--  ``FVP_Base_Cortex-A73x4``
--  ``FVP_Base_Cortex-A75x4``
--  ``FVP_Base_Cortex-A76x4``
--  ``FVP_Base_Cortex-A76AEx4``
--  ``FVP_Base_Cortex-A76AEx8``
--  ``FVP_Base_Cortex-A77x4`` (Version 11.7 build 36)
--  ``FVP_Base_Neoverse-N1x4``
--  ``FVP_Base_Zeusx4``
--  ``FVP_CSS_SGI-575`` (Version 11.3 build 42)
--  ``FVP_CSS_SGM-775`` (Version 11.3 build 42)
--  ``FVP_RD_E1Edge`` (Version 11.3 build 42)
--  ``FVP_RD_N1Edge``
--  ``Foundation_Platform``
-
-The latest version of the AArch32 build of TF-A has been tested on the following
-Arm FVPs without shifted affinities, and that do not support threaded CPU cores
-(64-bit host machine only).
-
--  ``FVP_Base_AEMv8A-AEMv8A``
--  ``FVP_Base_Cortex-A32x4``
-
-.. note::
-   The ``FVP_Base_RevC-2xAEMv8A`` FVP only supports shifted affinities, which
-   is not compatible with legacy GIC configurations. Therefore this FVP does not
-   support these legacy GIC configurations.
-
-.. note::
-   The build numbers quoted above are those reported by launching the FVP
-   with the ``--version`` parameter.
-
-.. note::
-   Linaro provides a ramdisk image in prebuilt FVP configurations and full
-   file systems that can be downloaded separately. To run an FVP with a virtio
-   file system image an additional FVP configuration option
-   ``-C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>`` can be
-   used.
-
-.. note::
-   The software will not work on Version 1.0 of the Foundation FVP.
-   The commands below would report an ``unhandled argument`` error in this case.
-
-.. note::
-   FVPs can be launched with ``--cadi-server`` option such that a
-   CADI-compliant debugger (for example, Arm DS-5) can connect to and control
-   its execution.
-
-.. warning::
-   Since FVP model Version 11.0 Build 11.0.34 and Version 8.5 Build 0.8.5202
-   the internal synchronisation timings changed compared to older versions of
-   the models. The models can be launched with ``-Q 100`` option if they are
-   required to match the run time characteristics of the older versions.
-
-The Foundation FVP is a cut down version of the AArch64 Base FVP. It can be
-downloaded for free from `Arm's website`_.
-
-The Cortex-A models listed above are also available to download from
-`Arm's website`_.
-
-Please refer to the FVP documentation for a detailed description of the model
-parameter options. A brief description of the important ones that affect TF-A
-and normal world software behavior is provided below.
-
-Obtaining the Flattened Device Trees
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Depending on the FVP configuration and Linux configuration used, different
-FDT files are required. FDT source files for the Foundation and Base FVPs can
-be found in the TF-A source directory under ``fdts/``. The Foundation FVP has
-a subset of the Base FVP components. For example, the Foundation FVP lacks
-CLCD and MMC support, and has only one CPU cluster.
-
-.. note::
-   It is not recommended to use the FDTs built along the kernel because not
-   all FDTs are available from there.
-
-The dynamic configuration capability is enabled in the firmware for FVPs.
-This means that the firmware can authenticate and load the FDT if present in
-FIP. A default FDT is packaged into FIP during the build based on
-the build configuration. This can be overridden by using the ``FVP_HW_CONFIG``
-or ``FVP_HW_CONFIG_DTS`` build options (refer to the
-`Arm FVP platform specific build options`_ section for detail on the options).
-
--  ``fvp-base-gicv2-psci.dts``
-
-   For use with models such as the Cortex-A57-A53 Base FVPs without shifted
-   affinities and with Base memory map configuration.
-
--  ``fvp-base-gicv2-psci-aarch32.dts``
-
-   For use with models such as the Cortex-A32 Base FVPs without shifted
-   affinities and running Linux in AArch32 state with Base memory map
-   configuration.
-
--  ``fvp-base-gicv3-psci.dts``
-
-   For use with models such as the Cortex-A57-A53 Base FVPs without shifted
-   affinities and with Base memory map configuration and Linux GICv3 support.
-
--  ``fvp-base-gicv3-psci-1t.dts``
-
-   For use with models such as the AEMv8-RevC Base FVP with shifted affinities,
-   single threaded CPUs, Base memory map configuration and Linux GICv3 support.
-
--  ``fvp-base-gicv3-psci-dynamiq.dts``
-
-   For use with models as the Cortex-A55-A75 Base FVPs with shifted affinities,
-   single cluster, single threaded CPUs, Base memory map configuration and Linux
-   GICv3 support.
-
--  ``fvp-base-gicv3-psci-aarch32.dts``
-
-   For use with models such as the Cortex-A32 Base FVPs without shifted
-   affinities and running Linux in AArch32 state with Base memory map
-   configuration and Linux GICv3 support.
-
--  ``fvp-foundation-gicv2-psci.dts``
-
-   For use with Foundation FVP with Base memory map configuration.
-
--  ``fvp-foundation-gicv3-psci.dts``
-
-   (Default) For use with Foundation FVP with Base memory map configuration
-   and Linux GICv3 support.
-
-Running on the Foundation FVP with reset to BL1 entrypoint
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following ``Foundation_Platform`` parameters should be used to boot Linux with
-4 CPUs using the AArch64 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/Foundation_Platform                   \
-    --cores=4                                       \
-    --arm-v8.0                                      \
-    --secure-memory                                 \
-    --visualization                                 \
-    --gicv3                                         \
-    --data="<path-to>/<bl1-binary>"@0x0             \
-    --data="<path-to>/<FIP-binary>"@0x08000000      \
-    --data="<path-to>/<kernel-binary>"@0x80080000   \
-    --data="<path-to>/<ramdisk-binary>"@0x84000000
-
-Notes:
-
--  BL1 is loaded at the start of the Trusted ROM.
--  The Firmware Image Package is loaded at the start of NOR FLASH0.
--  The firmware loads the FDT packaged in FIP to the DRAM. The FDT load address
-   is specified via the ``hw_config_addr`` property in ``TB_FW_CONFIG`` for FVP.
--  The default use-case for the Foundation FVP is to use the ``--gicv3`` option
-   and enable the GICv3 device in the model. Note that without this option,
-   the Foundation FVP defaults to legacy (Versatile Express) memory map which
-   is not supported by TF-A.
--  In order for TF-A to run correctly on the Foundation FVP, the architecture
-   versions must match. The Foundation FVP defaults to the highest v8.x
-   version it supports but the default build for TF-A is for v8.0. To avoid
-   issues either start the Foundation FVP to use v8.0 architecture using the
-   ``--arm-v8.0`` option, or build TF-A with an appropriate value for
-   ``ARM_ARCH_MINOR``.
-
-Running on the AEMv8 Base FVP with reset to BL1 entrypoint
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following ``FVP_Base_RevC-2xAEMv8A`` parameters should be used to boot Linux
-with 8 CPUs using the AArch64 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/FVP_Base_RevC-2xAEMv8A                            \
-    -C pctl.startup=0.0.0.0                                     \
-    -C bp.secure_memory=1                                       \
-    -C bp.tzc_400.diagnostics=1                                 \
-    -C cluster0.NUM_CORES=4                                     \
-    -C cluster1.NUM_CORES=4                                     \
-    -C cache_state_modelled=1                                   \
-    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>"      \
-    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"           \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
-    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-.. note::
-   The ``FVP_Base_RevC-2xAEMv8A`` has shifted affinities and requires
-   a specific DTS for all the CPUs to be loaded.
-
-Running on the AEMv8 Base FVP (AArch32) with reset to BL1 entrypoint
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following ``FVP_Base_AEMv8A-AEMv8A`` parameters should be used to boot Linux
-with 8 CPUs using the AArch32 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/FVP_Base_AEMv8A-AEMv8A                            \
-    -C pctl.startup=0.0.0.0                                     \
-    -C bp.secure_memory=1                                       \
-    -C bp.tzc_400.diagnostics=1                                 \
-    -C cluster0.NUM_CORES=4                                     \
-    -C cluster1.NUM_CORES=4                                     \
-    -C cache_state_modelled=1                                   \
-    -C cluster0.cpu0.CONFIG64=0                                 \
-    -C cluster0.cpu1.CONFIG64=0                                 \
-    -C cluster0.cpu2.CONFIG64=0                                 \
-    -C cluster0.cpu3.CONFIG64=0                                 \
-    -C cluster1.cpu0.CONFIG64=0                                 \
-    -C cluster1.cpu1.CONFIG64=0                                 \
-    -C cluster1.cpu2.CONFIG64=0                                 \
-    -C cluster1.cpu3.CONFIG64=0                                 \
-    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>"      \
-    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"           \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
-    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-Running on the Cortex-A57-A53 Base FVP with reset to BL1 entrypoint
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following ``FVP_Base_Cortex-A57x4-A53x4`` model parameters should be used to
-boot Linux with 8 CPUs using the AArch64 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/FVP_Base_Cortex-A57x4-A53x4                       \
-    -C pctl.startup=0.0.0.0                                     \
-    -C bp.secure_memory=1                                       \
-    -C bp.tzc_400.diagnostics=1                                 \
-    -C cache_state_modelled=1                                   \
-    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>"      \
-    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"           \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
-    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-Running on the Cortex-A32 Base FVP (AArch32) with reset to BL1 entrypoint
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following ``FVP_Base_Cortex-A32x4`` model parameters should be used to
-boot Linux with 4 CPUs using the AArch32 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/FVP_Base_Cortex-A32x4                             \
-    -C pctl.startup=0.0.0.0                                     \
-    -C bp.secure_memory=1                                       \
-    -C bp.tzc_400.diagnostics=1                                 \
-    -C cache_state_modelled=1                                   \
-    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>"      \
-    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"           \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
-    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-Running on the AEMv8 Base FVP with reset to BL31 entrypoint
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following ``FVP_Base_RevC-2xAEMv8A`` parameters should be used to boot Linux
-with 8 CPUs using the AArch64 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/FVP_Base_RevC-2xAEMv8A                             \
-    -C pctl.startup=0.0.0.0                                      \
-    -C bp.secure_memory=1                                        \
-    -C bp.tzc_400.diagnostics=1                                  \
-    -C cluster0.NUM_CORES=4                                      \
-    -C cluster1.NUM_CORES=4                                      \
-    -C cache_state_modelled=1                                    \
-    -C cluster0.cpu0.RVBAR=0x04010000                            \
-    -C cluster0.cpu1.RVBAR=0x04010000                            \
-    -C cluster0.cpu2.RVBAR=0x04010000                            \
-    -C cluster0.cpu3.RVBAR=0x04010000                            \
-    -C cluster1.cpu0.RVBAR=0x04010000                            \
-    -C cluster1.cpu1.RVBAR=0x04010000                            \
-    -C cluster1.cpu2.RVBAR=0x04010000                            \
-    -C cluster1.cpu3.RVBAR=0x04010000                            \
-    --data cluster0.cpu0="<path-to>/<bl31-binary>"@0x04010000    \
-    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0xff000000    \
-    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000    \
-    --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000            \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000  \
-    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-Notes:
-
--  If Position Independent Executable (PIE) support is enabled for BL31
-   in this config, it can be loaded at any valid address for execution.
-
--  Since a FIP is not loaded when using BL31 as reset entrypoint, the
-   ``--data="<path-to><bl31|bl32|bl33-binary>"@<base-address-of-binary>``
-   parameter is needed to load the individual bootloader images in memory.
-   BL32 image is only needed if BL31 has been built to expect a Secure-EL1
-   Payload. For the same reason, the FDT needs to be compiled from the DT source
-   and loaded via the ``--data cluster0.cpu0="<path-to>/<fdt>"@0x82000000``
-   parameter.
-
--  The ``FVP_Base_RevC-2xAEMv8A`` has shifted affinities and requires a
-   specific DTS for all the CPUs to be loaded.
-
--  The ``-C cluster<X>.cpu<Y>.RVBAR=@<base-address-of-bl31>`` parameter, where
-   X and Y are the cluster and CPU numbers respectively, is used to set the
-   reset vector for each core.
-
--  Changing the default value of ``ARM_TSP_RAM_LOCATION`` will also require
-   changing the value of
-   ``--data="<path-to><bl32-binary>"@<base-address-of-bl32>`` to the new value of
-   ``BL32_BASE``.
-
-Running on the AEMv8 Base FVP (AArch32) with reset to SP_MIN entrypoint
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following ``FVP_Base_AEMv8A-AEMv8A`` parameters should be used to boot Linux
-with 8 CPUs using the AArch32 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/FVP_Base_AEMv8A-AEMv8A                             \
-    -C pctl.startup=0.0.0.0                                      \
-    -C bp.secure_memory=1                                        \
-    -C bp.tzc_400.diagnostics=1                                  \
-    -C cluster0.NUM_CORES=4                                      \
-    -C cluster1.NUM_CORES=4                                      \
-    -C cache_state_modelled=1                                    \
-    -C cluster0.cpu0.CONFIG64=0                                  \
-    -C cluster0.cpu1.CONFIG64=0                                  \
-    -C cluster0.cpu2.CONFIG64=0                                  \
-    -C cluster0.cpu3.CONFIG64=0                                  \
-    -C cluster1.cpu0.CONFIG64=0                                  \
-    -C cluster1.cpu1.CONFIG64=0                                  \
-    -C cluster1.cpu2.CONFIG64=0                                  \
-    -C cluster1.cpu3.CONFIG64=0                                  \
-    -C cluster0.cpu0.RVBAR=0x04002000                            \
-    -C cluster0.cpu1.RVBAR=0x04002000                            \
-    -C cluster0.cpu2.RVBAR=0x04002000                            \
-    -C cluster0.cpu3.RVBAR=0x04002000                            \
-    -C cluster1.cpu0.RVBAR=0x04002000                            \
-    -C cluster1.cpu1.RVBAR=0x04002000                            \
-    -C cluster1.cpu2.RVBAR=0x04002000                            \
-    -C cluster1.cpu3.RVBAR=0x04002000                            \
-    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0x04002000    \
-    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000    \
-    --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000            \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000  \
-    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-.. note::
-   The load address of ``<bl32-binary>`` depends on the value ``BL32_BASE``.
-   It should match the address programmed into the RVBAR register as well.
-
-Running on the Cortex-A57-A53 Base FVP with reset to BL31 entrypoint
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following ``FVP_Base_Cortex-A57x4-A53x4`` model parameters should be used to
-boot Linux with 8 CPUs using the AArch64 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/FVP_Base_Cortex-A57x4-A53x4                        \
-    -C pctl.startup=0.0.0.0                                      \
-    -C bp.secure_memory=1                                        \
-    -C bp.tzc_400.diagnostics=1                                  \
-    -C cache_state_modelled=1                                    \
-    -C cluster0.cpu0.RVBARADDR=0x04010000                        \
-    -C cluster0.cpu1.RVBARADDR=0x04010000                        \
-    -C cluster0.cpu2.RVBARADDR=0x04010000                        \
-    -C cluster0.cpu3.RVBARADDR=0x04010000                        \
-    -C cluster1.cpu0.RVBARADDR=0x04010000                        \
-    -C cluster1.cpu1.RVBARADDR=0x04010000                        \
-    -C cluster1.cpu2.RVBARADDR=0x04010000                        \
-    -C cluster1.cpu3.RVBARADDR=0x04010000                        \
-    --data cluster0.cpu0="<path-to>/<bl31-binary>"@0x04010000    \
-    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0xff000000    \
-    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000    \
-    --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000            \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000  \
-    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-Running on the Cortex-A32 Base FVP (AArch32) with reset to SP_MIN entrypoint
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following ``FVP_Base_Cortex-A32x4`` model parameters should be used to
-boot Linux with 4 CPUs using the AArch32 build of TF-A.
-
-.. code:: shell
-
-    <path-to>/FVP_Base_Cortex-A32x4                             \
-    -C pctl.startup=0.0.0.0                                     \
-    -C bp.secure_memory=1                                       \
-    -C bp.tzc_400.diagnostics=1                                 \
-    -C cache_state_modelled=1                                   \
-    -C cluster0.cpu0.RVBARADDR=0x04002000                       \
-    -C cluster0.cpu1.RVBARADDR=0x04002000                       \
-    -C cluster0.cpu2.RVBARADDR=0x04002000                       \
-    -C cluster0.cpu3.RVBARADDR=0x04002000                       \
-    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0x04002000   \
-    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000   \
-    --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000           \
-    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
-    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-Running the software on Juno
-----------------------------
-
-This version of TF-A has been tested on variants r0, r1 and r2 of Juno.
-
-To execute the software stack on Juno, installing the latest Arm Platforms
-software deliverables is recommended. Please install the deliverables by
-following the `Instructions for using Linaro's deliverables on Juno`_.
-
-Preparing TF-A images
-~~~~~~~~~~~~~~~~~~~~~
-
-After building TF-A, the files ``bl1.bin`` and ``fip.bin`` need copying to the
-``SOFTWARE/`` directory of the Juno SD card.
-
-Other Juno software information
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Please visit the `Arm Platforms Portal`_ to get support and obtain any other Juno
-software information. Please also refer to the `Juno Getting Started Guide`_ to
-get more detailed information about the Juno Arm development platform and how to
-configure it.
-
-Testing SYSTEM SUSPEND on Juno
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The SYSTEM SUSPEND is a PSCI API which can be used to implement system suspend
-to RAM. For more details refer to section 5.16 of `PSCI`_. To test system suspend
-on Juno, at the linux shell prompt, issue the following command:
-
-.. code:: shell
-
-    echo +10 > /sys/class/rtc/rtc0/wakealarm
-    echo -n mem > /sys/power/state
-
-The Juno board should suspend to RAM and then wakeup after 10 seconds due to
-wakeup interrupt from RTC.
-
---------------
-
-*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.*
-
-.. _Arm Developer page: https://developer.arm.com/open-source/gnu-toolchain/gnu-a/downloads
-.. _Linaro Release: http://releases.linaro.org/members/arm/platforms
-.. _Linaro Release 19.06: http://releases.linaro.org/members/arm/platforms/19.06
-.. _Linaro instructions: https://git.linaro.org/landing-teams/working/arm/arm-reference-platforms.git/about
-.. _Arm Platforms User guide: https://git.linaro.org/landing-teams/working/arm/arm-reference-platforms.git/about/docs/user-guide.rst
-.. _Instructions for using Linaro's deliverables on Juno: https://community.arm.com/dev-platforms/w/docs/303/juno
-.. _Arm Platforms Portal: https://community.arm.com/dev-platforms/
-.. _Development Studio 5 (DS-5): https://developer.arm.com/products/software-development-tools/ds-5-development-studio
-.. _arm-trusted-firmware-a project page: https://review.trustedfirmware.org/admin/projects/TF-A/trusted-firmware-a
-.. _`Linux Coding Style`: https://www.kernel.org/doc/html/latest/process/coding-style.html
-.. _Linux master tree: https://github.com/torvalds/linux/tree/master/
-.. _Dia: https://wiki.gnome.org/Apps/Dia/Download
-.. _mbed TLS Repository: https://github.com/ARMmbed/mbedtls.git
-.. _mbed TLS Security Center: https://tls.mbed.org/security
-.. _Arm's website: `FVP models`_
-.. _FVP models: https://developer.arm.com/products/system-design/fixed-virtual-platforms
-.. _Juno Getting Started Guide: http://infocenter.arm.com/help/topic/com.arm.doc.dui0928e/DUI0928E_juno_arm_development_platform_gsg.pdf
-.. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
diff --git a/docs/global_substitutions.txt b/docs/global_substitutions.txt
index fdca9c3..491b160 100644
--- a/docs/global_substitutions.txt
+++ b/docs/global_substitutions.txt
@@ -1,11 +1,13 @@
 .. |AArch32| replace:: :term:`AArch32`
 .. |AArch64| replace:: :term:`AArch64`
 .. |API| replace:: :term:`API`
+.. |BTI| replace:: :term:`BTI`
 .. |CoT| replace:: :term:`CoT`
 .. |COT| replace:: :term:`COT`
 .. |CSS| replace:: :term:`CSS`
 .. |CVE| replace:: :term:`CVE`
 .. |DS-5| replace:: :term:`DS-5`
+.. |DSU| replace:: :term:`DSU`
 .. |DT| replace:: :term:`DT`
 .. |EL| replace:: :term:`EL`
 .. |EHF| replace:: :term:`EHF`
@@ -19,10 +21,12 @@
 .. |MMU| replace:: :term:`MMU`
 .. |MPAM| replace:: :term:`MPAM`
 .. |MPIDR| replace:: :term:`MPIDR`
+.. |MTE| replace:: :term:`MTE`
 .. |OEN| replace:: :term:`OEN`
 .. |OP-TEE| replace:: :term:`OP-TEE`
 .. |OTE| replace:: :term:`OTE`
 .. |PDD| replace:: :term:`PDD`
+.. |PAUTH| replace:: :term:`PAUTH`
 .. |PMF| replace:: :term:`PMF`
 .. |PSCI| replace:: :term:`PSCI`
 .. |RAS| replace:: :term:`RAS`
@@ -41,6 +45,7 @@
 .. |SPCI| replace:: :term:`SPCI`
 .. |SPD| replace:: :term:`SPD`
 .. |SPM| replace:: :term:`SPM`
+.. |SSBS| replace:: :term:`SSBS`
 .. |SVE| replace:: :term:`SVE`
 .. |TBB| replace:: :term:`TBB`
 .. |TBBR| replace:: :term:`TBBR`
@@ -51,6 +56,7 @@
 .. |TLK| replace:: :term:`TLK`
 .. |TSP| replace:: :term:`TSP`
 .. |TZC| replace:: :term:`TZC`
+.. |UBSAN| replace:: :term:`UBSAN`
 .. |UEFI| replace:: :term:`UEFI`
 .. |WDOG| replace:: :term:`WDOG`
-.. |XLAT| replace:: :term:`XLAT`
\ No newline at end of file
+.. |XLAT| replace:: :term:`XLAT`
diff --git a/docs/glossary.rst b/docs/glossary.rst
index 45caf46..2f19df5 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -18,6 +18,10 @@
    API
       Application Programming Interface
 
+   BTI
+      Branch Target Identification. An Armv8.5 extension providing additional
+      control flow integrity around indirect branches and their targets.
+
    CoT
    COT
       Chain of Trust
@@ -32,6 +36,9 @@
    DS-5
       Arm Development Studio 5
 
+   DSU
+      DynamIQ Shared Unit
+
    DT
       Device Tree
 
@@ -72,6 +79,10 @@
    MPIDR
       Multiprocessor Affinity Register
 
+   MTE
+      Memory Tagging Extension. An optional Armv8.5 extension that enables
+      hardware-assisted memory tagging.
+
    OEN
       Owning Entity Number
 
@@ -84,6 +95,9 @@
    PDD
       Platform Design Document
 
+   PAUTH
+      Pointer Authentication. An optional extension introduced in Armv8.3.
+
    PMF
       Performance Measurement Framework
 
@@ -138,6 +152,11 @@
    SPM
       Secure Partition Manager
 
+   SSBS
+      Speculative Store Bypass Safe. Introduced in Armv8.5, this configuration
+      bit can be set by software to allow or prevent the hardware from
+      performing speculative operations.
+
    SVE
       Scalable Vector Extension
 
@@ -168,6 +187,9 @@
    TZC
       TrustZone Controller
 
+   UBSAN
+      Undefined Behavior Sanitizer
+
    UEFI
       Unified Extensible Firmware Interface
 
@@ -177,4 +199,4 @@
    XLAT
       Translation (abbr.). For example, "XLAT table".
 
-.. _`Arm Glossary`: https://developer.arm.com/support/arm-glossary
\ No newline at end of file
+.. _`Arm Glossary`: https://developer.arm.com/support/arm-glossary
diff --git a/docs/index.rst b/docs/index.rst
index baadd42..5088bfd 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -15,6 +15,7 @@
    perf/index
    security_advisories/index
    change-log
+   change-log-upcoming
    glossary
    license
 
diff --git a/docs/perf/index.rst b/docs/perf/index.rst
index 50833b8..0f49b48 100644
--- a/docs/perf/index.rst
+++ b/docs/perf/index.rst
@@ -7,3 +7,8 @@
    :numbered:
 
    psci-performance-juno
+   tsp
+
+--------------
+
+*Copyright (c) 2019, Arm Limited. All rights reserved.*
diff --git a/docs/perf/tsp.rst b/docs/perf/tsp.rst
new file mode 100644
index 0000000..f8b0048
--- /dev/null
+++ b/docs/perf/tsp.rst
@@ -0,0 +1,27 @@
+Test Secure Payload (TSP) and Dispatcher (TSPD)
+===============================================
+
+Building the Test Secure Payload
+--------------------------------
+
+The TSP is coupled with a companion runtime service in the BL31 firmware,
+called the TSPD. Therefore, if you intend to use the TSP, the BL31 image
+must be recompiled as well. For more information on SPs and SPDs, see the
+:ref:`firmware_design_sel1_spd` section in the :ref:`Firmware Design`.
+
+First clean the TF-A build directory to get rid of any previous BL31 binary.
+Then to build the TSP image use:
+
+.. code:: shell
+
+    make PLAT=<platform> SPD=tspd all
+
+An additional boot loader binary file is created in the ``build`` directory:
+
+::
+
+    build/<platform>/<build-type>/bl32.bin
+
+--------------
+
+*Copyright (c) 2019, Arm Limited. All rights reserved.*
diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst
new file mode 100644
index 0000000..d24ad23
--- /dev/null
+++ b/docs/plat/arm/arm-build-options.rst
@@ -0,0 +1,114 @@
+Arm Development Platform Build Options
+======================================
+
+Arm Platform Build Options
+--------------------------
+
+-  ``ARM_BL31_IN_DRAM``: Boolean option to select loading of BL31 in TZC secured
+   DRAM. By default, BL31 is in the secure SRAM. Set this flag to 1 to load
+   BL31 in TZC secured DRAM. If TSP is present, then setting this option also
+   sets the TSP location to DRAM and ignores the ``ARM_TSP_RAM_LOCATION`` build
+   flag.
+
+-  ``ARM_CONFIG_CNTACR``: boolean option to unlock access to the ``CNTBase<N>``
+   frame registers by setting the ``CNTCTLBase.CNTACR<N>`` register bits. The
+   frame number ``<N>`` is defined by ``PLAT_ARM_NSTIMER_FRAME_ID``, which
+   should match the frame used by the Non-Secure image (normally the Linux
+   kernel). Default is true (access to the frame is allowed).
+
+-  ``ARM_DISABLE_TRUSTED_WDOG``: boolean option to disable the Trusted Watchdog.
+   By default, Arm platforms use a watchdog to trigger a system reset in case
+   an error is encountered during the boot process (for example, when an image
+   could not be loaded or authenticated). The watchdog is enabled in the early
+   platform setup hook at BL1 and disabled in the BL1 prepare exit hook. The
+   Trusted Watchdog may be disabled at build time for testing or development
+   purposes.
+
+-  ``ARM_LINUX_KERNEL_AS_BL33``: The Linux kernel expects registers x0-x3 to
+   have specific values at boot. This boolean option allows the Trusted Firmware
+   to have a Linux kernel image as BL33 by preparing the registers to these
+   values before jumping to BL33. This option defaults to 0 (disabled). For
+   AArch64 ``RESET_TO_BL31`` and for AArch32 ``RESET_TO_SP_MIN`` must be 1 when
+   using it. If this option is set to 1, ``ARM_PRELOADED_DTB_BASE`` must be set
+   to the location of a device tree blob (DTB) already loaded in memory. The
+   Linux Image address must be specified using the ``PRELOADED_BL33_BASE``
+   option.
+
+-  ``ARM_PLAT_MT``: This flag determines whether the Arm platform layer has to
+   cater for the multi-threading ``MT`` bit when accessing MPIDR. When this flag
+   is set, the functions which deal with MPIDR assume that the ``MT`` bit in
+   MPIDR is set and access the bit-fields in MPIDR accordingly. Default value of
+   this flag is 0. Note that this option is not used on FVP platforms.
+
+-  ``ARM_RECOM_STATE_ID_ENC``: The PSCI1.0 specification recommends an encoding
+   for the construction of composite state-ID in the power-state parameter.
+   The existing PSCI clients currently do not support this encoding of
+   State-ID yet. Hence this flag is used to configure whether to use the
+   recommended State-ID encoding or not. The default value of this flag is 0,
+   in which case the platform is configured to expect NULL in the State-ID
+   field of power-state parameter.
+
+-  ``ARM_ROTPK_LOCATION``: used when ``TRUSTED_BOARD_BOOT=1``. It specifies the
+   location of the ROTPK hash returned by the function ``plat_get_rotpk_info()``
+   for Arm platforms. Depending on the selected option, the proper private key
+   must be specified using the ``ROT_KEY`` option when building the Trusted
+   Firmware. This private key will be used by the certificate generation tool
+   to sign the BL2 and Trusted Key certificates. Available options for
+   ``ARM_ROTPK_LOCATION`` are:
+
+   -  ``regs`` : return the ROTPK hash stored in the Trusted root-key storage
+      registers. The private key corresponding to this ROTPK hash is not
+      currently available.
+   -  ``devel_rsa`` : return a development public key hash embedded in the BL1
+      and BL2 binaries. This hash has been obtained from the RSA public key
+      ``arm_rotpk_rsa.der``, located in ``plat/arm/board/common/rotpk``. To use
+      this option, ``arm_rotprivk_rsa.pem`` must be specified as ``ROT_KEY``
+      when creating the certificates.
+   -  ``devel_ecdsa`` : return a development public key hash embedded in the BL1
+      and BL2 binaries. This hash has been obtained from the ECDSA public key
+      ``arm_rotpk_ecdsa.der``, located in ``plat/arm/board/common/rotpk``. To
+      use this option, ``arm_rotprivk_ecdsa.pem`` must be specified as
+      ``ROT_KEY`` when creating the certificates.
+
+-  ``ARM_TSP_RAM_LOCATION``: location of the TSP binary. Options:
+
+   -  ``tsram`` : Trusted SRAM (default option when TBB is not enabled)
+   -  ``tdram`` : Trusted DRAM (if available)
+   -  ``dram`` : Secure region in DRAM (default option when TBB is enabled,
+      configured by the TrustZone controller)
+
+-  ``ARM_XLAT_TABLES_LIB_V1``: boolean option to compile TF-A with version 1
+   of the translation tables library instead of version 2. It is set to 0 by
+   default, which selects version 2.
+
+-  ``ARM_CRYPTOCELL_INTEG`` : bool option to enable TF-A to invoke Arm®
+   TrustZone® CryptoCell functionality for Trusted Board Boot on capable Arm
+   platforms. If this option is specified, then the path to the CryptoCell
+   SBROM library must be specified via ``CCSBROM_LIB_PATH`` flag.
+
+For a better understanding of these options, the Arm development platform memory
+map is explained in the :ref:`Firmware Design`.
+
+.. _build_options_arm_css_platform:
+
+Arm CSS Platform-Specific Build Options
+---------------------------------------
+
+-  ``CSS_DETECT_PRE_1_7_0_SCP``: Boolean flag to detect SCP version
+   incompatibility. Version 1.7.0 of the SCP firmware made a non-backwards
+   compatible change to the MTL protocol, used for AP/SCP communication.
+   TF-A no longer supports earlier SCP versions. If this option is set to 1
+   then TF-A will detect if an earlier version is in use. Default is 1.
+
+-  ``CSS_LOAD_SCP_IMAGES``: Boolean flag, which when set, adds SCP_BL2 and
+   SCP_BL2U to the FIP and FWU_FIP respectively, and enables them to be loaded
+   during boot. Default is 1.
+
+-  ``CSS_USE_SCMI_SDS_DRIVER``: Boolean flag which selects SCMI/SDS drivers
+   instead of SCPI/BOM driver for communicating with the SCP during power
+   management operations and for SCP RAM Firmware transfer. If this option
+   is set to 1, then SCMI/SDS drivers will be used. Default is 0.
+
+--------------
+
+*Copyright (c) 2019, Arm Limited. All rights reserved.*
diff --git a/docs/plat/fvp_ve.rst b/docs/plat/arm/fvp-ve/index.rst
similarity index 96%
rename from docs/plat/fvp_ve.rst
rename to docs/plat/arm/fvp-ve/index.rst
index 6abf9e5..8ac0741 100644
--- a/docs/plat/fvp_ve.rst
+++ b/docs/plat/arm/fvp-ve/index.rst
@@ -78,3 +78,7 @@
           -C motherboard.flashloader1.fname=<path_to_fip.bin> \
           --data cluster.cpu0=<path_to_zImage>@0x80080000  \
           --data cluster.cpu0=<path_to_ramdisk>@0x84000000
+
+--------------
+
+*Copyright (c) 2019, Arm Limited. All rights reserved.*
diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst
new file mode 100644
index 0000000..37010e1
--- /dev/null
+++ b/docs/plat/arm/fvp/index.rst
@@ -0,0 +1,637 @@
+Arm Fixed Virtual Platforms (FVP)
+=================================
+
+Fixed Virtual Platform (FVP) Support
+------------------------------------
+
+This section lists the supported Arm |FVP| platforms. Please refer to the FVP
+documentation for a detailed description of the model parameter options.
+
+The latest version of the AArch64 build of TF-A has been tested on the following
+Arm FVPs without shifted affinities, and that do not support threaded CPU cores
+(64-bit host machine only).
+
+.. note::
+   The FVP models used are Version 11.6 Build 45, unless otherwise stated.
+
+-  ``FVP_Base_AEMv8A-AEMv8A``
+-  ``FVP_Base_AEMv8A-AEMv8A-AEMv8A-AEMv8A-CCN502``
+-  ``FVP_Base_RevC-2xAEMv8A``
+-  ``FVP_Base_Cortex-A32x4``
+-  ``FVP_Base_Cortex-A35x4``
+-  ``FVP_Base_Cortex-A53x4``
+-  ``FVP_Base_Cortex-A55x4+Cortex-A75x4``
+-  ``FVP_Base_Cortex-A55x4``
+-  ``FVP_Base_Cortex-A57x1-A53x1``
+-  ``FVP_Base_Cortex-A57x2-A53x4``
+-  ``FVP_Base_Cortex-A57x4-A53x4``
+-  ``FVP_Base_Cortex-A57x4``
+-  ``FVP_Base_Cortex-A72x4-A53x4``
+-  ``FVP_Base_Cortex-A72x4``
+-  ``FVP_Base_Cortex-A73x4-A53x4``
+-  ``FVP_Base_Cortex-A73x4``
+-  ``FVP_Base_Cortex-A75x4``
+-  ``FVP_Base_Cortex-A76x4``
+-  ``FVP_Base_Cortex-A76AEx4``
+-  ``FVP_Base_Cortex-A76AEx8``
+-  ``FVP_Base_Cortex-A77x4`` (Version 11.7 build 36)
+-  ``FVP_Base_Neoverse-N1x4``
+-  ``FVP_Base_Zeusx4``
+-  ``FVP_CSS_SGI-575`` (Version 11.3 build 42)
+-  ``FVP_CSS_SGM-775`` (Version 11.3 build 42)
+-  ``FVP_RD_E1Edge`` (Version 11.3 build 42)
+-  ``FVP_RD_N1Edge``
+-  ``Foundation_Platform``
+
+The latest version of the AArch32 build of TF-A has been tested on the
+following Arm FVPs without shifted affinities, and that do not support threaded
+CPU cores (64-bit host machine only).
+
+-  ``FVP_Base_AEMv8A-AEMv8A``
+-  ``FVP_Base_Cortex-A32x4``
+
+.. note::
+   The ``FVP_Base_RevC-2xAEMv8A`` FVP only supports shifted affinities, which
+   is not compatible with legacy GIC configurations. Therefore this FVP does not
+   support these legacy GIC configurations.
+
+The *Foundation* and *Base* FVPs can be downloaded free of charge. See the `Arm
+FVP website`_. The Cortex-A models listed above are also available to download
+from `Arm's website`_.
+
+.. note::
+   The build numbers quoted above are those reported by launching the FVP
+   with the ``--version`` parameter.
+
+.. note::
+   Linaro provides a ramdisk image in prebuilt FVP configurations and full
+   file systems that can be downloaded separately. To run an FVP with a virtio
+   file system image an additional FVP configuration option
+   ``-C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>`` can be
+   used.
+
+.. note::
+   The software will not work on Version 1.0 of the Foundation FVP.
+   The commands below would report an ``unhandled argument`` error in this case.
+
+.. note::
+   FVPs can be launched with ``--cadi-server`` option such that a
+   CADI-compliant debugger (for example, Arm DS-5) can connect to and control
+   its execution.
+
+.. warning::
+   Since FVP model Version 11.0 Build 11.0.34 and Version 8.5 Build 0.8.5202
+   the internal synchronisation timings changed compared to older versions of
+   the models. The models can be launched with ``-Q 100`` option if they are
+   required to match the run time characteristics of the older versions.
+
+All the above platforms have been tested with `Linaro Release 19.06`_.
+
+.. _build_options_arm_fvp_platform:
+
+Arm FVP Platform Specific Build Options
+---------------------------------------
+
+-  ``FVP_CLUSTER_COUNT`` : Configures the cluster count to be used to
+   build the topology tree within TF-A. By default TF-A is configured for dual
+   cluster topology and this option can be used to override the default value.
+
+-  ``FVP_INTERCONNECT_DRIVER``: Selects the interconnect driver to be built. The
+   default interconnect driver depends on the value of ``FVP_CLUSTER_COUNT`` as
+   explained in the options below:
+
+   -  ``FVP_CCI`` : The CCI driver is selected. This is the default
+      if 0 < ``FVP_CLUSTER_COUNT`` <= 2.
+   -  ``FVP_CCN`` : The CCN driver is selected. This is the default
+      if ``FVP_CLUSTER_COUNT`` > 2.
+
+-  ``FVP_MAX_CPUS_PER_CLUSTER``: Sets the maximum number of CPUs implemented in
+   a single cluster.  This option defaults to 4.
+
+-  ``FVP_MAX_PE_PER_CPU``: Sets the maximum number of PEs implemented on any CPU
+   in the system. This option defaults to 1. Note that the build option
+   ``ARM_PLAT_MT`` doesn't have any effect on FVP platforms.
+
+-  ``FVP_USE_GIC_DRIVER`` : Selects the GIC driver to be built. Options:
+
+   -  ``FVP_GIC600`` : The GIC600 implementation of GICv3 is selected
+   -  ``FVP_GICV2`` : The GICv2 only driver is selected
+   -  ``FVP_GICV3`` : The GICv3 only driver is selected (default option)
+
+-  ``FVP_USE_SP804_TIMER`` : Use the SP804 timer instead of the Generic Timer
+   for functions that wait for an arbitrary time length (udelay and mdelay).
+   The default value is 0.
+
+-  ``FVP_HW_CONFIG_DTS`` : Specify the path to the DTS file to be compiled
+   to DTB and packaged in FIP as the HW_CONFIG. See :ref:`Firmware Design` for
+   details on HW_CONFIG. By default, this is initialized to a sensible DTS
+   file in ``fdts/`` folder depending on other build options. But some cases,
+   like shifted affinity format for MPIDR, cannot be detected at build time
+   and this option is needed to specify the appropriate DTS file.
+
+-  ``FVP_HW_CONFIG`` : Specify the path to the HW_CONFIG blob to be packaged in
+   FIP. See :ref:`Firmware Design` for details on HW_CONFIG. This option is
+   similar to the ``FVP_HW_CONFIG_DTS`` option, but it directly specifies the
+   HW_CONFIG blob instead of the DTS file. This option is useful to override
+   the default HW_CONFIG selected by the build system.
+
+Booting Firmware Update images
+------------------------------
+
+When Firmware Update (FWU) is enabled there are at least 2 new images
+that have to be loaded, the Non-Secure FWU ROM (NS-BL1U), and the
+FWU FIP.
+
+The additional fip images must be loaded with:
+
+::
+
+    --data cluster0.cpu0="<path_to>/ns_bl1u.bin"@0x0beb8000	[ns_bl1u_base_address]
+    --data cluster0.cpu0="<path_to>/fwu_fip.bin"@0x08400000	[ns_bl2u_base_address]
+
+The address ns_bl1u_base_address is the value of NS_BL1U_BASE.
+In the same way, the address ns_bl2u_base_address is the value of
+NS_BL2U_BASE.
+
+Booting an EL3 payload
+----------------------
+
+The EL3 payloads boot flow requires the CPU's mailbox to be cleared at reset for
+the secondary CPUs holding pen to work properly. Unfortunately, its reset value
+is undefined on the FVP platform and the FVP platform code doesn't clear it.
+Therefore, one must modify the way the model is normally invoked in order to
+clear the mailbox at start-up.
+
+One way to do that is to create an 8-byte file containing all zero bytes using
+the following command:
+
+.. code:: shell
+
+    dd if=/dev/zero of=mailbox.dat bs=1 count=8
+
+and pre-load it into the FVP memory at the mailbox address (i.e. ``0x04000000``)
+using the following model parameters:
+
+::
+
+    --data cluster0.cpu0=mailbox.dat@0x04000000   [Base FVPs]
+    --data=mailbox.dat@0x04000000                 [Foundation FVP]
+
+To provide the model with the EL3 payload image, the following methods may be
+used:
+
+#. If the EL3 payload is able to execute in place, it may be programmed into
+   flash memory. On Base Cortex and AEM FVPs, the following model parameter
+   loads it at the base address of the NOR FLASH1 (the NOR FLASH0 is already
+   used for the FIP):
+
+   ::
+
+       -C bp.flashloader1.fname="<path-to>/<el3-payload>"
+
+   On Foundation FVP, there is no flash loader component and the EL3 payload
+   may be programmed anywhere in flash using method 3 below.
+
+#. When using the ``SPIN_ON_BL1_EXIT=1`` loading method, the following DS-5
+   command may be used to load the EL3 payload ELF image over JTAG:
+
+   ::
+
+       load <path-to>/el3-payload.elf
+
+#. The EL3 payload may be pre-loaded in volatile memory using the following
+   model parameters:
+
+   ::
+
+       --data cluster0.cpu0="<path-to>/el3-payload>"@address   [Base FVPs]
+       --data="<path-to>/<el3-payload>"@address                [Foundation FVP]
+
+   The address provided to the FVP must match the ``EL3_PAYLOAD_BASE`` address
+   used when building TF-A.
+
+Booting a preloaded kernel image (Base FVP)
+-------------------------------------------
+
+The following example uses a simplified boot flow by directly jumping from the
+TF-A to the Linux kernel, which will use a ramdisk as filesystem. This can be
+useful if both the kernel and the device tree blob (DTB) are already present in
+memory (like in FVP).
+
+For example, if the kernel is loaded at ``0x80080000`` and the DTB is loaded at
+address ``0x82000000``, the firmware can be built like this:
+
+.. code:: shell
+
+    CROSS_COMPILE=aarch64-none-elf-  \
+    make PLAT=fvp DEBUG=1             \
+    RESET_TO_BL31=1                   \
+    ARM_LINUX_KERNEL_AS_BL33=1        \
+    PRELOADED_BL33_BASE=0x80080000    \
+    ARM_PRELOADED_DTB_BASE=0x82000000 \
+    all fip
+
+Now, it is needed to modify the DTB so that the kernel knows the address of the
+ramdisk. The following script generates a patched DTB from the provided one,
+assuming that the ramdisk is loaded at address ``0x84000000``. Note that this
+script assumes that the user is using a ramdisk image prepared for U-Boot, like
+the ones provided by Linaro. If using a ramdisk without this header,the ``0x40``
+offset in ``INITRD_START`` has to be removed.
+
+.. code:: bash
+
+    #!/bin/bash
+
+    # Path to the input DTB
+    KERNEL_DTB=<path-to>/<fdt>
+    # Path to the output DTB
+    PATCHED_KERNEL_DTB=<path-to>/<patched-fdt>
+    # Base address of the ramdisk
+    INITRD_BASE=0x84000000
+    # Path to the ramdisk
+    INITRD=<path-to>/<ramdisk.img>
+
+    # Skip uboot header (64 bytes)
+    INITRD_START=$(printf "0x%x" $((${INITRD_BASE} + 0x40)) )
+    INITRD_SIZE=$(stat -Lc %s ${INITRD})
+    INITRD_END=$(printf "0x%x" $((${INITRD_BASE} + ${INITRD_SIZE})) )
+
+    CHOSEN_NODE=$(echo                                        \
+    "/ {                                                      \
+            chosen {                                          \
+                    linux,initrd-start = <${INITRD_START}>;   \
+                    linux,initrd-end = <${INITRD_END}>;       \
+            };                                                \
+    };")
+
+    echo $(dtc -O dts -I dtb ${KERNEL_DTB}) ${CHOSEN_NODE} |  \
+            dtc -O dtb -o ${PATCHED_KERNEL_DTB} -
+
+And the FVP binary can be run with the following command:
+
+.. code:: shell
+
+    <path-to>/FVP_Base_AEMv8A-AEMv8A                            \
+    -C pctl.startup=0.0.0.0                                     \
+    -C bp.secure_memory=1                                       \
+    -C cluster0.NUM_CORES=4                                     \
+    -C cluster1.NUM_CORES=4                                     \
+    -C cache_state_modelled=1                                   \
+    -C cluster0.cpu0.RVBAR=0x04020000                           \
+    -C cluster0.cpu1.RVBAR=0x04020000                           \
+    -C cluster0.cpu2.RVBAR=0x04020000                           \
+    -C cluster0.cpu3.RVBAR=0x04020000                           \
+    -C cluster1.cpu0.RVBAR=0x04020000                           \
+    -C cluster1.cpu1.RVBAR=0x04020000                           \
+    -C cluster1.cpu2.RVBAR=0x04020000                           \
+    -C cluster1.cpu3.RVBAR=0x04020000                           \
+    --data cluster0.cpu0="<path-to>/bl31.bin"@0x04020000        \
+    --data cluster0.cpu0="<path-to>/<patched-fdt>"@0x82000000   \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+    --data cluster0.cpu0="<path-to>/<ramdisk.img>"@0x84000000
+
+Obtaining the Flattened Device Trees
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Depending on the FVP configuration and Linux configuration used, different
+FDT files are required. FDT source files for the Foundation and Base FVPs can
+be found in the TF-A source directory under ``fdts/``. The Foundation FVP has
+a subset of the Base FVP components. For example, the Foundation FVP lacks
+CLCD and MMC support, and has only one CPU cluster.
+
+.. note::
+   It is not recommended to use the FDTs built along the kernel because not
+   all FDTs are available from there.
+
+The dynamic configuration capability is enabled in the firmware for FVPs.
+This means that the firmware can authenticate and load the FDT if present in
+FIP. A default FDT is packaged into FIP during the build based on
+the build configuration. This can be overridden by using the ``FVP_HW_CONFIG``
+or ``FVP_HW_CONFIG_DTS`` build options (refer to
+:ref:`build_options_arm_fvp_platform` for details on the options).
+
+-  ``fvp-base-gicv2-psci.dts``
+
+   For use with models such as the Cortex-A57-A53 Base FVPs without shifted
+   affinities and with Base memory map configuration.
+
+-  ``fvp-base-gicv2-psci-aarch32.dts``
+
+   For use with models such as the Cortex-A32 Base FVPs without shifted
+   affinities and running Linux in AArch32 state with Base memory map
+   configuration.
+
+-  ``fvp-base-gicv3-psci.dts``
+
+   For use with models such as the Cortex-A57-A53 Base FVPs without shifted
+   affinities and with Base memory map configuration and Linux GICv3 support.
+
+-  ``fvp-base-gicv3-psci-1t.dts``
+
+   For use with models such as the AEMv8-RevC Base FVP with shifted affinities,
+   single threaded CPUs, Base memory map configuration and Linux GICv3 support.
+
+-  ``fvp-base-gicv3-psci-dynamiq.dts``
+
+   For use with models as the Cortex-A55-A75 Base FVPs with shifted affinities,
+   single cluster, single threaded CPUs, Base memory map configuration and Linux
+   GICv3 support.
+
+-  ``fvp-base-gicv3-psci-aarch32.dts``
+
+   For use with models such as the Cortex-A32 Base FVPs without shifted
+   affinities and running Linux in AArch32 state with Base memory map
+   configuration and Linux GICv3 support.
+
+-  ``fvp-foundation-gicv2-psci.dts``
+
+   For use with Foundation FVP with Base memory map configuration.
+
+-  ``fvp-foundation-gicv3-psci.dts``
+
+   (Default) For use with Foundation FVP with Base memory map configuration
+   and Linux GICv3 support.
+
+
+Running on the Foundation FVP with reset to BL1 entrypoint
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``Foundation_Platform`` parameters should be used to boot Linux with
+4 CPUs using the AArch64 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/Foundation_Platform                   \
+    --cores=4                                       \
+    --arm-v8.0                                      \
+    --secure-memory                                 \
+    --visualization                                 \
+    --gicv3                                         \
+    --data="<path-to>/<bl1-binary>"@0x0             \
+    --data="<path-to>/<FIP-binary>"@0x08000000      \
+    --data="<path-to>/<kernel-binary>"@0x80080000   \
+    --data="<path-to>/<ramdisk-binary>"@0x84000000
+
+Notes:
+
+-  BL1 is loaded at the start of the Trusted ROM.
+-  The Firmware Image Package is loaded at the start of NOR FLASH0.
+-  The firmware loads the FDT packaged in FIP to the DRAM. The FDT load address
+   is specified via the ``hw_config_addr`` property in `TB_FW_CONFIG for FVP`_.
+-  The default use-case for the Foundation FVP is to use the ``--gicv3`` option
+   and enable the GICv3 device in the model. Note that without this option,
+   the Foundation FVP defaults to legacy (Versatile Express) memory map which
+   is not supported by TF-A.
+-  In order for TF-A to run correctly on the Foundation FVP, the architecture
+   versions must match. The Foundation FVP defaults to the highest v8.x
+   version it supports but the default build for TF-A is for v8.0. To avoid
+   issues either start the Foundation FVP to use v8.0 architecture using the
+   ``--arm-v8.0`` option, or build TF-A with an appropriate value for
+   ``ARM_ARCH_MINOR``.
+
+Running on the AEMv8 Base FVP with reset to BL1 entrypoint
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``FVP_Base_RevC-2xAEMv8A`` parameters should be used to boot Linux
+with 8 CPUs using the AArch64 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/FVP_Base_RevC-2xAEMv8A                            \
+    -C pctl.startup=0.0.0.0                                     \
+    -C bp.secure_memory=1                                       \
+    -C bp.tzc_400.diagnostics=1                                 \
+    -C cluster0.NUM_CORES=4                                     \
+    -C cluster1.NUM_CORES=4                                     \
+    -C cache_state_modelled=1                                   \
+    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>"      \
+    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"           \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+.. note::
+   The ``FVP_Base_RevC-2xAEMv8A`` has shifted affinities and requires
+   a specific DTS for all the CPUs to be loaded.
+
+Running on the AEMv8 Base FVP (AArch32) with reset to BL1 entrypoint
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``FVP_Base_AEMv8A-AEMv8A`` parameters should be used to boot Linux
+with 8 CPUs using the AArch32 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/FVP_Base_AEMv8A-AEMv8A                            \
+    -C pctl.startup=0.0.0.0                                     \
+    -C bp.secure_memory=1                                       \
+    -C bp.tzc_400.diagnostics=1                                 \
+    -C cluster0.NUM_CORES=4                                     \
+    -C cluster1.NUM_CORES=4                                     \
+    -C cache_state_modelled=1                                   \
+    -C cluster0.cpu0.CONFIG64=0                                 \
+    -C cluster0.cpu1.CONFIG64=0                                 \
+    -C cluster0.cpu2.CONFIG64=0                                 \
+    -C cluster0.cpu3.CONFIG64=0                                 \
+    -C cluster1.cpu0.CONFIG64=0                                 \
+    -C cluster1.cpu1.CONFIG64=0                                 \
+    -C cluster1.cpu2.CONFIG64=0                                 \
+    -C cluster1.cpu3.CONFIG64=0                                 \
+    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>"      \
+    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"           \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+Running on the Cortex-A57-A53 Base FVP with reset to BL1 entrypoint
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``FVP_Base_Cortex-A57x4-A53x4`` model parameters should be used to
+boot Linux with 8 CPUs using the AArch64 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/FVP_Base_Cortex-A57x4-A53x4                       \
+    -C pctl.startup=0.0.0.0                                     \
+    -C bp.secure_memory=1                                       \
+    -C bp.tzc_400.diagnostics=1                                 \
+    -C cache_state_modelled=1                                   \
+    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>"      \
+    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"           \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+Running on the Cortex-A32 Base FVP (AArch32) with reset to BL1 entrypoint
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``FVP_Base_Cortex-A32x4`` model parameters should be used to
+boot Linux with 4 CPUs using the AArch32 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/FVP_Base_Cortex-A32x4                             \
+    -C pctl.startup=0.0.0.0                                     \
+    -C bp.secure_memory=1                                       \
+    -C bp.tzc_400.diagnostics=1                                 \
+    -C cache_state_modelled=1                                   \
+    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>"      \
+    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"           \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+
+Running on the AEMv8 Base FVP with reset to BL31 entrypoint
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``FVP_Base_RevC-2xAEMv8A`` parameters should be used to boot Linux
+with 8 CPUs using the AArch64 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/FVP_Base_RevC-2xAEMv8A                             \
+    -C pctl.startup=0.0.0.0                                      \
+    -C bp.secure_memory=1                                        \
+    -C bp.tzc_400.diagnostics=1                                  \
+    -C cluster0.NUM_CORES=4                                      \
+    -C cluster1.NUM_CORES=4                                      \
+    -C cache_state_modelled=1                                    \
+    -C cluster0.cpu0.RVBAR=0x04010000                            \
+    -C cluster0.cpu1.RVBAR=0x04010000                            \
+    -C cluster0.cpu2.RVBAR=0x04010000                            \
+    -C cluster0.cpu3.RVBAR=0x04010000                            \
+    -C cluster1.cpu0.RVBAR=0x04010000                            \
+    -C cluster1.cpu1.RVBAR=0x04010000                            \
+    -C cluster1.cpu2.RVBAR=0x04010000                            \
+    -C cluster1.cpu3.RVBAR=0x04010000                            \
+    --data cluster0.cpu0="<path-to>/<bl31-binary>"@0x04010000    \
+    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0xff000000    \
+    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000    \
+    --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000            \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000  \
+    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+Notes:
+
+-  If Position Independent Executable (PIE) support is enabled for BL31
+   in this config, it can be loaded at any valid address for execution.
+
+-  Since a FIP is not loaded when using BL31 as reset entrypoint, the
+   ``--data="<path-to><bl31|bl32|bl33-binary>"@<base-address-of-binary>``
+   parameter is needed to load the individual bootloader images in memory.
+   BL32 image is only needed if BL31 has been built to expect a Secure-EL1
+   Payload. For the same reason, the FDT needs to be compiled from the DT source
+   and loaded via the ``--data cluster0.cpu0="<path-to>/<fdt>"@0x82000000``
+   parameter.
+
+-  The ``FVP_Base_RevC-2xAEMv8A`` has shifted affinities and requires a
+   specific DTS for all the CPUs to be loaded.
+
+-  The ``-C cluster<X>.cpu<Y>.RVBAR=@<base-address-of-bl31>`` parameter, where
+   X and Y are the cluster and CPU numbers respectively, is used to set the
+   reset vector for each core.
+
+-  Changing the default value of ``ARM_TSP_RAM_LOCATION`` will also require
+   changing the value of
+   ``--data="<path-to><bl32-binary>"@<base-address-of-bl32>`` to the new value of
+   ``BL32_BASE``.
+
+
+Running on the AEMv8 Base FVP (AArch32) with reset to SP_MIN entrypoint
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``FVP_Base_AEMv8A-AEMv8A`` parameters should be used to boot Linux
+with 8 CPUs using the AArch32 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/FVP_Base_AEMv8A-AEMv8A                             \
+    -C pctl.startup=0.0.0.0                                      \
+    -C bp.secure_memory=1                                        \
+    -C bp.tzc_400.diagnostics=1                                  \
+    -C cluster0.NUM_CORES=4                                      \
+    -C cluster1.NUM_CORES=4                                      \
+    -C cache_state_modelled=1                                    \
+    -C cluster0.cpu0.CONFIG64=0                                  \
+    -C cluster0.cpu1.CONFIG64=0                                  \
+    -C cluster0.cpu2.CONFIG64=0                                  \
+    -C cluster0.cpu3.CONFIG64=0                                  \
+    -C cluster1.cpu0.CONFIG64=0                                  \
+    -C cluster1.cpu1.CONFIG64=0                                  \
+    -C cluster1.cpu2.CONFIG64=0                                  \
+    -C cluster1.cpu3.CONFIG64=0                                  \
+    -C cluster0.cpu0.RVBAR=0x04002000                            \
+    -C cluster0.cpu1.RVBAR=0x04002000                            \
+    -C cluster0.cpu2.RVBAR=0x04002000                            \
+    -C cluster0.cpu3.RVBAR=0x04002000                            \
+    -C cluster1.cpu0.RVBAR=0x04002000                            \
+    -C cluster1.cpu1.RVBAR=0x04002000                            \
+    -C cluster1.cpu2.RVBAR=0x04002000                            \
+    -C cluster1.cpu3.RVBAR=0x04002000                            \
+    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0x04002000    \
+    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000    \
+    --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000            \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000  \
+    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+.. note::
+   The load address of ``<bl32-binary>`` depends on the value ``BL32_BASE``.
+   It should match the address programmed into the RVBAR register as well.
+
+Running on the Cortex-A57-A53 Base FVP with reset to BL31 entrypoint
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``FVP_Base_Cortex-A57x4-A53x4`` model parameters should be used to
+boot Linux with 8 CPUs using the AArch64 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/FVP_Base_Cortex-A57x4-A53x4                        \
+    -C pctl.startup=0.0.0.0                                      \
+    -C bp.secure_memory=1                                        \
+    -C bp.tzc_400.diagnostics=1                                  \
+    -C cache_state_modelled=1                                    \
+    -C cluster0.cpu0.RVBARADDR=0x04010000                        \
+    -C cluster0.cpu1.RVBARADDR=0x04010000                        \
+    -C cluster0.cpu2.RVBARADDR=0x04010000                        \
+    -C cluster0.cpu3.RVBARADDR=0x04010000                        \
+    -C cluster1.cpu0.RVBARADDR=0x04010000                        \
+    -C cluster1.cpu1.RVBARADDR=0x04010000                        \
+    -C cluster1.cpu2.RVBARADDR=0x04010000                        \
+    -C cluster1.cpu3.RVBARADDR=0x04010000                        \
+    --data cluster0.cpu0="<path-to>/<bl31-binary>"@0x04010000    \
+    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0xff000000    \
+    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000    \
+    --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000            \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000  \
+    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+Running on the Cortex-A32 Base FVP (AArch32) with reset to SP_MIN entrypoint
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following ``FVP_Base_Cortex-A32x4`` model parameters should be used to
+boot Linux with 4 CPUs using the AArch32 build of TF-A.
+
+.. code:: shell
+
+    <path-to>/FVP_Base_Cortex-A32x4                             \
+    -C pctl.startup=0.0.0.0                                     \
+    -C bp.secure_memory=1                                       \
+    -C bp.tzc_400.diagnostics=1                                 \
+    -C cache_state_modelled=1                                   \
+    -C cluster0.cpu0.RVBARADDR=0x04002000                       \
+    -C cluster0.cpu1.RVBARADDR=0x04002000                       \
+    -C cluster0.cpu2.RVBARADDR=0x04002000                       \
+    -C cluster0.cpu3.RVBARADDR=0x04002000                       \
+    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0x04002000   \
+    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000   \
+    --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000           \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+    --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+--------------
+
+*Copyright (c) 2019, Arm Limited. All rights reserved.*
+
+.. _TB_FW_CONFIG for FVP: ../plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
+.. _Arm's website: `FVP models`_
+.. _FVP models: https://developer.arm.com/products/system-design/fixed-virtual-platforms
+.. _Linaro Release 19.06: http://releases.linaro.org/members/arm/platforms/19.06
+.. _Arm FVP website: https://developer.arm.com/products/system-design/fixed-virtual-platforms
diff --git a/docs/plat/arm/index.rst b/docs/plat/arm/index.rst
new file mode 100644
index 0000000..e26f75e
--- /dev/null
+++ b/docs/plat/arm/index.rst
@@ -0,0 +1,19 @@
+Arm Development Platforms
+=========================
+
+.. toctree::
+   :maxdepth: 1
+   :caption: Contents
+
+   juno/index
+   fvp/index
+   fvp-ve/index
+   arm-build-options
+
+This chapter holds documentation related to Arm's development platforms,
+including both software models (FVPs) and hardware development boards
+such as Juno.
+
+--------------
+
+*Copyright (c) 2019, Arm Limited. All rights reserved.*
diff --git a/docs/plat/arm/juno/index.rst b/docs/plat/arm/juno/index.rst
new file mode 100644
index 0000000..cf328fa
--- /dev/null
+++ b/docs/plat/arm/juno/index.rst
@@ -0,0 +1,246 @@
+Arm Juno Development Platform
+=============================
+
+Platform-specific build options
+-------------------------------
+
+-  ``JUNO_TZMP1`` : Boolean option to configure Juno to be used for TrustZone
+   Media Protection (TZ-MP1). Default value of this flag is 0.
+
+Running software on Juno
+------------------------
+
+This version of TF-A has been tested on variants r0, r1 and r2 of Juno.
+
+To execute the software stack on Juno, the version of the Juno board recovery
+image indicated in the `Linaro Release Notes`_ must be installed. If you have an
+earlier version installed or are unsure which version is installed, please
+re-install the recovery image by following the
+`Instructions for using Linaro's deliverables on Juno`_.
+
+Preparing TF-A images
+---------------------
+
+After building TF-A, the files ``bl1.bin`` and ``fip.bin`` need copying to the
+``SOFTWARE/`` directory of the Juno SD card.
+
+Creating a Firmware Image Package (FIP)
+---------------------------------------
+
+This section provides Juno and FVP specific instructions to build Trusted
+Firmware, obtain the additional required firmware, and pack it all together in
+a single FIP binary. It assumes that a Linaro release has been installed.
+
+.. note::
+   Pre-built binaries for AArch32 are available from Linaro Release 16.12
+   onwards. Before that release, pre-built binaries are only available for
+   AArch64.
+
+.. warning::
+   Follow the full instructions for one platform before switching to a
+   different one. Mixing instructions for different platforms may result in
+   corrupted binaries.
+
+.. warning::
+   The uboot image downloaded by the Linaro workspace script does not always
+   match the uboot image packaged as BL33 in the corresponding fip file. It is
+   recommended to use the version that is packaged in the fip file using the
+   instructions below.
+
+.. note::
+   For the FVP, the kernel FDT is packaged in FIP during build and loaded
+   by the firmware at runtime.
+
+#. Clean the working directory
+
+   .. code:: shell
+
+       make realclean
+
+#. Obtain SCP_BL2 (Juno) and BL33 (all platforms)
+
+   Use the fiptool to extract the SCP_BL2 and BL33 images from the FIP
+   package included in the Linaro release:
+
+   .. code:: shell
+
+       # Build the fiptool
+       make [DEBUG=1] [V=1] fiptool
+
+       # Unpack firmware images from Linaro FIP
+       ./tools/fiptool/fiptool unpack <path-to-linaro-release>/[SOFTWARE]/fip.bin
+
+   The unpack operation will result in a set of binary images extracted to the
+   current working directory. The SCP_BL2 image corresponds to
+   ``scp-fw.bin`` and BL33 corresponds to ``nt-fw.bin``.
+
+   .. note::
+      The fiptool will complain if the images to be unpacked already
+      exist in the current directory. If that is the case, either delete those
+      files or use the ``--force`` option to overwrite.
+
+   .. note::
+      For AArch32, the instructions below assume that nt-fw.bin is a
+      normal world boot loader that supports AArch32.
+
+#. Build TF-A images and create a new FIP for FVP
+
+   .. code:: shell
+
+       # AArch64
+       make PLAT=fvp BL33=nt-fw.bin all fip
+
+       # AArch32
+       make PLAT=fvp ARCH=aarch32 AARCH32_SP=sp_min BL33=nt-fw.bin all fip
+
+#. Build TF-A images and create a new FIP for Juno
+
+   For AArch64:
+
+   Building for AArch64 on Juno simply requires the addition of ``SCP_BL2``
+   as a build parameter.
+
+   .. code:: shell
+
+       make PLAT=juno BL33=nt-fw.bin SCP_BL2=scp-fw.bin all fip
+
+   For AArch32:
+
+   Hardware restrictions on Juno prevent cold reset into AArch32 execution mode,
+   therefore BL1 and BL2 must be compiled for AArch64, and BL32 is compiled
+   separately for AArch32.
+
+   -  Before building BL32, the environment variable ``CROSS_COMPILE`` must point
+      to the AArch32 Linaro cross compiler.
+
+      .. code:: shell
+
+          export CROSS_COMPILE=<path-to-aarch32-gcc>/bin/arm-linux-gnueabihf-
+
+   -  Build BL32 in AArch32.
+
+      .. code:: shell
+
+          make ARCH=aarch32 PLAT=juno AARCH32_SP=sp_min \
+          RESET_TO_SP_MIN=1 JUNO_AARCH32_EL3_RUNTIME=1 bl32
+
+   -  Save ``bl32.bin`` to a temporary location and clean the build products.
+
+      ::
+
+          cp <path-to-build>/bl32.bin <path-to-temporary>
+          make realclean
+
+   -  Before building BL1 and BL2, the environment variable ``CROSS_COMPILE``
+      must point to the AArch64 Linaro cross compiler.
+
+      .. code:: shell
+
+          export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf-
+
+   -  The following parameters should be used to build BL1 and BL2 in AArch64
+      and point to the BL32 file.
+
+      .. code:: shell
+
+          make ARCH=aarch64 PLAT=juno JUNO_AARCH32_EL3_RUNTIME=1 \
+          BL33=nt-fw.bin SCP_BL2=scp-fw.bin \
+          BL32=<path-to-temporary>/bl32.bin all fip
+
+The resulting BL1 and FIP images may be found in:
+
+::
+
+    # Juno
+    ./build/juno/release/bl1.bin
+    ./build/juno/release/fip.bin
+
+    # FVP
+    ./build/fvp/release/bl1.bin
+    ./build/fvp/release/fip.bin
+
+
+Booting Firmware Update images
+------------------------------
+
+The new images must be programmed in flash memory by adding
+an entry in the ``SITE1/HBI0262x/images.txt`` configuration file
+on the Juno SD card (where ``x`` depends on the revision of the Juno board).
+Refer to the `Juno Getting Started Guide`_, section 2.3 "Flash memory
+programming" for more information. User should ensure these do not
+overlap with any other entries in the file.
+
+::
+
+        NOR10UPDATE: AUTO                       ;Image Update:NONE/AUTO/FORCE
+        NOR10ADDRESS: 0x00400000                ;Image Flash Address [ns_bl2u_base_address]
+        NOR10FILE: \SOFTWARE\fwu_fip.bin        ;Image File Name
+        NOR10LOAD: 00000000                     ;Image Load Address
+        NOR10ENTRY: 00000000                    ;Image Entry Point
+
+        NOR11UPDATE: AUTO                       ;Image Update:NONE/AUTO/FORCE
+        NOR11ADDRESS: 0x03EB8000                ;Image Flash Address [ns_bl1u_base_address]
+        NOR11FILE: \SOFTWARE\ns_bl1u.bin        ;Image File Name
+        NOR11LOAD: 00000000                     ;Image Load Address
+
+The address ns_bl1u_base_address is the value of NS_BL1U_BASE - 0x8000000.
+In the same way, the address ns_bl2u_base_address is the value of
+NS_BL2U_BASE - 0x8000000.
+
+.. _plat_juno_booting_el3_payload:
+
+Booting an EL3 payload
+----------------------
+
+If the EL3 payload is able to execute in place, it may be programmed in flash
+memory by adding an entry in the ``SITE1/HBI0262x/images.txt`` configuration file
+on the Juno SD card (where ``x`` depends on the revision of the Juno board).
+Refer to the `Juno Getting Started Guide`_, section 2.3 "Flash memory
+programming" for more information.
+
+Alternatively, the same DS-5 command mentioned in the FVP section above can
+be used to load the EL3 payload's ELF file over JTAG on Juno.
+
+For more information on EL3 payloads in general, see
+:ref:`alt_boot_flows_el3_payload`.
+
+Booting a preloaded kernel image
+--------------------------------
+
+The Trusted Firmware must be compiled in a similar way as for FVP explained
+above. The process to load binaries to memory is the one explained in
+`plat_juno_booting_el3_payload`_.
+
+Testing System Suspend
+----------------------
+
+The SYSTEM SUSPEND is a PSCI API which can be used to implement system suspend
+to RAM. For more details refer to section 5.16 of `PSCI`_. To test system suspend
+on Juno, at the linux shell prompt, issue the following command:
+
+.. code:: shell
+
+    echo +10 > /sys/class/rtc/rtc0/wakealarm
+    echo -n mem > /sys/power/state
+
+The Juno board should suspend to RAM and then wakeup after 10 seconds due to
+wakeup interrupt from RTC.
+
+Additional Resources
+--------------------
+
+Please visit the `Arm Platforms Portal`_ to get support and obtain any other Juno
+software information. Please also refer to the `Juno Getting Started Guide`_ to
+get more detailed information about the Juno Arm development platform and how to
+configure it.
+
+--------------
+
+*Copyright (c) 2019, Arm Limited. All rights reserved.*
+
+.. _Linaro Release Notes: https://community.arm.com/dev-platforms/w/docs/226/old-release-notes
+.. _Instructions for using Linaro's deliverables on Juno: https://community.arm.com/dev-platforms/w/docs/303/juno
+.. _Arm Platforms Portal: https://community.arm.com/dev-platforms/
+.. _Juno Getting Started Guide: http://infocenter.arm.com/help/topic/com.arm.doc.dui0928e/DUI0928E_juno_arm_development_platform_gsg.pdf
+.. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
+.. _Juno Arm Development Platform: http://www.arm.com/products/tools/development-boards/versatile-express/juno-arm-development-platform.php
diff --git a/docs/plat/index.rst b/docs/plat/index.rst
index 5495280..63d29a9 100644
--- a/docs/plat/index.rst
+++ b/docs/plat/index.rst
@@ -8,10 +8,10 @@
    :hidden:
 
    allwinner
+   arm/index
    meson-gxbb
    meson-gxl
    meson-g12a
-   fvp_ve
    hikey
    hikey960
    intel-agilex
@@ -38,81 +38,19 @@
    xilinx-zynqmp
 
 This section provides a list of supported upstream *platform ports* and the
-documentation associated with them. The list of suported Arm |FVP| platforms is
-outlined in the following section.
+documentation associated with them.
 
 .. note::
    In addition to the platforms ports listed within the table of contents, there
    are several additional platforms that are supported upstream but which do not
    currently have associated documentation:
 
-   - Arm Juno Software Development Platform. Various |AArch32| and |AArch64|
-     builds of this release have been tested on r0, r1 and r2 variants of the
-     `Juno Arm Development Platform`_.
    - Arm Neoverse N1 System Development Platform (N1SDP)
    - Arm Neoverse Reference Design N1 Edge (RD-N1-Edge) FVP
    - Arm Neoverse Reference Design E1 Edge (RD-E1-Edge) FVP
    - Arm SGI-575 and SGM-775
    - MediaTek MT6795 and MT8173 SoCs
 
-Fixed Virtual Platform (FVP) Support
-------------------------------------
-
-The latest version of the AArch64 build of TF-A has been tested on the
-following Arm FVPs without shifted affinities, and that do not support threaded
-CPU cores (64-bit host machine only).
-
-.. note::
-   The FVP models used are Version 11.6 Build 45, unless otherwise stated.
-
--  ``FVP_Base_AEMv8A-AEMv8A``
--  ``FVP_Base_AEMv8A-AEMv8A-AEMv8A-AEMv8A-CCN502``
--  ``FVP_Base_RevC-2xAEMv8A``
--  ``FVP_Base_Cortex-A32x4``
--  ``FVP_Base_Cortex-A35x4``
--  ``FVP_Base_Cortex-A53x4``
--  ``FVP_Base_Cortex-A55x4+Cortex-A75x4``
--  ``FVP_Base_Cortex-A55x4``
--  ``FVP_Base_Cortex-A57x1-A53x1``
--  ``FVP_Base_Cortex-A57x2-A53x4``
--  ``FVP_Base_Cortex-A57x4-A53x4``
--  ``FVP_Base_Cortex-A57x4``
--  ``FVP_Base_Cortex-A72x4-A53x4``
--  ``FVP_Base_Cortex-A72x4``
--  ``FVP_Base_Cortex-A73x4-A53x4``
--  ``FVP_Base_Cortex-A73x4``
--  ``FVP_Base_Cortex-A75x4``
--  ``FVP_Base_Cortex-A76x4``
--  ``FVP_Base_Cortex-A76AEx4`` (Tested with internal model)
--  ``FVP_Base_Cortex-A76AEx8`` (Tested with internal model)
--  ``FVP_Base_Cortex-A77x4`` (Version 11.7 build 36)
--  ``FVP_Base_Zeusx4``
--  ``FVP_Base_Neoverse-N1x4`` (Tested with internal model)
--  ``FVP_CSS_SGI-575`` (Version 11.3 build 42)
--  ``FVP_CSS_SGM-775`` (Version 11.3 build 42)
--  ``FVP_RD_E1Edge`` (Version 11.3 build 42)
--  ``FVP_RD_N1Edge`` (Version 11.3 build 42)
--  ``Foundation_Platform``
-
-The latest version of the AArch32 build of TF-A has been tested on the
-following Arm FVPs without shifted affinities, and that do not support threaded
-CPU cores (64-bit host machine only).
-
--  ``FVP_Base_AEMv8A-AEMv8A``
--  ``FVP_Base_Cortex-A32x4``
-
-.. note::
-   The ``FVP_Base_RevC-2xAEMv8A`` FVP only supports shifted affinities.
-
-The *Foundation* and *Base* FVPs can be downloaded free of charge. See the
-`Arm FVP website`_.
-
-All the above platforms have been tested with `Linaro Release 19.06`_.
-
 --------------
 
 *Copyright (c) 2019, Arm Limited. All rights reserved.*
-
-.. _Juno Arm Development Platform: http://www.arm.com/products/tools/development-boards/versatile-express/juno-arm-development-platform.php
-.. _Arm FVP website: https://developer.arm.com/products/system-design/fixed-virtual-platforms
-.. _Linaro Release 19.06: http://releases.linaro.org/members/arm/platforms/19.06
diff --git a/docs/plat/marvell/build.rst b/docs/plat/marvell/build.rst
index c8923e4..c10bcff 100644
--- a/docs/plat/marvell/build.rst
+++ b/docs/plat/marvell/build.rst
@@ -194,8 +194,8 @@
     can interrupt UART recovery process). This MACRO definition is set in
     ``plat/marvell/a8k/common/include/platform_def.h`` file.
 
-For more information about build options, please refer to section
-'Summary of build options' in the :ref:`User Guide`.
+For more information about build options, please refer to the
+:ref:`Build Options` document.
 
 
 Build output
@@ -251,4 +251,3 @@
     (use the "mv_ddr-armada-atf-mainline" branch):
 
     https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git
-
diff --git a/docs/plat/nvidia-tegra.rst b/docs/plat/nvidia-tegra.rst
index bc9e35b..02ff38b 100644
--- a/docs/plat/nvidia-tegra.rst
+++ b/docs/plat/nvidia-tegra.rst
@@ -1,6 +1,17 @@
 NVIDIA Tegra
 ============
 
+-  .. rubric:: T194
+      :name: t194
+
+T194 has eight NVIDIA Carmel CPU cores in a coherent multi-processor
+configuration. The Carmel cores support the ARM Architecture version 8.2,
+executing both 64-bit AArch64 code, and 32-bit AArch32 code. The Carmel
+processors are organized as four dual-core clusters, where each cluster has
+a dedicated 2 MiB Level-2 unified cache. A high speed coherency fabric connects
+these processor complexes and allows heterogeneous multi-processing with all
+eight cores if required.
+
 -  .. rubric:: T186
       :name: t186
 
@@ -78,9 +89,10 @@
 
 These are the supported Trusted OS' by Tegra platforms.
 
-Tegra132: TLK
-Tegra210: TLK and Trusty
-Tegra186: Trusty
+- Tegra132: TLK
+- Tegra210: TLK and Trusty
+- Tegra186: Trusty
+- Tegra194: Trusty
 
 Scatter files
 -------------
@@ -98,7 +110,7 @@
 .. code:: shell
 
     CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf- make PLAT=tegra \
-    TARGET_SOC=<target-soc e.g. t186|t210|t132> SPD=<dispatcher e.g. trusty|tlkd>
+    TARGET_SOC=<target-soc e.g. t194|t186|t210|t132> SPD=<dispatcher e.g. trusty|tlkd>
     bl31
 
 Platforms wanting to use different TZDRAM\_BASE, can add ``TZDRAM_BASE=<value>``
diff --git a/docs/plat/rpi4.rst b/docs/plat/rpi4.rst
index 0f529c1..beb0227 100644
--- a/docs/plat/rpi4.rst
+++ b/docs/plat/rpi4.rst
@@ -24,11 +24,10 @@
 
     CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rpi4 DEBUG=1
 
-Copy the generated build/rpi4/debug/bl31.bin to the SD card, either
-renaming it to ``armstub8.bin`` or adding an entry starting with ``armstub=``,
-then followed by the respective file name to ``config.txt``.
-You should have AArch64 code in the file loaded as the "kernel", as BL31
-will drop into AArch64/EL2 to the respective load address.
+Copy the generated build/rpi4/debug/bl31.bin to the SD card, adding an entry
+starting with ``armstub=``, then followed by the respective file name to
+``config.txt``. You should have AArch64 code in the file loaded as the
+"kernel", as BL31 will drop into AArch64/EL2 to the respective load address.
 arm64 Linux kernels are known to work this way.
 
 Other options that should be set in ``config.txt`` to properly boot 64-bit
diff --git a/docs/plat/socionext-uniphier.rst b/docs/plat/socionext-uniphier.rst
index 964dd1d..9288193 100644
--- a/docs/plat/socionext-uniphier.rst
+++ b/docs/plat/socionext-uniphier.rst
@@ -80,7 +80,8 @@
 - Trusted Board Boot
 
   `mbed TLS`_ is needed as the cryptographic and image parser modules.
-  Refer to the :ref:`User Guide` for the appropriate version of mbed TLS.
+  Refer to the :ref:`Prerequisites` document for the appropriate version of
+  mbed TLS.
 
   To enable TBB, add the following options to the build command::
 
diff --git a/docs/plat/stm32mp1.rst b/docs/plat/stm32mp1.rst
index 88251d6..2c372a6 100644
--- a/docs/plat/stm32mp1.rst
+++ b/docs/plat/stm32mp1.rst
@@ -76,21 +76,34 @@
 
 Build Instructions
 ------------------
+Boot media(s) supported by BL2 must be specified in the build command.
+Available storage medias are:
+- ``STM32MP_SDMMC``
+- ``STM32MP_EMMC``
+- ``STM32MP_RAW_NAND``
+- ``STM32MP_SPI_NAND``
+- ``STM32MP_SPI_NOR``
 
-To build with SP_min:
+To build with SP_min and support for all bootable devices:
 
 .. code:: bash
 
-    make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=sp_min DTB_FILE_NAME=stm32mp157c-ev1.dtb
+    make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=sp_min STM32MP_SDMMC=1 STM32MP_EMMC=1 STM32MP_RAW_NAND=1 STM32MP_SPI_NAND=1
+    STM32MP_SPI_NOR=1 DTB_FILE_NAME=stm32mp157c-ev1.dtb
     cd <u-boot_directory>
     make stm32mp15_trusted_defconfig
     make DEVICE_TREE=stm32mp157c-ev1 all
 
-To build TF-A with with Op-TEE support:
-
+To build TF-A with OP-TEE support for all bootable devices:
 .. code:: bash
 
+    make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=optee STM32MP_SDMMC=1 STM32MP_EMMC=1 STM32MP_RAW_NAND=1 STM32MP_SPI_NAND=1 STM32MP_SPI_NOR=1 DTB_FILE_NAME=stm32mp157c-ev1.dtb
+    cd <optee_directory>
+    make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm PLATFORM=stm32mp1 CFG_EMBED_DTB_SOURCE_FILE=stm32mp157c-ev1.dts
+    cd <u-boot_directory>
+    make stm32mp15_optee_defconfig
+    make DEVICE_TREE=stm32mp157c-ev1 all
+
-    make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=optee
 
 The following build options are supported:
 
diff --git a/docs/process/contributing.rst b/docs/process/contributing.rst
index fdb702f..f569fcb 100644
--- a/docs/process/contributing.rst
+++ b/docs/process/contributing.rst
@@ -13,8 +13,8 @@
       raise a separate `issue`_ for this and ensure that the changes that
       include Third Party IP are made on a separate topic branch.
 
--  Clone `Trusted Firmware-A`_ on your own machine as suggested in the
-   :ref:`User Guide`.
+-  Clone `Trusted Firmware-A`_ on your own machine as described in
+   :ref:`prerequisites_get_source`.
 -  Create a local topic branch based on the `Trusted Firmware-A`_ ``master``
    branch.
 
@@ -26,8 +26,7 @@
 -  Follow the :ref:`Coding Style & Guidelines`.
 
    -  Use the checkpatch.pl script provided with the Linux source tree. A
-      Makefile target is provided for convenience (see the "Checking source code
-      style" section in the :ref:`User Guide`).
+      Makefile target is provided for convenience.
 
 -  Keep the commits on topic. If you need to fix another bug or make another
    enhancement, please create a separate `issue`_ and address it on a separate
@@ -38,8 +37,9 @@
    an `issue`_, include a reference.
 -  Where appropriate, please update the documentation.
 
-   -  Consider whether the :ref:`User Guide`, :ref:`Porting Guide`,
-      :ref:`Firmware Design` or other in-source documentation needs updating.
+   -  Consider whether the :ref:`Porting Guide`,
+      :ref:`Firmware Design` document or other in-source documentation needs
+      updating.
    -  Ensure that each changed file has the correct copyright and license
       information. Files that entirely consist of contributions to this
       project should have a copyright notice and BSD-3-Clause SPDX license
@@ -63,9 +63,9 @@
       include the documentation changes within the single commit.
 
 -  Please test your changes. As a minimum, ensure that Linux boots on the
-   Foundation FVP. See :ref:`user_guide_run_fvp` for more information. For
-   more extensive testing, consider running the `TF-A Tests`_ against your
-   patches.
+   Foundation FVP. See :ref:`Arm Fixed Virtual Platforms (FVP)` for more
+   information. For more extensive testing, consider running the `TF-A Tests`_
+   against your patches.
 
 Submitting Changes
 ------------------
@@ -82,7 +82,8 @@
 
 -  Ensure that each commit also has a unique ``Change-Id:`` line. If you have
    cloned the repository with the "`Clone with commit-msg hook`" clone method
-   (as advised on the :ref:`User Guide`), this should already be the case.
+   (following the :ref:`Prerequisites` document), this should already be the
+   case.
 
    More details may be found in the `Gerrit Change-Ids documentation`_.
 
diff --git a/docs/process/security-hardening.rst b/docs/process/security-hardening.rst
index 1a5524f..a18a792 100644
--- a/docs/process/security-hardening.rst
+++ b/docs/process/security-hardening.rst
@@ -9,7 +9,7 @@
 -------------
 
 Several build options can be used to check for security issues. Refer to the
-:ref:`User Guide` for detailed information on the specific build options.
+:ref:`Build Options` for detailed information on these.
 
 - The ``BRANCH_PROTECTION`` build flag can be used to enable Pointer
   Authentication and Branch Target Identification.
@@ -30,20 +30,18 @@
 
   - W=1
 
-    Adds ``Wextra``, ``Wmissing-declarations``, ``Wmissing-format-attribute``,
-    ``Wmissing-prototypes``, ``Wold-style-definition`` and
-    ``Wunused-const-variable``.
+    Adds ``Wextra``, ``Wmissing-format-attribute``, ``Wmissing-prototypes``,
+    ``Wold-style-definition`` and ``Wunused-const-variable``.
 
   - W=2
 
     Adds ``Waggregate-return``, ``Wcast-align``, ``Wnested-externs``,
-    ``Wshadow``, ``Wlogical-op``, ``Wmissing-field-initializers`` and
-    ``Wsign-compare``.
+    ``Wshadow``, ``Wlogical-op``.
 
   - W=3
 
     Adds ``Wbad-function-cast``, ``Wcast-qual``, ``Wconversion``, ``Wpacked``,
-    ``Wpadded``, ``Wpointer-arith``, ``Wredundant-decls`` and
+    ``Wpointer-arith``, ``Wredundant-decls`` and
     ``Wswitch-default``.
 
   Refer to the GCC or Clang documentation for more information on the individual
diff --git a/docs/security_advisories/security-advisory-tfv-5.rst b/docs/security_advisories/security-advisory-tfv-5.rst
index 2214f2d..97f7cd9 100644
--- a/docs/security_advisories/security-advisory-tfv-5.rst
+++ b/docs/security_advisories/security-advisory-tfv-5.rst
@@ -7,9 +7,9 @@
 +================+=============================================================+
 | CVE ID         | `CVE-2017-15031`_                                           |
 +----------------+-------------------------------------------------------------+
-| Date           | 02 Oct 2017                                                 |
+| Date           | 02 Oct 2017, updated on 04 Nov 2019                         |
 +----------------+-------------------------------------------------------------+
-| Versions       | All, up to and including v1.4                               |
+| Versions       | All, up to and including v2.1                               |
 | Affected       |                                                             |
 +----------------+-------------------------------------------------------------+
 | Configurations | All                                                         |
@@ -18,8 +18,12 @@
 | Impact         | Leakage of sensitive secure world timing information        |
 +----------------+-------------------------------------------------------------+
 | Fix Version    | `Pull Request #1127`_ (merged on 18 October 2017)           |
+|                |                                                             |
+|                | `Commit e290a8fcbc`_ (merged on 23 August 2019)             |
+|                |                                                             |
+|                | `Commit c3e8b0be9b`_ (merged on 27 September 2019)          |
 +----------------+-------------------------------------------------------------+
-| Credit         | Arm                                                         |
+| Credit         | Arm, Marek Bykowski                                         |
 +----------------+-------------------------------------------------------------+
 
 The ``PMCR_EL0`` (Performance Monitors Control Register) provides details of the
@@ -28,10 +32,11 @@
 bit is set to zero, the cycle counter (when enabled) counts during secure world
 execution, even when prohibited by the debug signals.
 
-Since Arm TF does not save and restore ``PMCR_EL0`` when switching between the
+Since TF-A does not save and restore ``PMCR_EL0`` when switching between the
 normal and secure worlds, normal world code can set ``PMCR_EL0.DP`` to zero to
 cause leakage of secure world timing information. This register should be added
-to the list of saved/restored registers.
+to the list of saved/restored registers both when entering EL3 and also
+transitioning to S-EL1.
 
 Furthermore, ``PMCR_EL0.DP`` has an architecturally ``UNKNOWN`` reset value.
 Since Arm TF does not initialize this register, it's possible that on at least
@@ -42,5 +47,11 @@
 The same issue exists for the equivalent AArch32 register, ``PMCR``, except that
 here ``PMCR_EL0.DP`` architecturally resets to zero.
 
+NOTE: The original pull request referenced above only fixed the issue for S-EL1
+whereas the EL3 was fixed in the later commits.
+
 .. _CVE-2017-15031: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-15031
 .. _Pull Request #1127: https://github.com/ARM-software/arm-trusted-firmware/pull/1127
+.. _Commit e290a8fcbc: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=e290a8fcbc
+.. _Commit c3e8b0be9b: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=c3e8b0be9b
+
diff --git a/drivers/allwinner/axp/axp803.c b/drivers/allwinner/axp/axp803.c
new file mode 100644
index 0000000..53b11c1
--- /dev/null
+++ b/drivers/allwinner/axp/axp803.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/allwinner/axp.h>
+
+const uint8_t axp_chip_id = AXP803_CHIP_ID;
+const char *const axp_compatible = "x-powers,axp803";
+
+const struct axp_regulator axp_regulators[] = {
+	{"dcdc1", 1600, 3400, 100, NA, 0x20, 0x10, 0},
+	{"dcdc5",  800, 1840,  10, 32, 0x24, 0x10, 4},
+	{"dcdc6",  600, 1520,  10, 50, 0x25, 0x10, 5},
+	{"dldo1",  700, 3300, 100, NA, 0x15, 0x12, 3},
+	{"dldo2",  700, 4200, 100, 27, 0x16, 0x12, 4},
+	{"dldo3",  700, 3300, 100, NA, 0x17, 0x12, 5},
+	{"dldo4",  700, 3300, 100, NA, 0x18, 0x12, 6},
+	{"fldo1",  700, 1450,  50, NA, 0x1c, 0x13, 2},
+	{}
+};
diff --git a/drivers/allwinner/axp/axp805.c b/drivers/allwinner/axp/axp805.c
new file mode 100644
index 0000000..8d029c0
--- /dev/null
+++ b/drivers/allwinner/axp/axp805.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/allwinner/axp.h>
+
+const uint8_t axp_chip_id = AXP805_CHIP_ID;
+const char *const axp_compatible = "x-powers,axp805";
+
+/*
+ * The "dcdcd" split changes the step size by a factor of 5, not 2;
+ * disallow values above the split to maintain accuracy.
+ */
+const struct axp_regulator axp_regulators[] = {
+	{"dcdca",  600, 1520,  10, 50, 0x12, 0x10, 0},
+	{"dcdcb", 1000, 2550,  50, NA, 0x13, 0x10, 1},
+	{"dcdcc",  600, 1520,  10, 50, 0x14, 0x10, 2},
+	{"dcdcd",  600, 1500,  20, NA, 0x15, 0x10, 3},
+	{"dcdce", 1100, 3400, 100, NA, 0x16, 0x10, 4},
+	{"aldo1",  700, 3300, 100, NA, 0x17, 0x10, 5},
+	{"aldo2",  700, 3300, 100, NA, 0x18, 0x10, 6},
+	{"aldo3",  700, 3300, 100, NA, 0x19, 0x10, 7},
+	{"bldo1",  700, 1900, 100, NA, 0x20, 0x11, 0},
+	{"bldo2",  700, 1900, 100, NA, 0x21, 0x11, 1},
+	{"bldo3",  700, 1900, 100, NA, 0x22, 0x11, 2},
+	{"bldo4",  700, 1900, 100, NA, 0x23, 0x11, 3},
+	{"cldo1",  700, 3300, 100, NA, 0x24, 0x11, 4},
+	{"cldo2",  700, 4200, 100, 27, 0x25, 0x11, 5},
+	{"cldo3",  700, 3300, 100, NA, 0x26, 0x11, 6},
+	{}
+};
diff --git a/drivers/allwinner/axp/common.c b/drivers/allwinner/axp/common.c
new file mode 100644
index 0000000..13437fe
--- /dev/null
+++ b/drivers/allwinner/axp/common.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <libfdt.h>
+
+#include <common/debug.h>
+#include <drivers/allwinner/axp.h>
+
+int axp_check_id(void)
+{
+	int ret;
+
+	ret = axp_read(0x03);
+	if (ret < 0)
+		return ret;
+
+	ret &= 0xcf;
+	if (ret != axp_chip_id) {
+		ERROR("PMIC: Found unknown PMIC %02x\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+int axp_clrsetbits(uint8_t reg, uint8_t clr_mask, uint8_t set_mask)
+{
+	uint8_t val;
+	int ret;
+
+	ret = axp_read(reg);
+	if (ret < 0)
+		return ret;
+
+	val = (ret & ~clr_mask) | set_mask;
+
+	return axp_write(reg, val);
+}
+
+void axp_power_off(void)
+{
+	/* Set "power disable control" bit */
+	axp_setbits(0x32, BIT(7));
+}
+
+/*
+ * Retrieve the voltage from a given regulator DTB node.
+ * Both the regulator-{min,max}-microvolt properties must be present and
+ * have the same value. Return that value in millivolts.
+ */
+static int fdt_get_regulator_millivolt(const void *fdt, int node)
+{
+	const fdt32_t *prop;
+	uint32_t min_volt;
+
+	prop = fdt_getprop(fdt, node, "regulator-min-microvolt", NULL);
+	if (prop == NULL)
+		return -EINVAL;
+	min_volt = fdt32_to_cpu(*prop);
+
+	prop = fdt_getprop(fdt, node, "regulator-max-microvolt", NULL);
+	if (prop == NULL)
+		return -EINVAL;
+
+	if (fdt32_to_cpu(*prop) != min_volt)
+		return -EINVAL;
+
+	return min_volt / 1000;
+}
+
+static int setup_regulator(const void *fdt, int node,
+			   const struct axp_regulator *reg)
+{
+	uint8_t val;
+	int mvolt;
+
+	mvolt = fdt_get_regulator_millivolt(fdt, node);
+	if (mvolt < reg->min_volt || mvolt > reg->max_volt)
+		return -EINVAL;
+
+	val = (mvolt / reg->step) - (reg->min_volt / reg->step);
+	if (val > reg->split)
+		val = ((val - reg->split) / 2) + reg->split;
+
+	axp_write(reg->volt_reg, val);
+	axp_setbits(reg->switch_reg, BIT(reg->switch_bit));
+
+	INFO("PMIC: %s voltage: %d.%03dV\n", reg->dt_name,
+	     mvolt / 1000, mvolt % 1000);
+
+	return 0;
+}
+
+static bool should_enable_regulator(const void *fdt, int node)
+{
+	if (fdt_getprop(fdt, node, "phandle", NULL) != NULL)
+		return true;
+	if (fdt_getprop(fdt, node, "regulator-always-on", NULL) != NULL)
+		return true;
+	return false;
+}
+
+void axp_setup_regulators(const void *fdt)
+{
+	int node;
+	bool sw = false;
+
+	if (fdt == NULL)
+		return;
+
+	/* locate the PMIC DT node, bail out if not found */
+	node = fdt_node_offset_by_compatible(fdt, -1, axp_compatible);
+	if (node < 0) {
+		WARN("PMIC: No PMIC DT node, skipping setup\n");
+		return;
+	}
+
+	/* This applies to AXP803 only. */
+	if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL)) {
+		axp_clrbits(0x8f, BIT(4));
+		axp_setbits(0x30, BIT(2));
+		INFO("PMIC: Enabling DRIVEVBUS\n");
+	}
+
+	/* descend into the "regulators" subnode */
+	node = fdt_subnode_offset(fdt, node, "regulators");
+	if (node < 0) {
+		WARN("PMIC: No regulators DT node, skipping setup\n");
+		return;
+	}
+
+	/* iterate over all regulators to find used ones */
+	fdt_for_each_subnode(node, fdt, node) {
+		const struct axp_regulator *reg;
+		const char *name;
+		int length;
+
+		/* We only care if it's always on or referenced. */
+		if (!should_enable_regulator(fdt, node))
+			continue;
+
+		name = fdt_get_name(fdt, node, &length);
+
+		/* Enable the switch last to avoid overheating. */
+		if (!strncmp(name, "dc1sw", length) ||
+		    !strncmp(name, "sw", length)) {
+			sw = true;
+			continue;
+		}
+
+		for (reg = axp_regulators; reg->dt_name; reg++) {
+			if (!strncmp(name, reg->dt_name, length)) {
+				setup_regulator(fdt, node, reg);
+				break;
+			}
+		}
+	}
+
+	/*
+	 * On the AXP803, if DLDO2 is enabled after DC1SW, the PMIC overheats
+	 * and shuts down. So always enable DC1SW as the very last regulator.
+	 */
+	if (sw) {
+		INFO("PMIC: Enabling DC SW\n");
+		if (axp_chip_id == AXP803_CHIP_ID)
+			axp_setbits(0x12, BIT(7));
+		if (axp_chip_id == AXP805_CHIP_ID)
+			axp_setbits(0x11, BIT(7));
+	}
+}
diff --git a/drivers/arm/css/scp/css_pm_scmi.c b/drivers/arm/css/scp/css_pm_scmi.c
index 8dbefa1..b945cda 100644
--- a/drivers/arm/css/scp/css_pm_scmi.c
+++ b/drivers/arm/css/scp/css_pm_scmi.c
@@ -186,7 +186,7 @@
 void css_scp_on(u_register_t mpidr)
 {
 	unsigned int lvl = 0;
-	int ret, core_pos;
+	int core_pos, ret;
 	uint32_t scmi_pwr_state = 0;
 
 	for (; lvl <= PLAT_MAX_PWR_LVL; lvl++)
@@ -196,7 +196,8 @@
 	SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1);
 
 	core_pos = plat_core_pos_by_mpidr(mpidr);
-	assert(core_pos >= 0 && core_pos < PLATFORM_CORE_COUNT);
+	assert((core_pos >= 0) &&
+		(((unsigned int)core_pos) < PLATFORM_CORE_COUNT));
 
 	ret = scmi_pwr_state_set(scmi_handle,
 		plat_css_core_pos_to_scmi_dmn_id_map[core_pos],
diff --git a/drivers/arm/gic/v3/gic600.c b/drivers/arm/gic/v3/gic600.c
index 9cb2ab2..59652da 100644
--- a/drivers/arm/gic/v3/gic600.c
+++ b/drivers/arm/gic/v3/gic600.c
@@ -1,14 +1,14 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 /*
- * Driver for GIC600-specific features. This driver only overrides APIs that are
- * different to those generic ones in GICv3 driver.
+ * Driver for GIC-600 specific features. This driver only overrides
+ * APIs that are different to those generic ones in GICv3 driver.
  *
- * GIC600 supports independently power-gating redistributor interface.
+ * GIC-600 supports independently power-gating redistributor interface.
  */
 
 #include <assert.h>
@@ -18,22 +18,28 @@
 
 #include "gicv3_private.h"
 
-/* GIC600-specific register offsets */
+/* GIC-600 specific register offsets */
 #define GICR_PWRR	0x24
 
 /* GICR_PWRR fields */
 #define PWRR_RDPD_SHIFT		0
+#define PWRR_RDAG_SHIFT		1
 #define PWRR_RDGPD_SHIFT	2
 #define PWRR_RDGPO_SHIFT	3
 
+#define PWRR_RDPD	(1 << PWRR_RDPD_SHIFT)
+#define PWRR_RDAG	(1 << PWRR_RDAG_SHIFT)
 #define PWRR_RDGPD	(1 << PWRR_RDGPD_SHIFT)
 #define PWRR_RDGPO	(1 << PWRR_RDGPO_SHIFT)
 
-/* Values to write to GICR_PWRR register to power redistributor */
+/*
+ * Values to write to GICR_PWRR register to power redistributor
+ * for operating through the core (GICR_PWRR.RDAG = 0)
+ */
 #define PWRR_ON		(0 << PWRR_RDPD_SHIFT)
 #define PWRR_OFF	(1 << PWRR_RDPD_SHIFT)
 
-/* GIC600-specific accessor functions */
+/* GIC-600 specific accessor functions */
 static void gicr_write_pwrr(uintptr_t base, unsigned int val)
 {
 	mmio_write_32(base + GICR_PWRR, val);
@@ -44,39 +50,46 @@
 	return mmio_read_32(base + GICR_PWRR);
 }
 
-static int gicr_group_powering_down(uint32_t pwrr)
+static void gicr_wait_group_not_in_transit(uintptr_t base)
 {
-	/*
-	 * Whether the redistributor group power down operation is in transit:
-	 * i.e. it's intending to, but not finished yet.
-	 */
-	return ((pwrr & PWRR_RDGPD) && !(pwrr & PWRR_RDGPO));
+	/* Check group not transitioning: RDGPD == RDGPO */
+	while (((gicr_read_pwrr(base) & PWRR_RDGPD) >> PWRR_RDGPD_SHIFT) !=
+		((gicr_read_pwrr(base) & PWRR_RDGPO) >> PWRR_RDGPO_SHIFT))
+		;
 }
 
 static void gic600_pwr_on(uintptr_t base)
 {
-	/* Power on redistributor */
-	gicr_write_pwrr(base, PWRR_ON);
+	do {	/* Wait until group not transitioning */
+		gicr_wait_group_not_in_transit(base);
 
-	/* Wait until the power on state is reflected */
-	while (gicr_read_pwrr(base) & PWRR_RDGPO)
-		;
+		/* Power on redistributor */
+		gicr_write_pwrr(base, PWRR_ON);
+
+		/*
+		 * Wait until the power on state is reflected.
+		 * If RDPD == 0 then powered on.
+		 */
+	} while ((gicr_read_pwrr(base) & PWRR_RDPD) != PWRR_ON);
 }
 
 static void gic600_pwr_off(uintptr_t base)
 {
+	/* Wait until group not transitioning */
+	gicr_wait_group_not_in_transit(base);
+
 	/* Power off redistributor */
 	gicr_write_pwrr(base, PWRR_OFF);
 
 	/*
 	 * If this is the last man, turning this redistributor frame off will
-	 * result in the group itself being powered off. In that case, wait as
-	 * long as it's in transition, or has aborted the transition altogether
-	 * for any reason.
+	 * result in the group itself being powered off and RDGPD = 1.
+	 * In that case, wait as long as it's in transition, or has aborted
+	 * the transition altogether for any reason.
 	 */
-	if (gicr_read_pwrr(base) & PWRR_RDGPD) {
-		while (gicr_group_powering_down(gicr_read_pwrr(base)))
-			;
+	if ((gicr_read_pwrr(base) & PWRR_RDGPD) != 0) {
+		/* Wait until group not transitioning */
+		gicr_wait_group_not_in_transit(base);
 	}
 }
 
@@ -91,7 +104,7 @@
 }
 
 /*
- * Power off GIC600 redistributor
+ * Power off GIC-600 redistributor
  */
 void gicv3_rdistif_off(unsigned int proc_num)
 {
@@ -109,7 +122,7 @@
 }
 
 /*
- * Power on GIC600 redistributor
+ * Power on GIC-600 redistributor
  */
 void gicv3_rdistif_on(unsigned int proc_num)
 {
diff --git a/drivers/arm/gic/v3/gic600_multichip.c b/drivers/arm/gic/v3/gic600_multichip.c
new file mode 100644
index 0000000..ca7c43b
--- /dev/null
+++ b/drivers/arm/gic/v3/gic600_multichip.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * GIC-600 driver extension for multichip setup
+ */
+
+#include <assert.h>
+
+#include <common/debug.h>
+#include <drivers/arm/gic600_multichip.h>
+#include <drivers/arm/gicv3.h>
+
+#include "../common/gic_common_private.h"
+#include "gic600_multichip_private.h"
+
+#warning "GIC-600 Multichip driver is currently experimental and the API may change in future."
+
+/*******************************************************************************
+ * GIC-600 multichip operation related helper functions
+ ******************************************************************************/
+static void gicd_dchipr_wait_for_power_update_progress(uintptr_t base)
+{
+	unsigned int retry = GICD_PUP_UPDATE_RETRIES;
+
+	while ((read_gicd_dchipr(base) & GICD_DCHIPR_PUP_BIT) != 0U) {
+		if (retry-- == 0) {
+			ERROR("GIC-600 connection to Routing Table Owner timed "
+					 "out\n");
+			panic();
+		}
+	}
+}
+
+/*******************************************************************************
+ * Sets up the routing table owner.
+ ******************************************************************************/
+static void set_gicd_dchipr_rt_owner(uintptr_t base, unsigned int rt_owner)
+{
+	/*
+	 * Ensure that Group enables in GICD_CTLR are disabled and no pending
+	 * register writes to GICD_CTLR.
+	 */
+	if ((gicd_read_ctlr(base) &
+			(CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1S_BIT |
+			 CTLR_ENABLE_G1NS_BIT | GICD_CTLR_RWP_BIT)) != 0) {
+		ERROR("GICD_CTLR group interrupts are either enabled or have "
+				"pending writes. Cannot set RT owner.\n");
+		panic();
+	}
+
+	/* Poll till PUP is zero before intiating write */
+	gicd_dchipr_wait_for_power_update_progress(base);
+
+	write_gicd_dchipr(base, read_gicd_dchipr(base) |
+			(rt_owner << GICD_DCHIPR_RT_OWNER_SHIFT));
+
+	/* Poll till PUP is zero to ensure write is complete */
+	gicd_dchipr_wait_for_power_update_progress(base);
+}
+
+/*******************************************************************************
+ * Configures the Chip Register to make connections to GICDs on
+ * a multichip platform.
+ ******************************************************************************/
+static void set_gicd_chipr_n(uintptr_t base,
+				unsigned int chip_id,
+				uint64_t chip_addr,
+				unsigned int spi_id_min,
+				unsigned int spi_id_max)
+{
+	unsigned int spi_block_min, spi_blocks;
+	uint64_t chipr_n_val;
+
+	/*
+	 * Ensure that group enables in GICD_CTLR are disabled and no pending
+	 * register writes to GICD_CTLR.
+	 */
+	if ((gicd_read_ctlr(base) &
+			(CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1S_BIT |
+			 CTLR_ENABLE_G1NS_BIT | GICD_CTLR_RWP_BIT)) != 0) {
+		ERROR("GICD_CTLR group interrupts are either enabled or have "
+				"pending writes. Cannot set CHIPR register.\n");
+		panic();
+	}
+
+	/*
+	 * spi_id_min and spi_id_max of value 0 is used to intidicate that the
+	 * chip doesn't own any SPI block. Re-assign min and max values as SPI
+	 * id starts from 32.
+	 */
+	if (spi_id_min == 0 && spi_id_max == 0) {
+		spi_id_min = GIC600_SPI_ID_MIN;
+		spi_id_max = GIC600_SPI_ID_MIN;
+	}
+
+	spi_block_min = SPI_BLOCK_MIN_VALUE(spi_id_min);
+	spi_blocks    = SPI_BLOCKS_VALUE(spi_id_min, spi_id_max);
+
+	chipr_n_val = (GICD_CHIPR_VALUE(chip_addr, spi_block_min, spi_blocks)) |
+		GICD_CHIPRx_SOCKET_STATE;
+
+	/*
+	 * Wait for DCHIPR.PUP to be zero before commencing writes to
+	 * GICD_CHIPRx.
+	 */
+	gicd_dchipr_wait_for_power_update_progress(base);
+
+	/*
+	 * Assign chip addr, spi min block, number of spi blocks and bring chip
+	 * online by setting SocketState.
+	 */
+	write_gicd_chipr_n(base, chip_id, chipr_n_val);
+
+	/*
+	 * Poll until DCHIP.PUP is zero to verify connection to rt_owner chip
+	 * is complete.
+	 */
+	gicd_dchipr_wait_for_power_update_progress(base);
+
+	/*
+	 * Ensure that write to GICD_CHIPRx is successful and the chip_n came
+	 * online.
+	 */
+	if (read_gicd_chipr_n(base, chip_id) != chipr_n_val) {
+		ERROR("GICD_CHIPR%u write failed\n", chip_id);
+		panic();
+	}
+
+	/* Ensure that chip is in consistent state */
+	if (((read_gicd_chipsr(base) & GICD_CHIPSR_RTS_MASK) >>
+				GICD_CHIPSR_RTS_SHIFT) !=
+			GICD_CHIPSR_RTS_STATE_CONSISTENT) {
+		ERROR("Chip %u routing table is not in consistent state\n",
+				chip_id);
+		panic();
+	}
+}
+
+/*******************************************************************************
+ * Validates the GIC-600 Multichip data structure passed by the platform.
+ ******************************************************************************/
+static void gic600_multichip_validate_data(
+		struct gic600_multichip_data *multichip_data)
+{
+	unsigned int i, spi_id_min, spi_id_max, blocks_of_32;
+	unsigned int multichip_spi_blocks = 0;
+
+	assert(multichip_data != NULL);
+
+	if (multichip_data->chip_count > GIC600_MAX_MULTICHIP) {
+		ERROR("GIC-600 Multichip count should not exceed %d\n",
+				GIC600_MAX_MULTICHIP);
+		panic();
+	}
+
+	for (i = 0; i < multichip_data->chip_count; i++) {
+		spi_id_min = multichip_data->spi_ids[i][SPI_MIN_INDEX];
+		spi_id_max = multichip_data->spi_ids[i][SPI_MAX_INDEX];
+
+		if ((spi_id_min != 0) || (spi_id_max != 0)) {
+
+			/* SPI IDs range check */
+			if (!(spi_id_min >= GIC600_SPI_ID_MIN) ||
+			    !(spi_id_max < GIC600_SPI_ID_MAX) ||
+			    !(spi_id_min <= spi_id_max) ||
+			    !((spi_id_max - spi_id_min + 1) % 32 == 0)) {
+				ERROR("Invalid SPI IDs {%u, %u} passed for "
+						"Chip %u\n", spi_id_min,
+						spi_id_max, i);
+				panic();
+			}
+
+			/* SPI IDs overlap check */
+			blocks_of_32 = BLOCKS_OF_32(spi_id_min, spi_id_max);
+			if ((multichip_spi_blocks & blocks_of_32) != 0) {
+				ERROR("SPI IDs of Chip %u overlapping\n", i);
+				panic();
+			}
+			multichip_spi_blocks |= blocks_of_32;
+		}
+	}
+}
+
+/*******************************************************************************
+ * Intialize GIC-600 Multichip operation.
+ ******************************************************************************/
+void gic600_multichip_init(struct gic600_multichip_data *multichip_data)
+{
+	unsigned int i;
+
+	gic600_multichip_validate_data(multichip_data);
+
+	INFO("GIC-600 Multichip driver is experimental\n");
+
+	/*
+	 * Ensure that G0/G1S/G1NS interrupts are disabled. This also ensures
+	 * that GIC-600 Multichip configuration is done first.
+	 */
+	if ((gicd_read_ctlr(multichip_data->rt_owner_base) &
+			(CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1S_BIT |
+			 CTLR_ENABLE_G1NS_BIT | GICD_CTLR_RWP_BIT)) != 0) {
+		ERROR("GICD_CTLR group interrupts are either enabled or have "
+				"pending writes.\n");
+		panic();
+	}
+
+	/* Ensure that the routing table owner is in disconnected state */
+	if (((read_gicd_chipsr(multichip_data->rt_owner_base) &
+		GICD_CHIPSR_RTS_MASK) >> GICD_CHIPSR_RTS_SHIFT) !=
+			GICD_CHIPSR_RTS_STATE_DISCONNECTED) {
+		ERROR("GIC-600 routing table owner is not in disconnected "
+				"state to begin multichip configuration\n");
+		panic();
+	}
+
+	/* Initialize the GICD which is marked as routing table owner first */
+	set_gicd_dchipr_rt_owner(multichip_data->rt_owner_base,
+			multichip_data->rt_owner);
+
+	set_gicd_chipr_n(multichip_data->rt_owner_base, multichip_data->rt_owner,
+			multichip_data->chip_addrs[multichip_data->rt_owner],
+			multichip_data->
+			spi_ids[multichip_data->rt_owner][SPI_MIN_INDEX],
+			multichip_data->
+			spi_ids[multichip_data->rt_owner][SPI_MAX_INDEX]);
+
+	for (i = 0; i < multichip_data->chip_count; i++) {
+		if (i == multichip_data->rt_owner)
+			continue;
+
+		set_gicd_chipr_n(multichip_data->rt_owner_base, i,
+				multichip_data->chip_addrs[i],
+				multichip_data->spi_ids[i][SPI_MIN_INDEX],
+				multichip_data->spi_ids[i][SPI_MAX_INDEX]);
+	}
+}
diff --git a/drivers/arm/gic/v3/gic600_multichip_private.h b/drivers/arm/gic/v3/gic600_multichip_private.h
new file mode 100644
index 0000000..b0217b6
--- /dev/null
+++ b/drivers/arm/gic/v3/gic600_multichip_private.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2019, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef GIC600_MULTICHIP_PRIVATE_H
+#define GIC600_MULTICHIP_PRIVATE_H
+
+#include <drivers/arm/gic600_multichip.h>
+
+#include "gicv3_private.h"
+
+/* GIC600 GICD multichip related offsets */
+#define GICD_CHIPSR			U(0xC000)
+#define GICD_DCHIPR			U(0xC004)
+#define GICD_CHIPR			U(0xC008)
+
+/* GIC600 GICD multichip related masks */
+#define GICD_CHIPRx_PUP_BIT		BIT_64(1)
+#define GICD_CHIPRx_SOCKET_STATE	BIT_64(0)
+#define GICD_DCHIPR_PUP_BIT		BIT_32(0)
+#define GICD_CHIPSR_RTS_MASK		(BIT_32(4) | BIT_32(5))
+
+/* GIC600 GICD multichip related shifts */
+#define GICD_CHIPRx_ADDR_SHIFT		16
+#define GICD_CHIPRx_SPI_BLOCK_MIN_SHIFT	10
+#define GICD_CHIPRx_SPI_BLOCKS_SHIFT	5
+#define GICD_CHIPSR_RTS_SHIFT		4
+#define GICD_DCHIPR_RT_OWNER_SHIFT	4
+
+#define GICD_CHIPSR_RTS_STATE_DISCONNECTED	U(0)
+#define GICD_CHIPSR_RTS_STATE_UPDATING		U(1)
+#define GICD_CHIPSR_RTS_STATE_CONSISTENT	U(2)
+
+/* SPI interrupt id minimum and maximum range */
+#define GIC600_SPI_ID_MIN		32
+#define GIC600_SPI_ID_MAX		960
+
+/* Number of retries for PUP update */
+#define GICD_PUP_UPDATE_RETRIES		10000
+
+#define SPI_MIN_INDEX			0
+#define SPI_MAX_INDEX			1
+
+#define SPI_BLOCK_MIN_VALUE(spi_id_min) \
+			(((spi_id_min) - GIC600_SPI_ID_MIN) / \
+			GIC600_SPI_ID_MIN)
+#define SPI_BLOCKS_VALUE(spi_id_min, spi_id_max) \
+			(((spi_id_max) - (spi_id_min) + 1) / \
+			GIC600_SPI_ID_MIN)
+#define GICD_CHIPR_VALUE(chip_addr, spi_block_min, spi_blocks) \
+			(((chip_addr) << GICD_CHIPRx_ADDR_SHIFT) | \
+			((spi_block_min) << GICD_CHIPRx_SPI_BLOCK_MIN_SHIFT) | \
+			((spi_blocks) << GICD_CHIPRx_SPI_BLOCKS_SHIFT))
+
+/*
+ * Multichip data assertion macros
+ */
+/* Set bits from 0 to ((spi_id_max + 1) / 32) */
+#define SPI_BLOCKS_TILL_MAX(spi_id_max)	((1 << (((spi_id_max) + 1) >> 5)) - 1)
+/* Set bits from 0 to (spi_id_min / 32) */
+#define SPI_BLOCKS_TILL_MIN(spi_id_min)	((1 << ((spi_id_min) >> 5)) - 1)
+/* Set bits from (spi_id_min / 32) to ((spi_id_max + 1) / 32) */
+#define BLOCKS_OF_32(spi_id_min, spi_id_max) \
+					SPI_BLOCKS_TILL_MAX(spi_id_max) ^ \
+					SPI_BLOCKS_TILL_MIN(spi_id_min)
+
+/*******************************************************************************
+ * GIC-600 multichip operation related helper functions
+ ******************************************************************************/
+static inline uint32_t read_gicd_dchipr(uintptr_t base)
+{
+	return mmio_read_32(base + GICD_DCHIPR);
+}
+
+static inline uint64_t read_gicd_chipr_n(uintptr_t base, uint8_t n)
+{
+	return mmio_read_64(base + (GICD_CHIPR + (8U * n)));
+}
+
+static inline uint32_t read_gicd_chipsr(uintptr_t base)
+{
+	return mmio_read_32(base + GICD_CHIPSR);
+}
+
+static inline void write_gicd_dchipr(uintptr_t base, uint32_t val)
+{
+	mmio_write_32(base + GICD_DCHIPR, val);
+}
+
+static inline void write_gicd_chipr_n(uintptr_t base, uint8_t n, uint64_t val)
+{
+	mmio_write_64(base + (GICD_CHIPR + (8U * n)), val);
+}
+
+#endif /* GIC600_MULTICHIP_PRIVATE_H */
diff --git a/drivers/arm/sbsa/sbsa.c b/drivers/arm/sbsa/sbsa.c
index 6f00a60..79c6f26 100644
--- a/drivers/arm/sbsa/sbsa.c
+++ b/drivers/arm/sbsa/sbsa.c
@@ -4,11 +4,11 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <plat/common/platform.h>
+#include <assert.h>
+#include <stdint.h>
 #include <drivers/arm/sbsa.h>
 #include <lib/mmio.h>
-#include <stdint_.h>
-#include <assert.h>
+#include <plat/common/platform.h>
 
 void sbsa_watchdog_offset_reg_write(uintptr_t base, uint64_t value)
 {
diff --git a/drivers/arm/scu/scu.c b/drivers/arm/scu/scu.c
new file mode 100644
index 0000000..aceac92
--- /dev/null
+++ b/drivers/arm/scu/scu.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <drivers/arm/scu.h>
+#include <lib/mmio.h>
+#include <plat/common/platform.h>
+#include <stdint.h>
+
+/*******************************************************************************
+ * Turn ON snoop control unit. This is needed to synchronize the data between
+ * CPU's.
+ ******************************************************************************/
+void enable_snoop_ctrl_unit(uintptr_t base)
+{
+	uint32_t scu_ctrl;
+
+	INFO("[SCU]: enabling snoop control unit ... \n");
+
+	assert(base != 0U);
+	scu_ctrl = mmio_read_32(base + SCU_CTRL_REG);
+
+	/* already enabled? */
+	if ((scu_ctrl & SCU_ENABLE_BIT) != 0) {
+		return;
+	}
+
+	scu_ctrl |= SCU_ENABLE_BIT;
+	mmio_write_32(base + SCU_CTRL_REG, scu_ctrl);
+}
+
+/*******************************************************************************
+ * Snoop Control Unit configuration register. This is read-only register and
+ * contains information such as
+ * - number of CPUs present
+ * - is a particular CPU operating in SMP mode or AMP mode
+ * - data cache size of a particular CPU
+ * - does SCU has ACP port
+ * - is L2CPRESENT
+ * NOTE: user of this API should interpert the bits in this register according
+ * to the TRM
+ ******************************************************************************/
+uint32_t read_snoop_ctrl_unit_cfg(uintptr_t base)
+{
+	assert(base != 0U);
+
+	return mmio_read_32(base + SCU_CFG_REG);
+}
diff --git a/drivers/arm/smmu/smmu_v3.c b/drivers/arm/smmu/smmu_v3.c
index 5493b85..a082a81 100644
--- a/drivers/arm/smmu/smmu_v3.c
+++ b/drivers/arm/smmu/smmu_v3.c
@@ -7,23 +7,27 @@
 #include <common/debug.h>
 #include <cdefs.h>
 #include <drivers/arm/smmu_v3.h>
+#include <drivers/delay_timer.h>
 #include <lib/mmio.h>
 
 /* SMMU poll number of retries */
-#define SMMU_POLL_RETRY		1000000
+#define SMMU_POLL_TIMEOUT_US	U(1000)
 
 static int __init smmuv3_poll(uintptr_t smmu_reg, uint32_t mask,
 				uint32_t value)
 {
-	uint32_t reg_val, retries = SMMU_POLL_RETRY;
+	uint32_t reg_val;
+	uint64_t timeout;
 
+	/* Set 1ms timeout value */
+	timeout = timeout_init_us(SMMU_POLL_TIMEOUT_US);
 	do {
 		reg_val = mmio_read_32(smmu_reg);
 		if ((reg_val & mask) == value)
 			return 0;
-	} while (--retries != 0U);
+	} while (!timeout_elapsed(timeout));
 
-	ERROR("Failed to poll SMMUv3 register @%p\n", (void *)smmu_reg);
+	ERROR("Timeout polling 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;
diff --git a/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c
index a6538c4..3fb2d1a 100644
--- a/drivers/auth/auth_mod.c
+++ b/drivers/auth/auth_mod.c
@@ -30,9 +30,6 @@
 
 #pragma weak plat_set_nv_ctr2
 
-/* Pointer to CoT */
-extern const auth_img_desc_t *const *const cot_desc_ptr;
-extern unsigned int auth_img_flags[MAX_NUMBER_IDS];
 
 static int cmp_auth_param_type_desc(const auth_param_type_desc_t *a,
 		const auth_param_type_desc_t *b)
diff --git a/drivers/auth/cryptocell/712/cryptocell_crypto.c b/drivers/auth/cryptocell/712/cryptocell_crypto.c
index 395c550..25eb6bc 100644
--- a/drivers/auth/cryptocell/712/cryptocell_crypto.c
+++ b/drivers/auth/cryptocell/712/cryptocell_crypto.c
@@ -225,7 +225,7 @@
 	/* Verify the signature */
 	error = CCSbVerifySignature((uintptr_t)PLAT_CRYPTOCELL_BASE,
 			(uint32_t *)data_ptr, &pk, &signature,
-			data_len, RSA_PSS_2048);
+			data_len, RSA_PSS);
 	if (error != CC_OK)
 		return CRYPTO_ERR_SIGNATURE;
 
diff --git a/drivers/auth/cryptocell/cryptocell_crypto.mk b/drivers/auth/cryptocell/cryptocell_crypto.mk
index d42a2e7..2fc4ddb 100644
--- a/drivers/auth/cryptocell/cryptocell_crypto.mk
+++ b/drivers/auth/cryptocell/cryptocell_crypto.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -12,6 +12,8 @@
 # Needs to be set to drive mbed TLS configuration correctly
 $(eval $(call add_define,TF_MBEDTLS_KEY_ALG_ID))
 
+$(eval $(call add_define,KEY_SIZE))
+
 # CCSBROM_LIB_PATH must be set to the Cryptocell SBROM library path
 ifeq (${CCSBROM_LIB_PATH},)
   $(error Error: CCSBROM_LIB_PATH not set)
diff --git a/drivers/delay_timer/delay_timer.c b/drivers/delay_timer/delay_timer.c
index 8c2996e..a3fd7bf 100644
--- a/drivers/delay_timer/delay_timer.c
+++ b/drivers/delay_timer/delay_timer.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,23 +27,32 @@
 		(timer_ops->clk_div != 0U) &&
 		(timer_ops->get_timer_value != NULL));
 
-	uint32_t start, delta, total_delta;
+	uint32_t start, delta;
+	uint64_t total_delta;
 
-	assert(usec < (UINT32_MAX / timer_ops->clk_div));
+	assert(usec < (UINT64_MAX / timer_ops->clk_div));
 
 	start = timer_ops->get_timer_value();
 
 	/* Add an extra tick to avoid delaying less than requested. */
 	total_delta =
-		div_round_up(usec * timer_ops->clk_div,
+		div_round_up((uint64_t)usec * timer_ops->clk_div,
 						timer_ops->clk_mult) + 1U;
+	/*
+	 * Precaution for the total_delta ~ UINT32_MAX and the fact that we
+	 * cannot catch every tick of the timer.
+	 * For example 100MHz timer over 25MHz APB will miss at least 4 ticks.
+	 * 1000U is an arbitrary big number which is believed to be sufficient.
+	 */
+	assert(total_delta < (UINT32_MAX - 1000U));
 
 	do {
 		/*
 		 * If the timer value wraps around, the subtraction will
 		 * overflow and it will still give the correct result.
+		 * delta is decreasing counter
 		 */
-		delta = start - timer_ops->get_timer_value(); /* Decreasing counter */
+		delta = start - timer_ops->get_timer_value();
 
 	} while (delta < total_delta);
 }
@@ -54,6 +63,7 @@
  ***********************************************************/
 void mdelay(uint32_t msec)
 {
+	assert((msec * 1000UL) < UINT32_MAX);
 	udelay(msec * 1000U);
 }
 
diff --git a/drivers/intel/soc/stratix10/io/s10_memmap_qspi.c b/drivers/intel/soc/stratix10/io/s10_memmap_qspi.c
index a0fc034..dcd1991 100644
--- a/drivers/intel/soc/stratix10/io/s10_memmap_qspi.c
+++ b/drivers/intel/soc/stratix10/io/s10_memmap_qspi.c
@@ -26,9 +26,9 @@
 	 * valid.
 	 */
 	int		in_use;
-	uintptr_t	base;
-	size_t		file_pos;
-	size_t		size;
+	uintptr_t		base;
+	unsigned long long	file_pos;
+	unsigned long long	size;
 } file_state_t;
 
 static file_state_t current_file = {0};
@@ -44,7 +44,7 @@
 static int memmap_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
 			     io_entity_t *entity);
 static int memmap_block_seek(io_entity_t *entity, int mode,
-			     ssize_t offset);
+			     signed long long offset);
 static int memmap_block_len(io_entity_t *entity, size_t *length);
 static int memmap_block_read(io_entity_t *entity, uintptr_t buffer,
 			     size_t length, size_t *length_read);
@@ -131,7 +131,8 @@
 
 
 /* Seek to a particular file offset on the memmap device */
-static int memmap_block_seek(io_entity_t *entity, int mode, ssize_t offset)
+static int memmap_block_seek(io_entity_t *entity, int mode,
+			     signed long long offset)
 {
 	int result = -ENOENT;
 	file_state_t *fp;
@@ -143,7 +144,8 @@
 		fp = (file_state_t *) entity->info;
 
 		/* Assert that new file position is valid */
-		assert((offset >= 0) && (offset < fp->size));
+		assert((offset >= 0) &&
+		       ((unsigned long long)offset < fp->size));
 
 		/* Reset file position */
 		fp->file_pos = offset;
@@ -171,7 +173,7 @@
 			     size_t length, size_t *length_read)
 {
 	file_state_t *fp;
-	size_t pos_after;
+	unsigned long long pos_after;
 
 	assert(entity != NULL);
 	assert(length_read != NULL);
@@ -198,7 +200,7 @@
 			      size_t length, size_t *length_written)
 {
 	file_state_t *fp;
-	size_t pos_after;
+	unsigned long long pos_after;
 
 	assert(entity != NULL);
 	assert(length_written != NULL);
diff --git a/drivers/io/io_block.c b/drivers/io/io_block.c
index f190a43..5d45c2f 100644
--- a/drivers/io/io_block.c
+++ b/drivers/io/io_block.c
@@ -19,17 +19,17 @@
 typedef struct {
 	io_block_dev_spec_t	*dev_spec;
 	uintptr_t		base;
-	size_t			file_pos;
-	size_t			size;
+	unsigned long long	file_pos;
+	unsigned long long	size;
 } block_dev_state_t;
 
-#define is_power_of_2(x)	((x != 0) && ((x & (x - 1)) == 0))
+#define is_power_of_2(x)	(((x) != 0U) && (((x) & ((x) - 1U)) == 0U))
 
 io_type_t device_type_block(void);
 
 static int block_open(io_dev_info_t *dev_info, const uintptr_t spec,
 		      io_entity_t *entity);
-static int block_seek(io_entity_t *entity, int mode, ssize_t offset);
+static int block_seek(io_entity_t *entity, int mode, signed long long offset);
 static int block_read(io_entity_t *entity, uintptr_t buffer, size_t length,
 		      size_t *length_read);
 static int block_write(io_entity_t *entity, const uintptr_t buffer,
@@ -148,21 +148,21 @@
 }
 
 /* parameter offset is relative address at here */
-static int block_seek(io_entity_t *entity, int mode, ssize_t offset)
+static int block_seek(io_entity_t *entity, int mode, signed long long offset)
 {
 	block_dev_state_t *cur;
 
 	assert(entity->info != (uintptr_t)NULL);
 
 	cur = (block_dev_state_t *)entity->info;
-	assert((offset >= 0) && (offset < cur->size));
+	assert((offset >= 0) && ((unsigned long long)offset < cur->size));
 
 	switch (mode) {
 	case IO_SEEK_SET:
-		cur->file_pos = offset;
+		cur->file_pos = (unsigned long long)offset;
 		break;
 	case IO_SEEK_CUR:
-		cur->file_pos += offset;
+		cur->file_pos += (unsigned long long)offset;
 		break;
 	default:
 		return -EINVAL;
@@ -270,7 +270,7 @@
 	buf = &(cur->dev_spec->buffer);
 	block_size = cur->dev_spec->block_size;
 	assert((length <= cur->size) &&
-	       (length > 0) &&
+	       (length > 0U) &&
 	       (ops->read != 0));
 
 	/*
@@ -279,7 +279,7 @@
 	 * on the low level driver.
 	 */
 	count = 0;
-	for (left = length; left > 0; left -= nbytes) {
+	for (left = length; left > 0U; left -= nbytes) {
 		/*
 		 * We must only request operations aligned to the block
 		 * size. Therefore if file_pos is not block-aligned,
@@ -288,7 +288,7 @@
 		 * similarly, the number of bytes requested must be a
 		 * block size multiple
 		 */
-		skip = cur->file_pos & (block_size - 1);
+		skip = cur->file_pos & (block_size - 1U);
 
 		/*
 		 * Calculate the block number containing file_pos
@@ -296,7 +296,7 @@
 		 */
 		lba = (cur->file_pos + cur->base) / block_size;
 
-		if (skip + left > buf->length) {
+		if ((skip + left) > buf->length) {
 			/*
 			 * The underlying read buffer is too small to
 			 * read all the required data - limit to just
@@ -311,7 +311,8 @@
 			 * block size.
 			 */
 			request = skip + left;
-			request = (request + (block_size - 1)) & ~(block_size - 1);
+			request = (request + (block_size - 1U)) &
+				~(block_size - 1U);
 		}
 		request = ops->read(lba, buf->offset, request);
 
@@ -330,7 +331,7 @@
 		 * the read data when copying to the user buffer.
 		 */
 		nbytes = request - skip;
-		padding = (nbytes > left) ? nbytes - left : 0;
+		padding = (nbytes > left) ? nbytes - left : 0U;
 		nbytes -= padding;
 
 		memcpy((void *)(buffer + count),
@@ -381,7 +382,7 @@
 	buf = &(cur->dev_spec->buffer);
 	block_size = cur->dev_spec->block_size;
 	assert((length <= cur->size) &&
-	       (length > 0) &&
+	       (length > 0U) &&
 	       (ops->read != 0) &&
 	       (ops->write != 0));
 
@@ -391,7 +392,7 @@
 	 * on the low level driver.
 	 */
 	count = 0;
-	for (left = length; left > 0; left -= nbytes) {
+	for (left = length; left > 0U; left -= nbytes) {
 		/*
 		 * We must only request operations aligned to the block
 		 * size. Therefore if file_pos is not block-aligned,
@@ -400,7 +401,7 @@
 		 * similarly, the number of bytes requested must be a
 		 * block size multiple
 		 */
-		skip = cur->file_pos & (block_size - 1);
+		skip = cur->file_pos & (block_size - 1U);
 
 		/*
 		 * Calculate the block number containing file_pos
@@ -408,7 +409,7 @@
 		 */
 		lba = (cur->file_pos + cur->base) / block_size;
 
-		if (skip + left > buf->length) {
+		if ((skip + left) > buf->length) {
 			/*
 			 * The underlying read buffer is too small to
 			 * read all the required data - limit to just
@@ -423,7 +424,8 @@
 			 * block size.
 			 */
 			request = skip + left;
-			request = (request + (block_size - 1)) & ~(block_size - 1);
+			request = (request + (block_size - 1U)) &
+				~(block_size - 1U);
 		}
 
 		/*
@@ -432,7 +434,7 @@
 		 * of the current request.
 		 */
 		nbytes = request - skip;
-		padding = (nbytes > left) ? nbytes - left : 0;
+		padding = (nbytes > left) ? nbytes - left : 0U;
 		nbytes -= padding;
 
 		/*
@@ -440,14 +442,14 @@
 		 * some content and it means that we have to read before
 		 * writing
 		 */
-		if (skip > 0 || padding > 0) {
+		if ((skip > 0U) || (padding > 0U)) {
 			request = ops->read(lba, buf->offset, request);
 			/*
 			 * The read may return size less than
 			 * requested. Round down to the nearest block
 			 * boundary
 			 */
-			request &= ~(block_size-1);
+			request &= ~(block_size - 1U);
 			if (request <= skip) {
 				/*
 				 * We couldn't read enough bytes to jump over
@@ -458,7 +460,7 @@
 				return -EIO;
 			}
 			nbytes = request - skip;
-			padding = (nbytes > left) ? nbytes - left : 0;
+			padding = (nbytes > left) ? nbytes - left : 0U;
 			nbytes -= padding;
 		}
 
@@ -477,7 +479,7 @@
 		 * buffer
 		 */
 		nbytes = request - skip;
-		padding = (nbytes > left) ? nbytes - left : 0;
+		padding = (nbytes > left) ? nbytes - left : 0U;
 		nbytes -= padding;
 
 		cur->file_pos += nbytes;
@@ -505,7 +507,7 @@
 
 	assert(dev_info != NULL);
 	result = allocate_dev_info(&info);
-	if (result)
+	if (result != 0)
 		return -ENOENT;
 
 	cur = (block_dev_state_t *)info->info;
@@ -513,10 +515,10 @@
 	cur->dev_spec = (io_block_dev_spec_t *)dev_spec;
 	buffer = &(cur->dev_spec->buffer);
 	block_size = cur->dev_spec->block_size;
-	assert((block_size > 0) &&
-	       (is_power_of_2(block_size) != 0) &&
-	       ((buffer->offset % block_size) == 0) &&
-	       ((buffer->length % block_size) == 0));
+	assert((block_size > 0U) &&
+	       (is_power_of_2(block_size) != 0U) &&
+	       ((buffer->offset % block_size) == 0U) &&
+	       ((buffer->length % block_size) == 0U));
 
 	*dev_info = info;	/* cast away const */
 	(void)block_size;
diff --git a/drivers/io/io_fip.c b/drivers/io/io_fip.c
index 544b37d..5d49fff 100644
--- a/drivers/io/io_fip.c
+++ b/drivers/io/io_fip.c
@@ -304,7 +304,8 @@
 	}
 
 	/* Seek past the FIP header into the Table of Contents */
-	result = io_seek(backend_handle, IO_SEEK_SET, sizeof(fip_toc_header_t));
+	result = io_seek(backend_handle, IO_SEEK_SET,
+			 (signed long long)sizeof(fip_toc_header_t));
 	if (result != 0) {
 		WARN("fip_file_open: failed to seek\n");
 		result = -ENOENT;
@@ -389,7 +390,8 @@
 
 	/* Seek to the position in the FIP where the payload lives */
 	file_offset = fp->entry.offset_address + fp->file_pos;
-	result = io_seek(backend_handle, IO_SEEK_SET, file_offset);
+	result = io_seek(backend_handle, IO_SEEK_SET,
+			 (signed long long)file_offset);
 	if (result != 0) {
 		WARN("fip_file_read: failed to seek\n");
 		result = -ENOENT;
diff --git a/drivers/io/io_memmap.c b/drivers/io/io_memmap.c
index 96590b6..eed50cc 100644
--- a/drivers/io/io_memmap.c
+++ b/drivers/io/io_memmap.c
@@ -23,10 +23,10 @@
 	/* Use the 'in_use' flag as any value for base and file_pos could be
 	 * valid.
 	 */
-	int		in_use;
-	uintptr_t	base;
-	size_t		file_pos;
-	size_t		size;
+	int			in_use;
+	uintptr_t		base;
+	unsigned long long	file_pos;
+	unsigned long long	size;
 } file_state_t;
 
 static file_state_t current_file = {0};
@@ -42,7 +42,7 @@
 static int memmap_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
 			     io_entity_t *entity);
 static int memmap_block_seek(io_entity_t *entity, int mode,
-			     ssize_t offset);
+			     signed long long offset);
 static int memmap_block_len(io_entity_t *entity, size_t *length);
 static int memmap_block_read(io_entity_t *entity, uintptr_t buffer,
 			     size_t length, size_t *length_read);
@@ -129,7 +129,8 @@
 
 
 /* Seek to a particular file offset on the memmap device */
-static int memmap_block_seek(io_entity_t *entity, int mode, ssize_t offset)
+static int memmap_block_seek(io_entity_t *entity, int mode,
+			     signed long long offset)
 {
 	int result = -ENOENT;
 	file_state_t *fp;
@@ -141,10 +142,11 @@
 		fp = (file_state_t *) entity->info;
 
 		/* Assert that new file position is valid */
-		assert((offset >= 0) && (offset < fp->size));
+		assert((offset >= 0) &&
+		       ((unsigned long long)offset < fp->size));
 
 		/* Reset file position */
-		fp->file_pos = offset;
+		fp->file_pos = (unsigned long long)offset;
 		result = 0;
 	}
 
@@ -158,7 +160,7 @@
 	assert(entity != NULL);
 	assert(length != NULL);
 
-	*length = ((file_state_t *)entity->info)->size;
+	*length = (size_t)((file_state_t *)entity->info)->size;
 
 	return 0;
 }
@@ -169,7 +171,7 @@
 			     size_t length, size_t *length_read)
 {
 	file_state_t *fp;
-	size_t pos_after;
+	unsigned long long pos_after;
 
 	assert(entity != NULL);
 	assert(length_read != NULL);
@@ -180,7 +182,8 @@
 	pos_after = fp->file_pos + length;
 	assert((pos_after >= fp->file_pos) && (pos_after <= fp->size));
 
-	memcpy((void *)buffer, (void *)(fp->base + fp->file_pos), length);
+	memcpy((void *)buffer,
+	       (void *)((uintptr_t)(fp->base + fp->file_pos)), length);
 
 	*length_read = length;
 
@@ -196,7 +199,7 @@
 			      size_t length, size_t *length_written)
 {
 	file_state_t *fp;
-	size_t pos_after;
+	unsigned long long pos_after;
 
 	assert(entity != NULL);
 	assert(length_written != NULL);
@@ -207,7 +210,8 @@
 	pos_after = fp->file_pos + length;
 	assert((pos_after >= fp->file_pos) && (pos_after <= fp->size));
 
-	memcpy((void *)(fp->base + fp->file_pos), (void *)buffer, length);
+	memcpy((void *)((uintptr_t)(fp->base + fp->file_pos)),
+	       (void *)buffer, length);
 
 	*length_written = length;
 
diff --git a/drivers/io/io_mtd.c b/drivers/io/io_mtd.c
new file mode 100644
index 0000000..7575fa2
--- /dev/null
+++ b/drivers/io/io_mtd.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+
+#include <platform_def.h>
+
+#include <common/debug.h>
+#include <drivers/io/io_driver.h>
+#include <drivers/io/io_mtd.h>
+#include <lib/utils.h>
+
+typedef struct {
+	io_mtd_dev_spec_t	*dev_spec;
+	uintptr_t		base;
+	unsigned long long	offset;		/* Offset in bytes */
+	unsigned long long	size;	/* Size of device in bytes */
+} mtd_dev_state_t;
+
+io_type_t device_type_mtd(void);
+
+static int mtd_open(io_dev_info_t *dev_info, const uintptr_t spec,
+		    io_entity_t *entity);
+static int mtd_seek(io_entity_t *entity, int mode, signed long long offset);
+static int mtd_read(io_entity_t *entity, uintptr_t buffer, size_t length,
+		    size_t *length_read);
+static int mtd_close(io_entity_t *entity);
+static int mtd_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info);
+static int mtd_dev_close(io_dev_info_t *dev_info);
+
+static const io_dev_connector_t mtd_dev_connector = {
+	.dev_open	= mtd_dev_open
+};
+
+static const io_dev_funcs_t mtd_dev_funcs = {
+	.type		= device_type_mtd,
+	.open		= mtd_open,
+	.seek		= mtd_seek,
+	.read		= mtd_read,
+	.close		= mtd_close,
+	.dev_close	= mtd_dev_close,
+};
+
+static mtd_dev_state_t state_pool[MAX_IO_MTD_DEVICES];
+static io_dev_info_t dev_info_pool[MAX_IO_MTD_DEVICES];
+
+io_type_t device_type_mtd(void)
+{
+	return IO_TYPE_MTD;
+}
+
+/* Locate a MTD state in the pool, specified by address */
+static int find_first_mtd_state(const io_mtd_dev_spec_t *dev_spec,
+				unsigned int *index_out)
+{
+	unsigned int index;
+	int result = -ENOENT;
+
+	for (index = 0U; index < MAX_IO_MTD_DEVICES; index++) {
+		/* dev_spec is used as identifier since it's unique */
+		if (state_pool[index].dev_spec == dev_spec) {
+			result = 0;
+			*index_out = index;
+			break;
+		}
+	}
+
+	return result;
+}
+
+/* Allocate a device info from the pool */
+static int allocate_dev_info(io_dev_info_t **dev_info)
+{
+	unsigned int index = 0U;
+	int result;
+
+	result = find_first_mtd_state(NULL, &index);
+	if (result != 0) {
+		return -ENOMEM;
+	}
+
+	dev_info_pool[index].funcs = &mtd_dev_funcs;
+	dev_info_pool[index].info = (uintptr_t)&state_pool[index];
+	*dev_info = &dev_info_pool[index];
+
+	return 0;
+}
+
+/* Release a device info from the pool */
+static int free_dev_info(io_dev_info_t *dev_info)
+{
+	int result;
+	unsigned int index = 0U;
+	mtd_dev_state_t *state;
+
+	state = (mtd_dev_state_t *)dev_info->info;
+	result = find_first_mtd_state(state->dev_spec, &index);
+	if (result != 0) {
+		return result;
+	}
+
+	zeromem(state, sizeof(mtd_dev_state_t));
+	zeromem(dev_info, sizeof(io_dev_info_t));
+
+	return 0;
+}
+
+static int mtd_open(io_dev_info_t *dev_info, const uintptr_t spec,
+		    io_entity_t *entity)
+{
+	mtd_dev_state_t *cur;
+
+	assert((dev_info->info != 0UL) && (entity->info == 0UL));
+
+	cur = (mtd_dev_state_t *)dev_info->info;
+	entity->info = (uintptr_t)cur;
+	cur->offset = 0U;
+
+	return 0;
+}
+
+/* Seek to a specific position using offset */
+static int mtd_seek(io_entity_t *entity, int mode, signed long long offset)
+{
+	mtd_dev_state_t *cur;
+
+	assert((entity->info != (uintptr_t)NULL) && (offset >= 0));
+
+	cur = (mtd_dev_state_t *)entity->info;
+
+	switch (mode) {
+	case IO_SEEK_SET:
+		if ((offset >= 0) &&
+		    ((unsigned long long)offset >= cur->size)) {
+			return -EINVAL;
+		}
+
+		cur->offset = offset;
+		break;
+	case IO_SEEK_CUR:
+		if (((cur->offset + (unsigned long long)offset) >=
+		     cur->size) ||
+		    ((cur->offset + (unsigned long long)offset) <
+		     cur->offset)) {
+			return -EINVAL;
+		}
+
+		cur->offset += (unsigned long long)offset;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int mtd_read(io_entity_t *entity, uintptr_t buffer, size_t length,
+		    size_t *out_length)
+{
+	mtd_dev_state_t *cur;
+	io_mtd_ops_t *ops;
+	int ret;
+
+	assert(entity->info != (uintptr_t)NULL);
+	assert((length > 0U) && (buffer != (uintptr_t)NULL));
+
+	cur = (mtd_dev_state_t *)entity->info;
+	ops = &cur->dev_spec->ops;
+	assert(ops->read != NULL);
+
+	VERBOSE("Read at %llx into %lx, length %zi\n",
+		cur->offset, buffer, length);
+	if ((cur->offset + length) > cur->dev_spec->device_size) {
+		return -EINVAL;
+	}
+
+	ret = ops->read(cur->offset, buffer, length, out_length);
+	if (ret < 0) {
+		return ret;
+	}
+
+	assert(*out_length == length);
+	cur->offset += *out_length;
+
+	return 0;
+}
+
+static int mtd_close(io_entity_t *entity)
+{
+	entity->info = (uintptr_t)NULL;
+
+	return 0;
+}
+
+static int mtd_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info)
+{
+	mtd_dev_state_t *cur;
+	io_dev_info_t *info;
+	io_mtd_ops_t *ops;
+	int result;
+
+	result = allocate_dev_info(&info);
+	if (result != 0) {
+		return -ENOENT;
+	}
+
+	cur = (mtd_dev_state_t *)info->info;
+	cur->dev_spec = (io_mtd_dev_spec_t *)dev_spec;
+	*dev_info = info;
+	ops = &(cur->dev_spec->ops);
+	if (ops->init != NULL) {
+		result = ops->init(&cur->dev_spec->device_size,
+				   &cur->dev_spec->erase_size);
+	}
+
+	if (result == 0) {
+		cur->size = cur->dev_spec->device_size;
+	} else {
+		cur->size = 0ULL;
+	}
+
+	return result;
+}
+
+static int mtd_dev_close(io_dev_info_t *dev_info)
+{
+	return free_dev_info(dev_info);
+}
+
+/* Exported functions */
+
+/* Register the MTD driver in the IO abstraction */
+int register_io_dev_mtd(const io_dev_connector_t **dev_con)
+{
+	int result;
+
+	result = io_register_device(&dev_info_pool[0]);
+	if (result == 0) {
+		*dev_con = &mtd_dev_connector;
+	}
+
+	return result;
+}
diff --git a/drivers/io/io_semihosting.c b/drivers/io/io_semihosting.c
index 23d09c1..4ceddc6 100644
--- a/drivers/io/io_semihosting.c
+++ b/drivers/io/io_semihosting.c
@@ -25,7 +25,7 @@
 static int sh_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info);
 static int sh_file_open(io_dev_info_t *dev_info, const uintptr_t spec,
 		io_entity_t *entity);
-static int sh_file_seek(io_entity_t *entity, int mode, ssize_t offset);
+static int sh_file_seek(io_entity_t *entity, int mode, signed long long offset);
 static int sh_file_len(io_entity_t *entity, size_t *length);
 static int sh_file_read(io_entity_t *entity, uintptr_t buffer, size_t length,
 		size_t *length_read);
@@ -90,7 +90,7 @@
 
 
 /* Seek to a particular file offset on the semi-hosting device */
-static int sh_file_seek(io_entity_t *entity, int mode, ssize_t offset)
+static int sh_file_seek(io_entity_t *entity, int mode, signed long long offset)
 {
 	long file_handle, sh_result;
 
@@ -98,7 +98,7 @@
 
 	file_handle = (long)entity->info;
 
-	sh_result = semihosting_file_seek(file_handle, offset);
+	sh_result = semihosting_file_seek(file_handle, (ssize_t)offset);
 
 	return (sh_result == 0) ? 0 : -ENOENT;
 }
diff --git a/drivers/io/io_storage.c b/drivers/io/io_storage.c
index e444f87..b8c1d64 100644
--- a/drivers/io/io_storage.c
+++ b/drivers/io/io_storage.c
@@ -237,7 +237,7 @@
 
 
 /* Seek to a specific position in an IO entity */
-int io_seek(uintptr_t handle, io_seek_mode_t mode, ssize_t offset)
+int io_seek(uintptr_t handle, io_seek_mode_t mode, signed long long offset)
 {
 	int result = -ENODEV;
 	assert(is_valid_entity(handle) && is_valid_seek_mode(mode));
diff --git a/drivers/marvell/comphy/phy-comphy-3700.c b/drivers/marvell/comphy/phy-comphy-3700.c
index 2e8c412..f6a40a5 100644
--- a/drivers/marvell/comphy/phy-comphy-3700.c
+++ b/drivers/marvell/comphy/phy-comphy-3700.c
@@ -195,6 +195,45 @@
 	ERROR("COMPHY[%d] mode[%d] is invalid\n", comphy_index, mode);
 }
 
+/*
+ * This is something like the inverse of the previous function: for given
+ * lane it returns COMPHY_*_MODE.
+ *
+ * It is useful when powering the phy off.
+ *
+ * This function returns COMPHY_USB3_MODE even if the phy was configured
+ * with COMPHY_USB3D_MODE or COMPHY_USB3H_MODE. (The usb3 phy initialization
+ * code does not differentiate between these modes.)
+ * Also it returns COMPHY_SGMII_MODE even if the phy was configures with
+ * COMPHY_HS_SGMII_MODE. (The sgmii phy initialization code does differentiate
+ * between these modes, but it is irrelevant when powering the phy off.)
+ */
+static int mvebu_a3700_comphy_get_mode(uint8_t comphy_index)
+{
+	uint32_t reg;
+
+	reg = mmio_read_32(MVEBU_COMPHY_REG_BASE + COMPHY_SELECTOR_PHY_REG);
+	switch (comphy_index) {
+	case COMPHY_LANE0:
+		if ((reg & COMPHY_SELECTOR_USB3_GBE1_SEL_BIT) != 0)
+			return COMPHY_USB3_MODE;
+		else
+			return COMPHY_SGMII_MODE;
+	case COMPHY_LANE1:
+		if ((reg & COMPHY_SELECTOR_PCIE_GBE0_SEL_BIT) != 0)
+			return COMPHY_PCIE_MODE;
+		else
+			return COMPHY_SGMII_MODE;
+	case COMPHY_LANE2:
+		if ((reg & COMPHY_SELECTOR_USB3_PHY_SEL_BIT) != 0)
+			return COMPHY_USB3_MODE;
+		else
+			return COMPHY_SATA_MODE;
+	}
+
+	return COMPHY_UNUSED;
+}
+
 /* It is only used for SATA and USB3 on comphy lane2. */
 static void comphy_set_indirect(uintptr_t addr, uint32_t offset, uint16_t data,
 				uint16_t mask, int mode)
@@ -547,6 +586,23 @@
 	return ret;
 }
 
+static int mvebu_a3700_comphy_sgmii_power_off(uint8_t comphy_index)
+{
+	int ret = 0;
+	uint32_t mask, data, offset;
+
+	debug_enter();
+
+	data = PIN_RESET_CORE_BIT | PIN_RESET_COMPHY_BIT;
+	mask = 0;
+	offset = MVEBU_COMPHY_REG_BASE + COMPHY_PHY_CFG1_OFFSET(comphy_index);
+	reg_set(offset, data, mask);
+
+	debug_exit();
+
+	return ret;
+}
+
 static int mvebu_a3700_comphy_usb3_power_on(uint8_t comphy_index,
 					    uint32_t comphy_mode)
 {
@@ -721,11 +777,11 @@
 	udelay(PLL_SET_DELAY_US);
 
 	if (comphy_index == COMPHY_LANE2) {
-		data = COMPHY_LOOPBACK_REG0 + USB3PHY_LANE2_REG_BASE_OFFSET;
+		data = COMPHY_REG_LANE_STATUS1_ADDR + USB3PHY_LANE2_REG_BASE_OFFSET;
 		mmio_write_32(reg_base + COMPHY_LANE2_INDIR_ADDR_OFFSET,
 			      data);
 
-		addr = COMPHY_LOOPBACK_REG0 + USB3PHY_LANE2_REG_BASE_OFFSET;
+		addr = reg_base + COMPHY_LANE2_INDIR_DATA_OFFSET;
 		ret = polling_with_timeout(addr, TXDCLK_PCLK_EN, TXDCLK_PCLK_EN,
 					   COMPHY_PLL_TIMEOUT, REG_32BIT);
 	} else {
@@ -908,7 +964,20 @@
 
 	debug_enter();
 
+	if (!mode) {
+		/*
+		 * The user did not specify which mode should be powered off.
+		 * In this case we can identify this by reading the phy selector
+		 * register.
+		 */
+		mode = mvebu_a3700_comphy_get_mode(comphy_index);
+	}
+
 	switch (mode) {
+	case(COMPHY_SGMII_MODE):
+	case(COMPHY_HS_SGMII_MODE):
+		err = mvebu_a3700_comphy_sgmii_power_off(comphy_index);
+		break;
 	case (COMPHY_USB3_MODE):
 	case (COMPHY_USB3H_MODE):
 		err = mvebu_a3700_comphy_usb3_power_off();
diff --git a/drivers/mentor/i2c/mi2cv.c b/drivers/mentor/i2c/mi2cv.c
index 1cdcf74..b0270c9 100644
--- a/drivers/mentor/i2c/mi2cv.c
+++ b/drivers/mentor/i2c/mi2cv.c
@@ -81,14 +81,14 @@
 	udelay(1);
 }
 
-static int mentor_i2c_interrupt_get(void)
+static bool mentor_i2c_interrupt_get(void)
 {
 	uint32_t reg;
 
 	/* get the interrupt flag bit */
 	reg = mmio_read_32((uintptr_t)&base->control);
 	reg &= I2C_CONTROL_IFLG;
-	return reg && I2C_CONTROL_IFLG;
+	return (reg != 0U);
 }
 
 static int mentor_i2c_wait_interrupt(void)
diff --git a/drivers/mtd/nand/core.c b/drivers/mtd/nand/core.c
new file mode 100644
index 0000000..44b001e
--- /dev/null
+++ b/drivers/mtd/nand/core.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stddef.h>
+
+#include <platform_def.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <drivers/nand.h>
+#include <lib/utils.h>
+
+/*
+ * Define a single nand_device used by specific NAND frameworks.
+ */
+static struct nand_device nand_dev;
+static uint8_t scratch_buff[PLATFORM_MTD_MAX_PAGE_SIZE];
+
+int nand_read(unsigned int offset, uintptr_t buffer, size_t length,
+	      size_t *length_read)
+{
+	unsigned int block = offset / nand_dev.block_size;
+	unsigned int end_block = (offset + length - 1U) / nand_dev.block_size;
+	unsigned int page_start =
+		(offset % nand_dev.block_size) / nand_dev.page_size;
+	unsigned int nb_pages = nand_dev.block_size / nand_dev.page_size;
+	unsigned int start_offset = offset % nand_dev.page_size;
+	unsigned int page;
+	unsigned int bytes_read;
+	int is_bad;
+	int ret;
+
+	VERBOSE("Block %u - %u, page_start %u, nb %u, length %zu, offset %u\n",
+		block, end_block, page_start, nb_pages, length, offset);
+
+	*length_read = 0UL;
+
+	if (((start_offset != 0U) || (length % nand_dev.page_size) != 0U) &&
+	    (sizeof(scratch_buff) < nand_dev.page_size)) {
+		return -EINVAL;
+	}
+
+	while (block <= end_block) {
+		is_bad = nand_dev.mtd_block_is_bad(block);
+		if (is_bad < 0) {
+			return is_bad;
+		}
+
+		if (is_bad == 1) {
+			/* Skip the block */
+			uint32_t max_block =
+				nand_dev.size / nand_dev.block_size;
+
+			block++;
+			end_block++;
+			if ((block < max_block) && (end_block < max_block)) {
+				continue;
+			}
+
+			return -EIO;
+		}
+
+		for (page = page_start; page < nb_pages; page++) {
+			if ((start_offset != 0U) ||
+			    (length < nand_dev.page_size)) {
+				ret = nand_dev.mtd_read_page(
+						&nand_dev,
+						(block * nb_pages) + page,
+						(uintptr_t)scratch_buff);
+				if (ret != 0) {
+					return ret;
+				}
+
+				bytes_read = MIN((size_t)(nand_dev.page_size -
+							  start_offset),
+						 length);
+
+				memcpy((uint8_t *)buffer,
+				       scratch_buff + start_offset,
+				       bytes_read);
+
+				start_offset = 0U;
+			} else {
+				ret = nand_dev.mtd_read_page(&nand_dev,
+						(block * nb_pages) + page,
+						buffer);
+				if (ret != 0) {
+					return ret;
+				}
+
+				bytes_read = nand_dev.page_size;
+			}
+
+			length -= bytes_read;
+			buffer += bytes_read;
+			*length_read += bytes_read;
+
+			if (length == 0U) {
+				break;
+			}
+		}
+
+		page_start = 0U;
+		block++;
+	}
+
+	return 0;
+}
+
+struct nand_device *get_nand_device(void)
+{
+	return &nand_dev;
+}
diff --git a/drivers/mtd/nand/raw_nand.c b/drivers/mtd/nand/raw_nand.c
new file mode 100644
index 0000000..48131fc
--- /dev/null
+++ b/drivers/mtd/nand/raw_nand.c
@@ -0,0 +1,446 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stddef.h>
+
+#include <platform_def.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <drivers/raw_nand.h>
+#include <lib/utils.h>
+
+#define ONFI_SIGNATURE_ADDR	0x20U
+
+/* CRC calculation */
+#define CRC_POLYNOM		0x8005U
+#define CRC_INIT_VALUE		0x4F4EU
+
+/* Status register */
+#define NAND_STATUS_READY	BIT(6)
+
+#define SZ_128M			0x08000000U
+#define SZ_512			0x200U
+
+static struct rawnand_device rawnand_dev;
+
+#pragma weak plat_get_raw_nand_data
+int plat_get_raw_nand_data(struct rawnand_device *device)
+{
+	return 0;
+}
+
+static int nand_send_cmd(uint8_t cmd, unsigned int tim)
+{
+	struct nand_req req;
+
+	zeromem(&req, sizeof(struct nand_req));
+	req.nand = rawnand_dev.nand_dev;
+	req.type = NAND_REQ_CMD | cmd;
+	req.inst_delay = tim;
+
+	return rawnand_dev.ops->exec(&req);
+}
+
+static int nand_send_addr(uint8_t addr, unsigned int tim)
+{
+	struct nand_req req;
+
+	zeromem(&req, sizeof(struct nand_req));
+	req.nand = rawnand_dev.nand_dev;
+	req.type = NAND_REQ_ADDR;
+	req.addr = &addr;
+	req.inst_delay = tim;
+
+	return rawnand_dev.ops->exec(&req);
+}
+
+static int nand_send_wait(unsigned int delay, unsigned int tim)
+{
+	struct nand_req req;
+
+	zeromem(&req, sizeof(struct nand_req));
+	req.nand = rawnand_dev.nand_dev;
+	req.type = NAND_REQ_WAIT;
+	req.inst_delay = tim;
+	req.delay_ms = delay;
+
+	return rawnand_dev.ops->exec(&req);
+}
+
+
+static int nand_read_data(uint8_t *data, unsigned int length, bool use_8bit)
+{
+	struct nand_req req;
+
+	zeromem(&req, sizeof(struct nand_req));
+	req.nand = rawnand_dev.nand_dev;
+	req.type = NAND_REQ_DATAIN | (use_8bit ? NAND_REQ_BUS_WIDTH_8 : 0U);
+	req.addr = data;
+	req.length = length;
+
+	return rawnand_dev.ops->exec(&req);
+}
+
+int nand_change_read_column_cmd(unsigned int offset, uintptr_t buffer,
+				unsigned int len)
+{
+	int ret;
+	uint8_t addr[2];
+	unsigned int i;
+
+	ret = nand_send_cmd(NAND_CMD_CHANGE_1ST, 0U);
+	if (ret !=  0) {
+		return ret;
+	}
+
+	if (rawnand_dev.nand_dev->buswidth == NAND_BUS_WIDTH_16) {
+		offset /= 2U;
+	}
+
+	addr[0] = offset;
+	addr[1] = offset >> 8;
+
+	for (i = 0; i < 2U; i++) {
+		ret = nand_send_addr(addr[i], 0U);
+		if (ret !=  0) {
+			return ret;
+		}
+	}
+
+	ret = nand_send_cmd(NAND_CMD_CHANGE_2ND, NAND_TCCS_MIN);
+	if (ret !=  0) {
+		return ret;
+	}
+
+	return nand_read_data((uint8_t *)buffer, len, false);
+}
+
+int nand_read_page_cmd(unsigned int page, unsigned int offset,
+		       uintptr_t buffer, unsigned int len)
+{
+	uint8_t addr[5];
+	uint8_t i = 0U;
+	uint8_t j;
+	int ret;
+
+	VERBOSE(">%s page %u offset %u buffer 0x%lx\n", __func__, page, offset,
+		buffer);
+
+	if (rawnand_dev.nand_dev->buswidth == NAND_BUS_WIDTH_16) {
+		offset /= 2U;
+	}
+
+	addr[i++] = offset;
+	addr[i++] = offset >> 8;
+
+	addr[i++] = page;
+	addr[i++] = page >> 8;
+	if (rawnand_dev.nand_dev->size > SZ_128M) {
+		addr[i++] = page >> 16;
+	}
+
+	ret = nand_send_cmd(NAND_CMD_READ_1ST, 0U);
+	if (ret != 0) {
+		return ret;
+	}
+
+	for (j = 0U; j < i; j++) {
+		ret = nand_send_addr(addr[j], 0U);
+		if (ret != 0) {
+			return ret;
+		}
+	}
+
+	ret = nand_send_cmd(NAND_CMD_READ_2ND, NAND_TWB_MAX);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = nand_send_wait(PSEC_TO_MSEC(NAND_TR_MAX), NAND_TRR_MIN);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (buffer != 0U) {
+		ret = nand_read_data((uint8_t *)buffer, len, false);
+	}
+
+	return ret;
+}
+
+static int nand_status(uint8_t *status)
+{
+	int ret;
+
+	ret = nand_send_cmd(NAND_CMD_STATUS, NAND_TWHR_MIN);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (status != NULL) {
+		ret = nand_read_data(status, 1U, true);
+	}
+
+	return ret;
+}
+
+int nand_wait_ready(unsigned long delay)
+{
+	uint8_t status;
+	int ret;
+	uint64_t timeout;
+
+	/* Wait before reading status */
+	udelay(1);
+
+	ret = nand_status(NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	timeout = timeout_init_us(delay);
+	while (!timeout_elapsed(timeout)) {
+		ret = nand_read_data(&status, 1U, true);
+		if (ret != 0) {
+			return ret;
+		}
+
+		if ((status & NAND_STATUS_READY) != 0U) {
+			return nand_send_cmd(NAND_CMD_READ_1ST, 0U);
+		}
+
+		udelay(10);
+	}
+
+	return -ETIMEDOUT;
+}
+
+#if NAND_ONFI_DETECT
+static uint16_t nand_check_crc(uint16_t crc, uint8_t *data_in,
+			       unsigned int data_len)
+{
+	uint32_t i;
+	uint32_t j;
+	uint32_t bit;
+
+	for (i = 0U; i < data_len; i++) {
+		uint8_t cur_param = *data_in++;
+
+		for (j = BIT(7); j != 0U; j >>= 1) {
+			bit = crc & BIT(15);
+			crc <<= 1;
+
+			if ((cur_param & j) != 0U) {
+				bit ^= BIT(15);
+			}
+
+			if (bit != 0U) {
+				crc ^= CRC_POLYNOM;
+			}
+		}
+
+		crc &= GENMASK(15, 0);
+	}
+
+	return crc;
+}
+
+static int nand_read_id(uint8_t addr, uint8_t *id, unsigned int size)
+{
+	int ret;
+
+	ret = nand_send_cmd(NAND_CMD_READID, 0U);
+	if (ret !=  0) {
+		return ret;
+	}
+
+	ret = nand_send_addr(addr, NAND_TWHR_MIN);
+	if (ret !=  0) {
+		return ret;
+	}
+
+	return nand_read_data(id, size, true);
+}
+
+static int nand_reset(void)
+{
+	int ret;
+
+	ret = nand_send_cmd(NAND_CMD_RESET, NAND_TWB_MAX);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return nand_send_wait(PSEC_TO_MSEC(NAND_TRST_MAX), 0U);
+}
+
+static int nand_read_param_page(void)
+{
+	struct nand_param_page page;
+	uint8_t addr = 0U;
+	int ret;
+
+	ret = nand_send_cmd(NAND_CMD_READ_PARAM_PAGE, 0U);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = nand_send_addr(addr, NAND_TWB_MAX);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = nand_send_wait(PSEC_TO_MSEC(NAND_TR_MAX), NAND_TRR_MIN);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = nand_read_data((uint8_t *)&page, sizeof(page), true);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (strncmp((char *)&page.page_sig, "ONFI", 4) != 0) {
+		WARN("Error ONFI detection\n");
+		return -EINVAL;
+	}
+
+	if (nand_check_crc(CRC_INIT_VALUE, (uint8_t *)&page, 254U) !=
+	    page.crc16) {
+		WARN("Error reading param\n");
+		return -EINVAL;
+	}
+
+	if ((page.features & ONFI_FEAT_BUS_WIDTH_16) != 0U) {
+		rawnand_dev.nand_dev->buswidth = NAND_BUS_WIDTH_16;
+	} else {
+		rawnand_dev.nand_dev->buswidth = NAND_BUS_WIDTH_8;
+	}
+
+	rawnand_dev.nand_dev->block_size = page.num_pages_per_blk *
+					   page.bytes_per_page;
+	rawnand_dev.nand_dev->page_size = page.bytes_per_page;
+	rawnand_dev.nand_dev->size = page.num_pages_per_blk *
+				     page.bytes_per_page *
+				     page.num_blk_in_lun * page.num_lun;
+
+	if (page.nb_ecc_bits != GENMASK_32(7, 0)) {
+		rawnand_dev.nand_dev->ecc.max_bit_corr = page.nb_ecc_bits;
+		rawnand_dev.nand_dev->ecc.size = SZ_512;
+	}
+
+	VERBOSE("Page size %u, block_size %u, Size %llu, ecc %u, buswidth %u\n",
+		rawnand_dev.nand_dev->page_size,
+		rawnand_dev.nand_dev->block_size, rawnand_dev.nand_dev->size,
+		rawnand_dev.nand_dev->ecc.max_bit_corr,
+		rawnand_dev.nand_dev->buswidth);
+
+	return 0;
+}
+
+static int detect_onfi(void)
+{
+	int ret;
+	char id[4];
+
+	ret = nand_reset();
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = nand_read_id(ONFI_SIGNATURE_ADDR, (uint8_t *)id, sizeof(id));
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (strncmp(id, "ONFI", sizeof(id)) != 0) {
+		WARN("NAND Non ONFI detected\n");
+		return -ENODEV;
+	}
+
+	return nand_read_param_page();
+}
+#endif
+
+static int nand_mtd_block_is_bad(unsigned int block)
+{
+	unsigned int nbpages_per_block = rawnand_dev.nand_dev->block_size /
+					 rawnand_dev.nand_dev->page_size;
+	uint8_t bbm_marker[2];
+	uint8_t page;
+	int ret;
+
+	for (page = 0U; page < 2U; page++) {
+		ret = nand_read_page_cmd(block * nbpages_per_block,
+					 rawnand_dev.nand_dev->page_size,
+					 (uintptr_t)bbm_marker,
+					 sizeof(bbm_marker));
+		if (ret != 0) {
+			return ret;
+		}
+
+		if ((bbm_marker[0] != GENMASK_32(7, 0)) ||
+		    (bbm_marker[1] != GENMASK_32(7, 0))) {
+			WARN("Block %u is bad\n", block);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+static int nand_mtd_read_page_raw(struct nand_device *nand, unsigned int page,
+				  uintptr_t buffer)
+{
+	return nand_read_page_cmd(page, 0U, buffer,
+				  rawnand_dev.nand_dev->page_size);
+}
+
+void nand_raw_ctrl_init(const struct nand_ctrl_ops *ops)
+{
+	rawnand_dev.ops = ops;
+}
+
+int nand_raw_init(unsigned long long *size, unsigned int *erase_size)
+{
+	rawnand_dev.nand_dev = get_nand_device();
+	if (rawnand_dev.nand_dev == NULL) {
+		return -EINVAL;
+	}
+
+	rawnand_dev.nand_dev->mtd_block_is_bad = nand_mtd_block_is_bad;
+	rawnand_dev.nand_dev->mtd_read_page = nand_mtd_read_page_raw;
+	rawnand_dev.nand_dev->ecc.mode = NAND_ECC_NONE;
+
+	if ((rawnand_dev.ops->setup == NULL) ||
+	    (rawnand_dev.ops->exec == NULL)) {
+		return -ENODEV;
+	}
+
+#if NAND_ONFI_DETECT
+	if (detect_onfi() != 0) {
+		WARN("Detect ONFI failed\n");
+	}
+#endif
+
+	if (plat_get_raw_nand_data(&rawnand_dev) != 0) {
+		return -EINVAL;
+	}
+
+	assert((rawnand_dev.nand_dev->page_size != 0U) &&
+	       (rawnand_dev.nand_dev->block_size != 0U) &&
+	       (rawnand_dev.nand_dev->size != 0U));
+
+	*size = rawnand_dev.nand_dev->size;
+	*erase_size = rawnand_dev.nand_dev->block_size;
+
+	rawnand_dev.ops->setup(rawnand_dev.nand_dev);
+
+	return 0;
+}
diff --git a/drivers/mtd/nand/spi_nand.c b/drivers/mtd/nand/spi_nand.c
new file mode 100644
index 0000000..d01a119
--- /dev/null
+++ b/drivers/mtd/nand/spi_nand.c
@@ -0,0 +1,320 @@
+/*
+ * Copyright (c) 2019,  STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stddef.h>
+
+#include <platform_def.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <drivers/spi_nand.h>
+#include <lib/utils.h>
+
+#define SPI_NAND_MAX_ID_LEN		4U
+#define DELAY_US_400MS			400000U
+#define MACRONIX_ID			0xC2U
+
+static struct spinand_device spinand_dev;
+
+#pragma weak plat_get_spi_nand_data
+int plat_get_spi_nand_data(struct spinand_device *device)
+{
+	return 0;
+}
+
+static int spi_nand_reg(bool read_reg, uint8_t reg, uint8_t *val,
+			enum spi_mem_data_dir dir)
+{
+	struct spi_mem_op op;
+
+	zeromem(&op, sizeof(struct spi_mem_op));
+	if (read_reg) {
+		op.cmd.opcode = SPI_NAND_OP_GET_FEATURE;
+	} else {
+		op.cmd.opcode = SPI_NAND_OP_SET_FEATURE;
+	}
+
+	op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+	op.addr.val = reg;
+	op.addr.nbytes = 1U;
+	op.addr.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+	op.data.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+	op.data.dir = dir;
+	op.data.nbytes = 1U;
+	op.data.buf = val;
+
+	return spi_mem_exec_op(&op);
+}
+
+static int spi_nand_read_reg(uint8_t reg, uint8_t *val)
+{
+	return spi_nand_reg(true, reg, val, SPI_MEM_DATA_IN);
+}
+
+static int spi_nand_write_reg(uint8_t reg, uint8_t val)
+{
+	return spi_nand_reg(false, reg, &val, SPI_MEM_DATA_OUT);
+}
+
+static int spi_nand_update_cfg(uint8_t mask, uint8_t val)
+{
+	int ret;
+	uint8_t cfg = spinand_dev.cfg_cache;
+
+	cfg &= ~mask;
+	cfg |= val;
+
+	if (cfg == spinand_dev.cfg_cache) {
+		return 0;
+	}
+
+	ret = spi_nand_write_reg(SPI_NAND_REG_CFG, cfg);
+	if (ret == 0) {
+		spinand_dev.cfg_cache = cfg;
+	}
+
+	return ret;
+}
+
+static int spi_nand_ecc_enable(bool enable)
+{
+	return spi_nand_update_cfg(SPI_NAND_CFG_ECC_EN,
+				   enable ? SPI_NAND_CFG_ECC_EN : 0U);
+}
+
+static int spi_nand_quad_enable(uint8_t manufacturer_id)
+{
+	bool enable = false;
+
+	if (manufacturer_id != MACRONIX_ID) {
+		return 0;
+	}
+
+	if (spinand_dev.spi_read_cache_op.data.buswidth ==
+	    SPI_MEM_BUSWIDTH_4_LINE) {
+		enable = true;
+	}
+
+	return spi_nand_update_cfg(SPI_NAND_CFG_QE,
+				   enable ? SPI_NAND_CFG_QE : 0U);
+}
+
+static int spi_nand_wait_ready(uint8_t *status)
+{
+	int ret;
+	uint64_t timeout = timeout_init_us(DELAY_US_400MS);
+
+	while (!timeout_elapsed(timeout)) {
+		ret = spi_nand_read_reg(SPI_NAND_REG_STATUS, status);
+		if (ret != 0) {
+			return ret;
+		}
+
+		VERBOSE("%s Status %x\n", __func__, *status);
+		if ((*status & SPI_NAND_STATUS_BUSY) == 0U) {
+			return 0;
+		}
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int spi_nand_reset(void)
+{
+	struct spi_mem_op op;
+	uint8_t status;
+	int ret;
+
+	zeromem(&op, sizeof(struct spi_mem_op));
+	op.cmd.opcode = SPI_NAND_OP_RESET;
+	op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+
+	ret = spi_mem_exec_op(&op);
+	if (ret != 0) {
+		return ret;
+	}
+
+	return spi_nand_wait_ready(&status);
+}
+
+static int spi_nand_read_id(uint8_t *id)
+{
+	struct spi_mem_op op;
+
+	zeromem(&op, sizeof(struct spi_mem_op));
+	op.cmd.opcode = SPI_NAND_OP_READ_ID;
+	op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+	op.data.dir = SPI_MEM_DATA_IN;
+	op.data.nbytes = SPI_NAND_MAX_ID_LEN;
+	op.data.buf = id;
+	op.data.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+
+	return spi_mem_exec_op(&op);
+}
+
+static int spi_nand_load_page(unsigned int page)
+{
+	struct spi_mem_op op;
+	uint32_t block_nb = page / spinand_dev.nand_dev->block_size;
+	uint32_t page_nb = page - (block_nb * spinand_dev.nand_dev->page_size);
+	uint32_t nbpages_per_block = spinand_dev.nand_dev->block_size /
+				     spinand_dev.nand_dev->page_size;
+	uint32_t block_sh = __builtin_ctz(nbpages_per_block) + 1U;
+
+	zeromem(&op, sizeof(struct spi_mem_op));
+	op.cmd.opcode = SPI_NAND_OP_LOAD_PAGE;
+	op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+	op.addr.val = (block_nb << block_sh) | page_nb;
+	op.addr.nbytes = 3U;
+	op.addr.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+
+	return spi_mem_exec_op(&op);
+}
+
+static int spi_nand_read_from_cache(unsigned int page, unsigned int offset,
+				    uint8_t *buffer, unsigned int len)
+{
+	uint32_t nbpages_per_block = spinand_dev.nand_dev->block_size /
+				     spinand_dev.nand_dev->page_size;
+	uint32_t block_nb = page / nbpages_per_block;
+	uint32_t page_sh = __builtin_ctz(spinand_dev.nand_dev->page_size) + 1U;
+
+	spinand_dev.spi_read_cache_op.addr.val = offset;
+
+	if ((spinand_dev.nand_dev->nb_planes > 1U) && ((block_nb % 2U) == 1U)) {
+		spinand_dev.spi_read_cache_op.addr.val |= 1U << page_sh;
+	}
+
+	spinand_dev.spi_read_cache_op.data.buf = buffer;
+	spinand_dev.spi_read_cache_op.data.nbytes = len;
+
+	return spi_mem_exec_op(&spinand_dev.spi_read_cache_op);
+}
+
+static int spi_nand_read_page(unsigned int page, unsigned int offset,
+			      uint8_t *buffer, unsigned int len,
+			      bool ecc_enabled)
+{
+	uint8_t status;
+	int ret;
+
+	ret = spi_nand_ecc_enable(ecc_enabled);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = spi_nand_load_page(page);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = spi_nand_wait_ready(&status);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = spi_nand_read_from_cache(page, offset, buffer, len);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (ecc_enabled && ((status & SPI_NAND_STATUS_ECC_UNCOR) != 0U)) {
+		return -EBADMSG;
+	}
+
+	return 0;
+}
+
+static int spi_nand_mtd_block_is_bad(unsigned int block)
+{
+	unsigned int nbpages_per_block = spinand_dev.nand_dev->block_size /
+					 spinand_dev.nand_dev->page_size;
+	uint8_t bbm_marker[2];
+	int ret;
+
+	ret = spi_nand_read_page(block * nbpages_per_block,
+				 spinand_dev.nand_dev->page_size,
+				 bbm_marker, sizeof(bbm_marker), false);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if ((bbm_marker[0] != GENMASK_32(7, 0)) ||
+	    (bbm_marker[1] != GENMASK_32(7, 0))) {
+		WARN("Block %i is bad\n", block);
+		return 1;
+	}
+
+	return 0;
+}
+
+static int spi_nand_mtd_read_page(struct nand_device *nand, unsigned int page,
+				  uintptr_t buffer)
+{
+	return spi_nand_read_page(page, 0, (uint8_t *)buffer,
+				  spinand_dev.nand_dev->page_size, true);
+}
+
+int spi_nand_init(unsigned long long *size, unsigned int *erase_size)
+{
+	uint8_t id[SPI_NAND_MAX_ID_LEN];
+	int ret;
+
+	spinand_dev.nand_dev = get_nand_device();
+	if (spinand_dev.nand_dev == NULL) {
+		return -EINVAL;
+	}
+
+	spinand_dev.nand_dev->mtd_block_is_bad = spi_nand_mtd_block_is_bad;
+	spinand_dev.nand_dev->mtd_read_page = spi_nand_mtd_read_page;
+	spinand_dev.nand_dev->nb_planes = 1;
+
+	spinand_dev.spi_read_cache_op.cmd.opcode = SPI_NAND_OP_READ_FROM_CACHE;
+	spinand_dev.spi_read_cache_op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+	spinand_dev.spi_read_cache_op.addr.nbytes = 2U;
+	spinand_dev.spi_read_cache_op.addr.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+	spinand_dev.spi_read_cache_op.dummy.nbytes = 1U;
+	spinand_dev.spi_read_cache_op.dummy.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+	spinand_dev.spi_read_cache_op.data.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+
+	if (plat_get_spi_nand_data(&spinand_dev) != 0) {
+		return -EINVAL;
+	}
+
+	ret = spi_nand_reset();
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = spi_nand_read_id(id);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = spi_nand_read_reg(SPI_NAND_REG_CFG, &spinand_dev.cfg_cache);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = spi_nand_quad_enable(id[0]);
+	if (ret != 0) {
+		return ret;
+	}
+
+	VERBOSE("SPI_NAND Detected ID 0x%x 0x%x\n", id[0], id[1]);
+
+	VERBOSE("Page size %i, Block size %i, size %lli\n",
+		spinand_dev.nand_dev->page_size,
+		spinand_dev.nand_dev->block_size,
+		spinand_dev.nand_dev->size);
+
+	*size = spinand_dev.nand_dev->size;
+	*erase_size = spinand_dev.nand_dev->block_size;
+
+	return 0;
+}
diff --git a/drivers/mtd/nor/spi_nor.c b/drivers/mtd/nor/spi_nor.c
new file mode 100644
index 0000000..22d3ae3
--- /dev/null
+++ b/drivers/mtd/nor/spi_nor.c
@@ -0,0 +1,387 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stddef.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <drivers/spi_nor.h>
+#include <lib/utils.h>
+
+#define SR_WIP			BIT(0)	/* Write in progress */
+#define CR_QUAD_EN_SPAN		BIT(1)	/* Spansion Quad I/O */
+#define SR_QUAD_EN_MX		BIT(6)	/* Macronix Quad I/O */
+#define FSR_READY		BIT(7)	/* Device status, 0 = Busy, 1 = Ready */
+
+/* Defined IDs for supported memories */
+#define SPANSION_ID		0x01U
+#define MACRONIX_ID		0xC2U
+#define MICRON_ID		0x2CU
+
+#define BANK_SIZE		0x1000000U
+
+#define SPI_READY_TIMEOUT_US	40000U
+
+static struct nor_device nor_dev;
+
+#pragma weak plat_get_nor_data
+int plat_get_nor_data(struct nor_device *device)
+{
+	return 0;
+}
+
+static int spi_nor_reg(uint8_t reg, uint8_t *buf, size_t len,
+		       enum spi_mem_data_dir dir)
+{
+	struct spi_mem_op op;
+
+	zeromem(&op, sizeof(struct spi_mem_op));
+	op.cmd.opcode = reg;
+	op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+	op.data.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+	op.data.dir = dir;
+	op.data.nbytes = len;
+	op.data.buf = buf;
+
+	return spi_mem_exec_op(&op);
+}
+
+static inline int spi_nor_read_id(uint8_t *id)
+{
+	return spi_nor_reg(SPI_NOR_OP_READ_ID, id, 1U, SPI_MEM_DATA_IN);
+}
+
+static inline int spi_nor_read_cr(uint8_t *cr)
+{
+	return spi_nor_reg(SPI_NOR_OP_READ_CR, cr, 1U, SPI_MEM_DATA_IN);
+}
+
+static inline int spi_nor_read_sr(uint8_t *sr)
+{
+	return spi_nor_reg(SPI_NOR_OP_READ_SR, sr, 1U, SPI_MEM_DATA_IN);
+}
+
+static inline int spi_nor_read_fsr(uint8_t *fsr)
+{
+	return spi_nor_reg(SPI_NOR_OP_READ_FSR, fsr, 1U, SPI_MEM_DATA_IN);
+}
+
+static inline int spi_nor_write_en(void)
+{
+	return spi_nor_reg(SPI_NOR_OP_WREN, NULL, 0U, SPI_MEM_DATA_OUT);
+}
+
+/*
+ * Check if device is ready.
+ *
+ * Return 0 if ready, 1 if busy or a negative error code otherwise
+ */
+static int spi_nor_ready(void)
+{
+	uint8_t sr;
+	int ret;
+
+	ret = spi_nor_read_sr(&sr);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if ((nor_dev.flags & SPI_NOR_USE_FSR) != 0U) {
+		uint8_t fsr;
+
+		ret = spi_nor_read_fsr(&fsr);
+		if (ret != 0) {
+			return ret;
+		}
+
+		return (((fsr & FSR_READY) != 0U) && ((sr & SR_WIP) == 0U)) ?
+			0 : 1;
+	}
+
+	return (((sr & SR_WIP) != 0U) ? 1 : 0);
+}
+
+static int spi_nor_wait_ready(void)
+{
+	int ret;
+	uint64_t timeout = timeout_init_us(SPI_READY_TIMEOUT_US);
+
+	while (!timeout_elapsed(timeout)) {
+		ret = spi_nor_ready();
+		if (ret <= 0) {
+			return ret;
+		}
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int spi_nor_macronix_quad_enable(void)
+{
+	uint8_t sr;
+	int ret;
+
+	ret = spi_nor_read_sr(&sr);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if ((sr & SR_QUAD_EN_MX) == 0U) {
+		return 0;
+	}
+
+	ret = spi_nor_write_en();
+	if (ret != 0) {
+		return ret;
+	}
+
+	sr |= SR_QUAD_EN_MX;
+	ret = spi_nor_reg(SPI_NOR_OP_WRSR, &sr, 1, SPI_MEM_DATA_OUT);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = spi_nor_wait_ready();
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = spi_nor_read_sr(&sr);
+	if ((ret != 0) || ((sr & SR_QUAD_EN_MX) == 0U)) {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int spi_nor_write_sr_cr(uint8_t *sr_cr)
+{
+	int ret;
+
+	ret = spi_nor_write_en();
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = spi_nor_reg(SPI_NOR_OP_WRSR, sr_cr, 2, SPI_MEM_DATA_OUT);
+	if (ret != 0) {
+		return -EINVAL;
+	}
+
+	ret = spi_nor_wait_ready();
+	if (ret != 0) {
+		return ret;
+	}
+
+	return 0;
+}
+
+static int spi_nor_quad_enable(void)
+{
+	uint8_t sr_cr[2];
+	int ret;
+
+	ret = spi_nor_read_cr(&sr_cr[1]);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if ((sr_cr[1] & CR_QUAD_EN_SPAN) != 0U) {
+		return 0;
+	}
+
+	sr_cr[1] |= CR_QUAD_EN_SPAN;
+	ret = spi_nor_read_sr(&sr_cr[0]);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = spi_nor_write_sr_cr(sr_cr);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = spi_nor_read_cr(&sr_cr[1]);
+	if ((ret != 0) || ((sr_cr[1] & CR_QUAD_EN_SPAN) == 0U)) {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int spi_nor_clean_bar(void)
+{
+	int ret;
+
+	if (nor_dev.selected_bank == 0U) {
+		return 0;
+	}
+
+	nor_dev.selected_bank = 0U;
+
+	ret = spi_nor_write_en();
+	if (ret != 0) {
+		return ret;
+	}
+
+	return spi_nor_reg(nor_dev.bank_write_cmd, &nor_dev.selected_bank,
+			   1, SPI_MEM_DATA_OUT);
+}
+
+static int spi_nor_write_bar(uint32_t offset)
+{
+	uint8_t selected_bank = offset / BANK_SIZE;
+	int ret;
+
+	if (selected_bank == nor_dev.selected_bank) {
+		return 0;
+	}
+
+	ret = spi_nor_write_en();
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = spi_nor_reg(nor_dev.bank_write_cmd, &selected_bank,
+			  1, SPI_MEM_DATA_OUT);
+	if (ret != 0) {
+		return ret;
+	}
+
+	nor_dev.selected_bank = selected_bank;
+
+	return 0;
+}
+
+static int spi_nor_read_bar(void)
+{
+	uint8_t selected_bank = 0;
+	int ret;
+
+	ret = spi_nor_reg(nor_dev.bank_read_cmd, &selected_bank,
+			  1, SPI_MEM_DATA_IN);
+	if (ret != 0) {
+		return ret;
+	}
+
+	nor_dev.selected_bank = selected_bank;
+
+	return 0;
+}
+
+int spi_nor_read(unsigned int offset, uintptr_t buffer, size_t length,
+		 size_t *length_read)
+{
+	size_t remain_len;
+	int ret;
+
+	*length_read = 0;
+	nor_dev.read_op.addr.val = offset;
+	nor_dev.read_op.data.buf = (void *)buffer;
+
+	VERBOSE("%s offset %i length %zu\n", __func__, offset, length);
+
+	while (length != 0U) {
+		if ((nor_dev.flags & SPI_NOR_USE_BANK) != 0U) {
+			ret = spi_nor_write_bar(nor_dev.read_op.addr.val);
+			if (ret != 0) {
+				return ret;
+			}
+
+			remain_len = (BANK_SIZE * (nor_dev.selected_bank + 1)) -
+				nor_dev.read_op.addr.val;
+			nor_dev.read_op.data.nbytes = MIN(length, remain_len);
+		} else {
+			nor_dev.read_op.data.nbytes = length;
+		}
+
+		ret = spi_mem_exec_op(&nor_dev.read_op);
+		if (ret != 0) {
+			spi_nor_clean_bar();
+			return ret;
+		}
+
+		length -= nor_dev.read_op.data.nbytes;
+		nor_dev.read_op.addr.val += nor_dev.read_op.data.nbytes;
+		nor_dev.read_op.data.buf += nor_dev.read_op.data.nbytes;
+		*length_read += nor_dev.read_op.data.nbytes;
+	}
+
+	if ((nor_dev.flags & SPI_NOR_USE_BANK) != 0U) {
+		ret = spi_nor_clean_bar();
+		if (ret != 0) {
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+int spi_nor_init(unsigned long long *size, unsigned int *erase_size)
+{
+	int ret = 0;
+	uint8_t id;
+
+	/* Default read command used */
+	nor_dev.read_op.cmd.opcode = SPI_NOR_OP_READ;
+	nor_dev.read_op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+	nor_dev.read_op.addr.nbytes = 3U;
+	nor_dev.read_op.addr.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+	nor_dev.read_op.data.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+	nor_dev.read_op.data.dir = SPI_MEM_DATA_IN;
+
+	if (plat_get_nor_data(&nor_dev) != 0) {
+		return -EINVAL;
+	}
+
+	assert(nor_dev.size != 0);
+
+	if (nor_dev.size > BANK_SIZE) {
+		nor_dev.flags |= SPI_NOR_USE_BANK;
+	}
+
+	*size = nor_dev.size;
+
+	ret = spi_nor_read_id(&id);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if ((nor_dev.flags & SPI_NOR_USE_BANK) != 0U) {
+		switch (id) {
+		case SPANSION_ID:
+			nor_dev.bank_read_cmd = SPINOR_OP_BRRD;
+			nor_dev.bank_write_cmd = SPINOR_OP_BRWR;
+			break;
+		default:
+			nor_dev.bank_read_cmd = SPINOR_OP_RDEAR;
+			nor_dev.bank_write_cmd = SPINOR_OP_WREAR;
+			break;
+		}
+	}
+
+	if (nor_dev.read_op.data.buswidth == 4U) {
+		switch (id) {
+		case MACRONIX_ID:
+			WARN("Enable Macronix quad support\n");
+			ret = spi_nor_macronix_quad_enable();
+			break;
+		case MICRON_ID:
+			break;
+		default:
+			ret = spi_nor_quad_enable();
+			break;
+		}
+	}
+
+	if ((ret == 0) && ((nor_dev.flags & SPI_NOR_USE_BANK) != 0U)) {
+		ret = spi_nor_read_bar();
+	}
+
+	return ret;
+}
diff --git a/drivers/mtd/spi-mem/spi_mem.c b/drivers/mtd/spi-mem/spi_mem.c
new file mode 100644
index 0000000..63ea769
--- /dev/null
+++ b/drivers/mtd/spi-mem/spi_mem.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <libfdt.h>
+
+#include <drivers/spi_mem.h>
+#include <lib/utils_def.h>
+
+#define SPI_MEM_DEFAULT_SPEED_HZ 100000U
+
+/*
+ * struct spi_slave - Representation of a SPI slave.
+ *
+ * @max_hz:		Maximum speed for this slave in Hertz.
+ * @cs:			ID of the chip select connected to the slave.
+ * @mode:		SPI mode to use for this slave (see SPI mode flags).
+ * @ops:		Ops defined by the bus.
+ */
+struct spi_slave {
+	unsigned int max_hz;
+	unsigned int cs;
+	unsigned int mode;
+	const struct spi_bus_ops *ops;
+};
+
+static struct spi_slave spi_slave;
+
+static bool spi_mem_check_buswidth_req(uint8_t buswidth, bool tx)
+{
+	switch (buswidth) {
+	case 1U:
+		return true;
+
+	case 2U:
+		if ((tx && (spi_slave.mode & (SPI_TX_DUAL | SPI_TX_QUAD)) !=
+		     0U) ||
+		    (!tx && (spi_slave.mode & (SPI_RX_DUAL | SPI_RX_QUAD)) !=
+		     0U)) {
+			return true;
+		}
+		break;
+
+	case 4U:
+		if ((tx && (spi_slave.mode & SPI_TX_QUAD) != 0U) ||
+		    (!tx && (spi_slave.mode & SPI_RX_QUAD) != 0U)) {
+			return true;
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	return false;
+}
+
+static bool spi_mem_supports_op(const struct spi_mem_op *op)
+{
+	if (!spi_mem_check_buswidth_req(op->cmd.buswidth, true)) {
+		return false;
+	}
+
+	if ((op->addr.nbytes != 0U) &&
+	    !spi_mem_check_buswidth_req(op->addr.buswidth, true)) {
+		return false;
+	}
+
+	if ((op->dummy.nbytes != 0U) &&
+	    !spi_mem_check_buswidth_req(op->dummy.buswidth, true)) {
+		return false;
+	}
+
+	if ((op->data.nbytes != 0U) &&
+	    !spi_mem_check_buswidth_req(op->data.buswidth,
+				       op->data.dir == SPI_MEM_DATA_OUT)) {
+		return false;
+	}
+
+	return true;
+}
+
+static int spi_mem_set_speed_mode(void)
+{
+	const struct spi_bus_ops *ops = spi_slave.ops;
+	int ret;
+
+	ret = ops->set_speed(spi_slave.max_hz);
+	if (ret != 0) {
+		VERBOSE("Cannot set speed (err=%d)\n", ret);
+		return ret;
+	}
+
+	ret = ops->set_mode(spi_slave.mode);
+	if (ret != 0) {
+		VERBOSE("Cannot set mode (err=%d)\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int spi_mem_check_bus_ops(const struct spi_bus_ops *ops)
+{
+	bool error = false;
+
+	if (ops->claim_bus == NULL) {
+		VERBOSE("Ops claim bus is not defined\n");
+		error = true;
+	}
+
+	if (ops->release_bus == NULL) {
+		VERBOSE("Ops release bus is not defined\n");
+		error = true;
+	}
+
+	if (ops->exec_op == NULL) {
+		VERBOSE("Ops exec op is not defined\n");
+		error = true;
+	}
+
+	if (ops->set_speed == NULL) {
+		VERBOSE("Ops set speed is not defined\n");
+		error = true;
+	}
+
+	if (ops->set_mode == NULL) {
+		VERBOSE("Ops set mode is not defined\n");
+		error = true;
+	}
+
+	return error ? -EINVAL : 0;
+}
+
+/*
+ * spi_mem_exec_op() - Execute a memory operation.
+ * @op: The memory operation to execute.
+ *
+ * This function first checks that @op is supported and then tries to execute
+ * it.
+ *
+ * Return: 0 in case of success, a negative error code otherwise.
+ */
+int spi_mem_exec_op(const struct spi_mem_op *op)
+{
+	const struct spi_bus_ops *ops = spi_slave.ops;
+	int ret;
+
+	VERBOSE("%s: cmd:%x mode:%d.%d.%d.%d addqr:%llx len:%x\n",
+		__func__, op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth,
+		op->dummy.buswidth, op->data.buswidth,
+		op->addr.val, op->data.nbytes);
+
+	if (!spi_mem_supports_op(op)) {
+		WARN("Error in spi_mem_support\n");
+		return -ENOTSUP;
+	}
+
+	ret = ops->claim_bus(spi_slave.cs);
+	if (ret != 0) {
+		WARN("Error claim_bus\n");
+		return ret;
+	}
+
+	ret = ops->exec_op(op);
+
+	ops->release_bus();
+
+	return ret;
+}
+
+/*
+ * spi_mem_init_slave() - SPI slave device initialization.
+ * @fdt: Pointer to the device tree blob.
+ * @bus_node: Offset of the bus node.
+ * @ops: The SPI bus ops defined.
+ *
+ * This function first checks that @ops are supported and then tries to find
+ * a SPI slave device.
+ *
+ * Return: 0 in case of success, a negative error code otherwise.
+ */
+int spi_mem_init_slave(void *fdt, int bus_node, const struct spi_bus_ops *ops)
+{
+	int ret;
+	int mode = 0;
+	int nchips = 0;
+	int bus_subnode = 0;
+	const fdt32_t *cuint = NULL;
+
+	ret = spi_mem_check_bus_ops(ops);
+	if (ret != 0) {
+		return ret;
+	}
+
+	fdt_for_each_subnode(bus_subnode, fdt, bus_node) {
+		nchips++;
+	}
+
+	if (nchips != 1) {
+		ERROR("Only one SPI device is currently supported\n");
+		return -EINVAL;
+	}
+
+	fdt_for_each_subnode(bus_subnode, fdt, bus_node) {
+		/* Get chip select */
+		cuint = fdt_getprop(fdt, bus_subnode, "reg", NULL);
+		if (cuint == NULL) {
+			ERROR("Chip select not well defined\n");
+			return -EINVAL;
+		}
+		spi_slave.cs = fdt32_to_cpu(*cuint);
+
+		/* Get max slave frequency */
+		spi_slave.max_hz = SPI_MEM_DEFAULT_SPEED_HZ;
+		cuint = fdt_getprop(fdt, bus_subnode,
+				    "spi-max-frequency", NULL);
+		if (cuint != NULL) {
+			spi_slave.max_hz = fdt32_to_cpu(*cuint);
+		}
+
+		/* Get mode */
+		if ((fdt_getprop(fdt, bus_subnode, "spi-cpol", NULL)) != NULL) {
+			mode |= SPI_CPOL;
+		}
+		if ((fdt_getprop(fdt, bus_subnode, "spi-cpha", NULL)) != NULL) {
+			mode |= SPI_CPHA;
+		}
+		if ((fdt_getprop(fdt, bus_subnode, "spi-cs-high", NULL)) !=
+		    NULL) {
+			mode |= SPI_CS_HIGH;
+		}
+		if ((fdt_getprop(fdt, bus_subnode, "spi-3wire", NULL)) !=
+		    NULL) {
+			mode |= SPI_3WIRE;
+		}
+		if ((fdt_getprop(fdt, bus_subnode, "spi-half-duplex", NULL)) !=
+		    NULL) {
+			mode |= SPI_PREAMBLE;
+		}
+
+		/* Get dual/quad mode */
+		cuint = fdt_getprop(fdt, bus_subnode, "spi-tx-bus-width", NULL);
+		if (cuint != NULL) {
+			switch (fdt32_to_cpu(*cuint)) {
+			case 1U:
+				break;
+			case 2U:
+				mode |= SPI_TX_DUAL;
+				break;
+			case 4U:
+				mode |= SPI_TX_QUAD;
+				break;
+			default:
+				WARN("spi-tx-bus-width %d not supported\n",
+				     fdt32_to_cpu(*cuint));
+				return -EINVAL;
+			}
+		}
+
+		cuint = fdt_getprop(fdt, bus_subnode, "spi-rx-bus-width", NULL);
+		if (cuint != NULL) {
+			switch (fdt32_to_cpu(*cuint)) {
+			case 1U:
+				break;
+			case 2U:
+				mode |= SPI_RX_DUAL;
+				break;
+			case 4U:
+				mode |= SPI_RX_QUAD;
+				break;
+			default:
+				WARN("spi-rx-bus-width %d not supported\n",
+				     fdt32_to_cpu(*cuint));
+				return -EINVAL;
+			}
+		}
+
+		spi_slave.mode = mode;
+		spi_slave.ops = ops;
+	}
+
+	return spi_mem_set_speed_mode();
+}
diff --git a/drivers/staging/renesas/rcar/ddr/boot_init_dram.h b/drivers/renesas/rcar/ddr/boot_init_dram.h
similarity index 100%
rename from drivers/staging/renesas/rcar/ddr/boot_init_dram.h
rename to drivers/renesas/rcar/ddr/boot_init_dram.h
diff --git a/drivers/renesas/rcar/ddr/ddr.mk b/drivers/renesas/rcar/ddr/ddr.mk
new file mode 100644
index 0000000..c26993d
--- /dev/null
+++ b/drivers/renesas/rcar/ddr/ddr.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifeq (${RCAR_LSI},${RCAR_E3})
+    include drivers/renesas/rcar/ddr/ddr_a/ddr_a.mk
+    BL2_SOURCES += drivers/renesas/rcar/ddr/dram_sub_func.c
+else ifeq (${RCAR_LSI},${RCAR_D3})
+    include drivers/renesas/rcar/ddr/ddr_a/ddr_a.mk
+else ifeq (${RCAR_LSI},${RCAR_V3M})
+    include drivers/renesas/rcar/ddr/ddr_a/ddr_a.mk
+else
+    include drivers/renesas/rcar/ddr/ddr_b/ddr_b.mk
+    BL2_SOURCES += drivers/renesas/rcar/ddr/dram_sub_func.c
+endif
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_a/boot_init_dram_regdef.h b/drivers/renesas/rcar/ddr/ddr_a/boot_init_dram_regdef.h
similarity index 100%
rename from drivers/staging/renesas/rcar/ddr/ddr_a/boot_init_dram_regdef.h
rename to drivers/renesas/rcar/ddr/ddr_a/boot_init_dram_regdef.h
diff --git a/drivers/renesas/rcar/ddr/ddr_a/ddr_a.mk b/drivers/renesas/rcar/ddr/ddr_a/ddr_a.mk
new file mode 100644
index 0000000..7882558
--- /dev/null
+++ b/drivers/renesas/rcar/ddr/ddr_a/ddr_a.mk
@@ -0,0 +1,13 @@
+#
+# Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifeq (${RCAR_LSI},${RCAR_E3})
+BL2_SOURCES += drivers/renesas/rcar/ddr/ddr_a/ddr_init_e3.c
+else ifeq (${RCAR_LSI},${RCAR_D3})
+BL2_SOURCES += drivers/renesas/rcar/ddr/ddr_a/ddr_init_d3.c
+else
+BL2_SOURCES += drivers/renesas/rcar/ddr/ddr_a/ddr_init_v3m.c
+endif
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_d3.c b/drivers/renesas/rcar/ddr/ddr_a/ddr_init_d3.c
similarity index 100%
rename from drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_d3.c
rename to drivers/renesas/rcar/ddr/ddr_a/ddr_init_d3.c
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_e3.c b/drivers/renesas/rcar/ddr/ddr_a/ddr_init_e3.c
similarity index 100%
rename from drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_e3.c
rename to drivers/renesas/rcar/ddr/ddr_a/ddr_init_e3.c
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_v3m.c b/drivers/renesas/rcar/ddr/ddr_a/ddr_init_v3m.c
similarity index 100%
rename from drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_v3m.c
rename to drivers/renesas/rcar/ddr/ddr_a/ddr_init_v3m.c
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram.c b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c
similarity index 99%
rename from drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram.c
rename to drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c
index 9f7c954..1d6e83a 100644
--- a/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram.c
+++ b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c
@@ -254,10 +254,10 @@
 static uint32_t ddrtbl_getval(uint32_t *tbl, uint32_t _regdef);
 static uint32_t ddrphy_regif_chk(void);
 static inline void ddrphy_regif_idle(void);
-static uint16_t _f_scale(uint32_t ddr_mbps, uint32_t ddr_mbpsdiv, uint32_t ps,
+static uint16_t _f_scale(uint32_t _ddr_mbps, uint32_t _ddr_mbpsdiv, uint32_t ps,
 			 uint16_t cyc);
-static void _f_scale_js2(uint32_t ddr_mbps, uint32_t ddr_mbpsdiv,
-			 uint16_t *js2);
+static void _f_scale_js2(uint32_t _ddr_mbps, uint32_t _ddr_mbpsdiv,
+			 uint16_t *_js2);
 static int16_t _f_scale_adj(int16_t ps);
 static void ddrtbl_load(void);
 static void ddr_config_sub(void);
@@ -991,15 +991,15 @@
 static uint8_t RL;
 static uint8_t WL;
 
-static uint16_t _f_scale(uint32_t ddr_mbps, uint32_t ddr_mbpsdiv, uint32_t ps,
+static uint16_t _f_scale(uint32_t _ddr_mbps, uint32_t _ddr_mbpsdiv, uint32_t ps,
 			 uint16_t cyc)
 {
 	uint32_t tmp;
 	uint32_t div;
 
-	tmp = (((uint32_t)(ps) + 9) / 10) * ddr_mbps;
-	div = tmp / (200000 * ddr_mbpsdiv);
-	if (tmp != (div * 200000 * ddr_mbpsdiv))
+	tmp = (((uint32_t)(ps) + 9) / 10) * _ddr_mbps;
+	div = tmp / (200000 * _ddr_mbpsdiv);
+	if (tmp != (div * 200000 * _ddr_mbpsdiv))
 		div = div + 1;
 
 	if (div > cyc)
@@ -1007,19 +1007,19 @@
 	return cyc;
 }
 
-static void _f_scale_js2(uint32_t ddr_mbps, uint32_t ddr_mbpsdiv,
-			 uint16_t *js2)
+static void _f_scale_js2(uint32_t _ddr_mbps, uint32_t _ddr_mbpsdiv,
+			 uint16_t *_js2)
 {
 	int i;
 
 	for (i = 0; i < JS2_TBLCNT; i++) {
-		js2[i] = _f_scale(ddr_mbps, ddr_mbpsdiv,
+		_js2[i] = _f_scale(_ddr_mbps, _ddr_mbpsdiv,
 				  1UL * jedec_spec2[JS2_DERATE][i].ps,
 				  jedec_spec2[JS2_DERATE][i].cyc);
 	}
 
-	js2[js2_trcpb] = js2[js2_tras] + js2[js2_trppb];
-	js2[js2_trcab] = js2[js2_tras] + js2[js2_trpab];
+	_js2[js2_trcpb] = _js2[js2_tras] + _js2[js2_trppb];
+	_js2[js2_trcab] = _js2[js2_tras] + _js2[js2_trpab];
 }
 
 /* scaler for DELAY value */
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c
similarity index 100%
rename from drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c
rename to drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h
similarity index 100%
rename from drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h
rename to drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_b/ddr_b.mk b/drivers/renesas/rcar/ddr/ddr_b/ddr_b.mk
similarity index 64%
rename from drivers/staging/renesas/rcar/ddr/ddr_b/ddr_b.mk
rename to drivers/renesas/rcar/ddr/ddr_b/ddr_b.mk
index 875f953..2bcc292 100644
--- a/drivers/staging/renesas/rcar/ddr/ddr_b/ddr_b.mk
+++ b/drivers/renesas/rcar/ddr/ddr_b/ddr_b.mk
@@ -4,4 +4,4 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-BL2_SOURCES += drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram.c
+BL2_SOURCES += drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_b/ddr_regdef.h b/drivers/renesas/rcar/ddr/ddr_b/ddr_regdef.h
similarity index 100%
rename from drivers/staging/renesas/rcar/ddr/ddr_b/ddr_regdef.h
rename to drivers/renesas/rcar/ddr/ddr_b/ddr_regdef.h
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_h3.h b/drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_h3.h
similarity index 100%
rename from drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_h3.h
rename to drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_h3.h
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_h3ver2.h b/drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_h3ver2.h
similarity index 100%
rename from drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_h3ver2.h
rename to drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_h3ver2.h
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3.h b/drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3.h
similarity index 100%
rename from drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3.h
rename to drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3.h
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h b/drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h
similarity index 100%
rename from drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h
rename to drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_regs.h b/drivers/renesas/rcar/ddr/ddr_regs.h
similarity index 100%
rename from drivers/staging/renesas/rcar/ddr/ddr_regs.h
rename to drivers/renesas/rcar/ddr/ddr_regs.h
diff --git a/drivers/staging/renesas/rcar/ddr/dram_sub_func.c b/drivers/renesas/rcar/ddr/dram_sub_func.c
similarity index 100%
rename from drivers/staging/renesas/rcar/ddr/dram_sub_func.c
rename to drivers/renesas/rcar/ddr/dram_sub_func.c
diff --git a/drivers/staging/renesas/rcar/ddr/dram_sub_func.h b/drivers/renesas/rcar/ddr/dram_sub_func.h
similarity index 100%
rename from drivers/staging/renesas/rcar/ddr/dram_sub_func.h
rename to drivers/renesas/rcar/ddr/dram_sub_func.h
diff --git a/drivers/renesas/rcar/io/io_emmcdrv.c b/drivers/renesas/rcar/io/io_emmcdrv.c
index 4b464fb..84240d2 100644
--- a/drivers/renesas/rcar/io/io_emmcdrv.c
+++ b/drivers/renesas/rcar/io/io_emmcdrv.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -25,7 +25,7 @@
 typedef struct {
 	uint32_t in_use;
 	uintptr_t base;
-	ssize_t file_pos;
+	signed long long file_pos;
 	EMMC_PARTITION_ID partition;
 } file_state_t;
 
@@ -39,7 +39,7 @@
 }
 
 static int32_t emmcdrv_block_seek(io_entity_t *entity, int32_t mode,
-				  ssize_t offset)
+				  signed long long offset)
 {
 	if (mode != IO_SEEK_SET)
 		return IO_FAIL;
@@ -59,12 +59,12 @@
 	sector_add = current_file.file_pos >> EMMC_SECTOR_SIZE_SHIFT;
 	sector_num = (length + EMMC_SECTOR_SIZE - 1U) >> EMMC_SECTOR_SIZE_SHIFT;
 
-	NOTICE("BL2: Load dst=0x%lx src=(p:%d)0x%lx(%d) len=0x%lx(%d)\n",
+	NOTICE("BL2: Load dst=0x%lx src=(p:%d)0x%llx(%d) len=0x%lx(%d)\n",
 	       buffer,
 	       current_file.partition, current_file.file_pos,
 	       sector_add, length, sector_num);
 
-	if (buffer + length - 1 <= UINT32_MAX)
+	if ((buffer + length - 1U) <= (uintptr_t)UINT32_MAX)
 		emmc_dma = LOADIMAGE_FLAGS_DMA_ENABLE;
 
 	if (emmc_read_sector((uint32_t *) buffer, sector_add, sector_num,
@@ -72,7 +72,7 @@
 		result = IO_FAIL;
 
 	*length_read = length;
-	fp->file_pos += length;
+	fp->file_pos += (signed long long)length;
 
 	return result;
 }
@@ -82,7 +82,7 @@
 {
 	const io_drv_spec_t *block_spec = (io_drv_spec_t *) spec;
 
-	if (current_file.in_use) {
+	if (current_file.in_use != 0U) {
 		WARN("mmc_block: Only one open spec at a time\n");
 		return IO_RESOURCES_EXHAUSTED;
 	}
@@ -103,9 +103,9 @@
 		return IO_FAIL;
 	}
 
-	if (PARTITION_ID_USER == block_spec->partition ||
-	    PARTITION_ID_BOOT_1 == block_spec->partition ||
-	    PARTITION_ID_BOOT_2 == block_spec->partition)
+	if ((PARTITION_ID_USER == block_spec->partition) ||
+	    (PARTITION_ID_BOOT_1 == block_spec->partition) ||
+	    (PARTITION_ID_BOOT_2 == block_spec->partition))
 		current_file.partition = block_spec->partition;
 	else
 		current_file.partition = emmcdrv_bootpartition;
diff --git a/drivers/renesas/rcar/io/io_memdrv.c b/drivers/renesas/rcar/io/io_memdrv.c
index 3f6b4c7..7e8c1d3 100644
--- a/drivers/renesas/rcar/io/io_memdrv.c
+++ b/drivers/renesas/rcar/io/io_memdrv.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -28,7 +28,7 @@
 typedef struct {
 	uint32_t in_use;
 	uintptr_t base;
-	ssize_t file_pos;
+	signed long long file_pos;
 } file_state_t;
 
 static file_state_t current_file = { 0 };
@@ -47,7 +47,7 @@
 	 * spec at a time. When we have dynamic memory we can malloc and set
 	 * entity->info.
 	 */
-	if (current_file.in_use)
+	if (current_file.in_use != 0U)
 		return IO_RESOURCES_EXHAUSTED;
 
 	/* File cursor offset for seek and incremental reads etc. */
@@ -61,7 +61,7 @@
 }
 
 static int32_t memdrv_block_seek(io_entity_t *entity, int32_t mode,
-				 ssize_t offset)
+				 signed long long offset)
 {
 	if (mode != IO_SEEK_SET)
 		return IO_FAIL;
@@ -78,16 +78,17 @@
 
 	fp = (file_state_t *) entity->info;
 
-	NOTICE("BL2: dst=0x%lx src=0x%lx len=%ld(0x%lx)\n",
-	       buffer, fp->base + fp->file_pos, length, length);
+	NOTICE("BL2: dst=0x%lx src=0x%llx len=%ld(0x%lx)\n",
+	       buffer, (unsigned long long)fp->base +
+	       (unsigned long long)fp->file_pos, length, length);
 
-	if (FLASH_MEMORY_SIZE < fp->file_pos + length) {
+	if (FLASH_MEMORY_SIZE < (fp->file_pos + (signed long long)length)) {
 		ERROR("BL2: check load image (source address)\n");
 		return IO_FAIL;
 	}
 
-	rcar_dma_exec(buffer, fp->base + fp->file_pos, length);
-	fp->file_pos += length;
+	rcar_dma_exec(buffer, fp->base + (uintptr_t)fp->file_pos, length);
+	fp->file_pos += (signed long long)length;
 	*cnt = length;
 
 	return IO_SUCCESS;
diff --git a/drivers/renesas/rcar/io/io_rcar.c b/drivers/renesas/rcar/io/io_rcar.c
index 650931b..b82c510 100644
--- a/drivers/renesas/rcar/io/io_rcar.c
+++ b/drivers/renesas/rcar/io/io_rcar.c
@@ -28,9 +28,6 @@
 extern int32_t plat_get_drv_source(uint32_t id, uintptr_t *dev,
 				   uintptr_t *image_spec);
 
-extern int auth_mod_verify_img(unsigned int img_id, void *ptr,
-				unsigned int len);
-
 static int32_t rcar_dev_open(const uintptr_t dev_spec __attribute__ ((unused)),
 			     io_dev_info_t **dev_info);
 static int32_t rcar_dev_close(io_dev_info_t *dev_info);
diff --git a/drivers/st/fmc/stm32_fmc2_nand.c b/drivers/st/fmc/stm32_fmc2_nand.c
new file mode 100644
index 0000000..b694fff
--- /dev/null
+++ b/drivers/st/fmc/stm32_fmc2_nand.c
@@ -0,0 +1,877 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdint.h>
+
+#include <libfdt.h>
+
+#include <platform_def.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <drivers/raw_nand.h>
+#include <drivers/st/stm32_fmc2_nand.h>
+#include <drivers/st/stm32_gpio.h>
+#include <drivers/st/stm32mp_reset.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+
+/* FMC2 Compatibility */
+#define DT_FMC2_COMPAT			"st,stm32mp15-fmc2"
+#define MAX_CS				2U
+
+/* FMC2 Controller Registers */
+#define FMC2_BCR1			0x00U
+#define FMC2_PCR			0x80U
+#define FMC2_SR				0x84U
+#define FMC2_PMEM			0x88U
+#define FMC2_PATT			0x8CU
+#define FMC2_HECCR			0x94U
+#define FMC2_BCHISR			0x254U
+#define FMC2_BCHDSR0			0x27CU
+#define FMC2_BCHDSR1			0x280U
+#define FMC2_BCHDSR2			0x284U
+#define FMC2_BCHDSR3			0x288U
+#define FMC2_BCHDSR4			0x28CU
+
+/* FMC2_BCR1 register */
+#define FMC2_BCR1_FMC2EN		BIT(31)
+/* FMC2_PCR register */
+#define FMC2_PCR_PWAITEN		BIT(1)
+#define FMC2_PCR_PBKEN			BIT(2)
+#define FMC2_PCR_PWID_MASK		GENMASK_32(5, 4)
+#define FMC2_PCR_PWID(x)		(((x) << 4) & FMC2_PCR_PWID_MASK)
+#define FMC2_PCR_PWID_8			0x0U
+#define FMC2_PCR_PWID_16		0x1U
+#define FMC2_PCR_ECCEN			BIT(6)
+#define FMC2_PCR_ECCALG			BIT(8)
+#define FMC2_PCR_TCLR_MASK		GENMASK_32(12, 9)
+#define FMC2_PCR_TCLR(x)		(((x) << 9) & FMC2_PCR_TCLR_MASK)
+#define FMC2_PCR_TCLR_DEFAULT		0xFU
+#define FMC2_PCR_TAR_MASK		GENMASK_32(16, 13)
+#define FMC2_PCR_TAR(x)			(((x) << 13) & FMC2_PCR_TAR_MASK)
+#define FMC2_PCR_TAR_DEFAULT		0xFU
+#define FMC2_PCR_ECCSS_MASK		GENMASK_32(19, 17)
+#define FMC2_PCR_ECCSS(x)		(((x) << 17) & FMC2_PCR_ECCSS_MASK)
+#define FMC2_PCR_ECCSS_512		0x1U
+#define FMC2_PCR_ECCSS_2048		0x3U
+#define FMC2_PCR_BCHECC			BIT(24)
+#define FMC2_PCR_WEN			BIT(25)
+/* FMC2_SR register */
+#define FMC2_SR_NWRF			BIT(6)
+/* FMC2_PMEM register*/
+#define FMC2_PMEM_MEMSET(x)		(((x) & GENMASK_32(7, 0)) << 0)
+#define FMC2_PMEM_MEMWAIT(x)		(((x) & GENMASK_32(7, 0)) << 8)
+#define FMC2_PMEM_MEMHOLD(x)		(((x) & GENMASK_32(7, 0)) << 16)
+#define FMC2_PMEM_MEMHIZ(x)		(((x) & GENMASK_32(7, 0)) << 24)
+#define FMC2_PMEM_DEFAULT		0x0A0A0A0AU
+/* FMC2_PATT register */
+#define FMC2_PATT_ATTSET(x)		(((x) & GENMASK_32(7, 0)) << 0)
+#define FMC2_PATT_ATTWAIT(x)		(((x) & GENMASK_32(7, 0)) << 8)
+#define FMC2_PATT_ATTHOLD(x)		(((x) & GENMASK_32(7, 0)) << 16)
+#define FMC2_PATT_ATTHIZ(x)		(((x) & GENMASK_32(7, 0)) << 24)
+#define FMC2_PATT_DEFAULT		0x0A0A0A0AU
+/* FMC2_BCHISR register */
+#define FMC2_BCHISR_DERF		BIT(1)
+/* FMC2_BCHDSR0 register */
+#define FMC2_BCHDSR0_DUE		BIT(0)
+#define FMC2_BCHDSR0_DEF		BIT(1)
+#define FMC2_BCHDSR0_DEN_MASK		GENMASK_32(7, 4)
+#define FMC2_BCHDSR0_DEN_SHIFT		4U
+/* FMC2_BCHDSR1 register */
+#define FMC2_BCHDSR1_EBP1_MASK		GENMASK_32(12, 0)
+#define FMC2_BCHDSR1_EBP2_MASK		GENMASK_32(28, 16)
+#define FMC2_BCHDSR1_EBP2_SHIFT		16U
+/* FMC2_BCHDSR2 register */
+#define FMC2_BCHDSR2_EBP3_MASK		GENMASK_32(12, 0)
+#define FMC2_BCHDSR2_EBP4_MASK		GENMASK_32(28, 16)
+#define FMC2_BCHDSR2_EBP4_SHIFT		16U
+/* FMC2_BCHDSR3 register */
+#define FMC2_BCHDSR3_EBP5_MASK		GENMASK_32(12, 0)
+#define FMC2_BCHDSR3_EBP6_MASK		GENMASK_32(28, 16)
+#define FMC2_BCHDSR3_EBP6_SHIFT		16U
+/* FMC2_BCHDSR4 register */
+#define FMC2_BCHDSR4_EBP7_MASK		GENMASK_32(12, 0)
+#define FMC2_BCHDSR4_EBP8_MASK		GENMASK_32(28, 16)
+#define FMC2_BCHDSR4_EBP8_SHIFT		16U
+
+/* Timings */
+#define FMC2_THIZ			0x01U
+#define FMC2_TIO			8000U
+#define FMC2_TSYNC			3000U
+#define FMC2_PCR_TIMING_MASK		GENMASK_32(3, 0)
+#define FMC2_PMEM_PATT_TIMING_MASK	GENMASK_32(7, 0)
+
+#define FMC2_BBM_LEN			2U
+#define FMC2_MAX_ECC_BYTES		14U
+#define TIMEOUT_US_10_MS		10000U
+#define FMC2_PSEC_PER_MSEC		(1000UL * 1000UL * 1000UL)
+
+enum stm32_fmc2_ecc {
+	FMC2_ECC_HAM = 1U,
+	FMC2_ECC_BCH4 = 4U,
+	FMC2_ECC_BCH8 = 8U
+};
+
+struct stm32_fmc2_cs_reg {
+	uintptr_t data_base;
+	uintptr_t cmd_base;
+	uintptr_t addr_base;
+};
+
+struct stm32_fmc2_nand_timings {
+	uint8_t tclr;
+	uint8_t tar;
+	uint8_t thiz;
+	uint8_t twait;
+	uint8_t thold_mem;
+	uint8_t tset_mem;
+	uint8_t thold_att;
+	uint8_t tset_att;
+};
+
+struct stm32_fmc2_nfc {
+	uintptr_t reg_base;
+	struct stm32_fmc2_cs_reg cs[MAX_CS];
+	unsigned long clock_id;
+	unsigned int reset_id;
+	uint8_t cs_sel;
+};
+
+static struct stm32_fmc2_nfc stm32_fmc2;
+
+static uintptr_t fmc2_base(void)
+{
+	return stm32_fmc2.reg_base;
+}
+
+static void stm32_fmc2_nand_setup_timing(void)
+{
+	struct stm32_fmc2_nand_timings tims;
+	unsigned long hclk = stm32mp_clk_get_rate(stm32_fmc2.clock_id);
+	unsigned long hclkp = FMC2_PSEC_PER_MSEC / (hclk / 1000U);
+	unsigned long timing, tar, tclr, thiz, twait;
+	unsigned long tset_mem, tset_att, thold_mem, thold_att;
+	uint32_t pcr, pmem, patt;
+
+	tar = MAX(hclkp, NAND_TAR_MIN);
+	timing = div_round_up(tar, hclkp) - 1U;
+	tims.tar = MIN(timing, (unsigned long)FMC2_PCR_TIMING_MASK);
+
+	tclr = MAX(hclkp, NAND_TCLR_MIN);
+	timing = div_round_up(tclr, hclkp) - 1U;
+	tims.tclr = MIN(timing, (unsigned long)FMC2_PCR_TIMING_MASK);
+
+	tims.thiz = FMC2_THIZ;
+	thiz = (tims.thiz + 1U) * hclkp;
+
+	/*
+	 * tWAIT > tRP
+	 * tWAIT > tWP
+	 * tWAIT > tREA + tIO
+	 */
+	twait = MAX(hclkp, NAND_TRP_MIN);
+	twait = MAX(twait, NAND_TWP_MIN);
+	twait = MAX(twait, NAND_TREA_MAX + FMC2_TIO);
+	timing = div_round_up(twait, hclkp);
+	tims.twait = CLAMP(timing, 1UL,
+			   (unsigned long)FMC2_PMEM_PATT_TIMING_MASK);
+
+	/*
+	 * tSETUP_MEM > tCS - tWAIT
+	 * tSETUP_MEM > tALS - tWAIT
+	 * tSETUP_MEM > tDS - (tWAIT - tHIZ)
+	 */
+	tset_mem = hclkp;
+	if ((twait < NAND_TCS_MIN) && (tset_mem < (NAND_TCS_MIN - twait))) {
+		tset_mem = NAND_TCS_MIN - twait;
+	}
+	if ((twait < NAND_TALS_MIN) && (tset_mem < (NAND_TALS_MIN - twait))) {
+		tset_mem = NAND_TALS_MIN - twait;
+	}
+	if ((twait > thiz) && ((twait - thiz) < NAND_TDS_MIN) &&
+	    (tset_mem < (NAND_TDS_MIN - (twait - thiz)))) {
+		tset_mem = NAND_TDS_MIN - (twait - thiz);
+	}
+	timing = div_round_up(tset_mem, hclkp);
+	tims.tset_mem = CLAMP(timing, 1UL,
+			      (unsigned long)FMC2_PMEM_PATT_TIMING_MASK);
+
+	/*
+	 * tHOLD_MEM > tCH
+	 * tHOLD_MEM > tREH - tSETUP_MEM
+	 * tHOLD_MEM > max(tRC, tWC) - (tSETUP_MEM + tWAIT)
+	 */
+	thold_mem = MAX(hclkp, NAND_TCH_MIN);
+	if ((tset_mem < NAND_TREH_MIN) &&
+	    (thold_mem < (NAND_TREH_MIN - tset_mem))) {
+		thold_mem = NAND_TREH_MIN - tset_mem;
+	}
+	if (((tset_mem + twait) < NAND_TRC_MIN) &&
+	    (thold_mem < (NAND_TRC_MIN - (tset_mem + twait)))) {
+		thold_mem = NAND_TRC_MIN  - (tset_mem + twait);
+	}
+	if (((tset_mem + twait) < NAND_TWC_MIN) &&
+	    (thold_mem < (NAND_TWC_MIN - (tset_mem + twait)))) {
+		thold_mem = NAND_TWC_MIN - (tset_mem + twait);
+	}
+	timing = div_round_up(thold_mem, hclkp);
+	tims.thold_mem = CLAMP(timing, 1UL,
+			       (unsigned long)FMC2_PMEM_PATT_TIMING_MASK);
+
+	/*
+	 * tSETUP_ATT > tCS - tWAIT
+	 * tSETUP_ATT > tCLS - tWAIT
+	 * tSETUP_ATT > tALS - tWAIT
+	 * tSETUP_ATT > tRHW - tHOLD_MEM
+	 * tSETUP_ATT > tDS - (tWAIT - tHIZ)
+	 */
+	tset_att = hclkp;
+	if ((twait < NAND_TCS_MIN) && (tset_att < (NAND_TCS_MIN - twait))) {
+		tset_att = NAND_TCS_MIN - twait;
+	}
+	if ((twait < NAND_TCLS_MIN) && (tset_att < (NAND_TCLS_MIN - twait))) {
+		tset_att = NAND_TCLS_MIN - twait;
+	}
+	if ((twait < NAND_TALS_MIN) && (tset_att < (NAND_TALS_MIN - twait))) {
+		tset_att = NAND_TALS_MIN - twait;
+	}
+	if ((thold_mem < NAND_TRHW_MIN) &&
+	    (tset_att < (NAND_TRHW_MIN - thold_mem))) {
+		tset_att = NAND_TRHW_MIN - thold_mem;
+	}
+	if ((twait > thiz) && ((twait - thiz) < NAND_TDS_MIN) &&
+	    (tset_att < (NAND_TDS_MIN - (twait - thiz)))) {
+		tset_att = NAND_TDS_MIN - (twait - thiz);
+	}
+	timing = div_round_up(tset_att, hclkp);
+	tims.tset_att = CLAMP(timing, 1UL,
+			      (unsigned long)FMC2_PMEM_PATT_TIMING_MASK);
+
+	/*
+	 * tHOLD_ATT > tALH
+	 * tHOLD_ATT > tCH
+	 * tHOLD_ATT > tCLH
+	 * tHOLD_ATT > tCOH
+	 * tHOLD_ATT > tDH
+	 * tHOLD_ATT > tWB + tIO + tSYNC - tSETUP_MEM
+	 * tHOLD_ATT > tADL - tSETUP_MEM
+	 * tHOLD_ATT > tWH - tSETUP_MEM
+	 * tHOLD_ATT > tWHR - tSETUP_MEM
+	 * tHOLD_ATT > tRC - (tSETUP_ATT + tWAIT)
+	 * tHOLD_ATT > tWC - (tSETUP_ATT + tWAIT)
+	 */
+	thold_att = MAX(hclkp, NAND_TALH_MIN);
+	thold_att = MAX(thold_att, NAND_TCH_MIN);
+	thold_att = MAX(thold_att, NAND_TCLH_MIN);
+	thold_att = MAX(thold_att, NAND_TCOH_MIN);
+	thold_att = MAX(thold_att, NAND_TDH_MIN);
+	if (((NAND_TWB_MAX + FMC2_TIO + FMC2_TSYNC) > tset_mem) &&
+	    (thold_att < (NAND_TWB_MAX + FMC2_TIO + FMC2_TSYNC - tset_mem))) {
+		thold_att = NAND_TWB_MAX + FMC2_TIO + FMC2_TSYNC - tset_mem;
+	}
+	if ((tset_mem < NAND_TADL_MIN) &&
+	    (thold_att < (NAND_TADL_MIN - tset_mem))) {
+		thold_att = NAND_TADL_MIN - tset_mem;
+	}
+	if ((tset_mem < NAND_TWH_MIN) &&
+	    (thold_att < (NAND_TWH_MIN - tset_mem))) {
+		thold_att = NAND_TWH_MIN - tset_mem;
+	}
+	if ((tset_mem < NAND_TWHR_MIN) &&
+	    (thold_att < (NAND_TWHR_MIN - tset_mem))) {
+		thold_att = NAND_TWHR_MIN - tset_mem;
+	}
+	if (((tset_att + twait) < NAND_TRC_MIN) &&
+	    (thold_att < (NAND_TRC_MIN - (tset_att + twait)))) {
+		thold_att = NAND_TRC_MIN - (tset_att + twait);
+	}
+	if (((tset_att + twait) < NAND_TWC_MIN) &&
+	    (thold_att < (NAND_TWC_MIN - (tset_att + twait)))) {
+		thold_att = NAND_TWC_MIN - (tset_att + twait);
+	}
+	timing = div_round_up(thold_att, hclkp);
+	tims.thold_att = CLAMP(timing, 1UL,
+			       (unsigned long)FMC2_PMEM_PATT_TIMING_MASK);
+
+	VERBOSE("NAND timings: %u - %u - %u - %u - %u - %u - %u - %u\n",
+		tims.tclr, tims.tar, tims.thiz, tims.twait,
+		tims.thold_mem, tims.tset_mem,
+		tims.thold_att, tims.tset_att);
+
+	/* Set tclr/tar timings */
+	pcr = mmio_read_32(fmc2_base() + FMC2_PCR);
+	pcr &= ~FMC2_PCR_TCLR_MASK;
+	pcr |= FMC2_PCR_TCLR(tims.tclr);
+	pcr &= ~FMC2_PCR_TAR_MASK;
+	pcr |= FMC2_PCR_TAR(tims.tar);
+
+	/* Set tset/twait/thold/thiz timings in common bank */
+	pmem = FMC2_PMEM_MEMSET(tims.tset_mem);
+	pmem |= FMC2_PMEM_MEMWAIT(tims.twait);
+	pmem |=	FMC2_PMEM_MEMHOLD(tims.thold_mem);
+	pmem |= FMC2_PMEM_MEMHIZ(tims.thiz);
+
+	/* Set tset/twait/thold/thiz timings in attribute bank */
+	patt = FMC2_PATT_ATTSET(tims.tset_att);
+	patt |= FMC2_PATT_ATTWAIT(tims.twait);
+	patt |= FMC2_PATT_ATTHOLD(tims.thold_att);
+	patt |= FMC2_PATT_ATTHIZ(tims.thiz);
+
+	mmio_write_32(fmc2_base() + FMC2_PCR, pcr);
+	mmio_write_32(fmc2_base() + FMC2_PMEM, pmem);
+	mmio_write_32(fmc2_base() + FMC2_PATT, patt);
+}
+
+static void stm32_fmc2_set_buswidth_16(bool set)
+{
+	mmio_clrsetbits_32(fmc2_base() + FMC2_PCR, FMC2_PCR_PWID_MASK,
+			   (set ? FMC2_PCR_PWID(FMC2_PCR_PWID_16) : 0U));
+}
+
+static void stm32_fmc2_set_ecc(bool enable)
+{
+	mmio_clrsetbits_32(fmc2_base() + FMC2_PCR, FMC2_PCR_ECCEN,
+			   (enable ? FMC2_PCR_ECCEN : 0U));
+}
+
+static int stm32_fmc2_ham_correct(uint8_t *buffer, uint8_t *eccbuffer,
+				  uint8_t *ecc)
+{
+	uint8_t xor_ecc_ones;
+	uint16_t xor_ecc_1b, xor_ecc_2b, xor_ecc_3b;
+	union {
+		uint32_t val;
+		uint8_t  bytes[4];
+	} xor_ecc;
+
+	/* Page size--------ECC_Code Size
+	 * 256---------------22 bits LSB  (ECC_CODE & 0x003FFFFF)
+	 * 512---------------24 bits      (ECC_CODE & 0x00FFFFFF)
+	 * 1024--------------26 bits      (ECC_CODE & 0x03FFFFFF)
+	 * 2048--------------28 bits      (ECC_CODE & 0x0FFFFFFF)
+	 * 4096--------------30 bits      (ECC_CODE & 0x3FFFFFFF)
+	 * 8192--------------32 bits      (ECC_CODE & 0xFFFFFFFF)
+	 */
+
+	/* For Page size 512, ECC_Code size 24 bits */
+	xor_ecc_1b = ecc[0] ^ eccbuffer[0];
+	xor_ecc_2b = ecc[1] ^ eccbuffer[1];
+	xor_ecc_3b = ecc[2] ^ eccbuffer[2];
+
+	xor_ecc.val = 0L;
+	xor_ecc.bytes[2] = xor_ecc_3b;
+	xor_ecc.bytes[1] = xor_ecc_2b;
+	xor_ecc.bytes[0] = xor_ecc_1b;
+
+	if (xor_ecc.val == 0U) {
+		return 0; /* No Error */
+	}
+
+	xor_ecc_ones = __builtin_popcount(xor_ecc.val);
+	if (xor_ecc_ones < 23U) {
+		if (xor_ecc_ones == 12U) {
+			uint16_t bit_address, byte_address;
+
+			/* Correctable ERROR */
+			bit_address = ((xor_ecc_1b >> 1) & BIT(0)) |
+				      ((xor_ecc_1b >> 2) & BIT(1)) |
+				      ((xor_ecc_1b >> 3) & BIT(2));
+
+			byte_address = ((xor_ecc_1b >> 7) & BIT(0)) |
+				       ((xor_ecc_2b) & BIT(1)) |
+				       ((xor_ecc_2b >> 1) & BIT(2)) |
+				       ((xor_ecc_2b >> 2) & BIT(3)) |
+				       ((xor_ecc_2b >> 3) & BIT(4)) |
+				       ((xor_ecc_3b << 4) & BIT(5)) |
+				       ((xor_ecc_3b << 3) & BIT(6)) |
+				       ((xor_ecc_3b << 2) & BIT(7)) |
+				       ((xor_ecc_3b << 1) & BIT(8));
+
+			/* Correct bit error in the data */
+			buffer[byte_address] =
+				buffer[byte_address] ^ BIT(bit_address);
+			VERBOSE("Hamming: 1 ECC error corrected\n");
+
+			return 0;
+		}
+
+		/* Non Correctable ERROR */
+		ERROR("%s: Uncorrectable ECC Errors\n", __func__);
+		return -1;
+	}
+
+	/* ECC ERROR */
+	ERROR("%s: Hamming correction error\n", __func__);
+	return -1;
+}
+
+
+static int stm32_fmc2_ham_calculate(uint8_t *buffer, uint8_t *ecc)
+{
+	uint32_t heccr;
+	uint64_t timeout = timeout_init_us(TIMEOUT_US_10_MS);
+
+	while ((mmio_read_32(fmc2_base() + FMC2_SR) & FMC2_SR_NWRF) == 0U) {
+		if (timeout_elapsed(timeout)) {
+			return -ETIMEDOUT;
+		}
+	}
+
+	heccr = mmio_read_32(fmc2_base() + FMC2_HECCR);
+
+	ecc[0] = heccr;
+	ecc[1] = heccr >> 8;
+	ecc[2] = heccr >> 16;
+
+	/* Disable ECC */
+	stm32_fmc2_set_ecc(false);
+
+	return 0;
+}
+
+static int stm32_fmc2_bch_correct(uint8_t *buffer, unsigned int eccsize)
+{
+	uint32_t bchdsr0, bchdsr1, bchdsr2, bchdsr3, bchdsr4;
+	uint16_t pos[8];
+	int i, den;
+	uint64_t timeout = timeout_init_us(TIMEOUT_US_10_MS);
+
+	while ((mmio_read_32(fmc2_base() + FMC2_BCHISR) &
+		FMC2_BCHISR_DERF) == 0U) {
+		if (timeout_elapsed(timeout)) {
+			return -ETIMEDOUT;
+		}
+	}
+
+	bchdsr0 = mmio_read_32(fmc2_base() + FMC2_BCHDSR0);
+	bchdsr1 = mmio_read_32(fmc2_base() + FMC2_BCHDSR1);
+	bchdsr2 = mmio_read_32(fmc2_base() + FMC2_BCHDSR2);
+	bchdsr3 = mmio_read_32(fmc2_base() + FMC2_BCHDSR3);
+	bchdsr4 = mmio_read_32(fmc2_base() + FMC2_BCHDSR4);
+
+	/* Disable ECC */
+	stm32_fmc2_set_ecc(false);
+
+	/* No error found */
+	if ((bchdsr0 & FMC2_BCHDSR0_DEF) == 0U) {
+		return 0;
+	}
+
+	/* Too many errors detected */
+	if ((bchdsr0 & FMC2_BCHDSR0_DUE) != 0U) {
+		return -EBADMSG;
+	}
+
+	pos[0] = bchdsr1 & FMC2_BCHDSR1_EBP1_MASK;
+	pos[1] = (bchdsr1 & FMC2_BCHDSR1_EBP2_MASK) >> FMC2_BCHDSR1_EBP2_SHIFT;
+	pos[2] = bchdsr2 & FMC2_BCHDSR2_EBP3_MASK;
+	pos[3] = (bchdsr2 & FMC2_BCHDSR2_EBP4_MASK) >> FMC2_BCHDSR2_EBP4_SHIFT;
+	pos[4] = bchdsr3 & FMC2_BCHDSR3_EBP5_MASK;
+	pos[5] = (bchdsr3 & FMC2_BCHDSR3_EBP6_MASK) >> FMC2_BCHDSR3_EBP6_SHIFT;
+	pos[6] = bchdsr4 & FMC2_BCHDSR4_EBP7_MASK;
+	pos[7] = (bchdsr4 & FMC2_BCHDSR4_EBP8_MASK) >> FMC2_BCHDSR4_EBP8_SHIFT;
+
+	den = (bchdsr0 & FMC2_BCHDSR0_DEN_MASK) >> FMC2_BCHDSR0_DEN_SHIFT;
+	for (i = 0; i < den; i++) {
+		if (pos[i] < (eccsize * 8U)) {
+			uint8_t bitmask = BIT(pos[i] % 8U);
+			uint32_t offset = pos[i] / 8U;
+
+			*(buffer + offset) ^= bitmask;
+		}
+	}
+
+	return 0;
+}
+
+static void stm32_fmc2_hwctl(struct nand_device *nand)
+{
+	stm32_fmc2_set_ecc(false);
+
+	if (nand->ecc.max_bit_corr != FMC2_ECC_HAM) {
+		mmio_clrbits_32(fmc2_base() + FMC2_PCR, FMC2_PCR_WEN);
+	}
+
+	stm32_fmc2_set_ecc(true);
+}
+
+static int stm32_fmc2_read_page(struct nand_device *nand,
+				unsigned int page, uintptr_t buffer)
+{
+	unsigned int eccsize = nand->ecc.size;
+	unsigned int eccbytes = nand->ecc.bytes;
+	unsigned int eccsteps = nand->page_size / eccsize;
+	uint8_t ecc_corr[FMC2_MAX_ECC_BYTES];
+	uint8_t ecc_cal[FMC2_MAX_ECC_BYTES] = {0U};
+	uint8_t *p;
+	unsigned int i;
+	unsigned int s;
+	int ret;
+
+	VERBOSE(">%s page %i buffer %lx\n", __func__, page, buffer);
+
+	ret = nand_read_page_cmd(page, 0U, 0U, 0U);
+	if (ret != 0) {
+		return ret;
+	}
+
+	for (s = 0U, i = nand->page_size + FMC2_BBM_LEN, p = (uint8_t *)buffer;
+	     s < eccsteps;
+	     s++, i += eccbytes, p += eccsize) {
+		stm32_fmc2_hwctl(nand);
+
+		/* Read the NAND page sector (512 bytes) */
+		ret = nand_change_read_column_cmd(s * eccsize, (uintptr_t)p,
+						  eccsize);
+		if (ret != 0) {
+			return ret;
+		}
+
+		if (nand->ecc.max_bit_corr == FMC2_ECC_HAM) {
+			ret = stm32_fmc2_ham_calculate(p, ecc_cal);
+			if (ret != 0) {
+				return ret;
+			}
+		}
+
+		/* Read the corresponding ECC bytes */
+		ret = nand_change_read_column_cmd(i, (uintptr_t)ecc_corr,
+						  eccbytes);
+		if (ret != 0) {
+			return ret;
+		}
+
+		/* Correct the data */
+		if (nand->ecc.max_bit_corr == FMC2_ECC_HAM) {
+			ret = stm32_fmc2_ham_correct(p, ecc_corr, ecc_cal);
+		} else {
+			ret = stm32_fmc2_bch_correct(p, eccsize);
+		}
+
+		if (ret != 0) {
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static void stm32_fmc2_read_data(struct nand_device *nand,
+				 uint8_t *buff, unsigned int length,
+				 bool use_bus8)
+{
+	uintptr_t data_base = stm32_fmc2.cs[stm32_fmc2.cs_sel].data_base;
+
+	if (use_bus8 && (nand->buswidth == NAND_BUS_WIDTH_16)) {
+		stm32_fmc2_set_buswidth_16(false);
+	}
+
+	if ((((uintptr_t)buff & BIT(0)) != 0U) && (length != 0U)) {
+		*buff = mmio_read_8(data_base);
+		buff += sizeof(uint8_t);
+		length -= sizeof(uint8_t);
+	}
+
+	if ((((uintptr_t)buff & GENMASK_32(1, 0)) != 0U) &&
+	    (length >= sizeof(uint16_t))) {
+		*(uint16_t *)buff = mmio_read_16(data_base);
+		buff += sizeof(uint16_t);
+		length -= sizeof(uint16_t);
+	}
+
+	/* 32bit aligned */
+	while (length >= sizeof(uint32_t)) {
+		*(uint32_t *)buff = mmio_read_32(data_base);
+		buff += sizeof(uint32_t);
+		length -= sizeof(uint32_t);
+	}
+
+	/* Read remaining bytes */
+	if (length >= sizeof(uint16_t)) {
+		*(uint16_t *)buff = mmio_read_16(data_base);
+		buff += sizeof(uint16_t);
+		length -= sizeof(uint16_t);
+	}
+
+	if (length != 0U) {
+		*buff = mmio_read_8(data_base);
+	}
+
+	if (use_bus8 && (nand->buswidth == NAND_BUS_WIDTH_16)) {
+		/* Reconfigure bus width to 16-bit */
+		stm32_fmc2_set_buswidth_16(true);
+	}
+}
+
+static void stm32_fmc2_write_data(struct nand_device *nand,
+				  uint8_t *buff, unsigned int length,
+				  bool use_bus8)
+{
+	uintptr_t data_base = stm32_fmc2.cs[stm32_fmc2.cs_sel].data_base;
+
+	if (use_bus8 && (nand->buswidth == NAND_BUS_WIDTH_16)) {
+		/* Reconfigure bus width to 8-bit */
+		stm32_fmc2_set_buswidth_16(false);
+	}
+
+	if ((((uintptr_t)buff & BIT(0)) != 0U) && (length != 0U)) {
+		mmio_write_8(data_base, *buff);
+		buff += sizeof(uint8_t);
+		length -= sizeof(uint8_t);
+	}
+
+	if ((((uintptr_t)buff & GENMASK_32(1, 0)) != 0U) &&
+	    (length >= sizeof(uint16_t))) {
+		mmio_write_16(data_base, *(uint16_t *)buff);
+		buff += sizeof(uint16_t);
+		length -= sizeof(uint16_t);
+	}
+
+	/* 32bits aligned */
+	while (length >= sizeof(uint32_t)) {
+		mmio_write_32(data_base, *(uint32_t *)buff);
+		buff += sizeof(uint32_t);
+		length -= sizeof(uint32_t);
+	}
+
+	/* Read remaining bytes */
+	if (length >= sizeof(uint16_t)) {
+		mmio_write_16(data_base, *(uint16_t *)buff);
+		buff += sizeof(uint16_t);
+		length -= sizeof(uint16_t);
+	}
+
+	if (length != 0U) {
+		mmio_write_8(data_base, *buff);
+	}
+
+	if (use_bus8 && (nand->buswidth == NAND_BUS_WIDTH_16)) {
+		/* Reconfigure bus width to 16-bit */
+		stm32_fmc2_set_buswidth_16(true);
+	}
+}
+
+static void stm32_fmc2_ctrl_init(void)
+{
+	uint32_t pcr = mmio_read_32(fmc2_base() + FMC2_PCR);
+	uint32_t bcr1 = mmio_read_32(fmc2_base() + FMC2_BCR1);
+
+	/* Enable wait feature and NAND flash memory bank */
+	pcr |= FMC2_PCR_PWAITEN;
+	pcr |= FMC2_PCR_PBKEN;
+
+	/* Set buswidth to 8 bits mode for identification */
+	pcr &= ~FMC2_PCR_PWID_MASK;
+
+	/* ECC logic is disabled */
+	pcr &= ~FMC2_PCR_ECCEN;
+
+	/* Default mode */
+	pcr &= ~FMC2_PCR_ECCALG;
+	pcr &= ~FMC2_PCR_BCHECC;
+	pcr &= ~FMC2_PCR_WEN;
+
+	/* Set default ECC sector size */
+	pcr &= ~FMC2_PCR_ECCSS_MASK;
+	pcr |= FMC2_PCR_ECCSS(FMC2_PCR_ECCSS_2048);
+
+	/* Set default TCLR/TAR timings */
+	pcr &= ~FMC2_PCR_TCLR_MASK;
+	pcr |= FMC2_PCR_TCLR(FMC2_PCR_TCLR_DEFAULT);
+	pcr &= ~FMC2_PCR_TAR_MASK;
+	pcr |= FMC2_PCR_TAR(FMC2_PCR_TAR_DEFAULT);
+
+	/* Enable FMC2 controller */
+	bcr1 |= FMC2_BCR1_FMC2EN;
+
+	mmio_write_32(fmc2_base() + FMC2_BCR1, bcr1);
+	mmio_write_32(fmc2_base() + FMC2_PCR, pcr);
+	mmio_write_32(fmc2_base() + FMC2_PMEM, FMC2_PMEM_DEFAULT);
+	mmio_write_32(fmc2_base() + FMC2_PATT, FMC2_PATT_DEFAULT);
+}
+
+static int stm32_fmc2_exec(struct nand_req *req)
+{
+	int ret = 0;
+
+	switch (req->type & NAND_REQ_MASK) {
+	case NAND_REQ_CMD:
+		VERBOSE("Write CMD %x\n", (uint8_t)req->type);
+		mmio_write_8(stm32_fmc2.cs[stm32_fmc2.cs_sel].cmd_base,
+			     (uint8_t)req->type);
+		break;
+	case NAND_REQ_ADDR:
+		VERBOSE("Write ADDR %x\n", *(req->addr));
+		mmio_write_8(stm32_fmc2.cs[stm32_fmc2.cs_sel].addr_base,
+			     *(req->addr));
+		break;
+	case NAND_REQ_DATAIN:
+		VERBOSE("Read data\n");
+		stm32_fmc2_read_data(req->nand, req->addr, req->length,
+				     ((req->type & NAND_REQ_BUS_WIDTH_8) !=
+				      0U));
+		break;
+	case NAND_REQ_DATAOUT:
+		VERBOSE("Write data\n");
+		stm32_fmc2_write_data(req->nand, req->addr, req->length,
+				      ((req->type & NAND_REQ_BUS_WIDTH_8) !=
+				      0U));
+		break;
+	case NAND_REQ_WAIT:
+		VERBOSE("WAIT Ready\n");
+		ret = nand_wait_ready(req->delay_ms);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	};
+
+	return ret;
+}
+
+static void stm32_fmc2_setup(struct nand_device *nand)
+{
+	uint32_t pcr = mmio_read_32(fmc2_base() + FMC2_PCR);
+
+	/* Set buswidth */
+	pcr &= ~FMC2_PCR_PWID_MASK;
+	if (nand->buswidth == NAND_BUS_WIDTH_16) {
+		pcr |= FMC2_PCR_PWID(FMC2_PCR_PWID_16);
+	}
+
+	if (nand->ecc.mode == NAND_ECC_HW) {
+		nand->mtd_read_page = stm32_fmc2_read_page;
+
+		pcr &= ~FMC2_PCR_ECCALG;
+		pcr &= ~FMC2_PCR_BCHECC;
+
+		pcr &= ~FMC2_PCR_ECCSS_MASK;
+		pcr |= FMC2_PCR_ECCSS(FMC2_PCR_ECCSS_512);
+
+		switch (nand->ecc.max_bit_corr) {
+		case FMC2_ECC_HAM:
+			nand->ecc.bytes = 3;
+			break;
+		case FMC2_ECC_BCH8:
+			pcr |= FMC2_PCR_ECCALG;
+			pcr |= FMC2_PCR_BCHECC;
+			nand->ecc.bytes = 13;
+			break;
+		default:
+			/* Use FMC2 ECC BCH4 */
+			pcr |= FMC2_PCR_ECCALG;
+			nand->ecc.bytes = 7;
+			break;
+		}
+
+		if ((nand->buswidth & NAND_BUS_WIDTH_16) != 0) {
+			nand->ecc.bytes++;
+		}
+	}
+
+	mmio_write_32(stm32_fmc2.reg_base + FMC2_PCR, pcr);
+}
+
+static const struct nand_ctrl_ops ctrl_ops = {
+	.setup = stm32_fmc2_setup,
+	.exec = stm32_fmc2_exec
+};
+
+int stm32_fmc2_init(void)
+{
+	int fmc_node;
+	int fmc_subnode = 0;
+	int nchips = 0;
+	unsigned int i;
+	void *fdt = NULL;
+	const fdt32_t *cuint;
+	struct dt_node_info info;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	fmc_node = dt_get_node(&info, -1, DT_FMC2_COMPAT);
+	if (fmc_node == -FDT_ERR_NOTFOUND) {
+		WARN("No FMC2 node found\n");
+		return fmc_node;
+	}
+
+	if (info.status == DT_DISABLED) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	stm32_fmc2.reg_base = info.base;
+
+	if ((info.clock < 0) || (info.reset < 0)) {
+		return -FDT_ERR_BADVALUE;
+	}
+
+	stm32_fmc2.clock_id = (unsigned long)info.clock;
+	stm32_fmc2.reset_id = (unsigned int)info.reset;
+
+	cuint = fdt_getprop(fdt, fmc_node, "reg", NULL);
+	if (cuint == NULL) {
+		return -FDT_ERR_BADVALUE;
+	}
+
+	cuint += 2;
+
+	for (i = 0U; i < MAX_CS; i++) {
+		stm32_fmc2.cs[i].data_base = fdt32_to_cpu(*cuint);
+		stm32_fmc2.cs[i].cmd_base = fdt32_to_cpu(*(cuint + 2));
+		stm32_fmc2.cs[i].addr_base = fdt32_to_cpu(*(cuint + 4));
+		cuint += 6;
+	}
+
+	/* Pinctrl initialization */
+	if (dt_set_pinctrl_config(fmc_node) != 0) {
+		return -FDT_ERR_BADVALUE;
+	}
+
+	/* Parse flash nodes */
+	fdt_for_each_subnode(fmc_subnode, fdt, fmc_node) {
+		nchips++;
+	}
+
+	if (nchips != 1) {
+		WARN("Only one SLC NAND device supported\n");
+		return -FDT_ERR_BADVALUE;
+	}
+
+	fdt_for_each_subnode(fmc_subnode, fdt, fmc_node) {
+		/* Get chip select */
+		cuint = fdt_getprop(fdt, fmc_subnode, "reg", NULL);
+		if (cuint == NULL) {
+			WARN("Chip select not well defined\n");
+			return -FDT_ERR_BADVALUE;
+		}
+		stm32_fmc2.cs_sel = fdt32_to_cpu(*cuint);
+		VERBOSE("NAND CS %i\n", stm32_fmc2.cs_sel);
+	}
+
+	/* Enable Clock */
+	stm32mp_clk_enable(stm32_fmc2.clock_id);
+
+	/* Reset IP */
+	stm32mp_reset_assert(stm32_fmc2.reset_id);
+	stm32mp_reset_deassert(stm32_fmc2.reset_id);
+
+	/* Setup default IP registers */
+	stm32_fmc2_ctrl_init();
+
+	/* Setup default timings */
+	stm32_fmc2_nand_setup_timing();
+
+	/* Init NAND RAW framework */
+	nand_raw_ctrl_init(&ctrl_ops);
+
+	return 0;
+}
diff --git a/drivers/st/io/io_mmc.c b/drivers/st/io/io_mmc.c
index a239b5f..44b7d19 100644
--- a/drivers/st/io/io_mmc.c
+++ b/drivers/st/io/io_mmc.c
@@ -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
  */
@@ -20,14 +20,15 @@
 static int mmc_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
 			  io_entity_t *entity);
 static int mmc_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params);
-static int mmc_block_seek(io_entity_t *entity, int mode, ssize_t offset);
+static int mmc_block_seek(io_entity_t *entity, int mode,
+			  signed long long offset);
 static int mmc_block_read(io_entity_t *entity, uintptr_t buffer, size_t length,
 			  size_t *length_read);
 static int mmc_block_close(io_entity_t *entity);
 static int mmc_dev_close(io_dev_info_t *dev_info);
 static io_type_t device_type_mmc(void);
 
-static ssize_t seek_offset;
+static signed long long seek_offset;
 
 static const io_dev_connector_t mmc_dev_connector = {
 	.dev_open = mmc_dev_open
@@ -85,7 +86,8 @@
 }
 
 /* Seek to a particular file offset on the mmc device */
-static int mmc_block_seek(io_entity_t *entity, int mode, ssize_t offset)
+static int mmc_block_seek(io_entity_t *entity, int mode,
+			  signed long long offset)
 {
 	seek_offset = offset;
 	return 0;
diff --git a/drivers/st/spi/stm32_qspi.c b/drivers/st/spi/stm32_qspi.c
new file mode 100644
index 0000000..188d2ff
--- /dev/null
+++ b/drivers/st/spi/stm32_qspi.c
@@ -0,0 +1,500 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#include <libfdt.h>
+
+#include <platform_def.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <drivers/spi_mem.h>
+#include <drivers/st/stm32_gpio.h>
+#include <drivers/st/stm32mp_reset.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+
+/* QUADSPI registers */
+#define QSPI_CR			0x00U
+#define QSPI_DCR		0x04U
+#define QSPI_SR			0x08U
+#define QSPI_FCR		0x0CU
+#define QSPI_DLR		0x10U
+#define QSPI_CCR		0x14U
+#define QSPI_AR			0x18U
+#define QSPI_ABR		0x1CU
+#define QSPI_DR			0x20U
+#define QSPI_PSMKR		0x24U
+#define QSPI_PSMAR		0x28U
+#define QSPI_PIR		0x2CU
+#define QSPI_LPTR		0x30U
+
+/* QUADSPI control register */
+#define QSPI_CR_EN		BIT(0)
+#define QSPI_CR_ABORT		BIT(1)
+#define QSPI_CR_DMAEN		BIT(2)
+#define QSPI_CR_TCEN		BIT(3)
+#define QSPI_CR_SSHIFT		BIT(4)
+#define QSPI_CR_DFM		BIT(6)
+#define QSPI_CR_FSEL		BIT(7)
+#define QSPI_CR_FTHRES_SHIFT	8U
+#define QSPI_CR_TEIE		BIT(16)
+#define QSPI_CR_TCIE		BIT(17)
+#define QSPI_CR_FTIE		BIT(18)
+#define QSPI_CR_SMIE		BIT(19)
+#define QSPI_CR_TOIE		BIT(20)
+#define QSPI_CR_APMS		BIT(22)
+#define QSPI_CR_PMM		BIT(23)
+#define QSPI_CR_PRESCALER_MASK	GENMASK_32(31, 24)
+#define QSPI_CR_PRESCALER_SHIFT	24U
+
+/* QUADSPI device configuration register */
+#define QSPI_DCR_CKMODE		BIT(0)
+#define QSPI_DCR_CSHT_MASK	GENMASK_32(10, 8)
+#define QSPI_DCR_CSHT_SHIFT	8U
+#define QSPI_DCR_FSIZE_MASK	GENMASK_32(20, 16)
+#define QSPI_DCR_FSIZE_SHIFT	16U
+
+/* QUADSPI status register */
+#define QSPI_SR_TEF		BIT(0)
+#define QSPI_SR_TCF		BIT(1)
+#define QSPI_SR_FTF		BIT(2)
+#define QSPI_SR_SMF		BIT(3)
+#define QSPI_SR_TOF		BIT(4)
+#define QSPI_SR_BUSY		BIT(5)
+
+/* QUADSPI flag clear register */
+#define QSPI_FCR_CTEF		BIT(0)
+#define QSPI_FCR_CTCF		BIT(1)
+#define QSPI_FCR_CSMF		BIT(3)
+#define QSPI_FCR_CTOF		BIT(4)
+
+/* QUADSPI communication configuration register */
+#define QSPI_CCR_DDRM		BIT(31)
+#define QSPI_CCR_DHHC		BIT(30)
+#define QSPI_CCR_SIOO		BIT(28)
+#define QSPI_CCR_FMODE_SHIFT	26U
+#define QSPI_CCR_DMODE_SHIFT	24U
+#define QSPI_CCR_DCYC_SHIFT	18U
+#define QSPI_CCR_ABSIZE_SHIFT	16U
+#define QSPI_CCR_ABMODE_SHIFT	14U
+#define QSPI_CCR_ADSIZE_SHIFT	12U
+#define QSPI_CCR_ADMODE_SHIFT	10U
+#define QSPI_CCR_IMODE_SHIFT	8U
+#define QSPI_CCR_IND_WRITE	0U
+#define QSPI_CCR_IND_READ	1U
+#define QSPI_CCR_MEM_MAP	3U
+
+#define QSPI_MAX_CHIP		2U
+
+#define QSPI_FIFO_TIMEOUT_US	30U
+#define QSPI_CMD_TIMEOUT_US	1000U
+#define QSPI_BUSY_TIMEOUT_US	100U
+#define QSPI_ABT_TIMEOUT_US	100U
+
+#define DT_QSPI_COMPAT		"st,stm32f469-qspi"
+
+#define FREQ_100MHZ		100000000U
+
+struct stm32_qspi_ctrl {
+	uintptr_t reg_base;
+	uintptr_t mm_base;
+	size_t mm_size;
+	unsigned long clock_id;
+	unsigned int reset_id;
+};
+
+static struct stm32_qspi_ctrl stm32_qspi;
+
+static uintptr_t qspi_base(void)
+{
+	return stm32_qspi.reg_base;
+}
+
+static int stm32_qspi_wait_for_not_busy(void)
+{
+	uint64_t timeout = timeout_init_us(QSPI_BUSY_TIMEOUT_US);
+
+	while ((mmio_read_32(qspi_base() + QSPI_SR) & QSPI_SR_BUSY) != 0U) {
+		if (timeout_elapsed(timeout)) {
+			ERROR("%s: busy timeout\n", __func__);
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static int stm32_qspi_wait_cmd(const struct spi_mem_op *op)
+{
+	int ret = 0;
+	uint64_t timeout;
+
+	if (op->data.nbytes == 0U) {
+		return stm32_qspi_wait_for_not_busy();
+	}
+
+	timeout = timeout_init_us(QSPI_CMD_TIMEOUT_US);
+	while ((mmio_read_32(qspi_base() + QSPI_SR) & QSPI_SR_TCF) == 0U) {
+		if (timeout_elapsed(timeout)) {
+			ret = -ETIMEDOUT;
+			break;
+		}
+	}
+
+	if (ret == 0) {
+		if ((mmio_read_32(qspi_base() + QSPI_SR) & QSPI_SR_TEF) != 0U) {
+			ERROR("%s: transfer error\n", __func__);
+			ret = -EIO;
+		}
+	} else {
+		ERROR("%s: cmd timeout\n", __func__);
+	}
+
+	/* Clear flags */
+	mmio_write_32(qspi_base() + QSPI_FCR, QSPI_FCR_CTCF | QSPI_FCR_CTEF);
+
+	return ret;
+}
+
+static void stm32_qspi_read_fifo(uint8_t *val, uintptr_t addr)
+{
+	*val = mmio_read_8(addr);
+}
+
+static void stm32_qspi_write_fifo(uint8_t *val, uintptr_t addr)
+{
+	mmio_write_8(addr, *val);
+}
+
+static int stm32_qspi_poll(const struct spi_mem_op *op)
+{
+	void (*fifo)(uint8_t *val, uintptr_t addr);
+	uint32_t len = op->data.nbytes;
+	uint8_t *buf;
+	uint64_t timeout;
+
+	if (op->data.dir == SPI_MEM_DATA_IN) {
+		fifo = stm32_qspi_read_fifo;
+	} else {
+		fifo = stm32_qspi_write_fifo;
+	}
+
+	buf = (uint8_t *)op->data.buf;
+
+	for (len = op->data.nbytes; len != 0U; len--) {
+		timeout = timeout_init_us(QSPI_FIFO_TIMEOUT_US);
+		while ((mmio_read_32(qspi_base() + QSPI_SR) &
+			QSPI_SR_FTF) == 0U) {
+			if (timeout_elapsed(timeout)) {
+				ERROR("%s: fifo timeout\n", __func__);
+				return -ETIMEDOUT;
+			}
+		}
+
+		fifo(buf++, qspi_base() + QSPI_DR);
+	}
+
+	return 0;
+}
+
+static int stm32_qspi_mm(const struct spi_mem_op *op)
+{
+	memcpy(op->data.buf,
+	       (void *)(stm32_qspi.mm_base + (size_t)op->addr.val),
+	       op->data.nbytes);
+
+	return 0;
+}
+
+static int stm32_qspi_tx(const struct spi_mem_op *op, uint8_t mode)
+{
+	if (op->data.nbytes == 0U) {
+		return 0;
+	}
+
+	if (mode == QSPI_CCR_MEM_MAP) {
+		return stm32_qspi_mm(op);
+	}
+
+	return stm32_qspi_poll(op);
+}
+
+static unsigned int stm32_qspi_get_mode(uint8_t buswidth)
+{
+	if (buswidth == 4U) {
+		return 3U;
+	}
+
+	return buswidth;
+}
+
+static int stm32_qspi_exec_op(const struct spi_mem_op *op)
+{
+	uint64_t timeout;
+	uint32_t ccr;
+	size_t addr_max;
+	uint8_t mode = QSPI_CCR_IND_WRITE;
+	int ret;
+
+	VERBOSE("%s: cmd:%x mode:%d.%d.%d.%d addr:%llx len:%x\n",
+		__func__, op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth,
+		op->dummy.buswidth, op->data.buswidth,
+		op->addr.val, op->data.nbytes);
+
+	ret = stm32_qspi_wait_for_not_busy();
+	if (ret != 0) {
+		return ret;
+	}
+
+	addr_max = op->addr.val + op->data.nbytes + 1U;
+
+	if ((op->data.dir == SPI_MEM_DATA_IN) && (op->data.nbytes != 0U)) {
+		if ((addr_max < stm32_qspi.mm_size) &&
+		    (op->addr.buswidth != 0U)) {
+			mode = QSPI_CCR_MEM_MAP;
+		} else {
+			mode = QSPI_CCR_IND_READ;
+		}
+	}
+
+	if (op->data.nbytes != 0U) {
+		mmio_write_32(qspi_base() + QSPI_DLR, op->data.nbytes - 1U);
+	}
+
+	ccr = mode << QSPI_CCR_FMODE_SHIFT;
+	ccr |= op->cmd.opcode;
+	ccr |= stm32_qspi_get_mode(op->cmd.buswidth) << QSPI_CCR_IMODE_SHIFT;
+
+	if (op->addr.nbytes != 0U) {
+		ccr |= (op->addr.nbytes - 1U) << QSPI_CCR_ADSIZE_SHIFT;
+		ccr |= stm32_qspi_get_mode(op->addr.buswidth) <<
+			QSPI_CCR_ADMODE_SHIFT;
+	}
+
+	if ((op->dummy.buswidth != 0U) && (op->dummy.nbytes != 0U)) {
+		ccr |= (op->dummy.nbytes * 8U / op->dummy.buswidth) <<
+			QSPI_CCR_DCYC_SHIFT;
+	}
+
+	if (op->data.nbytes != 0U) {
+		ccr |= stm32_qspi_get_mode(op->data.buswidth) <<
+			QSPI_CCR_DMODE_SHIFT;
+	}
+
+	mmio_write_32(qspi_base() + QSPI_CCR, ccr);
+
+	if ((op->addr.nbytes != 0U) && (mode != QSPI_CCR_MEM_MAP)) {
+		mmio_write_32(qspi_base() + QSPI_AR, op->addr.val);
+	}
+
+	ret = stm32_qspi_tx(op, mode);
+
+	/*
+	 * Abort in:
+	 * - Error case.
+	 * - Memory mapped read: prefetching must be stopped if we read the last
+	 *   byte of device (device size - fifo size). If device size is not
+	 *   known then prefetching is always stopped.
+	 */
+	if ((ret != 0) || (mode == QSPI_CCR_MEM_MAP)) {
+		goto abort;
+	}
+
+	/* Wait end of TX in indirect mode */
+	ret = stm32_qspi_wait_cmd(op);
+	if (ret != 0) {
+		goto abort;
+	}
+
+	return 0;
+
+abort:
+	mmio_setbits_32(qspi_base() + QSPI_CR, QSPI_CR_ABORT);
+
+	/* Wait clear of abort bit by hardware */
+	timeout = timeout_init_us(QSPI_ABT_TIMEOUT_US);
+	while ((mmio_read_32(qspi_base() + QSPI_CR) & QSPI_CR_ABORT) != 0U) {
+		if (timeout_elapsed(timeout)) {
+			ret = -ETIMEDOUT;
+			break;
+		}
+	}
+
+	mmio_write_32(qspi_base() + QSPI_FCR, QSPI_FCR_CTCF);
+
+	if (ret != 0) {
+		ERROR("%s: exec op error\n", __func__);
+	}
+
+	return ret;
+}
+
+static int stm32_qspi_claim_bus(unsigned int cs)
+{
+	uint32_t cr;
+
+	if (cs >= QSPI_MAX_CHIP) {
+		return -ENODEV;
+	}
+
+	/* Set chip select and enable the controller */
+	cr = QSPI_CR_EN;
+	if (cs == 1U) {
+		cr |= QSPI_CR_FSEL;
+	}
+
+	mmio_clrsetbits_32(qspi_base() + QSPI_CR, QSPI_CR_FSEL, cr);
+
+	return 0;
+}
+
+static void stm32_qspi_release_bus(void)
+{
+	mmio_clrbits_32(qspi_base() + QSPI_CR, QSPI_CR_EN);
+}
+
+static int stm32_qspi_set_speed(unsigned int hz)
+{
+	unsigned long qspi_clk = stm32mp_clk_get_rate(stm32_qspi.clock_id);
+	uint32_t prescaler = UINT8_MAX;
+	uint32_t csht;
+	int ret;
+
+	if (qspi_clk == 0U) {
+		return -EINVAL;
+	}
+
+	if (hz > 0U) {
+		prescaler = div_round_up(qspi_clk, hz) - 1U;
+		if (prescaler > UINT8_MAX) {
+			prescaler = UINT8_MAX;
+		}
+	}
+
+	csht = div_round_up((5U * qspi_clk) / (prescaler + 1U), FREQ_100MHZ);
+	csht = ((csht - 1U) << QSPI_DCR_CSHT_SHIFT) & QSPI_DCR_CSHT_MASK;
+
+	ret = stm32_qspi_wait_for_not_busy();
+	if (ret != 0) {
+		return ret;
+	}
+
+	mmio_clrsetbits_32(qspi_base() + QSPI_CR, QSPI_CR_PRESCALER_MASK,
+			   prescaler << QSPI_CR_PRESCALER_SHIFT);
+
+	mmio_clrsetbits_32(qspi_base() + QSPI_DCR, QSPI_DCR_CSHT_MASK, csht);
+
+	VERBOSE("%s: speed=%lu\n", __func__, qspi_clk / (prescaler + 1U));
+
+	return 0;
+}
+
+static int stm32_qspi_set_mode(unsigned int mode)
+{
+	int ret;
+
+	ret = stm32_qspi_wait_for_not_busy();
+	if (ret != 0) {
+		return ret;
+	}
+
+	if ((mode & SPI_CS_HIGH) != 0U) {
+		return -ENODEV;
+	}
+
+	if (((mode & SPI_CPHA) != 0U) && ((mode & SPI_CPOL) != 0U)) {
+		mmio_setbits_32(qspi_base() + QSPI_DCR, QSPI_DCR_CKMODE);
+	} else if (((mode & SPI_CPHA) == 0U) && ((mode & SPI_CPOL) == 0U)) {
+		mmio_clrbits_32(qspi_base() + QSPI_DCR, QSPI_DCR_CKMODE);
+	} else {
+		return -ENODEV;
+	}
+
+	VERBOSE("%s: mode=0x%x\n", __func__, mode);
+
+	if ((mode & SPI_RX_QUAD) != 0U) {
+		VERBOSE("rx: quad\n");
+	} else if ((mode & SPI_RX_DUAL) != 0U) {
+		VERBOSE("rx: dual\n");
+	} else {
+		VERBOSE("rx: single\n");
+	}
+
+	if ((mode & SPI_TX_QUAD) != 0U) {
+		VERBOSE("tx: quad\n");
+	} else if ((mode & SPI_TX_DUAL) != 0U) {
+		VERBOSE("tx: dual\n");
+	} else {
+		VERBOSE("tx: single\n");
+	}
+
+	return 0;
+}
+
+static const struct spi_bus_ops stm32_qspi_bus_ops = {
+	.claim_bus = stm32_qspi_claim_bus,
+	.release_bus = stm32_qspi_release_bus,
+	.set_speed = stm32_qspi_set_speed,
+	.set_mode = stm32_qspi_set_mode,
+	.exec_op = stm32_qspi_exec_op,
+};
+
+int stm32_qspi_init(void)
+{
+	size_t size;
+	int qspi_node;
+	struct dt_node_info info;
+	void *fdt = NULL;
+	int ret;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	qspi_node = dt_get_node(&info, -1, DT_QSPI_COMPAT);
+	if (qspi_node < 0) {
+		ERROR("No QSPI ctrl found\n");
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	if (info.status == DT_DISABLED) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	ret = fdt_get_reg_props_by_name(qspi_node, "qspi",
+					&stm32_qspi.reg_base, &size);
+	if (ret != 0) {
+		return ret;
+	}
+
+	ret = fdt_get_reg_props_by_name(qspi_node, "qspi_mm",
+					&stm32_qspi.mm_base,
+					&stm32_qspi.mm_size);
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (dt_set_pinctrl_config(qspi_node) != 0) {
+		return -FDT_ERR_BADVALUE;
+	}
+
+	if ((info.clock < 0) || (info.reset < 0)) {
+		return -FDT_ERR_BADVALUE;
+	}
+
+	stm32_qspi.clock_id = (unsigned long)info.clock;
+	stm32_qspi.reset_id = (unsigned int)info.reset;
+
+	stm32mp_clk_enable(stm32_qspi.clock_id);
+
+	stm32mp_reset_assert(stm32_qspi.reset_id);
+	stm32mp_reset_deassert(stm32_qspi.reset_id);
+
+	mmio_write_32(qspi_base() + QSPI_CR, QSPI_CR_SSHIFT);
+	mmio_write_32(qspi_base() + QSPI_DCR, QSPI_DCR_FSIZE_MASK);
+
+	return spi_mem_init_slave(fdt, qspi_node, &stm32_qspi_bus_ops);
+};
diff --git a/drivers/staging/renesas/rcar/ddr/ddr.mk b/drivers/staging/renesas/rcar/ddr/ddr.mk
deleted file mode 100644
index ed7adc3..0000000
--- a/drivers/staging/renesas/rcar/ddr/ddr.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-ifeq (${RCAR_LSI},${RCAR_E3})
-    include drivers/staging/renesas/rcar/ddr/ddr_a/ddr_a.mk
-    BL2_SOURCES += drivers/staging/renesas/rcar/ddr/dram_sub_func.c
-else ifeq (${RCAR_LSI},${RCAR_D3})
-    include drivers/staging/renesas/rcar/ddr/ddr_a/ddr_a.mk
-else ifeq (${RCAR_LSI},${RCAR_V3M})
-    include drivers/staging/renesas/rcar/ddr/ddr_a/ddr_a.mk
-else
-    include drivers/staging/renesas/rcar/ddr/ddr_b/ddr_b.mk
-    BL2_SOURCES += drivers/staging/renesas/rcar/ddr/dram_sub_func.c
-endif
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_a/ddr_a.mk b/drivers/staging/renesas/rcar/ddr/ddr_a/ddr_a.mk
deleted file mode 100644
index aee27a5..0000000
--- a/drivers/staging/renesas/rcar/ddr/ddr_a/ddr_a.mk
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-ifeq (${RCAR_LSI},${RCAR_E3})
-BL2_SOURCES += drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_e3.c
-else ifeq (${RCAR_LSI},${RCAR_D3})
-BL2_SOURCES += drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_d3.c
-else
-BL2_SOURCES += drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_v3m.c
-endif
diff --git a/drivers/ti/uart/aarch32/16550_console.S b/drivers/ti/uart/aarch32/16550_console.S
index 6921884..5cd9b30 100644
--- a/drivers/ti/uart/aarch32/16550_console.S
+++ b/drivers/ti/uart/aarch32/16550_console.S
@@ -89,16 +89,19 @@
 	.globl console_16550_register
 
 	/* -------------------------------------------------------
-	 * int console_stm32_register(uintptr_t baseaddr,
+	 * int console_16550_register(uintptr_t baseaddr,
 	 *     uint32_t clock, uint32_t baud,
-	 *     struct console_stm32 *console);
-	 * Function to initialize and register a new STM32
+	 *     console_16550_t *console);
+	 * Function to initialize and register a new 16550
 	 * console. Storage passed in for the console struct
 	 * *must* be persistent (i.e. not from the stack).
+	 * If r1 (UART clock) is 0, initialisation will be
+         * skipped, relying on previous code to have done
+         * this already. r2 is ignored then as well.
 	 * In: r0 - UART register base address
 	 *     r1 - UART clock in Hz
-	 *     r2 - Baud rate
-	 *     r3 - pointer to empty console_stm32 struct
+	 *     r2 - Baud rate (ignored if r1 is 0)
+	 *     r3 - pointer to empty console_16550_t struct
 	 * Out: return 1 on success, 0 on error
 	 * Clobber list : r0, r1, r2
 	 * -------------------------------------------------------
@@ -110,10 +113,15 @@
 	beq	register_fail
 	str	r0, [r4, #CONSOLE_T_16550_BASE]
 
+	/* A clock rate of zero means to skip the initialisation. */
+	cmp	r1, #0
+	beq	register_16550
+
 	bl	console_16550_core_init
 	cmp	r0, #0
 	beq	register_fail
 
+register_16550:
 	mov	r0, r4
 	pop	{r4, lr}
 	finish_console_register 16550 putc=1, getc=1, flush=1
diff --git a/drivers/ti/uart/aarch64/16550_console.S b/drivers/ti/uart/aarch64/16550_console.S
index dab46e8..80c1b86 100644
--- a/drivers/ti/uart/aarch64/16550_console.S
+++ b/drivers/ti/uart/aarch64/16550_console.S
@@ -92,9 +92,12 @@
 	 * Function to initialize and register a new 16550
 	 * console. Storage passed in for the console struct
 	 * *must* be persistent (i.e. not from the stack).
+	 * If w1 (UART clock) is 0, initialisation will be
+	 * skipped, relying on previous code to have done
+	 * this already. w2 is ignored then as well.
 	 * In: x0 - UART register base address
 	 *     w1 - UART clock in Hz
-	 *     w2 - Baud rate
+	 *     w2 - Baud rate (ignored if w1 is 0)
 	 *     x3 - pointer to empty console_16550_t struct
 	 * Out: return 1 on success, 0 on error
 	 * Clobber list : x0, x1, x2, x6, x7, x14
@@ -106,9 +109,13 @@
 	cbz	x6, register_fail
 	str	x0, [x6, #CONSOLE_T_16550_BASE]
 
+	/* A clock rate of zero means to skip the initialisation. */
+	cbz	w1, register_16550
+
 	bl	console_16550_core_init
 	cbz	x0, register_fail
 
+register_16550:
 	mov	x0, x6
 	mov	x30, x7
 	finish_console_register 16550 putc=1, getc=1, flush=1
diff --git a/fdts/a5ds.dts b/fdts/a5ds.dts
index 91212e8..31d635a 100644
--- a/fdts/a5ds.dts
+++ b/fdts/a5ds.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,29 +22,30 @@
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
+		enable-method = "psci";
 		cpu@0 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a5";
-			enable-method = "psci";
 			reg = <0>;
+			next-level-cache = <&L2>;
 		};
 		cpu@1 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a5";
-			enable-method = "psci";
 			reg = <1>;
+			next-level-cache = <&L2>;
 		};
 		cpu@2 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a5";
-			enable-method = "psci";
 			reg = <2>;
+			next-level-cache = <&L2>;
 		};
 		cpu@3 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a5";
-			enable-method = "psci";
 			reg = <3>;
+			next-level-cache = <&L2>;
 		};
 	};
 
@@ -53,10 +54,27 @@
 		reg = <0x80000000 0x7F000000>;
 	};
 
-	refclk100mhz: refclk100mhz {
+	L2: cache-controller@1C010000 {
+		compatible = "arm,pl310-cache";
+		reg = <0x1C010000 0x1000>;
+		interrupts = <0 84 4>;
+		cache-level = <2>;
+		cache-unified;
+		arm,data-latency = <1 1 1>;
+		arm,tag-latency = <1 1 1>;
+	};
+
+	refclk7500khz: refclk7500khz {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <7500000>;
+		clock-output-names = "apb_pclk";
+	};
+
+	refclk24mhz: refclk24mhz {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
-		clock-frequency = <100000000>;
+		clock-frequency = <24000000>;
 		clock-output-names = "apb_pclk";
 	};
 
@@ -71,7 +89,7 @@
 	rtc@1a220000 {
 		compatible = "arm,pl031", "arm,primecell";
 		reg = <0x1a220000 0x1000>;
-		clocks = <&refclk100mhz>;
+		clocks = <&refclk24mhz>;
 		interrupts = <0 6 0xf04>;
 		clock-names = "apb_pclk";
 	};
@@ -91,7 +109,7 @@
 		reg = <0x1a200000 0x1000>;
 		interrupt-parent = <&gic>;
 		interrupts = <0 8 0xf04>;
-		clocks = <&refclk100mhz>;
+		clocks = <&refclk7500khz>;
 		clock-names = "apb_pclk";
 	};
 
@@ -100,7 +118,7 @@
 		reg = <0x1a210000 0x1000>;
 		interrupt-parent = <&gic>;
 		interrupts = <0 9 0xf04>;
-		clocks = <&refclk100mhz>;
+		clocks = <&refclk7500khz>;
 		clock-names = "apb_pclk";
 	};
 
diff --git a/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts b/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts
new file mode 100644
index 0000000..f35eaf4
--- /dev/null
+++ b/fdts/fvp-base-gicv3-psci-dynamiq-2t.dts
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/include/ "fvp-base-gicv3-psci-common.dtsi"
+
+&CPU0 {
+	reg = <0x0 0x0>;
+};
+
+&CPU1 {
+	reg = <0x0 0x1>;
+};
+
+&CPU2 {
+	reg = <0x0 0x100>;
+};
+
+&CPU3 {
+	reg = <0x0 0x101>;
+};
+
+&CPU4 {
+	reg = <0x0 0x200>;
+};
+
+&CPU5 {
+	reg = <0x0 0x201>;
+};
+
+&CPU6 {
+	reg = <0x0 0x300>;
+};
+
+&CPU7 {
+	reg = <0x0 0x301>;
+};
diff --git a/fdts/stm32mp157-pinctrl.dtsi b/fdts/stm32mp157-pinctrl.dtsi
index 8e480b2..7fd902b 100644
--- a/fdts/stm32mp157-pinctrl.dtsi
+++ b/fdts/stm32mp157-pinctrl.dtsi
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
- * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
+ * Copyright (C) STMicroelectronics 2017-2019 - All Rights Reserved
  * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
  */
 #include <dt-bindings/pinctrl/stm32-pinfunc.h>
@@ -135,6 +135,31 @@
 				status = "disabled";
 			};
 
+			fmc_pins_a: fmc-0 {
+				pins1 {
+					pinmux = <STM32_PINMUX('D', 4, AF12)>, /* FMC_NOE */
+						 <STM32_PINMUX('D', 5, AF12)>, /* FMC_NWE */
+						 <STM32_PINMUX('D', 11, AF12)>, /* FMC_A16_FMC_CLE */
+						 <STM32_PINMUX('D', 12, AF12)>, /* FMC_A17_FMC_ALE */
+						 <STM32_PINMUX('D', 14, AF12)>, /* FMC_D0 */
+						 <STM32_PINMUX('D', 15, AF12)>, /* FMC_D1 */
+						 <STM32_PINMUX('D', 0, AF12)>, /* FMC_D2 */
+						 <STM32_PINMUX('D', 1, AF12)>, /* FMC_D3 */
+						 <STM32_PINMUX('E', 7, AF12)>, /* FMC_D4 */
+						 <STM32_PINMUX('E', 8, AF12)>, /* FMC_D5 */
+						 <STM32_PINMUX('E', 9, AF12)>, /* FMC_D6 */
+						 <STM32_PINMUX('E', 10, AF12)>, /* FMC_D7 */
+						 <STM32_PINMUX('G', 9, AF12)>; /* FMC_NE2_FMC_NCE */
+					bias-disable;
+					drive-push-pull;
+					slew-rate = <1>;
+				};
+				pins2 {
+					pinmux = <STM32_PINMUX('D', 6, AF12)>; /* FMC_NWAIT */
+					bias-pull-up;
+				};
+			};
+
 			qspi_bk1_pins_a: qspi-bk1-0 {
 				pins1 {
 					pinmux = <STM32_PINMUX('F', 8, AF10)>, /* QSPI_BK1_IO0 */
diff --git a/fdts/stm32mp157c-ev1.dts b/fdts/stm32mp157c-ev1.dts
index cfde8ed..50c0b93 100644
--- a/fdts/stm32mp157c-ev1.dts
+++ b/fdts/stm32mp157c-ev1.dts
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 /*
- * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
+ * Copyright (C) STMicroelectronics 2017-2019 - All Rights Reserved
  * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
  */
 /dts-v1/;
@@ -21,21 +21,20 @@
 };
 
 &fmc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&fmc_pins_a>;
 	status = "okay";
 	#address-cells = <1>;
 	#size-cells = <0>;
 
 	nand: nand@0 {
 		reg = <0>;
-		nand-on-flash-bbt;
-		#address-cells = <1>;
-		#size-cells = <1>;
 	};
 };
 
 &qspi {
 	pinctrl-names = "default";
-	pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a &qspi_bk2_pins_a>;
+	pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a>;
 	reg = <0x58003000 0x1000>, <0x70000000 0x4000000>;
 	#address-cells = <1>;
 	#size-cells = <0>;
@@ -49,15 +48,6 @@
 		#address-cells = <1>;
 		#size-cells = <1>;
 	};
-
-	flash1: mx66l51235l@1 {
-		compatible = "jedec,spi-nor";
-		reg = <1>;
-		spi-rx-bus-width = <4>;
-		spi-max-frequency = <108000000>;
-		#address-cells = <1>;
-		#size-cells = <1>;
-	};
 };
 
 &usart3 {
diff --git a/include/arch/aarch32/smccc_helpers.h b/include/arch/aarch32/smccc_helpers.h
index b2ee3cf..2ce7874 100644
--- a/include/arch/aarch32/smccc_helpers.h
+++ b/include/arch/aarch32/smccc_helpers.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -130,6 +130,22 @@
 	((smc_ctx_t *)(_h))->r3 = (_r3);	\
 	SMC_RET3(_h, (_r0), (_r1), (_r2));	\
 }
+#define SMC_RET5(_h, _r0, _r1, _r2, _r3, _r4) {	\
+	((smc_ctx_t *)(_h))->r4 = (_r4);	\
+	SMC_RET4(_h, (_r0), (_r1), (_r2), (_r3));	\
+}
+#define SMC_RET6(_h, _r0, _r1, _r2, _r3, _r4, _r5) {	\
+	((smc_ctx_t *)(_h))->r5 = (_r5);	\
+	SMC_RET5(_h, (_r0), (_r1), (_r2), (_r3), (_r4));	\
+}
+#define SMC_RET7(_h, _r0, _r1, _r2, _r3, _r4, _r5, _r6) {	\
+	((smc_ctx_t *)(_h))->r6 = (_r6);	\
+	SMC_RET6(_h, (_r0), (_r1), (_r2), (_r3), (_r4), (_r5));	\
+}
+#define SMC_RET8(_h, _r0, _r1, _r2, _r3, _r4, _r5, _r6, _r7) {	\
+	((smc_ctx_t *)(_h))->r7 = (_r7);	\
+	SMC_RET7(_h, (_r0), (_r1), (_r2), (_r3), (_r4), (_r5), (_r6));	\
+}
 
 /*
  * Helper macro to retrieve the SMC parameters from smc_ctx_t.
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 3ff2912..1fcd0f9 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -140,6 +140,8 @@
 #define ID_AA64PFR0_GIC_MASK	ULL(0xf)
 #define ID_AA64PFR0_SVE_SHIFT	U(32)
 #define ID_AA64PFR0_SVE_MASK	ULL(0xf)
+#define ID_AA64PFR0_SEL2_SHIFT	U(36)
+#define ID_AA64PFR0_SEL2_MASK	ULL(0xf)
 #define ID_AA64PFR0_MPAM_SHIFT	U(40)
 #define ID_AA64PFR0_MPAM_MASK	ULL(0xf)
 #define ID_AA64PFR0_DIT_SHIFT	U(48)
@@ -285,6 +287,7 @@
 #define SCR_RES1_BITS		((U(1) << 4) | (U(1) << 5))
 #define SCR_ATA_BIT		(U(1) << 26)
 #define SCR_FIEN_BIT		(U(1) << 21)
+#define SCR_EEL2_BIT		(U(1) << 18)
 #define SCR_API_BIT		(U(1) << 17)
 #define SCR_APK_BIT		(U(1) << 16)
 #define SCR_TWE_BIT		(U(1) << 13)
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index 378e827..156b18a 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -232,11 +232,18 @@
  *
  * _exception_vectors:
  *	Address of the exception vectors to program in the VBAR_EL3 register.
+ *
+ * _pie_fixup_size:
+ *	Size of memory region to fixup Global Descriptor Table (GDT).
+ *
+ *	A non-zero value is expected when firmware needs GDT to be fixed-up.
+ *
  * -----------------------------------------------------------------------------
  */
 	.macro el3_entrypoint_common					\
 		_init_sctlr, _warm_boot_mailbox, _secondary_cold_boot,	\
-		_init_memory, _init_c_runtime, _exception_vectors
+		_init_memory, _init_c_runtime, _exception_vectors,	\
+		_pie_fixup_size
 
 	.if \_init_sctlr
 		/* -------------------------------------------------------------
@@ -283,6 +290,26 @@
 	do_cold_boot:
 	.endif /* _warm_boot_mailbox */
 
+	.if \_pie_fixup_size
+#if ENABLE_PIE
+		/*
+		 * ------------------------------------------------------------
+		 * If PIE is enabled fixup the Global descriptor Table only
+		 * once during primary core cold boot path.
+		 *
+		 * Compile time base address, required for fixup, is calculated
+		 * using "pie_fixup" label present within first page.
+		 * ------------------------------------------------------------
+		 */
+	pie_fixup:
+		ldr	x0, =pie_fixup
+		and	x0, x0, #~(PAGE_SIZE - 1)
+		mov_imm	x1, \_pie_fixup_size
+		add	x1, x1, x0
+		bl	fixup_gdt_reloc
+#endif /* ENABLE_PIE */
+	.endif /* _pie_fixup_size */
+
 	/* ---------------------------------------------------------------------
 	 * Set the exception vectors.
 	 * ---------------------------------------------------------------------
@@ -355,6 +382,14 @@
 		add	x1, x1, :lo12:__RW_END__
 		sub	x1, x1, x0
 		bl	inv_dcache_range
+#if defined(IMAGE_BL31) && SEPARATE_NOBITS_REGION
+		adrp	x0, __NOBITS_START__
+		add	x0, x0, :lo12:__NOBITS_START__
+		adrp	x1, __NOBITS_END__
+		add	x1, x1, :lo12:__NOBITS_END__
+		sub	x1, x1, x0
+		bl	inv_dcache_range
+#endif
 #endif
 		adrp	x0, __BSS_START__
 		add	x0, x0, :lo12:__BSS_START__
diff --git a/include/drivers/allwinner/axp.h b/include/drivers/allwinner/axp.h
new file mode 100644
index 0000000..9c0035f
--- /dev/null
+++ b/include/drivers/allwinner/axp.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef AXP_H
+#define AXP_H
+
+#include <stdint.h>
+
+#define NA 0xff
+
+enum {
+	AXP803_CHIP_ID = 0x41,
+	AXP805_CHIP_ID = 0x40,
+};
+
+struct axp_regulator {
+	const char *dt_name;
+	uint16_t min_volt;
+	uint16_t max_volt;
+	uint16_t step;
+	unsigned char split;
+	unsigned char volt_reg;
+	unsigned char switch_reg;
+	unsigned char switch_bit;
+};
+
+extern const uint8_t axp_chip_id;
+extern const char *const axp_compatible;
+extern const struct axp_regulator axp_regulators[];
+
+/*
+ * Since the PMIC can be connected to multiple bus types,
+ * low-level read/write functions must be provided by the platform
+ */
+int axp_read(uint8_t reg);
+int axp_write(uint8_t reg, uint8_t val);
+int axp_clrsetbits(uint8_t reg, uint8_t clr_mask, uint8_t set_mask);
+#define axp_clrbits(reg, clr_mask) axp_clrsetbits(reg, clr_mask, 0)
+#define axp_setbits(reg, set_mask) axp_clrsetbits(reg, 0, set_mask)
+
+int axp_check_id(void);
+void axp_power_off(void);
+void axp_setup_regulators(const void *fdt);
+
+#endif /* AXP_H */
diff --git a/include/drivers/arm/cryptocell/712/rsa.h b/include/drivers/arm/cryptocell/712/rsa.h
index cd9925b..825214d 100644
--- a/include/drivers/arm/cryptocell/712/rsa.h
+++ b/include/drivers/arm/cryptocell/712/rsa.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,19 +21,21 @@
 
 /************************ Defines ******************************/
 
-/* the modulus size ion bits */
+/* the modulus size in bits */
+#if (KEY_SIZE == 2048)
 #define RSA_MOD_SIZE_IN_BITS				2048UL
+#elif (KEY_SIZE == 3072)
+#define RSA_MOD_SIZE_IN_BITS				3072UL
+#else
+#error Unsupported CryptoCell key size requested
+#endif
+
 #define RSA_MOD_SIZE_IN_BYTES				(CALC_FULL_BYTES(RSA_MOD_SIZE_IN_BITS))
 #define RSA_MOD_SIZE_IN_WORDS				(CALC_FULL_32BIT_WORDS(RSA_MOD_SIZE_IN_BITS))
 #define RSA_MOD_SIZE_IN_256BITS				(RSA_MOD_SIZE_IN_WORDS/8)
 #define RSA_EXP_SIZE_IN_BITS				17UL
 #define RSA_EXP_SIZE_IN_BYTES				(CALC_FULL_BYTES(RSA_EXP_SIZE_IN_BITS))
 
-/* size of buffer for Barrett modulus tag NP, used in PKA algorithms */
-#define RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_BITS	132
-#define RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_BYTES	(CALC_FULL_BYTES(RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_BITS))
-#define RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_WORDS	(CALC_FULL_32BIT_WORDS(RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_BITS))
-
 /*
  * @brief The RSA_CalcNp calculates Np value and saves it into Np_ptr:
  *
diff --git a/include/drivers/arm/cryptocell/712/secureboot_gen_defs.h b/include/drivers/arm/cryptocell/712/secureboot_gen_defs.h
index 68b9ef8..ed1f283 100644
--- a/include/drivers/arm/cryptocell/712/secureboot_gen_defs.h
+++ b/include/drivers/arm/cryptocell/712/secureboot_gen_defs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -24,7 +24,14 @@
 /***********************/
 
 /*RSA definitions*/
+#if (KEY_SIZE == 2048)
 #define SB_RSA_MOD_SIZE_IN_WORDS		 64
+#elif (KEY_SIZE == 3072)
+#define SB_RSA_MOD_SIZE_IN_WORDS		96
+#else
+#error Unsupported CryptoCell key size requested
+#endif
+
 #define SB_RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_WORDS 5
 
 
@@ -43,9 +50,12 @@
 /********* Supported algorithms definitions ***********/
 
 /*! RSA supported algorithms */
+/* Note: this applies to either 2k or 3k based on CryptoCell SBROM library
+ * version - it means 2k in version 1 and 3k in version 2 (yes, really).
+ */
 typedef enum {
-	RSA_PSS_2048           = 0x01,			/*!< RSA PSS 2048 after hash SHA 256 */
-	RSA_PKCS15_2048	       = 0x02,			/*!< RSA PKX15 */
+	RSA_PSS                = 0x01,			/*!< RSA PSS after hash SHA 256 */
+	RSA_PKCS15	       = 0x02,			/*!< RSA PKX15 */
 	RSA_Last               = 0x7FFFFFFF
 } CCSbRsaAlg_t;
 
diff --git a/include/drivers/arm/gic600_multichip.h b/include/drivers/arm/gic600_multichip.h
new file mode 100644
index 0000000..bda406b
--- /dev/null
+++ b/include/drivers/arm/gic600_multichip.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2019, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef GIC600_MULTICHIP_H
+#define GIC600_MULTICHIP_H
+
+#include <stdint.h>
+
+/*
+ * GIC-600 microarchitecture supports coherent multichip environments containing
+ * up to 16 chips.
+ */
+#define GIC600_MAX_MULTICHIP	16
+
+/* SPI IDs array consist of min and max ids */
+#define GIC600_SPI_IDS_SIZE	2
+
+/*******************************************************************************
+ * GIC-600 multichip data structure describes platform specific attributes
+ * related to GIC-600 multichip. Platform port is expected to define these
+ * attributes to initialize the multichip related registers and create
+ * successful connections between the GIC-600s in a multichip system.
+ *
+ * The 'rt_owner_base' field contains the base address of the GIC Distributor
+ * which owns the routing table.
+ *
+ * The 'rt_owner' field contains the chip number which owns the routing table.
+ * Chip number or chip_id starts from 0.
+ *
+ * The 'chip_count' field contains the total number of chips in a multichip
+ * system. This should match the number of entries in 'chip_addrs' and 'spi_ids'
+ * fields.
+ *
+ * The 'chip_addrs' field contains array of chip addresses. These addresses are
+ * implementation specific values.
+ *
+ * The 'spi_ids' field contains array of minimum and maximum SPI interrupt ids
+ * that each chip owns. Note that SPI interrupt ids can range from 32 to 960 and
+ * it should be group of 32 (i.e., SPI minimum and (SPI maximum + 1) should be
+ * a multiple of 32). If a chip doesn't own any SPI interrupts a value of {0, 0}
+ * should be passed.
+ ******************************************************************************/
+struct gic600_multichip_data {
+	uintptr_t rt_owner_base;
+	unsigned int rt_owner;
+	unsigned int chip_count;
+	uint64_t chip_addrs[GIC600_MAX_MULTICHIP];
+	unsigned int spi_ids[GIC600_MAX_MULTICHIP][GIC600_SPI_IDS_SIZE];
+};
+
+void gic600_multichip_init(struct gic600_multichip_data *multichip_data);
+#endif /* GIC600_MULTICHIP_H */
diff --git a/include/drivers/arm/scu.h b/include/drivers/arm/scu.h
new file mode 100644
index 0000000..992539f
--- /dev/null
+++ b/include/drivers/arm/scu.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SCU_H
+#define SCU_H
+
+#include <stdint.h>
+
+#define SCU_CTRL_REG	0x00
+#define SCU_CFG_REG	0x04
+
+#define SCU_ENABLE_BIT	(1 << 0)
+
+void enable_snoop_ctrl_unit(uintptr_t base);
+uint32_t read_snoop_ctrl_unit_cfg(uintptr_t base);
+
+#endif /* SCU_H */
diff --git a/include/drivers/io/io_driver.h b/include/drivers/io/io_driver.h
index 2b704f4..d8bb435 100644
--- a/include/drivers/io/io_driver.h
+++ b/include/drivers/io/io_driver.h
@@ -39,7 +39,7 @@
 	io_type_t (*type)(void);
 	int (*open)(io_dev_info_t *dev_info, const uintptr_t spec,
 			io_entity_t *entity);
-	int (*seek)(io_entity_t *entity, int mode, ssize_t offset);
+	int (*seek)(io_entity_t *entity, int mode, signed long long offset);
 	int (*size)(io_entity_t *entity, size_t *length);
 	int (*read)(io_entity_t *entity, uintptr_t buffer, size_t length,
 			size_t *length_read);
diff --git a/include/drivers/io/io_mtd.h b/include/drivers/io/io_mtd.h
new file mode 100644
index 0000000..1395ff6
--- /dev/null
+++ b/include/drivers/io/io_mtd.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IO_MTD_H
+#define IO_MTD_H
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include <drivers/io/io_storage.h>
+
+/* MTD devices ops */
+typedef struct io_mtd_ops {
+	/*
+	 * Initialize MTD framework and retrieve device information.
+	 *
+	 * @size:  [out] MTD device size in bytes.
+	 * @erase_size: [out] MTD erase size in bytes.
+	 * Return 0 on success, a negative error code otherwise.
+	 */
+	int (*init)(unsigned long long *size, unsigned int *erase_size);
+
+	/*
+	 * Execute a read memory operation.
+	 *
+	 * @offset: Offset in bytes to start read operation.
+	 * @buffer: [out] Buffer to store read data.
+	 * @length: Required length to be read in bytes.
+	 * @out_length: [out] Length read in bytes.
+	 * Return 0 on success, a negative error code otherwise.
+	 */
+	int (*read)(unsigned int offset, uintptr_t buffer, size_t length,
+		    size_t *out_length);
+
+	/*
+	 * Execute a write memory operation.
+	 *
+	 * @offset: Offset in bytes to start write operation.
+	 * @buffer: Buffer to be written in device.
+	 * @length: Required length to be written in bytes.
+	 * Return 0 on success, a negative error code otherwise.
+	 */
+	int (*write)(unsigned int offset, uintptr_t buffer, size_t length);
+} io_mtd_ops_t;
+
+typedef struct io_mtd_dev_spec {
+	unsigned long long device_size;
+	unsigned int erase_size;
+	io_mtd_ops_t ops;
+} io_mtd_dev_spec_t;
+
+struct io_dev_connector;
+
+int register_io_dev_mtd(const struct io_dev_connector **dev_con);
+
+#endif /* IO_MTD_H */
diff --git a/include/drivers/io/io_storage.h b/include/drivers/io/io_storage.h
index 084c67c..0e6ffd6 100644
--- a/include/drivers/io/io_storage.h
+++ b/include/drivers/io/io_storage.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,6 +22,7 @@
 	IO_TYPE_DUMMY,
 	IO_TYPE_FIRMWARE_IMAGE_PACKAGE,
 	IO_TYPE_BLOCK,
+	IO_TYPE_MTD,
 	IO_TYPE_MMC,
 	IO_TYPE_STM32IMAGE,
 	IO_TYPE_MAX
@@ -86,7 +87,7 @@
 /* Synchronous operations */
 int io_open(uintptr_t dev_handle, const uintptr_t spec, uintptr_t *handle);
 
-int io_seek(uintptr_t handle, io_seek_mode_t mode, ssize_t offset);
+int io_seek(uintptr_t handle, io_seek_mode_t mode, signed long long offset);
 
 int io_size(uintptr_t handle, size_t *length);
 
diff --git a/include/drivers/nand.h b/include/drivers/nand.h
new file mode 100644
index 0000000..1dbb008
--- /dev/null
+++ b/include/drivers/nand.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DRIVERS_NAND_H
+#define DRIVERS_NAND_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <lib/utils_def.h>
+
+#define PSEC_TO_MSEC(x)	div_round_up((x), 1000000000ULL)
+
+struct ecc {
+	unsigned int mode; /* ECC mode NAND_ECC_MODE_{NONE|HW|ONDIE} */
+	unsigned int size; /* Data byte per ECC step */
+	unsigned int bytes; /* ECC bytes per step */
+	unsigned int max_bit_corr; /* Max correctible bits per ECC steps */
+};
+
+struct nand_device {
+	unsigned int block_size;
+	unsigned int page_size;
+	unsigned long long size;
+	unsigned int nb_planes;
+	unsigned int buswidth;
+	struct ecc ecc;
+	int (*mtd_block_is_bad)(unsigned int block);
+	int (*mtd_read_page)(struct nand_device *nand, unsigned int page,
+			     uintptr_t buffer);
+};
+
+/*
+ * Read bytes from NAND device
+ *
+ * @offset: Byte offset to read from in device
+ * @buffer: [out] Bytes read from device
+ * @length: Number of bytes to read
+ * @length_read: [out] Number of bytes read from device
+ * Return: 0 on success, a negative errno on failure
+ */
+int nand_read(unsigned int offset, uintptr_t buffer, size_t length,
+	      size_t *length_read);
+
+/*
+ * Get NAND device instance
+ *
+ * Return: NAND device instance reference
+ */
+struct nand_device *get_nand_device(void);
+
+#endif	/* DRIVERS_NAND_H */
diff --git a/include/drivers/raw_nand.h b/include/drivers/raw_nand.h
new file mode 100644
index 0000000..18e4b73
--- /dev/null
+++ b/include/drivers/raw_nand.h
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DRIVERS_RAW_NAND_H
+#define DRIVERS_RAW_NAND_H
+
+#include <stdint.h>
+
+#include <drivers/nand.h>
+
+/* NAND ONFI default value mode 0 in picosecond */
+#define NAND_TADL_MIN			400000UL
+#define NAND_TALH_MIN			20000UL
+#define NAND_TALS_MIN			50000UL
+#define NAND_TAR_MIN			25000UL
+#define NAND_TCCS_MIN			500000UL
+#define NAND_TCEA_MIN			100000UL
+#define NAND_TCEH_MIN			20000UL
+#define NAND_TCH_MIN			20000UL
+#define NAND_TCHZ_MAX			100000UL
+#define NAND_TCLH_MIN			20000UL
+#define NAND_TCLR_MIN			20000UL
+#define NAND_TCLS_MIN			50000UL
+#define NAND_TCOH_MIN			0UL
+#define NAND_TCS_MIN			70000UL
+#define NAND_TDH_MIN			20000UL
+#define NAND_TDS_MIN			40000UL
+#define NAND_TFEAT_MAX			1000000UL
+#define NAND_TIR_MIN			10000UL
+#define NAND_TITC_MIN			1000000UL
+#define NAND_TR_MAX			200000000UL
+#define NAND_TRC_MIN			100000UL
+#define NAND_TREA_MAX			40000UL
+#define NAND_TREH_MIN			30000UL
+#define NAND_TRHOH_MIN			0UL
+#define NAND_TRHW_MIN			200000UL
+#define NAND_TRHZ_MAX			200000UL
+#define NAND_TRLOH_MIN			0UL
+#define NAND_TRP_MIN			50000UL
+#define NAND_TRR_MIN			40000UL
+#define NAND_TRST_MAX			250000000000ULL
+#define NAND_TWB_MAX			200000UL
+#define NAND_TWC_MIN			100000UL
+#define NAND_TWH_MIN			30000UL
+#define NAND_TWHR_MIN			120000UL
+#define NAND_TWP_MIN			50000UL
+#define NAND_TWW_MIN			100000UL
+
+/* NAND request types */
+#define NAND_REQ_CMD			0x0000U
+#define NAND_REQ_ADDR			0x1000U
+#define NAND_REQ_DATAIN			0x2000U
+#define NAND_REQ_DATAOUT		0x3000U
+#define NAND_REQ_WAIT			0x4000U
+#define NAND_REQ_MASK			GENMASK(14, 12)
+#define NAND_REQ_BUS_WIDTH_8		BIT(15)
+
+#define PARAM_PAGE_SIZE			256
+
+/* NAND ONFI commands */
+#define NAND_CMD_READ_1ST		0x00U
+#define NAND_CMD_CHANGE_1ST		0x05U
+#define NAND_CMD_READID_SIG_ADDR	0x20U
+#define NAND_CMD_READ_2ND		0x30U
+#define NAND_CMD_STATUS			0x70U
+#define NAND_CMD_READID			0x90U
+#define NAND_CMD_CHANGE_2ND		0xE0U
+#define NAND_CMD_READ_PARAM_PAGE	0xECU
+#define NAND_CMD_RESET			0xFFU
+
+#define ONFI_REV_21			BIT(3)
+#define ONFI_FEAT_BUS_WIDTH_16		BIT(0)
+#define ONFI_FEAT_EXTENDED_PARAM	BIT(7)
+
+/* NAND ECC type */
+#define NAND_ECC_NONE			U(0)
+#define NAND_ECC_HW			U(1)
+#define NAND_ECC_ONDIE			U(2)
+
+/* NAND bus width */
+#define NAND_BUS_WIDTH_8		U(0)
+#define NAND_BUS_WIDTH_16		U(1)
+
+struct nand_req {
+	struct nand_device *nand;
+	uint16_t type;
+	uint8_t *addr;
+	unsigned int length;
+	unsigned int delay_ms;
+	unsigned int inst_delay;
+};
+
+struct nand_param_page {
+	/* Rev information and feature block */
+	uint32_t page_sig;
+	uint16_t rev;
+	uint16_t features;
+	uint16_t opt_cmd;
+	uint8_t jtg;
+	uint8_t train_cmd;
+	uint16_t ext_param_length;
+	uint8_t nb_param_pages;
+	uint8_t reserved1[17];
+	/* Manufacturer information */
+	uint8_t manufacturer[12];
+	uint8_t model[20];
+	uint8_t manufacturer_id;
+	uint16_t data_code;
+	uint8_t reserved2[13];
+	/* Memory organization */
+	uint32_t bytes_per_page;
+	uint16_t spare_per_page;
+	uint32_t bytes_per_partial;
+	uint16_t spare_per_partial;
+	uint32_t num_pages_per_blk;
+	uint32_t num_blk_in_lun;
+	uint8_t num_lun;
+	uint8_t num_addr_cycles;
+	uint8_t bit_per_cell;
+	uint16_t max_bb_per_lun;
+	uint16_t blk_endur;
+	uint8_t valid_blk_begin;
+	uint16_t blk_enbur_valid;
+	uint8_t nb_prog_page;
+	uint8_t partial_prog_attr;
+	uint8_t nb_ecc_bits;
+	uint8_t plane_addr;
+	uint8_t mplanes_ops;
+	uint8_t ez_nand;
+	uint8_t reserved3[12];
+	/* Electrical parameters */
+	uint8_t io_pin_cap_max;
+	uint16_t sdr_timing_mode;
+	uint16_t sdr_prog_cache_timing;
+	uint16_t tprog;
+	uint16_t tbers;
+	uint16_t tr;
+	uint16_t tccs;
+	uint8_t nvddr_timing_mode;
+	uint8_t nvddr2_timing_mode;
+	uint8_t nvddr_features;
+	uint16_t clk_input_cap_typ;
+	uint16_t io_pin_cap_typ;
+	uint16_t input_pin_cap_typ;
+	uint8_t input_pin_cap_max;
+	uint8_t drv_strength_support;
+	uint16_t tr_max;
+	uint16_t tadl;
+	uint16_t tr_typ;
+	uint8_t reserved4[6];
+	/* Vendor block */
+	uint16_t vendor_revision;
+	uint8_t vendor[88];
+	uint16_t crc16;
+} __packed;
+
+struct nand_ctrl_ops {
+	int (*exec)(struct nand_req *req);
+	void (*setup)(struct nand_device *nand);
+};
+
+struct rawnand_device {
+	struct nand_device *nand_dev;
+	const struct nand_ctrl_ops *ops;
+};
+
+int nand_raw_init(unsigned long long *size, unsigned int *erase_size);
+int nand_wait_ready(unsigned long delay);
+int nand_read_page_cmd(unsigned int page, unsigned int offset,
+		       uintptr_t buffer, unsigned int len);
+int nand_change_read_column_cmd(unsigned int offset, uintptr_t buffer,
+				unsigned int len);
+void nand_raw_ctrl_init(const struct nand_ctrl_ops *ops);
+
+/*
+ * Platform can implement this to override default raw NAND instance
+ * configuration.
+ *
+ * @device: target raw NAND instance.
+ * Return 0 on success, negative value otherwise.
+ */
+int plat_get_raw_nand_data(struct rawnand_device *device);
+
+#endif	/* DRIVERS_RAW_NAND_H */
diff --git a/include/drivers/spi_mem.h b/include/drivers/spi_mem.h
new file mode 100644
index 0000000..d1953ac
--- /dev/null
+++ b/include/drivers/spi_mem.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DRIVERS_SPI_MEM_H
+#define DRIVERS_SPI_MEM_H
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#define SPI_MEM_BUSWIDTH_1_LINE		1U
+#define SPI_MEM_BUSWIDTH_2_LINE		2U
+#define SPI_MEM_BUSWIDTH_4_LINE		4U
+
+/*
+ * enum spi_mem_data_dir - Describes the direction of a SPI memory data
+ *			   transfer from the controller perspective.
+ * @SPI_MEM_DATA_IN: data coming from the SPI memory.
+ * @SPI_MEM_DATA_OUT: data sent to the SPI memory.
+ */
+enum spi_mem_data_dir {
+	SPI_MEM_DATA_IN,
+	SPI_MEM_DATA_OUT,
+};
+
+/*
+ * struct spi_mem_op - Describes a SPI memory operation.
+ *
+ * @cmd.buswidth: Number of IO lines used to transmit the command.
+ * @cmd.opcode: Operation opcode.
+ * @addr.nbytes: Number of address bytes to send. Can be zero if the operation
+ *		 does not need to send an address.
+ * @addr.buswidth: Number of IO lines used to transmit the address.
+ * @addr.val: Address value. This value is always sent MSB first on the bus.
+ *	      Note that only @addr.nbytes are taken into account in this
+ *	      address value, so users should make sure the value fits in the
+ *	      assigned number of bytes.
+ * @dummy.nbytes: Number of dummy bytes to send after an opcode or address. Can
+ *		  be zero if the operation does not require dummy bytes.
+ * @dummy.buswidth: Number of IO lines used to transmit the dummy bytes.
+ * @data.buswidth: Number of IO lines used to send/receive the data.
+ * @data.dir: Direction of the transfer.
+ * @data.nbytes: Number of data bytes to transfer.
+ * @data.buf: Input or output data buffer depending on data::dir.
+ */
+struct spi_mem_op {
+	struct {
+		uint8_t buswidth;
+		uint8_t opcode;
+	} cmd;
+
+	struct {
+		uint8_t nbytes;
+		uint8_t buswidth;
+		uint64_t val;
+	} addr;
+
+	struct {
+		uint8_t nbytes;
+		uint8_t buswidth;
+	} dummy;
+
+	struct {
+		uint8_t buswidth;
+		enum spi_mem_data_dir dir;
+		unsigned int nbytes;
+		void *buf;
+	} data;
+};
+
+/* SPI mode flags */
+#define SPI_CPHA	BIT(0)			/* clock phase */
+#define SPI_CPOL	BIT(1)			/* clock polarity */
+#define SPI_CS_HIGH	BIT(2)			/* CS active high */
+#define SPI_LSB_FIRST	BIT(3)			/* per-word bits-on-wire */
+#define SPI_3WIRE	BIT(4)			/* SI/SO signals shared */
+#define SPI_PREAMBLE	BIT(5)			/* Skip preamble bytes */
+#define SPI_TX_DUAL	BIT(6)			/* transmit with 2 wires */
+#define SPI_TX_QUAD	BIT(7)			/* transmit with 4 wires */
+#define SPI_RX_DUAL	BIT(8)			/* receive with 2 wires */
+#define SPI_RX_QUAD	BIT(9)			/* receive with 4 wires */
+
+struct spi_bus_ops {
+	/*
+	 * Claim the bus and prepare it for communication.
+	 *
+	 * @cs:	The chip select.
+	 * Returns: 0 if the bus was claimed successfully, or a negative value
+	 * if it wasn't.
+	 */
+	int (*claim_bus)(unsigned int cs);
+
+	/*
+	 * Release the SPI bus.
+	 */
+	void (*release_bus)(void);
+
+	/*
+	 * Set transfer speed.
+	 *
+	 * @hz:	The transfer speed in Hertz.
+	 * Returns: 0 on success, a negative error code otherwise.
+	 */
+	int (*set_speed)(unsigned int hz);
+
+	/*
+	 * Set the SPI mode/flags.
+	 *
+	 * @mode: Requested SPI mode (SPI_... flags).
+	 * Returns: 0 on success, a negative error code otherwise.
+	 */
+	int (*set_mode)(unsigned int mode);
+
+	/*
+	 * Execute a SPI memory operation.
+	 *
+	 * @op:	The memory operation to execute.
+	 * Returns: 0 on success, a negative error code otherwise.
+	 */
+	int (*exec_op)(const struct spi_mem_op *op);
+};
+
+int spi_mem_exec_op(const struct spi_mem_op *op);
+int spi_mem_init_slave(void *fdt, int bus_node,
+		       const struct spi_bus_ops *ops);
+
+#endif /* DRIVERS_SPI_MEM_H */
diff --git a/include/drivers/spi_nand.h b/include/drivers/spi_nand.h
new file mode 100644
index 0000000..40e2063
--- /dev/null
+++ b/include/drivers/spi_nand.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DRIVERS_SPI_NAND_H
+#define DRIVERS_SPI_NAND_H
+
+#include <drivers/nand.h>
+#include <drivers/spi_mem.h>
+
+#define SPI_NAND_OP_GET_FEATURE		0x0FU
+#define SPI_NAND_OP_SET_FEATURE		0x1FU
+#define SPI_NAND_OP_READ_ID		0x9FU
+#define SPI_NAND_OP_LOAD_PAGE		0x13U
+#define SPI_NAND_OP_RESET		0xFFU
+#define SPI_NAND_OP_READ_FROM_CACHE	0x03U
+#define SPI_NAND_OP_READ_FROM_CACHE_2X	0x3BU
+#define SPI_NAND_OP_READ_FROM_CACHE_4X	0x6BU
+
+/* Configuration register */
+#define SPI_NAND_REG_CFG		0xB0U
+#define SPI_NAND_CFG_ECC_EN		BIT(4)
+#define SPI_NAND_CFG_QE			BIT(0)
+
+/* Status register */
+#define SPI_NAND_REG_STATUS		0xC0U
+#define SPI_NAND_STATUS_BUSY		BIT(0)
+#define SPI_NAND_STATUS_ECC_UNCOR	BIT(5)
+
+struct spinand_device {
+	struct nand_device *nand_dev;
+	struct spi_mem_op spi_read_cache_op;
+	uint8_t cfg_cache; /* Cached value of SPI NAND device register CFG */
+};
+
+int spi_nand_init(unsigned long long *size, unsigned int *erase_size);
+
+/*
+ * Platform can implement this to override default SPI-NAND instance
+ * configuration.
+ *
+ * @device: target SPI-NAND instance.
+ * Return 0 on success, negative value otherwise.
+ */
+int plat_get_spi_nand_data(struct spinand_device *device);
+
+#endif /* DRIVERS_SPI_NAND_H */
diff --git a/include/drivers/spi_nor.h b/include/drivers/spi_nor.h
new file mode 100644
index 0000000..72cfe5b
--- /dev/null
+++ b/include/drivers/spi_nor.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DRIVERS_SPI_NOR_H
+#define DRIVERS_SPI_NOR_H
+
+#include <drivers/spi_mem.h>
+
+/* OPCODE */
+#define SPI_NOR_OP_WREN		0x06U	/* Write enable */
+#define SPI_NOR_OP_WRSR		0x01U	/* Write status register 1 byte */
+#define SPI_NOR_OP_READ_ID	0x9FU	/* Read JEDEC ID */
+#define SPI_NOR_OP_READ_CR	0x35U	/* Read configuration register */
+#define SPI_NOR_OP_READ_SR	0x05U	/* Read status register */
+#define SPI_NOR_OP_READ_FSR	0x70U	/* Read flag status register */
+#define SPINOR_OP_RDEAR		0xC8U	/* Read Extended Address Register */
+#define SPINOR_OP_WREAR		0xC5U	/* Write Extended Address Register */
+
+/* Used for Spansion flashes only. */
+#define SPINOR_OP_BRWR		0x17U	/* Bank register write */
+#define SPINOR_OP_BRRD		0x16U	/* Bank register read */
+
+#define SPI_NOR_OP_READ		0x03U	/* Read data bytes (low frequency) */
+#define SPI_NOR_OP_READ_FAST	0x0BU	/* Read data bytes (high frequency) */
+#define SPI_NOR_OP_READ_1_1_2	0x3BU	/* Read data bytes (Dual Output SPI) */
+#define SPI_NOR_OP_READ_1_2_2	0xBBU	/* Read data bytes (Dual I/O SPI) */
+#define SPI_NOR_OP_READ_1_1_4	0x6BU	/* Read data bytes (Quad Output SPI) */
+#define SPI_NOR_OP_READ_1_4_4	0xEBU	/* Read data bytes (Quad I/O SPI) */
+
+/* Flags for NOR specific configuration */
+#define SPI_NOR_USE_FSR		BIT(0)
+#define SPI_NOR_USE_BANK	BIT(1)
+
+struct nor_device {
+	struct spi_mem_op read_op;
+	uint32_t size;
+	uint32_t flags;
+	uint8_t selected_bank;
+	uint8_t bank_write_cmd;
+	uint8_t bank_read_cmd;
+};
+
+int spi_nor_read(unsigned int offset, uintptr_t buffer, size_t length,
+		 size_t *length_read);
+int spi_nor_init(unsigned long long *device_size, unsigned int *erase_size);
+
+/*
+ * Platform can implement this to override default NOR instance configuration.
+ *
+ * @device: target NOR instance.
+ * Return 0 on success, negative value otherwise.
+ */
+int plat_get_nor_data(struct nor_device *device);
+
+#endif /* DRIVERS_SPI_NOR_H */
diff --git a/include/drivers/st/io_stm32image.h b/include/drivers/st/io_stm32image.h
index 6806055..f9fa363 100644
--- a/include/drivers/st/io_stm32image.h
+++ b/include/drivers/st/io_stm32image.h
@@ -23,7 +23,7 @@
 
 struct stm32image_device_info {
 	struct stm32image_part_info part_info[STM32_PART_NUM];
-	uint32_t device_size;
+	unsigned long long device_size;
 	uint32_t lba_size;
 };
 
diff --git a/include/drivers/st/stm32_fmc2_nand.h b/include/drivers/st/stm32_fmc2_nand.h
new file mode 100644
index 0000000..81d5b9d
--- /dev/null
+++ b/include/drivers/st/stm32_fmc2_nand.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#ifndef STM32_FMC2_NAND_H
+#define STM32_FMC2_NAND_H
+
+int stm32_fmc2_init(void);
+
+#endif /* STM32_FMC2_NAND_H */
diff --git a/include/drivers/st/stm32_qspi.h b/include/drivers/st/stm32_qspi.h
new file mode 100644
index 0000000..f47fca4
--- /dev/null
+++ b/include/drivers/st/stm32_qspi.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#ifndef STM32_QSPI_H
+#define STM32_QSPI_H
+
+int stm32_qspi_init(void);
+
+#endif /* STM32_QSPI_H */
diff --git a/include/drivers/ti/uart/uart_16550.h b/include/drivers/ti/uart/uart_16550.h
index 32e38f0..2b95fa3 100644
--- a/include/drivers/ti/uart/uart_16550.h
+++ b/include/drivers/ti/uart/uart_16550.h
@@ -87,6 +87,11 @@
  * framework. The |console| pointer must point to storage that will be valid
  * for the lifetime of the console, such as a global or static local variable.
  * Its contents will be reinitialized from scratch.
+ * When |clock| has a value of 0, the UART will *not* be initialised. This
+ * means the UART should already be enabled and the baudrate and clock setup
+ * should have been done already, either by platform specific code or by
+ * previous firmware stages. The |baud| parameter will be ignored in this
+ * case as well.
  */
 int console_16550_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
 			   console_16550_t *console);
diff --git a/include/export/lib/utils_def_exp.h b/include/export/lib/utils_def_exp.h
index 86c409c..d4a4a85 100644
--- a/include/export/lib/utils_def_exp.h
+++ b/include/export/lib/utils_def_exp.h
@@ -25,11 +25,13 @@
 # define   L(_x)	(_x)
 # define  LL(_x)	(_x)
 #else
-# define   U(_x)	(_x##U)
+# define  U_(_x)	(_x##U)
+# define   U(_x)	U_(_x)
 # define  UL(_x)	(_x##UL)
 # define ULL(_x)	(_x##ULL)
 # define   L(_x)	(_x##L)
 # define  LL(_x)	(_x##LL)
+
 #endif
 
 #endif /* ARM_TRUSTED_FIRMWARE_EXPORT_LIB_UTILS_DEF_EXP_H */
diff --git a/include/lib/cpus/aarch64/cortex_a72.h b/include/lib/cpus/aarch64/cortex_a72.h
index 4a444c6..28b440e 100644
--- a/include/lib/cpus/aarch64/cortex_a72.h
+++ b/include/lib/cpus/aarch64/cortex_a72.h
@@ -43,7 +43,14 @@
  ******************************************************************************/
 #define CORTEX_A72_L2ACTLR_EL1					S3_1_C15_C0_0
 
+#define CORTEX_A72_L2ACTLR_FORCE_TAG_BANK_CLK_ACTIVE		(ULL(1) << 28)
+#define CORTEX_A72_L2ACTLR_FORCE_L2_LOGIC_CLK_ACTIVE		(ULL(1) << 27)
+#define CORTEX_A72_L2ACTLR_FORCE_L2_GIC_TIMER_RCG_CLK_ACTIVE	(ULL(1) << 26)
 #define CORTEX_A72_L2ACTLR_ENABLE_UNIQUE_CLEAN			(ULL(1) << 14)
+#define CORTEX_A72_L2ACTLR_DISABLE_DSB_WITH_NO_DVM_SYNC		(ULL(1) << 11)
+#define CORTEX_A72_L2ACTLR_DISABLE_DVM_CMO_BROADCAST		(ULL(1) << 8)
+#define CORTEX_A72_L2ACTLR_ENABLE_HAZARD_DETECT_TIMEOUT		(ULL(1) << 7)
+#define CORTEX_A72_L2ACTLR_DISABLE_ACE_SH_OR_CHI		(ULL(1) << 6)
 
 /*******************************************************************************
  * L2 Control register specific definitions.
@@ -51,8 +58,12 @@
 #define CORTEX_A72_L2CTLR_EL1				S3_1_C11_C0_2
 
 #define CORTEX_A72_L2CTLR_DATA_RAM_LATENCY_SHIFT	U(0)
+#define CORTEX_A72_L2CTLR_DATA_RAM_SETUP_SHIFT		U(5)
 #define CORTEX_A72_L2CTLR_TAG_RAM_LATENCY_SHIFT		U(6)
+#define CORTEX_A72_L2CTLR_TAG_RAM_SETUP_SHIFT		U(9)
 
+#define CORTEX_A72_L2_DATA_RAM_LATENCY_MASK		U(0x7)
+#define CORTEX_A72_L2_TAG_RAM_LATENCY_MASK		U(0x7)
 #define CORTEX_A72_L2_DATA_RAM_LATENCY_3_CYCLES		U(0x2)
 #define CORTEX_A72_L2_TAG_RAM_LATENCY_2_CYCLES		U(0x1)
 #define CORTEX_A72_L2_TAG_RAM_LATENCY_3_CYCLES		U(0x2)
diff --git a/include/lib/cpus/aarch64/cortex_hercules.h b/include/lib/cpus/aarch64/cortex_hercules.h
index b943e7a..d5ca85e 100644
--- a/include/lib/cpus/aarch64/cortex_hercules.h
+++ b/include/lib/cpus/aarch64/cortex_hercules.h
@@ -27,6 +27,9 @@
  ******************************************************************************/
 #define CORTEX_HERCULES_ACTLR_TAM_BIT				(ULL(1) << 30)
 
+#define CORTEX_HERCULES_ACTLR2_EL1				S3_0_C15_C1_1
+#define CORTEX_HERCULES_ACTLR2_EL1_BIT_1			(ULL(1) << 1)
+
 /*******************************************************************************
  * CPU Activity Monitor Unit register specific definitions.
  ******************************************************************************/
diff --git a/include/lib/debugfs.h b/include/lib/debugfs.h
new file mode 100644
index 0000000..8ed237a
--- /dev/null
+++ b/include/lib/debugfs.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DEBUGFS_H
+#define DEBUGFS_H
+
+#define NAMELEN   13 /* Maximum length of a file name */
+#define PATHLEN   41 /* Maximum length of a path */
+#define STATLEN   41 /* Size of static part of dir format */
+#define ROOTLEN   (2 + 4) /* Size needed to encode root string */
+#define FILNAMLEN (2 + NAMELEN) /* Size needed to encode filename */
+#define DIRLEN    (STATLEN + FILNAMLEN + 3*ROOTLEN) /* Size of dir entry */
+
+#define KSEEK_SET 0
+#define KSEEK_CUR 1
+#define KSEEK_END 2
+
+#define NELEM(tab) (sizeof(tab) / sizeof((tab)[0]))
+
+typedef unsigned short qid_t; /* FIXME: short type not recommended? */
+
+/*******************************************************************************
+ * This structure contains the necessary information to represent a 9p
+ * directory.
+ ******************************************************************************/
+typedef struct {
+	char		name[NAMELEN];
+	long		length;
+	unsigned char	mode;
+	unsigned char	index;
+	unsigned char	dev;
+	qid_t		qid;
+} dir_t;
+
+/* Permission definitions used as flags */
+#define O_READ		(1 << 0)
+#define O_WRITE		(1 << 1)
+#define O_RDWR		(1 << 2)
+#define O_BIND		(1 << 3)
+#define O_DIR		(1 << 4)
+#define O_STAT		(1 << 5)
+
+/* 9p interface */
+int mount(const char *srv, const char *mnt, const char *spec);
+int create(const char *name, int flags);
+int open(const char *name, int flags);
+int close(int fd);
+int read(int fd, void *buf, int n);
+int write(int fd, void *buf, int n);
+int seek(int fd, long off, int whence);
+int bind(const char *path, const char *where);
+int stat(const char *path, dir_t *dir);
+
+/* DebugFS initialization */
+void debugfs_init(void);
+int debugfs_smc_setup(void);
+
+/* Debugfs version returned through SMC interface */
+#define DEBUGFS_VERSION		(0x000000001U)
+
+/* Function ID for accessing the debugfs interface */
+#define DEBUGFS_FID_VALUE	(0x30U)
+
+#define is_debugfs_fid(_fid)	\
+	(((_fid) & FUNCID_NUM_MASK) == DEBUGFS_FID_VALUE)
+
+/* Error code for debugfs SMC interface failures */
+#define DEBUGFS_E_INVALID_PARAMS	(-2)
+#define DEBUGFS_E_DENIED		(-3)
+
+uintptr_t debugfs_smc_handler(unsigned int smc_fid,
+			      u_register_t cmd,
+			      u_register_t arg2,
+			      u_register_t arg3,
+			      u_register_t arg4,
+			      void *cookie,
+			      void *handle,
+			      uintptr_t flags);
+
+#endif /* DEBUGFS_H */
diff --git a/include/lib/libc/aarch32/stddef_.h b/include/lib/libc/aarch32/stddef_.h
index 1babfad..36dc20b 100644
--- a/include/lib/libc/aarch32/stddef_.h
+++ b/include/lib/libc/aarch32/stddef_.h
@@ -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
  */
@@ -12,9 +12,4 @@
 #define SIZET_
 #endif
 
-#ifndef _PTRDIFF_T
-typedef long ptrdiff_t;
-#define _PTRDIFF_T
-#endif
-
 #endif /* STDDEF__H */
diff --git a/include/lib/libc/aarch32/stdint_.h b/include/lib/libc/aarch32/stdint_.h
deleted file mode 100644
index 4f49485..0000000
--- a/include/lib/libc/aarch32/stdint_.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#define INT8_MAX  0x7F
-#define INT8_MIN  (-INT8_MAX - 1)
-#define UINT8_MAX 0xFFU
-
-#define INT16_MAX  0x7FFF
-#define INT16_MIN  (-INT16_MAX - 1)
-#define UINT16_MAX 0xFFFFU
-
-#define INT32_MAX  0x7FFFFFFF
-#define INT32_MIN  (-INT32_MAX - 1)
-#define UINT32_MAX 0xFFFFFFFFU
-
-#define INT64_MAX  0x7FFFFFFFFFFFFFFFLL
-#define INT64_MIN  (-INT64_MAX - 1LL)
-#define UINT64_MAX 0xFFFFFFFFFFFFFFFFULL
-
-#define INT_LEAST8_MIN  INT8_MIN
-#define INT_LEAST8_MAX  INT8_MAX
-#define UINT_LEAST8_MAX UINT8_MAX
-
-#define INT_LEAST16_MIN  INT16_MIN
-#define INT_LEAST16_MAX  INT16_MAX
-#define UINT_LEAST16_MAX UINT16_MAX
-
-#define INT_LEAST32_MIN  INT32_MIN
-#define INT_LEAST32_MAX  INT32_MAX
-#define UINT_LEAST32_MAX UINT32_MAX
-
-#define INT_LEAST64_MIN  INT64_MIN
-#define INT_LEAST64_MAX  INT64_MAX
-#define UINT_LEAST64_MAX UINT64_MAX
-
-#define INT_FAST8_MIN  INT32_MIN
-#define INT_FAST8_MAX  INT32_MAX
-#define UINT_FAST8_MAX UINT32_MAX
-
-#define INT_FAST16_MIN  INT32_MIN
-#define INT_FAST16_MAX  INT32_MAX
-#define UINT_FAST16_MAX UINT32_MAX
-
-#define INT_FAST32_MIN  INT32_MIN
-#define INT_FAST32_MAX  INT32_MAX
-#define UINT_FAST32_MAX UINT32_MAX
-
-#define INT_FAST64_MIN  INT64_MIN
-#define INT_FAST64_MAX  INT64_MAX
-#define UINT_FAST64_MAX UINT64_MAX
-
-#define INTPTR_MIN  INT32_MIN
-#define INTPTR_MAX  INT32_MAX
-#define UINTPTR_MAX UINT32_MAX
-
-#define INTMAX_MIN  INT64_MIN
-#define INTMAX_MAX  INT64_MAX
-#define UINTMAX_MAX UINT64_MAX
-
-#define PTRDIFF_MIN INT32_MIN
-#define PTRDIFF_MAX INT32_MAX
-
-#define SIZE_MAX UINT32_MAX
-
-#define INT8_C(x)  x
-#define INT16_C(x) x
-#define INT32_C(x) x
-#define INT64_C(x) x ## LL
-
-#define UINT8_C(x)  x
-#define UINT16_C(x) x
-#define UINT32_C(x) x ## U
-#define UINT64_C(x) x ## ULL
-
-#define INTMAX_C(x)  x ## LL
-#define UINTMAX_C(x) x ## ULL
-
-typedef signed char int8_t;
-typedef short int16_t;
-typedef int int32_t;
-typedef long long int64_t;
-
-typedef unsigned char uint8_t;
-typedef unsigned short uint16_t;
-typedef unsigned int uint32_t;
-typedef unsigned long long uint64_t;
-
-typedef signed char int8_least_t;
-typedef short int16_least_t;
-typedef int int32_least_t;
-typedef long long int64_least_t;
-
-typedef unsigned char uint8_least_t;
-typedef unsigned short uint16_least_t;
-typedef unsigned int uint32_least_t;
-typedef unsigned long long uint64_least_t;
-
-typedef int int8_fast_t;
-typedef int int16_fast_t;
-typedef int int32_fast_t;
-typedef long long int64_fast_t;
-
-typedef unsigned int uint8_fast_t;
-typedef unsigned int uint16_fast_t;
-typedef unsigned int uint32_fast_t;
-typedef unsigned long long uint64_fast_t;
-
-typedef long intptr_t;
-typedef unsigned long uintptr_t;
-
-typedef long long intmax_t;
-typedef unsigned long long uintmax_t;
-
-typedef long register_t;
-typedef unsigned long u_register_t;
diff --git a/include/lib/libc/aarch32/stdio_.h b/include/lib/libc/aarch32/stdio_.h
index 50d3cc2..5e49425 100644
--- a/include/lib/libc/aarch32/stdio_.h
+++ b/include/lib/libc/aarch32/stdio_.h
@@ -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
  */
@@ -7,11 +7,6 @@
 #ifndef STDIO__H
 #define STDIO__H
 
-#ifndef SIZET_
-typedef unsigned int size_t;
-#define SIZET_
-#endif
-
 #ifndef SSIZET_
 typedef int ssize_t;
 #define SSIZET_
diff --git a/include/lib/libc/aarch32/stdlib_.h b/include/lib/libc/aarch32/stdlib_.h
deleted file mode 100644
index 9c07857..0000000
--- a/include/lib/libc/aarch32/stdlib_.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef STDLIB__H
-#define STDLIB__H
-
-#ifndef SIZET_
-typedef unsigned int size_t;
-#define SIZET_
-#endif
-
-#define EXIT_FAILURE 1
-#define EXIT_SUCCESS 0
-
-#endif /* STDLIB__H */
diff --git a/include/lib/libc/aarch32/string_.h b/include/lib/libc/aarch32/string_.h
deleted file mode 100644
index 4e139b0..0000000
--- a/include/lib/libc/aarch32/string_.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef STRING__H
-#define STRING__H
-
-#ifndef SIZET_
-typedef unsigned int size_t;
-#define SIZET_
-#endif
-
-#endif /* STRING__H */
diff --git a/include/lib/libc/aarch32/time_.h b/include/lib/libc/aarch32/time_.h
deleted file mode 100644
index a9169c2..0000000
--- a/include/lib/libc/aarch32/time_.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef TIME__H
-#define TIME__H
-
-#ifndef SIZET_
-typedef unsigned int size_t;
-#define SIZET_
-#endif
-
-typedef long int time_t;
-
-#endif /* TIME__H */
diff --git a/include/lib/libc/aarch64/stddef_.h b/include/lib/libc/aarch64/stddef_.h
index b7d8209..6ecc606 100644
--- a/include/lib/libc/aarch64/stddef_.h
+++ b/include/lib/libc/aarch64/stddef_.h
@@ -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
  */
@@ -12,9 +12,4 @@
 #define SIZET_
 #endif
 
-#ifndef _PTRDIFF_T
-typedef long ptrdiff_t;
-#define _PTRDIFF_T
-#endif
-
 #endif /* STDDEF__H */
diff --git a/include/lib/libc/aarch64/stdint_.h b/include/lib/libc/aarch64/stdint_.h
deleted file mode 100644
index b17a435..0000000
--- a/include/lib/libc/aarch64/stdint_.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#define INT8_MAX  0x7F
-#define INT8_MIN  (-INT8_MAX - 1)
-#define UINT8_MAX 0xFFU
-
-#define INT16_MAX  0x7FFF
-#define INT16_MIN  (-INT16_MAX - 1)
-#define UINT16_MAX 0xFFFFU
-
-#define INT32_MAX  0x7FFFFFFF
-#define INT32_MIN  (-INT32_MAX - 1)
-#define UINT32_MAX 0xFFFFFFFFU
-
-#define INT64_MAX  0x7FFFFFFFFFFFFFFFLL
-#define INT64_MIN  (-INT64_MAX - 1LL)
-#define UINT64_MAX 0xFFFFFFFFFFFFFFFFULL
-
-#define INT_LEAST8_MIN  INT8_MIN
-#define INT_LEAST8_MAX  INT8_MAX
-#define UINT_LEAST8_MAX UINT8_MAX
-
-#define INT_LEAST16_MIN  INT16_MIN
-#define INT_LEAST16_MAX  INT16_MAX
-#define UINT_LEAST16_MAX UINT16_MAX
-
-#define INT_LEAST32_MIN  INT32_MIN
-#define INT_LEAST32_MAX  INT32_MAX
-#define UINT_LEAST32_MAX UINT32_MAX
-
-#define INT_LEAST64_MIN  INT64_MIN
-#define INT_LEAST64_MAX  INT64_MAX
-#define UINT_LEAST64_MAX UINT64_MAX
-
-#define INT_FAST8_MIN  INT32_MIN
-#define INT_FAST8_MAX  INT32_MAX
-#define UINT_FAST8_MAX UINT32_MAX
-
-#define INT_FAST16_MIN  INT32_MIN
-#define INT_FAST16_MAX  INT32_MAX
-#define UINT_FAST16_MAX UINT32_MAX
-
-#define INT_FAST32_MIN  INT32_MIN
-#define INT_FAST32_MAX  INT32_MAX
-#define UINT_FAST32_MAX UINT32_MAX
-
-#define INT_FAST64_MIN  INT64_MIN
-#define INT_FAST64_MAX  INT64_MAX
-#define UINT_FAST64_MAX UINT64_MAX
-
-#define INTPTR_MIN  INT64_MIN
-#define INTPTR_MAX  INT64_MAX
-#define UINTPTR_MAX UINT64_MAX
-
-#define INTMAX_MIN  INT64_MIN
-#define INTMAX_MAX  INT64_MAX
-#define UINTMAX_MAX UINT64_MAX
-
-#define PTRDIFF_MIN INT64_MIN
-#define PTRDIFF_MAX INT64_MAX
-
-#define SIZE_MAX UINT64_MAX
-
-#define INT8_C(x)  x
-#define INT16_C(x) x
-#define INT32_C(x) x
-#define INT64_C(x) x ## LL
-
-#define UINT8_C(x)  x
-#define UINT16_C(x) x
-#define UINT32_C(x) x ## U
-#define UINT64_C(x) x ## ULL
-
-#define INTMAX_C(x)  x ## L
-#define UINTMAX_C(x) x ## ULL
-
-typedef signed char int8_t;
-typedef short int16_t;
-typedef int int32_t;
-typedef long long int64_t;
-
-typedef unsigned char uint8_t;
-typedef unsigned short uint16_t;
-typedef unsigned int uint32_t;
-typedef unsigned long long uint64_t;
-
-typedef signed char int8_least_t;
-typedef short int16_least_t;
-typedef int int32_least_t;
-typedef long long int64_least_t;
-
-typedef unsigned char uint8_least_t;
-typedef unsigned short uint16_least_t;
-typedef unsigned int uint32_least_t;
-typedef unsigned long long uint64_least_t;
-
-typedef int int8_fast_t;
-typedef int int16_fast_t;
-typedef int int32_fast_t;
-typedef long long int64_fast_t;
-
-typedef unsigned int uint8_fast_t;
-typedef unsigned int uint16_fast_t;
-typedef unsigned int uint32_fast_t;
-typedef unsigned long long uint64_fast_t;
-
-typedef long intptr_t;
-typedef unsigned long uintptr_t;
-
-typedef long intmax_t;
-typedef unsigned long uintmax_t;
-
-typedef long register_t;
-typedef unsigned long u_register_t;
-
-typedef __int128 int128_t;
-typedef unsigned __int128 uint128_t;
diff --git a/include/lib/libc/aarch64/stdio_.h b/include/lib/libc/aarch64/stdio_.h
index 09b0172..afaeadc 100644
--- a/include/lib/libc/aarch64/stdio_.h
+++ b/include/lib/libc/aarch64/stdio_.h
@@ -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
  */
@@ -7,11 +7,6 @@
 #ifndef STDIO__H
 #define STDIO__H
 
-#ifndef SIZET_
-typedef unsigned long size_t;
-#define SIZET_
-#endif
-
 #ifndef SSIZET_
 typedef long ssize_t;
 #define SSIZET_
diff --git a/include/lib/libc/aarch64/stdlib_.h b/include/lib/libc/aarch64/stdlib_.h
deleted file mode 100644
index 81a39d1..0000000
--- a/include/lib/libc/aarch64/stdlib_.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef STDLIB__H
-#define STDLIB__H
-
-#ifndef SIZET_
-typedef unsigned long size_t;
-#define SIZET_
-#endif
-
-#define EXIT_FAILURE 1
-#define EXIT_SUCCESS 0
-
-#endif /* STDLIB__H */
diff --git a/include/lib/libc/aarch64/string_.h b/include/lib/libc/aarch64/string_.h
deleted file mode 100644
index 71c51a6..0000000
--- a/include/lib/libc/aarch64/string_.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef STRING__H
-#define STRING__H
-
-#ifndef SIZET_
-typedef unsigned long size_t;
-#define SIZET_
-#endif
-
-#endif /* STRING__H */
diff --git a/include/lib/libc/aarch64/time_.h b/include/lib/libc/aarch64/time_.h
deleted file mode 100644
index 68ab1b8..0000000
--- a/include/lib/libc/aarch64/time_.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef TIME__H
-#define TIME__H
-
-#ifndef SIZET_
-typedef unsigned long size_t;
-#define SIZET_
-#endif
-
-typedef long int time_t;
-
-#endif /* TIME__H */
diff --git a/include/lib/libc/stddef.h b/include/lib/libc/stddef.h
index c9957bd..58a519e 100644
--- a/include/lib/libc/stddef.h
+++ b/include/lib/libc/stddef.h
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 /*
- * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * Portions copyright (c) 2018-2019, ARM Limited and Contributors.
  * All rights reserved.
  */
 
@@ -13,6 +13,11 @@
 
 #include <stddef_.h>
 
+#ifndef _PTRDIFF_T
+typedef long ptrdiff_t;
+#define _PTRDIFF_T
+#endif
+
 #ifndef NULL
 #define NULL ((void *) 0)
 #endif
diff --git a/include/lib/libc/stdint.h b/include/lib/libc/stdint.h
index d44a973..818870e 100644
--- a/include/lib/libc/stdint.h
+++ b/include/lib/libc/stdint.h
@@ -4,13 +4,135 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 /*
- * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * Portions copyright (c) 2018-2019, ARM Limited and Contributors.
  * All rights reserved.
  */
 
 #ifndef STDINT_H
 #define STDINT_H
 
-#include <stdint_.h>
+#include <limits.h>
+
+#define INT8_MAX  CHAR_MAX
+#define INT8_MIN  CHAR_MIN
+#define UINT8_MAX UCHAR_MAX
+
+#define INT16_MAX  SHRT_MAX
+#define INT16_MIN  SHRT_MIN
+#define UINT16_MAX USHRT_MAX
+
+#define INT32_MAX  INT_MAX
+#define INT32_MIN  INT_MIN
+#define UINT32_MAX UINT_MAX
+
+#define INT64_MAX  LLONG_MAX
+#define INT64_MIN  LLONG_MIN
+#define UINT64_MAX ULLONG_MAX
+
+#define INT_LEAST8_MIN  INT8_MIN
+#define INT_LEAST8_MAX  INT8_MAX
+#define UINT_LEAST8_MAX UINT8_MAX
+
+#define INT_LEAST16_MIN  INT16_MIN
+#define INT_LEAST16_MAX  INT16_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+
+#define INT_LEAST32_MIN  INT32_MIN
+#define INT_LEAST32_MAX  INT32_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+
+#define INT_LEAST64_MIN  INT64_MIN
+#define INT_LEAST64_MAX  INT64_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+#define INT_FAST8_MIN  INT32_MIN
+#define INT_FAST8_MAX  INT32_MAX
+#define UINT_FAST8_MAX UINT32_MAX
+
+#define INT_FAST16_MIN  INT32_MIN
+#define INT_FAST16_MAX  INT32_MAX
+#define UINT_FAST16_MAX UINT32_MAX
+
+#define INT_FAST32_MIN  INT32_MIN
+#define INT_FAST32_MAX  INT32_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+
+#define INT_FAST64_MIN  INT64_MIN
+#define INT_FAST64_MAX  INT64_MAX
+#define UINT_FAST64_MAX UINT64_MAX
+
+#define INTPTR_MIN  LONG_MIN
+#define INTPTR_MAX  LONG_MAX
+#define UINTPTR_MAX ULONG_MAX
+
+#define INTMAX_MIN  LLONG_MIN
+#define INTMAX_MAX  LLONG_MAX
+#define UINTMAX_MAX ULLONG_MAX
+
+#define PTRDIFF_MIN LONG_MIN
+#define PTRDIFF_MAX LONG_MAX
+
+#define SIZE_MAX ULONG_MAX
+
+#define INT8_C(x)  x
+#define INT16_C(x) x
+#define INT32_C(x) x
+#define INT64_C(x) x ## LL
+
+#define UINT8_C(x)  x
+#define UINT16_C(x) x
+#define UINT32_C(x) x ## U
+#define UINT64_C(x) x ## ULL
+
+#define INTMAX_C(x)  x ## LL
+#define UINTMAX_C(x) x ## ULL
+
+typedef signed char int8_t;
+typedef short int16_t;
+typedef int int32_t;
+typedef long long int64_t;
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+
+typedef signed char int8_least_t;
+typedef short int16_least_t;
+typedef int int32_least_t;
+typedef long long int64_least_t;
+
+typedef unsigned char uint8_least_t;
+typedef unsigned short uint16_least_t;
+typedef unsigned int uint32_least_t;
+typedef unsigned long long uint64_least_t;
+
+typedef int int8_fast_t;
+typedef int int16_fast_t;
+typedef int int32_fast_t;
+typedef long long int64_fast_t;
+
+typedef unsigned int uint8_fast_t;
+typedef unsigned int uint16_fast_t;
+typedef unsigned int uint32_fast_t;
+typedef unsigned long long uint64_fast_t;
+
+typedef long intptr_t;
+typedef unsigned long uintptr_t;
+
+/*
+* Conceptually, these are supposed to be the largest integers representable in C,
+* but GCC and Clang define them as long long for compatibility.
+*/
+typedef long long intmax_t;
+typedef unsigned long long uintmax_t;
+
+typedef long register_t;
+typedef unsigned long u_register_t;
+
+#ifdef __aarch64__
+typedef __int128 int128_t;
+typedef unsigned __int128 uint128_t;
+#endif /* __aarch64__ */
 
 #endif /* STDINT_H */
diff --git a/include/lib/libc/stdio.h b/include/lib/libc/stdio.h
index 3d9323e..2d9e655 100644
--- a/include/lib/libc/stdio.h
+++ b/include/lib/libc/stdio.h
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 /*
- * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * Portions copyright (c) 2018-2019, ARM Limited and Contributors.
  * All rights reserved.
  */
 
@@ -12,12 +12,9 @@
 #define STDIO_H
 
 #include <cdefs.h>
+#include <stddef.h>
 #include <stdio_.h>
 
-#ifndef NULL
-#define NULL ((void *) 0)
-#endif
-
 #define EOF            -1
 
 int printf(const char *fmt, ...) __printflike(1, 2);
diff --git a/include/lib/libc/stdlib.h b/include/lib/libc/stdlib.h
index edd6265..24e7bae 100644
--- a/include/lib/libc/stdlib.h
+++ b/include/lib/libc/stdlib.h
@@ -4,18 +4,17 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 /*
- * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * Portions copyright (c) 2018-2019, ARM Limited and Contributors.
  * All rights reserved.
  */
 
 #ifndef STDLIB_H
 #define STDLIB_H
 
-#include <stdlib_.h>
+#include <stddef.h>
 
-#ifndef NULL
-#define NULL ((void *) 0)
-#endif
+#define EXIT_FAILURE 1
+#define EXIT_SUCCESS 0
 
 #define _ATEXIT_MAX 1
 
diff --git a/include/lib/libc/string.h b/include/lib/libc/string.h
index ee6eeac..71774b0 100644
--- a/include/lib/libc/string.h
+++ b/include/lib/libc/string.h
@@ -4,18 +4,14 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 /*
- * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * Portions copyright (c) 2018-2019, ARM Limited and Contributors.
  * All rights reserved.
  */
 
 #ifndef STRING_H
 #define STRING_H
 
-#include <string_.h>
-
-#ifndef NULL
-#define NULL ((void *) 0)
-#endif
+#include <stddef.h>
 
 void *memcpy(void *dst, const void *src, size_t len);
 void *memmove(void *dst, const void *src, size_t len);
@@ -23,6 +19,7 @@
 int strcmp(const char *s1, const char *s2);
 int strncmp(const char *s1, const char *s2, size_t n);
 void *memchr(const void *src, int c, size_t len);
+void *memrchr(const void *src, int c, size_t len);
 char *strchr(const char *s, int c);
 void *memset(void *dst, int val, size_t count);
 size_t strlen(const char *s);
diff --git a/include/lib/libc/time.h b/include/lib/libc/time.h
index 71d3e7e..c1c95e5 100644
--- a/include/lib/libc/time.h
+++ b/include/lib/libc/time.h
@@ -4,17 +4,15 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 /*
- * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * Portions copyright (c) 2018-2019, ARM Limited and Contributors.
  * All rights reserved.
  */
 
 #ifndef TIME_H
 #define TIME_H
 
-#include <time_.h>
+#include <stddef.h>
 
-#ifndef NULL
-#define NULL ((void *) 0)
-#endif
+typedef long int time_t;
 
 #endif /* TIME_H */
diff --git a/include/lib/pmf/aarch32/pmf_asm_macros.S b/include/lib/pmf/aarch32/pmf_asm_macros.S
new file mode 100644
index 0000000..1dbb408
--- /dev/null
+++ b/include/lib/pmf/aarch32/pmf_asm_macros.S
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PMF_ASM_MACROS_S
+#define PMF_ASM_MACROS_S
+
+#define PMF_TS_SIZE	8
+
+	/*
+	 * This macro calculates the address of the per-cpu timestamp
+	 * for the given service name and local timestamp id.
+	 * Clobbers: r0 - r4
+	 */
+	.macro pmf_calc_timestamp_addr _name, _tid
+	mov	r4, lr
+	bl	plat_my_core_pos
+	mov	lr, r4
+	ldr	r1, =__PERCPU_TIMESTAMP_SIZE__
+	mov	r2, #(\_tid * PMF_TS_SIZE)
+	mla	r0, r0, r1, r2
+	ldr	r1, =pmf_ts_mem_\_name
+	add	r0, r0, r1
+	.endm
+
+#endif /* PMF_ASM_MACROS_S */
diff --git a/include/lib/pmf/pmf_asm_macros.S b/include/lib/pmf/aarch64/pmf_asm_macros.S
similarity index 100%
rename from include/lib/pmf/pmf_asm_macros.S
rename to include/lib/pmf/aarch64/pmf_asm_macros.S
diff --git a/include/lib/pmf/pmf.h b/include/lib/pmf/pmf.h
index df7c9ff..3fc8e38 100644
--- a/include/lib/pmf/pmf.h
+++ b/include/lib/pmf/pmf.h
@@ -54,108 +54,6 @@
 #define PMF_PSCI_STAT_SVC_ID	0
 #define PMF_RT_INSTR_SVC_ID	1
 
-#if ENABLE_PMF
-/*
- * Convenience macros for capturing time-stamp.
- */
-#define PMF_DECLARE_CAPTURE_TIMESTAMP(_name)			\
-	void pmf_capture_timestamp_with_cache_maint_ ## _name(	\
-				unsigned int tid,		\
-				unsigned long long ts);		\
-	void pmf_capture_timestamp_ ## _name(			\
-				unsigned int tid,		\
-				unsigned long long ts);
-
-#define PMF_CAPTURE_TIMESTAMP(_name, _tid, _flags)			\
-	do {								\
-		unsigned long long ts = read_cntpct_el0();		\
-		if (((_flags) & PMF_CACHE_MAINT) != 0U)			\
-			pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), ts);\
-		else							\
-			pmf_capture_timestamp_ ## _name((_tid), ts);	\
-	} while (0)
-
-#define PMF_CAPTURE_AND_GET_TIMESTAMP(_name, _tid, _flags, _tsval)	\
-	do {								\
-		(_tsval) = read_cntpct_el0();				\
-		CASSERT(sizeof(_tsval) == sizeof(unsigned long long), invalid_tsval_size);\
-		if (((_flags) & PMF_CACHE_MAINT) != 0U)			\
-			pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), (_tsval));\
-		else							\
-			pmf_capture_timestamp_ ## _name((_tid), (_tsval));\
-	} while (0)
-
-#define PMF_WRITE_TIMESTAMP(_name, _tid, _flags, _wrval)		\
-	do {								\
-		CASSERT(sizeof(_wrval) == sizeof(unsigned long long), invalid_wrval_size);\
-		if (((_flags) & PMF_CACHE_MAINT) != 0U)			\
-			pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), (_wrval));\
-		else							\
-			pmf_capture_timestamp_ ## _name((_tid), (_wrval));\
-	} while (0)
-
-/*
- * Convenience macros for retrieving time-stamp.
- */
-#define PMF_DECLARE_GET_TIMESTAMP(_name)			\
-	unsigned long long pmf_get_timestamp_by_index_ ## _name(\
-		unsigned int tid,				\
-		unsigned int cpuid,				\
-		unsigned int flags);				\
-	unsigned long long pmf_get_timestamp_by_mpidr_ ## _name(\
-		unsigned int tid,				\
-		u_register_t mpidr,				\
-		unsigned int flags);
-
-#define PMF_GET_TIMESTAMP_BY_MPIDR(_name, _tid, _mpidr, _flags, _tsval)\
-	_tsval = pmf_get_timestamp_by_mpidr_ ## _name(_tid, _mpidr, _flags)
-
-#define PMF_GET_TIMESTAMP_BY_INDEX(_name, _tid, _cpuid, _flags, _tsval)\
-	_tsval = pmf_get_timestamp_by_index_ ## _name(_tid, _cpuid, _flags)
-
-/* Convenience macros to register a PMF service.*/
-/*
- * This macro is used to register a PMF Service. It allocates PMF memory
- * and defines default service-specific PMF functions.
- */
-#define PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags)	\
-	PMF_ALLOCATE_TIMESTAMP_MEMORY(_name, _totalid)		\
-	PMF_DEFINE_CAPTURE_TIMESTAMP(_name, _flags)		\
-	PMF_DEFINE_GET_TIMESTAMP(_name)
-
-/*
- * This macro is used to register a PMF service, including an
- * SMC interface to that service.
- */
-#define PMF_REGISTER_SERVICE_SMC(_name, _svcid, _totalid, _flags)\
-	PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags)	\
-	PMF_DEFINE_SERVICE_DESC(_name, PMF_ARM_TIF_IMPL_ID,	\
-			_svcid, _totalid, NULL,			\
-			pmf_get_timestamp_by_mpidr_ ## _name)
-
-/*
- * This macro is used to register a PMF service that has an SMC interface
- * but provides its own service-specific PMF functions.
- */
-#define PMF_REGISTER_SERVICE_SMC_OWN(_name, _implid, _svcid, _totalid,	\
-		 _init, _getts)						\
-	PMF_DEFINE_SERVICE_DESC(_name, _implid, _svcid, _totalid,	\
-		 _init, _getts)
-
-#else
-
-#define PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags)
-#define PMF_REGISTER_SERVICE_SMC(_name, _svcid, _totalid, _flags)
-#define PMF_REGISTER_SERVICE_SMC_OWN(_name, _implid, _svcid, _totalid,	\
-				_init, _getts)
-#define PMF_DECLARE_CAPTURE_TIMESTAMP(_name)
-#define PMF_DECLARE_GET_TIMESTAMP(_name)
-#define PMF_CAPTURE_TIMESTAMP(_name, _tid, _flags)
-#define PMF_GET_TIMESTAMP_BY_MPIDR(_name, _tid, _mpidr, _flags, _tsval)
-#define PMF_GET_TIMESTAMP_BY_INDEX(_name, _tid, _cpuid, _flags, _tsval)
-
-#endif /* ENABLE_PMF */
-
 /*******************************************************************************
  * Function & variable prototypes
  ******************************************************************************/
diff --git a/include/lib/pmf/pmf_helpers.h b/include/lib/pmf/pmf_helpers.h
index e6798a7..db38e55 100644
--- a/include/lib/pmf/pmf_helpers.h
+++ b/include/lib/pmf/pmf_helpers.h
@@ -43,6 +43,108 @@
 	pmf_svc_get_ts_t get_ts;
 } pmf_svc_desc_t;
 
+#if ENABLE_PMF
+/*
+ * Convenience macros for capturing time-stamp.
+ */
+#define PMF_DECLARE_CAPTURE_TIMESTAMP(_name)			\
+	void pmf_capture_timestamp_with_cache_maint_ ## _name(	\
+				unsigned int tid,		\
+				unsigned long long ts);		\
+	void pmf_capture_timestamp_ ## _name(			\
+				unsigned int tid,		\
+				unsigned long long ts);
+
+#define PMF_CAPTURE_TIMESTAMP(_name, _tid, _flags)			\
+	do {								\
+		unsigned long long ts = read_cntpct_el0();		\
+		if (((_flags) & PMF_CACHE_MAINT) != 0U)			\
+			pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), ts);\
+		else							\
+			pmf_capture_timestamp_ ## _name((_tid), ts);	\
+	} while (0)
+
+#define PMF_CAPTURE_AND_GET_TIMESTAMP(_name, _tid, _flags, _tsval)	\
+	do {								\
+		(_tsval) = read_cntpct_el0();				\
+		CASSERT(sizeof(_tsval) == sizeof(unsigned long long), invalid_tsval_size);\
+		if (((_flags) & PMF_CACHE_MAINT) != 0U)			\
+			pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), (_tsval));\
+		else							\
+			pmf_capture_timestamp_ ## _name((_tid), (_tsval));\
+	} while (0)
+
+#define PMF_WRITE_TIMESTAMP(_name, _tid, _flags, _wrval)		\
+	do {								\
+		CASSERT(sizeof(_wrval) == sizeof(unsigned long long), invalid_wrval_size);\
+		if (((_flags) & PMF_CACHE_MAINT) != 0U)			\
+			pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), (_wrval));\
+		else							\
+			pmf_capture_timestamp_ ## _name((_tid), (_wrval));\
+	} while (0)
+
+/*
+ * Convenience macros for retrieving time-stamp.
+ */
+#define PMF_DECLARE_GET_TIMESTAMP(_name)			\
+	unsigned long long pmf_get_timestamp_by_index_ ## _name(\
+		unsigned int tid,				\
+		unsigned int cpuid,				\
+		unsigned int flags);				\
+	unsigned long long pmf_get_timestamp_by_mpidr_ ## _name(\
+		unsigned int tid,				\
+		u_register_t mpidr,				\
+		unsigned int flags);
+
+#define PMF_GET_TIMESTAMP_BY_MPIDR(_name, _tid, _mpidr, _flags, _tsval)\
+	_tsval = pmf_get_timestamp_by_mpidr_ ## _name(_tid, _mpidr, _flags)
+
+#define PMF_GET_TIMESTAMP_BY_INDEX(_name, _tid, _cpuid, _flags, _tsval)\
+	_tsval = pmf_get_timestamp_by_index_ ## _name(_tid, _cpuid, _flags)
+
+/* Convenience macros to register a PMF service.*/
+/*
+ * This macro is used to register a PMF Service. It allocates PMF memory
+ * and defines default service-specific PMF functions.
+ */
+#define PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags)	\
+	PMF_ALLOCATE_TIMESTAMP_MEMORY(_name, _totalid)		\
+	PMF_DEFINE_CAPTURE_TIMESTAMP(_name, _flags)		\
+	PMF_DEFINE_GET_TIMESTAMP(_name)
+
+/*
+ * This macro is used to register a PMF service, including an
+ * SMC interface to that service.
+ */
+#define PMF_REGISTER_SERVICE_SMC(_name, _svcid, _totalid, _flags)\
+	PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags)	\
+	PMF_DEFINE_SERVICE_DESC(_name, PMF_ARM_TIF_IMPL_ID,	\
+			_svcid, _totalid, NULL,			\
+			pmf_get_timestamp_by_mpidr_ ## _name)
+
+/*
+ * This macro is used to register a PMF service that has an SMC interface
+ * but provides its own service-specific PMF functions.
+ */
+#define PMF_REGISTER_SERVICE_SMC_OWN(_name, _implid, _svcid, _totalid,	\
+		 _init, _getts)						\
+	PMF_DEFINE_SERVICE_DESC(_name, _implid, _svcid, _totalid,	\
+		 _init, _getts)
+
+#else
+
+#define PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags)
+#define PMF_REGISTER_SERVICE_SMC(_name, _svcid, _totalid, _flags)
+#define PMF_REGISTER_SERVICE_SMC_OWN(_name, _implid, _svcid, _totalid,	\
+				_init, _getts)
+#define PMF_DECLARE_CAPTURE_TIMESTAMP(_name)
+#define PMF_DECLARE_GET_TIMESTAMP(_name)
+#define PMF_CAPTURE_TIMESTAMP(_name, _tid, _flags)
+#define PMF_GET_TIMESTAMP_BY_MPIDR(_name, _tid, _mpidr, _flags, _tsval)
+#define PMF_GET_TIMESTAMP_BY_INDEX(_name, _tid, _cpuid, _flags, _tsval)
+
+#endif /* ENABLE_PMF */
+
 /*
  * Convenience macro to allocate memory for a PMF service.
  *
@@ -69,9 +171,6 @@
 #define PMF_DEFINE_CAPTURE_TIMESTAMP(_name, _flags)			\
 	void pmf_capture_timestamp_ ## _name(				\
 			unsigned int tid,				\
-			unsigned long long ts);				\
-	void pmf_capture_timestamp_ ## _name(				\
-			unsigned int tid,				\
 			unsigned long long ts)				\
 	{								\
 		CASSERT(_flags, select_proper_config);			\
@@ -84,9 +183,6 @@
 	}								\
 	void pmf_capture_timestamp_with_cache_maint_ ## _name(		\
 			unsigned int tid,				\
-			unsigned long long ts);				\
-	void pmf_capture_timestamp_with_cache_maint_ ## _name(		\
-			unsigned int tid,				\
 			unsigned long long ts)				\
 	{								\
 		CASSERT(_flags, select_proper_config);			\
@@ -105,8 +201,6 @@
  */
 #define PMF_DEFINE_GET_TIMESTAMP(_name)					\
 	unsigned long long pmf_get_timestamp_by_index_ ## _name(	\
-		unsigned int tid, unsigned int cpuid, unsigned int flags);\
-	unsigned long long pmf_get_timestamp_by_index_ ## _name(	\
 		unsigned int tid, unsigned int cpuid, unsigned int flags)\
 	{								\
 		PMF_VALIDATE_TID(_name, tid);				\
@@ -114,8 +208,6 @@
 		return __pmf_get_timestamp(base_addr, tid, cpuid, flags);\
 	}								\
 	unsigned long long pmf_get_timestamp_by_mpidr_ ## _name(	\
-		unsigned int tid, u_register_t mpidr, unsigned int flags);\
-	unsigned long long pmf_get_timestamp_by_mpidr_ ## _name(	\
 		unsigned int tid, u_register_t mpidr, unsigned int flags)\
 	{								\
 		PMF_VALIDATE_TID(_name, tid);				\
diff --git a/include/lib/psci/psci.h b/include/lib/psci/psci.h
index 7f7b7e3..b56e98b 100644
--- a/include/lib/psci/psci.h
+++ b/include/lib/psci/psci.h
@@ -20,7 +20,7 @@
 #ifdef PLAT_NUM_PWR_DOMAINS
 #define PSCI_NUM_PWR_DOMAINS	PLAT_NUM_PWR_DOMAINS
 #else
-#define PSCI_NUM_PWR_DOMAINS	(2 * PLATFORM_CORE_COUNT)
+#define PSCI_NUM_PWR_DOMAINS	(U(2) * PLATFORM_CORE_COUNT)
 #endif
 
 #define PSCI_NUM_NON_CPU_PWR_DOMAINS	(PSCI_NUM_PWR_DOMAINS - \
diff --git a/include/lib/smccc.h b/include/lib/smccc.h
index 76e6023..5e13e6f 100644
--- a/include/lib/smccc.h
+++ b/include/lib/smccc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,7 +20,7 @@
 						SMCCC_VERSION_MINOR_SHIFT))
 
 #define SMCCC_MAJOR_VERSION U(1)
-#define SMCCC_MINOR_VERSION U(1)
+#define SMCCC_MINOR_VERSION U(2)
 
 /*******************************************************************************
  * Bit definitions inside the function id as per the SMC calling convention
@@ -41,6 +41,8 @@
 #define FUNCID_NUM_MASK			U(0xffff)
 #define FUNCID_NUM_WIDTH		U(16)
 
+#define GET_SMC_NUM(id)			(((id) >> FUNCID_NUM_SHIFT) & \
+					 FUNCID_NUM_MASK)
 #define GET_SMC_TYPE(id)		(((id) >> FUNCID_TYPE_SHIFT) & \
 					 FUNCID_TYPE_MASK)
 #define GET_SMC_CC(id)			(((id) >> FUNCID_CC_SHIFT) & \
@@ -83,6 +85,12 @@
 #define SMC_UNK				-1
 #define SMC_PREEMPTED			-2	/* Not defined by the SMCCC */
 
+/* Return codes for Arm Architecture Service SMC calls */
+#define SMC_ARCH_CALL_SUCCESS		0
+#define SMC_ARCH_CALL_NOT_SUPPORTED	-1
+#define SMC_ARCH_CALL_NOT_REQUIRED	-2
+#define SMC_ARCH_CALL_INVAL_PARAM	-3
+
 /* Various flags passed to SMC handlers */
 #define SMC_FROM_SECURE		(U(0) << 0)
 #define SMC_FROM_NON_SECURE	(U(1) << 0)
diff --git a/include/lib/sprt/sprt_common.h b/include/lib/sprt/sprt_common.h
deleted file mode 100644
index 27d5027..0000000
--- a/include/lib/sprt/sprt_common.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPRT_COMMON_H
-#define SPRT_COMMON_H
-
-#define SPRT_MAX_MSG_ARGS	6
-
-/*
- * Message types supported.
- */
-#define SPRT_MSG_TYPE_SERVICE_HANDLE_OPEN		1
-#define SPRT_MSG_TYPE_SERVICE_HANDLE_CLOSE		2
-/* TODO: Add other types of SPRT messages. */
-#define SPRT_MSG_TYPE_SERVICE_TUN_REQUEST		10
-
-/*
- * Struct that defines the layout of the fields corresponding to a request in
- * shared memory.
- */
-struct __attribute__((__packed__)) sprt_queue_entry_message {
-	uint32_t type;		/* Type of message (result of an SPCI call). */
-	uint16_t client_id;	/* SPCI client ID */
-	uint16_t service_handle;/* SPCI service handle */
-	uint32_t session_id;	/* Optional SPCI session ID */
-	uint32_t token;		/* SPCI request token */
-	uint64_t args[SPRT_MAX_MSG_ARGS];
-};
-
-#define SPRT_QUEUE_ENTRY_MSG_SIZE	(sizeof(struct sprt_queue_entry_message))
-
-#define SPRT_QUEUE_NUM_BLOCKING		0
-#define SPRT_QUEUE_NUM_NON_BLOCKING	1
-
-#endif /* SPRT_COMMON_H */
diff --git a/include/lib/sprt/sprt_host.h b/include/lib/sprt/sprt_host.h
deleted file mode 100644
index f888141..0000000
--- a/include/lib/sprt/sprt_host.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-#ifndef SPRT_HOST_H
-#define SPRT_HOST_H
-
-#include <stddef.h>
-
-#include "sprt_common.h"
-
-/*
- * Initialize the specified buffer to be used by SPM.
- */
-void sprt_initialize_queues(void *buffer_base, size_t buffer_size);
-
-/*
- * Push a message to the queue number `queue_num` in a buffer that has been
- * initialized by `sprt_initialize_queues`.
- */
-int sprt_push_message(void *buffer_base,
-		      const struct sprt_queue_entry_message *message,
-		      int queue_num);
-
-#endif /* SPRT_HOST_H */
diff --git a/include/lib/utils.h b/include/lib/utils.h
index cdb125c..17ee936 100644
--- a/include/lib/utils.h
+++ b/include/lib/utils.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -79,13 +79,11 @@
  * which is constant and does not depend on the execute address of the binary.
  */
 #define DEFINE_LOAD_SYM_ADDR(_name)		\
-static inline u_register_t load_addr_## _name(void)		\
-{								\
-	u_register_t v;						\
-	/* Create a void reference to silence compiler */	\
-	(void) _name;						\
-	__asm__ volatile ("ldr %0, =" #_name : "=r" (v));	\
-	return v;						\
+static inline u_register_t load_addr_## _name(void)			\
+{									\
+	u_register_t v;							\
+	__asm__ volatile ("ldr %0, =" #_name : "=r" (v) : "X" (#_name));\
+	return v;							\
 }
 
 /* Helper to invoke the function defined by DEFINE_LOAD_SYM_ADDR() */
diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h
index 35ae33a..23f59bd 100644
--- a/include/lib/utils_def.h
+++ b/include/lib/utils_def.h
@@ -77,6 +77,15 @@
 	_x > _y ? _x : _y;		\
 })
 
+#define CLAMP(x, min, max) __extension__ ({ \
+	__typeof__(x) _x = (x); \
+	__typeof__(min) _min = (min); \
+	__typeof__(max) _max = (max); \
+	(void)(&_x == &_min); \
+	(void)(&_x == &_max); \
+	(_x > _max ? _max : (_x < _min ? _min : _x)); \
+})
+
 /*
  * The round_up() macro rounds up a value to the given boundary in a
  * type-agnostic yet type-safe manner. The boundary must be a power of two.
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 53bd13f..b419c85 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -21,7 +21,7 @@
 /* Special value used to verify platform parameters from BL2 to BL31 */
 #define ARM_BL31_PLAT_PARAM_VAL		ULL(0x0f1e2d3c4b5a6978)
 
-#define ARM_SYSTEM_COUNT		1
+#define ARM_SYSTEM_COUNT		U(1)
 
 #define ARM_CACHE_WRITEBACK_SHIFT	6
 
@@ -403,21 +403,16 @@
 #define BL31_LIMIT			(ARM_AP_TZC_DRAM1_BASE +	\
 						PLAT_ARM_MAX_BL31_SIZE)
 #elif (RESET_TO_BL31)
-
-# if ENABLE_PIE
+/* Ensure Position Independent support (PIE) is enabled for this config.*/
+# if !ENABLE_PIE
+#  error "BL31 must be a PIE if RESET_TO_BL31=1."
+#endif
 /*
  * Since this is PIE, we can define BL31_BASE to 0x0 since this macro is solely
  * used for building BL31 and not used for loading BL31.
  */
 #  define BL31_BASE			0x0
 #  define BL31_LIMIT			PLAT_ARM_MAX_BL31_SIZE
-# else
-/* Put BL31_BASE in the middle of the Trusted SRAM.*/
-#  define BL31_BASE			(ARM_TRUSTED_SRAM_BASE + \
-					(PLAT_ARM_TRUSTED_SRAM_SIZE >> 1))
-#  define BL31_LIMIT			(ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)
-# endif /* ENABLE_PIE */
-
 #else
 /* Put BL31 below BL2 in the Trusted SRAM.*/
 #define BL31_BASE			((ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)\
@@ -462,7 +457,7 @@
  * Trusted DRAM (if available) or the DRAM region secured by the TrustZone
  * controller.
  */
-# if ENABLE_SPM
+# if SPM_MM
 #  define TSP_SEC_MEM_BASE		(ARM_AP_TZC_DRAM1_BASE + ULL(0x200000))
 #  define TSP_SEC_MEM_SIZE		(ARM_AP_TZC_DRAM1_SIZE - ULL(0x200000))
 #  define BL32_BASE			(ARM_AP_TZC_DRAM1_BASE + ULL(0x200000))
@@ -505,9 +500,9 @@
  * SPD and no SPM, as they are the only ones that can be used as BL32.
  */
 #if defined(__aarch64__) && !JUNO_AARCH32_EL3_RUNTIME
-# if defined(SPD_none) && !ENABLE_SPM
+# if defined(SPD_none) && !SPM_MM
 #  undef BL32_BASE
-# endif /* defined(SPD_none) && !ENABLE_SPM */
+# endif /* defined(SPD_none) && !SPM_MM*/
 #endif /* defined(__aarch64__) && !JUNO_AARCH32_EL3_RUNTIME */
 
 /*******************************************************************************
diff --git a/include/plat/arm/common/arm_reclaim_init.ld.S b/include/plat/arm/common/arm_reclaim_init.ld.S
index 8f22170..b5bf473 100644
--- a/include/plat/arm/common/arm_reclaim_init.ld.S
+++ b/include/plat/arm/common/arm_reclaim_init.ld.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
  */
@@ -27,10 +27,9 @@
             "BL31 init has exceeded progbits limit.")
 #endif
 
-#if RECLAIM_INIT_CODE
     ASSERT(__INIT_CODE_END__ <= __STACKS_END__,
         "Init code ends past the end of the stacks")
-#endif
+
 }
 
 #endif /* ARM_RECLAIM_INIT_LD_S */
diff --git a/include/plat/arm/common/arm_sip_svc.h b/include/plat/arm/common/arm_sip_svc.h
index 16573ce..85fdb28 100644
--- a/include/plat/arm/common/arm_sip_svc.h
+++ b/include/plat/arm/common/arm_sip_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,9 +16,15 @@
 /*					U(0x8200ff02) is reserved */
 #define ARM_SIP_SVC_VERSION		U(0x8200ff03)
 
+/* PMF_SMC_GET_TIMESTAMP_32		0x82000010 */
+/* PMF_SMC_GET_TIMESTAMP_64		0xC2000010 */
+
 /* Function ID for requesting state switch of lower EL */
 #define ARM_SIP_SVC_EXE_STATE_SWITCH	U(0x82000020)
 
+/* DEBUGFS_SMC_32			0x82000030U */
+/* DEBUGFS_SMC_64			0xC2000030U */
+
 /* ARM SiP Service Calls version numbers */
 #define ARM_SIP_SVC_VERSION_MAJOR		U(0x0)
 #define ARM_SIP_SVC_VERSION_MINOR		U(0x2)
diff --git a/include/plat/arm/common/arm_spm_def.h b/include/plat/arm/common/arm_spm_def.h
index 16c806b..c43583d 100644
--- a/include/plat/arm/common/arm_spm_def.h
+++ b/include/plat/arm/common/arm_spm_def.h
@@ -10,31 +10,6 @@
 #include <lib/xlat_tables/xlat_tables_defs.h>
 
 /*
- * Reserve 4 MiB for binaries of Secure Partitions and Resource Description
- * blobs.
- */
-#define PLAT_SP_PACKAGE_BASE	BL32_BASE
-#define PLAT_SP_PACKAGE_SIZE	ULL(0x400000)
-
-#define PLAT_MAP_SP_PACKAGE_MEM_RO	MAP_REGION_FLAT(		\
-						PLAT_SP_PACKAGE_BASE,	\
-						PLAT_SP_PACKAGE_SIZE,	\
-						MT_MEMORY | MT_RO | MT_SECURE)
-#define PLAT_MAP_SP_PACKAGE_MEM_RW	MAP_REGION_FLAT(		\
-						PLAT_SP_PACKAGE_BASE,	\
-						PLAT_SP_PACKAGE_SIZE,	\
-						MT_MEMORY | MT_RW | MT_SECURE)
-
-/*
- * The rest of the memory reserved for BL32 is free for SPM to use it as memory
- * pool to allocate memory regions requested in the resource description.
- */
-#define PLAT_SPM_HEAP_BASE	(PLAT_SP_PACKAGE_BASE + PLAT_SP_PACKAGE_SIZE)
-#define PLAT_SPM_HEAP_SIZE	(BL32_LIMIT - BL32_BASE - PLAT_SP_PACKAGE_SIZE)
-
-#if SPM_MM
-
-/*
  * If BL31 is placed in DRAM, place the Secure Partition in DRAM right after the
  * region used by BL31. If BL31 it is placed in SRAM, put the Secure Partition
  * at the base of DRAM.
@@ -121,23 +96,8 @@
 /* Total number of memory regions with distinct properties */
 #define ARM_SP_IMAGE_NUM_MEM_REGIONS	6
 
-#endif /* SPM_MM */
-
 /* Cookies passed to the Secure Partition at boot. Not used by ARM platforms. */
 #define PLAT_SPM_COOKIE_0		ULL(0)
 #define PLAT_SPM_COOKIE_1		ULL(0)
 
-/*
- * Max number of elements supported by SPM in this platform. The defines below
- * are used to allocate memory at compile time for different arrays in SPM.
- */
-#define PLAT_SPM_MAX_PARTITIONS		U(2)
-
-#define PLAT_SPM_MEM_REGIONS_MAX	U(80)
-#define PLAT_SPM_NOTIFICATIONS_MAX	U(30)
-#define PLAT_SPM_SERVICES_MAX		U(30)
-
-#define PLAT_SPCI_HANDLES_MAX_NUM	U(20)
-#define PLAT_SPM_RESPONSES_MAX		U(30)
-
 #endif /* ARM_SPM_DEF_H */
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 07a46c5..02feec7 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -38,7 +38,7 @@
  *   - Region 1 with secure access only;
  *   - the remaining DRAM regions access from the given Non-Secure masters.
  ******************************************************************************/
-#if ENABLE_SPM && SPM_MM
+#if SPM_MM
 #define ARM_TZC_REGIONS_DEF						\
 	{ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END,			\
 		TZC_REGION_S_RDWR, 0},					\
@@ -254,6 +254,11 @@
 int plat_arm_bl1_fwu_needed(void);
 __dead2 void plat_arm_error_handler(int err);
 
+/*
+ * Optional function in ARM standard platforms
+ */
+void plat_arm_override_gicr_frames(const uintptr_t *plat_gicr_frames);
+
 #if ARM_PLAT_MT
 unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr);
 #endif
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index eeae621..332cfca 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -22,7 +22,7 @@
 struct bl_load_info;
 struct bl_params;
 struct mmap_region;
-struct secure_partition_boot_info;
+struct spm_mm_boot_info;
 struct sp_res_desc;
 
 /*******************************************************************************
@@ -237,7 +237,7 @@
 void plat_psci_stat_accounting_stop(const psci_power_state_t *state_info);
 u_register_t plat_psci_stat_get_residency(unsigned int lvl,
 			const psci_power_state_t *state_info,
-			int last_cpu_idx);
+			unsigned int last_cpu_idx);
 plat_local_state_t plat_get_target_pwr_state(unsigned int lvl,
 			const plat_local_state_t *states,
 			unsigned int ncpu);
@@ -267,7 +267,7 @@
  * Secure Partitions functions
  ******************************************************************************/
 const struct mmap_region *plat_get_secure_partition_mmap(void *cookie);
-const struct secure_partition_boot_info *plat_get_secure_partition_boot_info(
+const struct spm_mm_boot_info *plat_get_secure_partition_boot_info(
 		void *cookie);
 int plat_spm_sp_rd_load(struct sp_res_desc *rd, const void *ptr, size_t size);
 int plat_spm_sp_get_next_address(void **sp_base, size_t *sp_size,
diff --git a/include/plat/marvell/a8k/common/armada_common.h b/include/plat/marvell/a8k/common/armada_common.h
index dd2a24a..709d009 100644
--- a/include/plat/marvell/a8k/common/armada_common.h
+++ b/include/plat/marvell/a8k/common/armada_common.h
@@ -124,5 +124,6 @@
 			       uint32_t *size, uintptr_t base);
 int marvell_get_ccu_memory_map(int ap_idx, struct addr_map_win **win,
 			       uint32_t *size);
+int system_power_off(void);
 
 #endif /* ARMADA_COMMON_H */
diff --git a/include/services/mm_svc.h b/include/services/mm_svc.h
deleted file mode 100644
index c111326..0000000
--- a/include/services/mm_svc.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef MM_SVC_H
-#define MM_SVC_H
-
-#if SPM_MM
-
-#include <lib/utils_def.h>
-
-#define MM_VERSION_MAJOR	U(1)
-#define MM_VERSION_MAJOR_SHIFT	16
-#define MM_VERSION_MAJOR_MASK	U(0x7FFF)
-#define MM_VERSION_MINOR	U(0)
-#define MM_VERSION_MINOR_SHIFT	0
-#define MM_VERSION_MINOR_MASK	U(0xFFFF)
-#define MM_VERSION_FORM(major, minor)	((major << MM_VERSION_MAJOR_SHIFT) | (minor))
-#define MM_VERSION_COMPILED	MM_VERSION_FORM(MM_VERSION_MAJOR, MM_VERSION_MINOR)
-
-/*
- * SMC IDs defined in [1] for accessing MM services from the Non-secure world.
- * These FIDs occupy the range 0x40 - 0x5f.
- * [1] DEN0060A_ARM_MM_Interface_Specification.pdf
- */
-#define MM_VERSION_AARCH32		U(0x84000040)
-
-#define MM_COMMUNICATE_AARCH64		U(0xC4000041)
-#define MM_COMMUNICATE_AARCH32		U(0x84000041)
-
-#endif /* SPM_MM */
-
-#endif /* MM_SVC_H */
diff --git a/include/services/sp_res_desc.h b/include/services/sp_res_desc.h
deleted file mode 100644
index b8be72e..0000000
--- a/include/services/sp_res_desc.h
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPM_RES_DESC_H
-#define SPM_RES_DESC_H
-
-#include <stdint.h>
-
-#include <services/sp_res_desc_def.h>
-
-/*******************************************************************************
- * Attribute Section
- ******************************************************************************/
-
-struct sp_rd_sect_attribute {
-	/*
-	 * Version of the resource description.
-	 */
-	uint16_t version;
-
-	/*
-	 * Type of the Secure Partition:
-	 * - bit[0]: SP Type
-	 *   - b'0: UP SP
-	 *   - b'1: MP SP
-	 * If UP SP:
-	 * - bit[1]: Type of UP SP
-	 *   - b'0: Migratable UP SP
-	 *   - b'1: Pinned UP SP
-	 */
-	uint16_t sp_type;
-
-	/*
-	 * If this is a Pinned UP SP, PE on which the Pinned UP SP will run.
-	 */
-	uint32_t pe_mpidr;
-
-	/*
-	 * Run-Time Exception Level:
-	 * - 0: SEL0 SP
-	 * - 1: SEL1 SP
-	 */
-	uint8_t runtime_el;
-
-	/*
-	 * Type of Execution:
-	 * - 0: Init-time only
-	 * - 1: Run-time Execution
-	 */
-	uint8_t exec_type;
-
-	/*
-	 * Expected behavior upon failure:
-	 * - 0: Restartable
-	 * - 1: One-Shot
-	 */
-	uint8_t panic_policy;
-
-	/*
-	 * Translation Granule to use in the SP translation regime:
-	 * - 0: 4KB
-	 * - 1: 16KB
-	 * - 2: 64KB
-	 */
-	uint8_t xlat_granule;
-
-	/*
-	 * Size of the SP binary in bytes.
-	 */
-	uint32_t binary_size;
-
-	/*
-	 * - If SP is NOT PIE:
-	 *   - VA Address where the SP expects to be loaded.
-	 * - If SP is PIE:
-	 *   - Ignored.
-	 */
-	uint64_t load_address;
-
-	/*
-	 * Initial execution address. This is a VA as the SP sees it.
-	 */
-	uint64_t entrypoint;
-};
-
-/*******************************************************************************
- * Memory Region Section
- ******************************************************************************/
-
-struct sp_rd_sect_mem_region {
-	/*
-	 * Name of a Memory region, including null terminator. Reserved names:
-	 * - "Client Shared Memory Region":
-	 *   Memory region where memory shared by clients shall be mapped.
-	 * - "Queue Memory Region":
-	 *   Memory region shared with SPM for SP queue management.
-	 */
-	char name[RD_MEM_REGION_NAME_LEN];
-
-	/*
-	 * Memory Attributes:
-	 * - bits[3:0]: Type of memory
-	 *   - 0: Device
-	 *   - 1: Code
-	 *   - 2: Data
-	 *   - 3: BSS
-	 *   - 4: Read-only Data
-	 *   - 5: SPM-to-SP Shared Memory Region
-	 *   - 6: Client Shared Memory Region
-	 *   - 7: Miscellaneous
-	 * - If memory is { SPM-to-SP shared Memory, Client Shared Memory,
-	 *   Miscellaneous }
-	 *   - bits[4]: Position Independent
-	 *     - b'0: Position Dependent
-	 *     - b'1: Position Independent
-	 */
-	uint32_t attr;
-
-	/*
-	 * Base address of the memory region.
-	 */
-	uint64_t base;
-
-	/*
-	 * Size of the memory region.
-	 */
-	uint64_t size;
-
-	/*
-	 * Pointer to next memory region (or NULL if this is the last one).
-	 */
-	struct sp_rd_sect_mem_region *next;
-};
-
-/*******************************************************************************
- * Notification Section
- ******************************************************************************/
-
-struct sp_rd_sect_notification {
-	/*
-	 * Notification attributes:
-	 * - bit[31]: Notification Type
-	 *   - b'0: Platform Notification
-	 *   - b'1: Interrupt
-	 * If Notification Type == Platform Notification
-	 * - bits[15:0]: Implementation-defined Notification ID
-	 * If Notification Type == Interrupt
-	 * - bits[15:0]: IRQ number
-	 * - bits[23:16]: Interrupt Priority
-	 * - bit[24]: Trigger Type
-	 *   - b'0: Edge Triggered
-	 *   - b'1: Level Triggered
-	 * - bit[25]: Trigger Level
-	 *   - b'0: Falling or Low
-	 *   - b'1: Rising or High
-	 */
-	uint32_t attr;
-
-	/*
-	 * Processing Element.
-	 * If Notification Type == Interrupt && IRQ number is { SGI, LPI }
-	 * - PE ID to which IRQ will be forwarded
-	 */
-	uint32_t pe;
-
-	/*
-	 * Pointer to next notification (or NULL if this is the last one).
-	 */
-	struct sp_rd_sect_notification *next;
-};
-
-/*******************************************************************************
- * Service Description Section
- ******************************************************************************/
-
-struct sp_rd_sect_service {
-	/*
-	 * Service identifier.
-	 */
-	uint32_t uuid[4];
-
-	/*
-	 * Accessibility Options:
-	 * - bit[0]: Accessibility by secure-world clients
-	 *   - b'0: Not Accessible
-	 *   - b'1: Accessible
-	 * - bit[1]: Accessible by EL3
-	 *   - b'0: Not Accessible
-	 *   - b'1: Accessible
-	 * - bit[2]: Accessible by normal-world clients
-	 *   - b'0: Not Accessible
-	 *   - b'1: Accessible
-	 */
-	uint8_t accessibility;
-
-	/*
-	 * Request type supported:
-	 * - bit[0]: Blocking request
-	 *   - b'0: Not Enable
-	 *   - b'1: Enable
-	 * - bit[1]: Non-blocking request
-	 *   - b'0: Not Enable
-	 *   - b'1: Enable
-	 */
-	uint8_t request_type;
-
-	/*
-	 * Maximum number of client connections that the service can support.
-	 */
-	uint16_t connection_quota;
-
-	/*
-	 * If the service requires secure world memory to be shared with its
-	 * clients:
-	 * - Maximum amount of secure world memory in bytes to reserve from the
-	 *   secure world memory pool for the service.
-	 */
-	uint32_t secure_mem_size;
-
-	/*
-	 * Interrupt number used to notify the SP for the service.
-	 * - Should also be enabled in the Notification Section.
-	 */
-	uint32_t interrupt_num;
-
-	/*
-	 * Pointer to next service (or NULL if this is the last one).
-	 */
-	struct sp_rd_sect_service *next;
-};
-
-/*******************************************************************************
- * Complete resource description struct
- ******************************************************************************/
-
-struct sp_res_desc {
-
-	/* Attribute Section */
-	struct sp_rd_sect_attribute attribute;
-
-	/* System Resource Section */
-	struct sp_rd_sect_mem_region *mem_region;
-
-	struct sp_rd_sect_notification *notification;
-
-	/* Service Section */
-	struct sp_rd_sect_service *service;
-};
-
-#endif /* SPM_RES_DESC_H */
diff --git a/include/services/sp_res_desc_def.h b/include/services/sp_res_desc_def.h
deleted file mode 100644
index 5a3c50d..0000000
--- a/include/services/sp_res_desc_def.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPM_RES_DESC_DEFS_H
-#define SPM_RES_DESC_DEFS_H
-
-#include <lib/utils_def.h>
-
-/*******************************************************************************
- * Attribute Section
- ******************************************************************************/
-
-#define RD_ATTR_TYPE_UP_MIGRATABLE	U(0)
-#define RD_ATTR_TYPE_UP_PINNED		U(2)
-#define RD_ATTR_TYPE_MP			U(1)
-
-#define RD_ATTR_RUNTIME_SEL0		U(0)
-#define RD_ATTR_RUNTIME_SEL1		U(1)
-
-#define RD_ATTR_INIT_ONLY		U(0)
-#define RD_ATTR_RUNTIME			U(1)
-
-#define RD_ATTR_PANIC_RESTART		U(0)
-#define RD_ATTR_PANIC_ONESHOT		U(1)
-
-#define RD_ATTR_XLAT_GRANULE_4KB	U(0)
-#define RD_ATTR_XLAT_GRANULE_16KB	U(1)
-#define RD_ATTR_XLAT_GRANULE_64KB	U(2)
-
-/*******************************************************************************
- * Memory Region Section
- ******************************************************************************/
-
-#define RD_MEM_REGION_NAME_LEN		U(32)
-
-#define RD_MEM_DEVICE			U(0)
-#define RD_MEM_NORMAL_CODE		U(1)
-#define RD_MEM_NORMAL_DATA		U(2)
-#define RD_MEM_NORMAL_BSS		U(3)
-#define RD_MEM_NORMAL_RODATA		U(4)
-#define RD_MEM_NORMAL_SPM_SP_SHARED_MEM	U(5)
-#define RD_MEM_NORMAL_CLIENT_SHARED_MEM	U(6)
-#define RD_MEM_NORMAL_MISCELLANEOUS	U(7)
-
-#define RD_MEM_MASK			U(15)
-
-#define RD_MEM_IS_PIE			(U(1) << 4)
-
-/*******************************************************************************
- * Notification Section
- ******************************************************************************/
-
-#define RD_NOTIF_TYPE_PLATFORM		(U(0) << 31)
-#define RD_NOTIF_TYPE_INTERRUPT		(U(1) << 31)
-
-#define RD_NOTIF_PLAT_ID_MASK		U(0xFFFF)
-#define RD_NOTIF_PLAT_ID_SHIFT		U(0)
-
-#define RD_NOTIF_PLATFORM(id)						\
-	(RD_NOTIF_TYPE_PLATFORM						\
-	| (((id) & RD_NOTIF_PLAT_ID_MASK) << RD_NOTIF_PLAT_ID_SHIFT))
-
-#define RD_NOTIF_IRQ_NUM_MASK		U(0xFFFF)
-#define RD_NOTIF_IRQ_NUM_SHIFT		U(0)
-#define RD_NOTIF_IRQ_PRIO_MASK		U(0xFF)
-#define RD_NOTIF_IRQ_PRIO_SHIFT		U(16)
-
-#define RD_NOTIF_IRQ_EDGE_FALLING	U(0)
-#define RD_NOTIF_IRQ_EDGE_RISING	U(2)
-#define RD_NOTIF_IRQ_LEVEL_LOW		U(1)
-#define RD_NOTIF_IRQ_LEVEL_HIGH		U(3)
-#define RD_NOTIF_IRQ_TRIGGER_SHIFT	U(24)
-
-#define RD_NOTIF_IRQ(num, prio, trig)					\
-	(RD_NOTIF_TYPE_IRQ						\
-	| (((num) & RD_NOTIF_IRQ_NUM_MASK) << RD_NOTIF_IRQ_NUM_SHIFT)	\
-	| (((prio) & RD_NOTIF_IRQ_PRIO_MASK) << RD_NOTIF_IRQ_PRIO_SHIFT) \
-	| (((trig) << RD_NOTIF_IRQ_TRIGGER_SHIFT)))
-
-/*******************************************************************************
- * Service Description Section
- ******************************************************************************/
-
-#define RD_SERV_ACCESS_SECURE		(U(1) << 0)
-#define RD_SERV_ACCESS_EL3		(U(1) << 1)
-#define RD_SERV_ACCESS_NORMAL		(U(1) << 2)
-
-#define RD_SERV_SUPPORT_BLOCKING	(U(1) << 0)
-#define RD_SERV_SUPPORT_NON_BLOCKING	(U(1) << 0)
-
-#endif /* SPM_RES_DESC_DEFS_H */
diff --git a/include/services/spci_svc.h b/include/services/spci_svc.h
deleted file mode 100644
index 1d02bfa..0000000
--- a/include/services/spci_svc.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPCI_SVC_H
-#define SPCI_SVC_H
-
-#include <lib/smccc.h>
-#include <lib/utils_def.h>
-
-/* SPCI_VERSION helpers */
-
-#define SPCI_VERSION_MAJOR		U(0)
-#define SPCI_VERSION_MAJOR_SHIFT	16
-#define SPCI_VERSION_MAJOR_MASK		U(0x7FFF)
-#define SPCI_VERSION_MINOR		U(1)
-#define SPCI_VERSION_MINOR_SHIFT	0
-#define SPCI_VERSION_MINOR_MASK		U(0xFFFF)
-#define SPCI_VERSION_FORM(major, minor)	((((major) & SPCI_VERSION_MAJOR_MASK)  \
-						<< SPCI_VERSION_MAJOR_SHIFT) | \
-					((minor) & SPCI_VERSION_MINOR_MASK))
-#define SPCI_VERSION_COMPILED		SPCI_VERSION_FORM(SPCI_VERSION_MAJOR, \
-							  SPCI_VERSION_MINOR)
-
-/* Definitions to build the complete SMC ID */
-
-#define SPCI_FID_MISC_FLAG		(U(0) << 27)
-#define SPCI_FID_MISC_SHIFT		U(20)
-#define SPCI_FID_MISC_MASK		U(0x7F)
-
-#define SPCI_FID_TUN_FLAG		(U(1) << 27)
-#define SPCI_FID_TUN_SHIFT		U(24)
-#define SPCI_FID_TUN_MASK		U(0x7)
-
-#define OEN_SPCI_START			U(0x30)
-#define OEN_SPCI_END			U(0x3F)
-
-#define SPCI_SMC(spci_fid)	((OEN_SPCI_START << FUNCID_OEN_SHIFT) | \
-				 (U(1) << 31) | (spci_fid))
-#define SPCI_MISC_32(misc_fid)	((SMC_32 << FUNCID_CC_SHIFT) |	\
-				 SPCI_FID_MISC_FLAG |		\
-				 SPCI_SMC((misc_fid) << SPCI_FID_MISC_SHIFT))
-#define SPCI_MISC_64(misc_fid)	((SMC_64 << FUNCID_CC_SHIFT) |	\
-				 SPCI_FID_MISC_FLAG |		\
-				 SPCI_SMC((misc_fid) << SPCI_FID_MISC_SHIFT))
-#define SPCI_TUN_32(tun_fid)	((SMC_32 << FUNCID_CC_SHIFT) |	\
-				 SPCI_FID_TUN_FLAG |		\
-				 SPCI_SMC((tun_fid) << SPCI_FID_TUN_SHIFT))
-#define SPCI_TUN_64(tun_fid)	((SMC_64 << FUNCID_CC_SHIFT) |	\
-				 SPCI_FID_TUN_FLAG |		\
-				 SPCI_SMC((tun_fid) << SPCI_FID_TUN_SHIFT))
-
-/* SPCI miscellaneous functions */
-
-#define SPCI_FID_VERSION			U(0x0)
-#define SPCI_FID_SERVICE_HANDLE_OPEN		U(0x2)
-#define SPCI_FID_SERVICE_HANDLE_CLOSE		U(0x3)
-#define SPCI_FID_SERVICE_MEM_REGISTER		U(0x4)
-#define SPCI_FID_SERVICE_MEM_UNREGISTER		U(0x5)
-#define SPCI_FID_SERVICE_MEM_PUBLISH		U(0x6)
-#define SPCI_FID_SERVICE_REQUEST_BLOCKING	U(0x7)
-#define SPCI_FID_SERVICE_REQUEST_START		U(0x8)
-#define SPCI_FID_SERVICE_GET_RESPONSE		U(0x9)
-#define SPCI_FID_SERVICE_RESET_CLIENT_STATE	U(0xA)
-
-/* SPCI tunneling functions */
-
-#define SPCI_FID_SERVICE_TUN_REQUEST_START	U(0x0)
-#define SPCI_FID_SERVICE_REQUEST_RESUME		U(0x1)
-#define SPCI_FID_SERVICE_TUN_REQUEST_BLOCKING	U(0x2)
-
-/* Complete SMC IDs and associated values */
-
-#define SPCI_VERSION				SPCI_MISC_32(SPCI_FID_VERSION)
-
-#define SPCI_SERVICE_HANDLE_OPEN		SPCI_MISC_32(SPCI_FID_SERVICE_HANDLE_OPEN)
-#define SPCI_SERVICE_HANDLE_OPEN_NOTIFY_BIT	U(1)
-
-#define SPCI_SERVICE_HANDLE_CLOSE		SPCI_MISC_32(SPCI_FID_SERVICE_HANDLE_CLOSE)
-
-#define SPCI_SERVICE_MEM_REGISTER_AARCH32	SPCI_MISC_32(SPCI_FID_SERVICE_MEM_REGISTER)
-#define SPCI_SERVICE_MEM_REGISTER_AARCH64	SPCI_MISC_64(SPCI_FID_SERVICE_MEM_REGISTER)
-
-#define SPCI_SERVICE_MEM_UNREGISTER_AARCH32	SPCI_MISC_32(SPCI_FID_SERVICE_MEM_UNREGISTER)
-#define SPCI_SERVICE_MEM_UNREGISTER_AARCH64	SPCI_MISC_64(SPCI_FID_SERVICE_MEM_UNREGISTER)
-
-#define SPCI_SERVICE_MEM_PUBLISH_AARCH32	SPCI_MISC_32(SPCI_FID_SERVICE_MEM_PUBLISH)
-#define SPCI_SERVICE_MEM_PUBLISH_AARCH64	SPCI_MISC_64(SPCI_FID_SERVICE_MEM_PUBLISH)
-
-#define SPCI_SERVICE_REQUEST_BLOCKING_AARCH32	SPCI_MISC_32(SPCI_FID_SERVICE_REQUEST_BLOCKING)
-#define SPCI_SERVICE_REQUEST_BLOCKING_AARCH64	SPCI_MISC_64(SPCI_FID_SERVICE_REQUEST_BLOCKING)
-
-#define SPCI_SERVICE_REQUEST_START_AARCH32	SPCI_MISC_32(SPCI_FID_SERVICE_REQUEST_START)
-#define SPCI_SERVICE_REQUEST_START_AARCH64	SPCI_MISC_64(SPCI_FID_SERVICE_REQUEST_START)
-
-#define SPCI_SERVICE_GET_RESPONSE_AARCH32	SPCI_MISC_32(SPCI_FID_SERVICE_GET_RESPONSE)
-#define SPCI_SERVICE_GET_RESPONSE_AARCH64	SPCI_MISC_64(SPCI_FID_SERVICE_GET_RESPONSE)
-
-#define SPCI_SERVICE_RESET_CLIENT_STATE_AARCH32	SPCI_MISC_32(SPCI_FID_SERVICE_RESET_CLIENT_STATE)
-#define SPCI_SERVICE_RESET_CLIENT_STATE_AARCH64	SPCI_MISC_64(SPCI_FID_SERVICE_RESET_CLIENT_STATE)
-
-#define SPCI_SERVICE_TUN_REQUEST_START_AARCH32	SPCI_TUN_32(SPCI_FID_SERVICE_TUN_REQUEST_START)
-#define SPCI_SERVICE_TUN_REQUEST_START_AARCH64	SPCI_TUN_64(SPCI_FID_SERVICE_TUN_REQUEST_START)
-
-#define SPCI_SERVICE_REQUEST_RESUME_AARCH32	SPCI_TUN_32(SPCI_FID_SERVICE_REQUEST_RESUME)
-#define SPCI_SERVICE_REQUEST_RESUME_AARCH64	SPCI_TUN_64(SPCI_FID_SERVICE_REQUEST_RESUME)
-
-#define SPCI_SERVICE_TUN_REQUEST_BLOCKING_AARCH32 SPCI_TUN_32(SPCI_FID_SERVICE_TUN_REQUEST_BLOCKING)
-#define SPCI_SERVICE_TUN_REQUEST_BLOCKING_AARCH64 SPCI_TUN_64(SPCI_FID_SERVICE_TUN_REQUEST_BLOCKING)
-
-/* SPCI error codes. */
-
-#define SPCI_SUCCESS		 0
-#define SPCI_NOT_SUPPORTED	-1
-#define SPCI_INVALID_PARAMETER	-2
-#define SPCI_NO_MEMORY		-3
-#define SPCI_BUSY		-4
-#define SPCI_QUEUED		-5
-#define SPCI_DENIED		-6
-#define SPCI_NOT_PRESENT	-7
-
-#endif /* SPCI_SVC_H */
diff --git a/include/services/secure_partition.h b/include/services/spm_mm_partition.h
similarity index 70%
rename from include/services/secure_partition.h
rename to include/services/spm_mm_partition.h
index 0510f80..ad5ceef 100644
--- a/include/services/secure_partition.h
+++ b/include/services/spm_mm_partition.h
@@ -4,17 +4,15 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef SECURE_PARTITION_H
-#define SECURE_PARTITION_H
-
-#if SPM_MM
+#ifndef SPM_MM_PARTITION_H
+#define SPM_MM_PARTITION_H
 
 #include <stdint.h>
 
 #include <lib/utils_def.h>
 
 /*
- * Flags used by the secure_partition_mp_info structure to describe the
+ * Flags used by the spm_mm_mp_info structure to describe the
  * characteristics of a cpu. Only a single flag is defined at the moment to
  * indicate the primary cpu.
  */
@@ -24,13 +22,13 @@
  * This structure is used to provide information required to initialise a S-EL0
  * partition.
  */
-typedef struct secure_partition_mp_info {
+typedef struct spm_mm_mp_info {
 	uint64_t		mpidr;
 	uint32_t		linear_id;
 	uint32_t		flags;
-} secure_partition_mp_info_t;
+} spm_mm_mp_info_t;
 
-typedef struct secure_partition_boot_info {
+typedef struct spm_mm_boot_info {
 	param_header_t		h;
 	uint64_t		sp_mem_base;
 	uint64_t		sp_mem_limit;
@@ -46,9 +44,7 @@
 	uint64_t		sp_shared_buf_size;
 	uint32_t		num_sp_mem_regions;
 	uint32_t		num_cpus;
-	secure_partition_mp_info_t	*mp_info;
-} secure_partition_boot_info_t;
-
-#endif /* SPM_MM */
+	spm_mm_mp_info_t	*mp_info;
+} spm_mm_boot_info_t;
 
-#endif /* SECURE_PARTITION_H */
+#endif /* SPM_MM_PARTITION_H */
diff --git a/include/services/spm_mm_svc.h b/include/services/spm_mm_svc.h
new file mode 100644
index 0000000..3148beb
--- /dev/null
+++ b/include/services/spm_mm_svc.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPM_MM_SVC_H
+#define SPM_MM_SVC_H
+
+#include <lib/utils_def.h>
+
+/*
+ * The MM_VERSION_XXX definitions are used when responding to the
+ * MM_VERSION_AARCH32 service request. The version returned is different between
+ * this request and the SPM_MM_VERSION_AARCH32 request - both have been retained
+ * for compatibility.
+ */
+#define MM_VERSION_MAJOR	U(1)
+#define MM_VERSION_MAJOR_SHIFT	16
+#define MM_VERSION_MAJOR_MASK	U(0x7FFF)
+#define MM_VERSION_MINOR	U(0)
+#define MM_VERSION_MINOR_SHIFT	0
+#define MM_VERSION_MINOR_MASK	U(0xFFFF)
+#define MM_VERSION_FORM(major, minor) ((major << MM_VERSION_MAJOR_SHIFT) | \
+				       (minor))
+#define MM_VERSION_COMPILED	MM_VERSION_FORM(MM_VERSION_MAJOR, \
+						MM_VERSION_MINOR)
+
+#define SPM_MM_VERSION_MAJOR		  U(0)
+#define SPM_MM_VERSION_MAJOR_SHIFT	  16
+#define SPM_MM_VERSION_MAJOR_MASK	  U(0x7FFF)
+#define SPM_MM_VERSION_MINOR		  U(1)
+#define SPM_MM_VERSION_MINOR_SHIFT	  0
+#define SPM_MM_VERSION_MINOR_MASK	  U(0xFFFF)
+#define SPM_MM_VERSION_FORM(major, minor) ((major << \
+					    SPM_MM_VERSION_MAJOR_SHIFT) | \
+					   (minor))
+#define SPM_MM_VERSION_COMPILED	SPM_MM_VERSION_FORM(SPM_MM_VERSION_MAJOR, \
+						    SPM_MM_VERSION_MINOR)
+
+/* These macros are used to identify SPM-MM calls using the SMC function ID */
+#define SPM_MM_FID_MASK			U(0xffff)
+#define SPM_MM_FID_MIN_VALUE		U(0x40)
+#define SPM_MM_FID_MAX_VALUE		U(0x7f)
+#define is_spm_mm_fid(_fid)						 \
+		((((_fid) & SPM_MM_FID_MASK) >= SPM_MM_FID_MIN_VALUE) && \
+		 (((_fid) & SPM_MM_FID_MASK) <= SPM_MM_FID_MAX_VALUE))
+
+/*
+ * SMC IDs defined in [1] for accessing MM services from the Non-secure world.
+ * These FIDs occupy the range 0x40 - 0x5f.
+ * [1] DEN0060A_ARM_MM_Interface_Specification.pdf
+ */
+#define MM_VERSION_AARCH32		U(0x84000040)
+#define MM_COMMUNICATE_AARCH64		U(0xC4000041)
+#define MM_COMMUNICATE_AARCH32		U(0x84000041)
+
+/*
+ * SMC IDs defined for accessing services implemented by the Secure Partition
+ * Manager from the Secure Partition(s). These services enable a partition to
+ * handle delegated events and request privileged operations from the manager.
+ * They occupy the range 0x60-0x7f.
+ */
+#define SPM_MM_VERSION_AARCH32			U(0x84000060)
+#define MM_SP_EVENT_COMPLETE_AARCH64		U(0xC4000061)
+#define MM_SP_MEMORY_ATTRIBUTES_GET_AARCH64	U(0xC4000064)
+#define MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64	U(0xC4000065)
+
+/*
+ * Macros used by MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64.
+ */
+
+#define MM_SP_MEMORY_ATTRIBUTES_ACCESS_NOACCESS	U(0)
+#define MM_SP_MEMORY_ATTRIBUTES_ACCESS_RW	U(1)
+/* Value U(2) is reserved. */
+#define MM_SP_MEMORY_ATTRIBUTES_ACCESS_RO	U(3)
+#define MM_SP_MEMORY_ATTRIBUTES_ACCESS_MASK	U(3)
+#define MM_SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT	0
+
+#define MM_SP_MEMORY_ATTRIBUTES_EXEC		(U(0) << 2)
+#define MM_SP_MEMORY_ATTRIBUTES_NON_EXEC	(U(1) << 2)
+
+
+/* SPM error codes. */
+#define SPM_MM_SUCCESS		  0
+#define SPM_MM_NOT_SUPPORTED	 -1
+#define SPM_MM_INVALID_PARAMETER -2
+#define SPM_MM_DENIED		 -3
+#define SPM_MM_NO_MEMORY	 -5
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+int32_t spm_mm_setup(void);
+
+uint64_t spm_mm_smc_handler(uint32_t smc_fid,
+			    uint64_t x1,
+			    uint64_t x2,
+			    uint64_t x3,
+			    uint64_t x4,
+			    void *cookie,
+			    void *handle,
+			    uint64_t flags);
+
+/* Helper to enter a secure partition */
+uint64_t spm_mm_sp_call(uint32_t smc_fid,
+			uint64_t x1,
+			uint64_t x2,
+			uint64_t x3);
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* SPM_MM_SVC_H */
diff --git a/include/services/spm_svc.h b/include/services/spm_svc.h
deleted file mode 100644
index a3723a0..0000000
--- a/include/services/spm_svc.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPM_SVC_H
-#define SPM_SVC_H
-
-#if SPM_MM
-
-#include <lib/utils_def.h>
-
-#define SPM_VERSION_MAJOR	U(0)
-#define SPM_VERSION_MAJOR_SHIFT	16
-#define SPM_VERSION_MAJOR_MASK	U(0x7FFF)
-#define SPM_VERSION_MINOR	U(1)
-#define SPM_VERSION_MINOR_SHIFT	0
-#define SPM_VERSION_MINOR_MASK	U(0xFFFF)
-#define SPM_VERSION_FORM(major, minor)	((major << SPM_VERSION_MAJOR_SHIFT) | (minor))
-#define SPM_VERSION_COMPILED	SPM_VERSION_FORM(SPM_VERSION_MAJOR, SPM_VERSION_MINOR)
-
-/* The macros below are used to identify SPM calls from the SMC function ID */
-#define SPM_FID_MASK			U(0xffff)
-#define SPM_FID_MIN_VALUE		U(0x40)
-#define SPM_FID_MAX_VALUE		U(0x7f)
-#define is_spm_fid(_fid)						\
-		((((_fid) & SPM_FID_MASK) >= SPM_FID_MIN_VALUE) &&	\
-		 (((_fid) & SPM_FID_MASK) <= SPM_FID_MAX_VALUE))
-
-/*
- * SMC IDs defined for accessing services implemented by the Secure Partition
- * Manager from the Secure Partition(s). These services enable a partition to
- * handle delegated events and request privileged operations from the manager.
- * They occupy the range 0x60-0x7f.
- */
-#define SPM_VERSION_AARCH32			U(0x84000060)
-#define SP_EVENT_COMPLETE_AARCH64		U(0xC4000061)
-#define SP_MEMORY_ATTRIBUTES_GET_AARCH64	U(0xC4000064)
-#define SP_MEMORY_ATTRIBUTES_SET_AARCH64	U(0xC4000065)
-
-/*
- * Macros used by SP_MEMORY_ATTRIBUTES_SET_AARCH64.
- */
-
-#define SP_MEMORY_ATTRIBUTES_ACCESS_NOACCESS	U(0)
-#define SP_MEMORY_ATTRIBUTES_ACCESS_RW		U(1)
-/* Value U(2) is reserved. */
-#define SP_MEMORY_ATTRIBUTES_ACCESS_RO		U(3)
-#define SP_MEMORY_ATTRIBUTES_ACCESS_MASK	U(3)
-#define SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT	0
-
-#define SP_MEMORY_ATTRIBUTES_EXEC		(U(0) << 2)
-#define SP_MEMORY_ATTRIBUTES_NON_EXEC		(U(1) << 2)
-
-
-/* SPM error codes. */
-#define SPM_SUCCESS		0
-#define SPM_NOT_SUPPORTED	-1
-#define SPM_INVALID_PARAMETER	-2
-#define SPM_DENIED		-3
-#define SPM_NO_MEMORY		-5
-
-#endif /* SPM_MM */
-
-#ifndef __ASSEMBLER__
-
-#include <stdint.h>
-
-int32_t spm_setup(void);
-
-#if SPM_MM
-
-uint64_t spm_smc_handler(uint32_t smc_fid,
-			 uint64_t x1,
-			 uint64_t x2,
-			 uint64_t x3,
-			 uint64_t x4,
-			 void *cookie,
-			 void *handle,
-			 uint64_t flags);
-
-/* Helper to enter a Secure Partition */
-uint64_t spm_sp_call(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3);
-
-#endif /* SPM_MM */
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* SPM_SVC_H */
diff --git a/include/services/sprt_svc.h b/include/services/sprt_svc.h
deleted file mode 100644
index 2421ea2..0000000
--- a/include/services/sprt_svc.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPRT_SVC_H
-#define SPRT_SVC_H
-
-#include <lib/smccc.h>
-#include <lib/utils_def.h>
-
-/* SPRT_VERSION helpers */
-
-#define SPRT_VERSION_MAJOR		U(0)
-#define SPRT_VERSION_MAJOR_SHIFT	16
-#define SPRT_VERSION_MAJOR_MASK		U(0x7FFF)
-#define SPRT_VERSION_MINOR		U(1)
-#define SPRT_VERSION_MINOR_SHIFT	0
-#define SPRT_VERSION_MINOR_MASK		U(0xFFFF)
-#define SPRT_VERSION_FORM(major, minor)	((((major) & SPRT_VERSION_MAJOR_MASK)  \
-						<< SPRT_VERSION_MAJOR_SHIFT) | \
-					((minor) & SPRT_VERSION_MINOR_MASK))
-#define SPRT_VERSION_COMPILED		SPRT_VERSION_FORM(SPRT_VERSION_MAJOR, \
-							  SPRT_VERSION_MINOR)
-
-/* SPRT function IDs */
-
-#define SPRT_FID_VERSION		U(0x0)
-#define SPRT_FID_PUT_RESPONSE		U(0x1)
-#define SPRT_FID_YIELD			U(0x5)
-#define SPRT_FID_PANIC			U(0x7)
-#define SPRT_FID_MEMORY_PERM_ATTR_GET	U(0xB)
-#define SPRT_FID_MEMORY_PERM_ATTR_SET	U(0xC)
-
-#define SPRT_FID_MASK			U(0xFF)
-
-/* Definitions to build the complete SMC ID */
-
-#define OEN_SPRT_START			U(0x20)
-#define OEN_SPRT_END			U(0x2F)
-
-#define SPRT_SMC_64(sprt_fid)	((OEN_SPRT_START << FUNCID_OEN_SHIFT) | \
-				 (U(1) << 31) | ((sprt_fid) & SPRT_FID_MASK) | \
-				 (SMC_64 << FUNCID_CC_SHIFT))
-#define SPRT_SMC_32(sprt_fid)	((OEN_SPRT_START << FUNCID_OEN_SHIFT) | \
-				 (U(1) << 31) | ((sprt_fid) & SPRT_FID_MASK) | \
-				 (SMC_32 << FUNCID_CC_SHIFT))
-
-/* Complete SMC IDs */
-
-#define SPRT_VERSION				SPRT_SMC_32(SPRT_FID_VERSION)
-#define SPRT_PUT_RESPONSE_AARCH64		SPRT_SMC_64(SPRT_FID_PUT_RESPONSE)
-#define SPRT_YIELD_AARCH64			SPRT_SMC_64(SPRT_FID_YIELD)
-#define SPRT_PANIC_AARCH64			SPRT_SMC_64(SPRT_FID_PANIC)
-#define SPRT_MEMORY_PERM_ATTR_GET_AARCH64	SPRT_SMC_64(SPRT_FID_MEMORY_PERM_ATTR_GET)
-#define SPRT_MEMORY_PERM_ATTR_SET_AARCH64	SPRT_SMC_64(SPRT_FID_MEMORY_PERM_ATTR_SET)
-
-/* Defines used by SPRT_MEMORY_PERM_ATTR_{GET,SET}_AARCH64 */
-
-#define SPRT_MEMORY_PERM_ATTR_RO	U(0)
-#define SPRT_MEMORY_PERM_ATTR_RW	U(1)
-#define SPRT_MEMORY_PERM_ATTR_RO_EXEC	U(2)
-/* U(3) is reserved */
-#define SPRT_MEMORY_PERM_ATTR_MASK	U(3)
-#define SPRT_MEMORY_PERM_ATTR_SHIFT	3
-
-/* SPRT error codes. */
-
-#define SPRT_SUCCESS		 0
-#define SPRT_NOT_SUPPORTED	-1
-#define SPRT_INVALID_PARAMETER	-2
-
-#endif /* SPRT_SVC_H */
diff --git a/lib/compiler-rt/builtins/arm/aeabi_ldivmod.S b/lib/compiler-rt/builtins/arm/aeabi_ldivmod.S
new file mode 100644
index 0000000..038ae5d
--- /dev/null
+++ b/lib/compiler-rt/builtins/arm/aeabi_ldivmod.S
@@ -0,0 +1,46 @@
+//===-- aeabi_ldivmod.S - EABI ldivmod implementation ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+// struct { int64_t quot, int64_t rem}
+//        __aeabi_ldivmod(int64_t numerator, int64_t denominator) {
+//   int64_t rem, quot;
+//   quot = __divmoddi4(numerator, denominator, &rem);
+//   return {quot, rem};
+// }
+
+#if defined(__MINGW32__)
+#define __aeabi_ldivmod __rt_sdiv64
+#endif
+
+        .syntax unified
+        .p2align 2
+DEFINE_COMPILERRT_FUNCTION(__aeabi_ldivmod)
+        push    {r6, lr}
+        sub     sp, sp, #16
+        add     r6, sp, #8
+        str     r6, [sp]
+#if defined(__MINGW32__)
+        movs    r6, r0
+        movs    r0, r2
+        movs    r2, r6
+        movs    r6, r1
+        movs    r1, r3
+        movs    r3, r6
+#endif
+        bl      SYMBOL_NAME(__divmoddi4)
+        ldr     r2, [sp, #8]
+        ldr     r3, [sp, #12]
+        add     sp, sp, #16
+        pop     {r6, pc}
+END_COMPILERRT_FUNCTION(__aeabi_ldivmod)
+
+NO_EXEC_STACK_DIRECTIVE
+
diff --git a/lib/compiler-rt/builtins/divdi3.c b/lib/compiler-rt/builtins/divdi3.c
new file mode 100644
index 0000000..b8eebcb
--- /dev/null
+++ b/lib/compiler-rt/builtins/divdi3.c
@@ -0,0 +1,29 @@
+/* ===-- divdi3.c - Implement __divdi3 -------------------------------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __divdi3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: a / b */
+
+COMPILER_RT_ABI di_int
+__divdi3(di_int a, di_int b)
+{
+    const int bits_in_dword_m1 = (int)(sizeof(di_int) * CHAR_BIT) - 1;
+    di_int s_a = a >> bits_in_dword_m1;           /* s_a = a < 0 ? -1 : 0 */
+    di_int s_b = b >> bits_in_dword_m1;           /* s_b = b < 0 ? -1 : 0 */
+    a = (a ^ s_a) - s_a;                         /* negate if s_a == -1 */
+    b = (b ^ s_b) - s_b;                         /* negate if s_b == -1 */
+    s_a ^= s_b;                                  /*sign of quotient */
+    return (__udivmoddi4(a, b, (du_int*)0) ^ s_a) - s_a;  /* negate if s_a == -1 */
+}
diff --git a/lib/compiler-rt/builtins/divmoddi4.c b/lib/compiler-rt/builtins/divmoddi4.c
new file mode 100644
index 0000000..0d4df67
--- /dev/null
+++ b/lib/compiler-rt/builtins/divmoddi4.c
@@ -0,0 +1,25 @@
+/*===-- divmoddi4.c - Implement __divmoddi4 --------------------------------===
+ *
+ *                    The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __divmoddi4 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: a / b, *rem = a % b  */
+
+COMPILER_RT_ABI di_int
+__divmoddi4(di_int a, di_int b, di_int* rem)
+{
+  di_int d = __divdi3(a,b);
+  *rem = a - (d*b);
+  return d;
+}
diff --git a/lib/compiler-rt/builtins/popcountdi2.c b/lib/compiler-rt/builtins/popcountdi2.c
new file mode 100644
index 0000000..5e8a62f
--- /dev/null
+++ b/lib/compiler-rt/builtins/popcountdi2.c
@@ -0,0 +1,36 @@
+/* ===-- popcountdi2.c - Implement __popcountdi2 ----------------------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __popcountdi2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: count of 1 bits */
+
+COMPILER_RT_ABI si_int
+__popcountdi2(di_int a)
+{
+    du_int x2 = (du_int)a;
+    x2 = x2 - ((x2 >> 1) & 0x5555555555555555uLL);
+    /* Every 2 bits holds the sum of every pair of bits (32) */
+    x2 = ((x2 >> 2) & 0x3333333333333333uLL) + (x2 & 0x3333333333333333uLL);
+    /* Every 4 bits holds the sum of every 4-set of bits (3 significant bits) (16) */
+    x2 = (x2 + (x2 >> 4)) & 0x0F0F0F0F0F0F0F0FuLL;
+    /* Every 8 bits holds the sum of every 8-set of bits (4 significant bits) (8) */
+    su_int x = (su_int)(x2 + (x2 >> 32));
+    /* The lower 32 bits hold four 16 bit sums (5 significant bits). */
+    /*   Upper 32 bits are garbage */
+    x = x + (x >> 16);
+    /* The lower 16 bits hold two 32 bit sums (6 significant bits). */
+    /*   Upper 16 bits are garbage */
+    return (x + (x >> 8)) & 0x0000007F;  /* (7 significant bits) */
+}
diff --git a/lib/compiler-rt/builtins/popcountsi2.c b/lib/compiler-rt/builtins/popcountsi2.c
new file mode 100644
index 0000000..44544ff
--- /dev/null
+++ b/lib/compiler-rt/builtins/popcountsi2.c
@@ -0,0 +1,33 @@
+/* ===-- popcountsi2.c - Implement __popcountsi2 ---------------------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __popcountsi2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: count of 1 bits */
+
+COMPILER_RT_ABI si_int
+__popcountsi2(si_int a)
+{
+    su_int x = (su_int)a;
+    x = x - ((x >> 1) & 0x55555555);
+    /* Every 2 bits holds the sum of every pair of bits */
+    x = ((x >> 2) & 0x33333333) + (x & 0x33333333);
+    /* Every 4 bits holds the sum of every 4-set of bits (3 significant bits) */
+    x = (x + (x >> 4)) & 0x0F0F0F0F;
+    /* Every 8 bits holds the sum of every 8-set of bits (4 significant bits) */
+    x = (x + (x >> 16));
+    /* The lower 16 bits hold two 8 bit sums (5 significant bits).*/
+    /*    Upper 16 bits are garbage */
+    return (x + (x >> 8)) & 0x0000003F;  /* (6 significant bits) */
+}
diff --git a/lib/compiler-rt/compiler-rt.mk b/lib/compiler-rt/compiler-rt.mk
index 49e497e..40c669f 100644
--- a/lib/compiler-rt/compiler-rt.mk
+++ b/lib/compiler-rt/compiler-rt.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are met:
@@ -28,9 +28,15 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
+COMPILER_RT_SRCS	:=	lib/compiler-rt/builtins/popcountdi2.c		\
+				lib/compiler-rt/builtins/popcountsi2.c
+
 ifeq (${ARCH},aarch32)
-COMPILER_RT_SRCS	:=	lib/compiler-rt/builtins/arm/aeabi_uldivmod.S	\
-				lib/compiler-rt/builtins/udivmoddi4.c		\
+COMPILER_RT_SRCS	+=	lib/compiler-rt/builtins/arm/aeabi_ldivmod.S	\
+				lib/compiler-rt/builtins/arm/aeabi_uldivmod.S	\
 				lib/compiler-rt/builtins/ctzdi2.c		\
-				lib/compiler-rt/builtins/lshrdi3.c
+				lib/compiler-rt/builtins/divdi3.c		\
+				lib/compiler-rt/builtins/divmoddi4.c		\
+				lib/compiler-rt/builtins/lshrdi3.c		\
+				lib/compiler-rt/builtins/udivmoddi4.c
 endif
diff --git a/lib/cpus/aarch64/cortex_hercules.S b/lib/cpus/aarch64/cortex_hercules.S
index 4e04814..a239196 100644
--- a/lib/cpus/aarch64/cortex_hercules.S
+++ b/lib/cpus/aarch64/cortex_hercules.S
@@ -16,12 +16,49 @@
 #error "cortex_hercules must be compiled with HW_ASSISTED_COHERENCY enabled"
 #endif
 
+
+/* --------------------------------------------------
+ * Errata Workaround for Hercules Erratum 1688305.
+ * This applies to revision r0p0 and r1p0 of Hercules.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_hercules_1688305_wa
+	/* Compare x0 against revision r1p0 */
+	mov	x17, x30
+	bl	check_errata_1688305
+	cbz	x0, 1f
+	mrs     x1, CORTEX_HERCULES_ACTLR2_EL1
+	orr	x1, x1, CORTEX_HERCULES_ACTLR2_EL1_BIT_1
+	msr     CORTEX_HERCULES_ACTLR2_EL1, x1
+	isb
+1:
+	ret	x17
+endfunc errata_hercules_1688305_wa
+
+func check_errata_1688305
+	/* Applies to r0p0 and r1p0 */
+	mov	x1, #0x10
+	b	cpu_rev_var_ls
+endfunc check_errata_1688305
+
 	/* -------------------------------------------------
 	 * The CPU Ops reset function for Cortex-Hercules
 	 * -------------------------------------------------
 	 */
-#if ENABLE_AMU
 func cortex_hercules_reset_func
+	mov	x19, x30
+	bl	cpu_get_rev_var
+	mov	x18, x0
+
+#if ERRATA_HERCULES_1688305
+	mov     x0, x18
+	bl	errata_hercules_1688305_wa
+#endif
+
+#if ENABLE_AMU
 	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
 	mrs	x0, actlr_el3
 	bic	x0, x0, #CORTEX_HERCULES_ACTLR_TAM_BIT
@@ -39,11 +76,11 @@
 	/* Enable group1 counters */
 	mov	x0, #CORTEX_HERCULES_AMU_GROUP1_MASK
 	msr	CPUAMCNTENSET1_EL0, x0
-	isb
+#endif
 
-	ret
+	isb
+	ret	x19
 endfunc cortex_hercules_reset_func
-#endif
 
 	/* ---------------------------------------------
 	 * HW will do the cache maintenance while powering down
@@ -66,6 +103,18 @@
 	 */
 #if REPORT_ERRATA
 func cortex_hercules_errata_report
+	stp	x8, x30, [sp, #-16]!
+
+	bl	cpu_get_rev_var
+	mov	x8, x0
+
+	/*
+	 * Report all errata. The revision-variant information is passed to
+	 * checking functions of each errata.
+	 */
+	report_errata ERRATA_HERCULES_1688305, cortex_hercules, 1688305
+
+	ldp	x8, x30, [sp], #16
 	ret
 endfunc cortex_hercules_errata_report
 #endif
@@ -89,12 +138,6 @@
 	ret
 endfunc cortex_hercules_cpu_reg_dump
 
-#if ENABLE_AMU
-#define HERCULES_RESET_FUNC cortex_hercules_reset_func
-#else
-#define HERCULES_RESET_FUNC CPU_NO_RESET_FUNC
-#endif
-
 declare_cpu_ops cortex_hercules, CORTEX_HERCULES_MIDR, \
-	HERCULES_RESET_FUNC, \
+	cortex_hercules_reset_func, \
 	cortex_hercules_core_pwr_dwn
diff --git a/lib/cpus/aarch64/neoverse_n1.S b/lib/cpus/aarch64/neoverse_n1.S
index c9bb005..faf53a8 100644
--- a/lib/cpus/aarch64/neoverse_n1.S
+++ b/lib/cpus/aarch64/neoverse_n1.S
@@ -21,9 +21,7 @@
 #error "Neoverse-N1 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
-#if ERRATA_N1_IC_TRAP
 	.global neoverse_n1_errata_ic_trap_handler
-#endif
 
 /* --------------------------------------------------
  * Errata Workaround for Neoverse N1 Erratum 1043202.
@@ -356,7 +354,7 @@
 	bl	check_errata_1542419
 	cbz	x0, 1f
 
-        /* Apply instruction patching sequence */
+	/* Apply instruction patching sequence */
 	ldr	x0, =0x0
 	msr	CPUPSELR_EL3, x0
 	ldr	x0, =0xEE670D35
@@ -536,10 +534,10 @@
 	tlbi	vae3is, xzr
 	dsb	sy
 
-        # Skip the IC instruction itself
-        mrs     x3, elr_el3
-        add     x3, x3, #4
-        msr     elr_el3, x3
+	# Skip the IC instruction itself
+	mrs     x3, elr_el3
+	add     x3, x3, #4
+	msr     elr_el3, x3
 
 	ldp	x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
 	ldp	x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 078888e..c9b9b38 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -234,6 +234,10 @@
 # only to revision <= r3p0 of the Cortex A76 cpu.
 ERRATA_A76_1286807	?=0
 
+# Flag to apply erratum 1688305 workaround during reset. This erratum applies
+# to revisions r0p0 - r1p0 of the Hercules cpu.
+ERRATA_HERCULES_1688305	?=0
+
 # Flag to apply T32 CLREX workaround during reset. This erratum applies
 # only to r0p0 and r1p0 of the Neoverse N1 cpu.
 ERRATA_N1_1043202	?=1
@@ -467,6 +471,10 @@
 $(eval $(call assert_boolean,ERRATA_A76_1286807))
 $(eval $(call add_define,ERRATA_A76_1286807))
 
+# Process ERRATA_HERCULES_1688305 flag
+$(eval $(call assert_boolean,ERRATA_HERCULES_1688305))
+$(eval $(call add_define,ERRATA_HERCULES_1688305))
+
 # Process ERRATA_N1_1043202 flag
 $(eval $(call assert_boolean,ERRATA_N1_1043202))
 $(eval $(call add_define,ERRATA_N1_1043202))
diff --git a/lib/debugfs/blobs.h b/lib/debugfs/blobs.h
new file mode 100644
index 0000000..54ca9f7
--- /dev/null
+++ b/lib/debugfs/blobs.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "dev.h"
+
+static const dirtab_t blobtab[] = {
+	{"ctl", DEV_ROOT_QBLOBCTL, 0, O_READ},
+	{"fip.bin", DEV_ROOT_QBLOBCTL + 1, 0x100000, O_READ, (void *)0x8000000}
+};
diff --git a/lib/debugfs/debugfs.mk b/lib/debugfs/debugfs.mk
new file mode 100644
index 0000000..138fc72
--- /dev/null
+++ b/lib/debugfs/debugfs.mk
@@ -0,0 +1,13 @@
+#
+# Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+DEBUGFS_SRCS	:=	$(addprefix lib/debugfs/,	\
+			dev.c				\
+			devc.c				\
+			devroot.c			\
+			devfip.c)
+
+DEBUGFS_SRCS    += lib/debugfs/debugfs_smc.c
diff --git a/lib/debugfs/debugfs_smc.c b/lib/debugfs/debugfs_smc.c
new file mode 100644
index 0000000..400c166
--- /dev/null
+++ b/lib/debugfs/debugfs_smc.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <lib/debugfs.h>
+#include <lib/smccc.h>
+#include <lib/spinlock.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <smccc_helpers.h>
+
+#define MAX_PATH_LEN	256
+
+#define MOUNT		0
+#define CREATE		1
+#define OPEN		2
+#define CLOSE		3
+#define READ		4
+#define WRITE		5
+#define SEEK		6
+#define BIND		7
+#define STAT		8
+#define INIT		10
+#define VERSION		11
+
+/* This is the virtual address to which we map the NS shared buffer */
+#define DEBUGFS_SHARED_BUF_VIRT		((void *)0x81000000U)
+
+static union debugfs_parms {
+	struct {
+		char fname[MAX_PATH_LEN];
+	} open;
+
+	struct {
+		char srv[MAX_PATH_LEN];
+		char where[MAX_PATH_LEN];
+		char spec[MAX_PATH_LEN];
+	} mount;
+
+	struct {
+		char path[MAX_PATH_LEN];
+		dir_t dir;
+	} stat;
+
+	struct {
+		char oldpath[MAX_PATH_LEN];
+		char newpath[MAX_PATH_LEN];
+	} bind;
+} parms;
+
+/* debugfs_access_lock protects shared buffer and internal */
+/* FS functions from concurrent acccesses.                 */
+static spinlock_t debugfs_access_lock;
+
+static bool debugfs_initialized;
+
+uintptr_t debugfs_smc_handler(unsigned int smc_fid,
+			      u_register_t cmd,
+			      u_register_t arg2,
+			      u_register_t arg3,
+			      u_register_t arg4,
+			      void *cookie,
+			      void *handle,
+			      u_register_t flags)
+{
+	int64_t smc_ret = DEBUGFS_E_INVALID_PARAMS, smc_resp = 0;
+	int ret;
+
+	/* Allow calls from non-secure only */
+	if (is_caller_secure(flags)) {
+		SMC_RET1(handle, DEBUGFS_E_DENIED);
+	}
+
+	/* Expect a SiP service fast call */
+	if ((GET_SMC_TYPE(smc_fid) != SMC_TYPE_FAST) ||
+		(GET_SMC_OEN(smc_fid) != OEN_SIP_START)) {
+		SMC_RET1(handle, SMC_UNK);
+	}
+
+	/* Truncate parameters if 32b SMC convention call */
+	if (GET_SMC_CC(smc_fid) == SMC_32) {
+		arg2 &= 0xffffffff;
+		arg3 &= 0xffffffff;
+		arg4 &= 0xffffffff;
+	}
+
+	spin_lock(&debugfs_access_lock);
+
+	if (debugfs_initialized == true) {
+		/* Copy NS shared buffer to internal secure location */
+		memcpy(&parms, (void *)DEBUGFS_SHARED_BUF_VIRT,
+		       sizeof(union debugfs_parms));
+	}
+
+	switch (cmd) {
+	case INIT:
+		if (debugfs_initialized == false) {
+			/* TODO: check PA validity e.g. whether */
+			/* it is an NS region.                  */
+			ret = mmap_add_dynamic_region(arg2,
+				(uintptr_t)DEBUGFS_SHARED_BUF_VIRT,
+				PAGE_SIZE_4KB,
+				MT_MEMORY | MT_RW | MT_NS);
+			if (ret == 0) {
+				debugfs_initialized = true;
+				smc_ret = SMC_OK;
+				smc_resp = 0;
+			}
+		}
+		break;
+
+	case VERSION:
+		smc_ret = SMC_OK;
+		smc_resp = DEBUGFS_VERSION;
+		break;
+
+	case MOUNT:
+		ret = mount(parms.mount.srv,
+			    parms.mount.where,
+			    parms.mount.spec);
+		if (ret == 0) {
+			smc_ret = SMC_OK;
+			smc_resp = 0;
+		}
+		break;
+
+	case OPEN:
+		ret = open(parms.open.fname, arg2);
+		if (ret >= 0) {
+			smc_ret = SMC_OK;
+			smc_resp = ret;
+		}
+		break;
+
+	case CLOSE:
+		ret = close(arg2);
+		if (ret == 0) {
+			smc_ret = SMC_OK;
+			smc_resp = 0;
+		}
+		break;
+
+	case READ:
+		ret = read(arg2, DEBUGFS_SHARED_BUF_VIRT, arg3);
+		if (ret >= 0) {
+			smc_ret = SMC_OK;
+			smc_resp = ret;
+		}
+		break;
+
+	case SEEK:
+		ret = seek(arg2, arg3, arg4);
+		if (ret == 0) {
+			smc_ret = SMC_OK;
+			smc_resp = 0;
+		}
+		break;
+
+	case BIND:
+		ret = bind(parms.bind.oldpath, parms.bind.newpath);
+		if (ret == 0) {
+			smc_ret = SMC_OK;
+			smc_resp = 0;
+		}
+		break;
+
+	case STAT:
+		ret = stat(parms.stat.path, &parms.stat.dir);
+		if (ret == 0) {
+			memcpy((void *)DEBUGFS_SHARED_BUF_VIRT, &parms,
+			       sizeof(union debugfs_parms));
+			smc_ret = SMC_OK;
+			smc_resp = 0;
+		}
+		break;
+
+	/* Not implemented */
+	case CREATE:
+		/* Intentional fall-through */
+
+	/* Not implemented */
+	case WRITE:
+		/* Intentional fall-through */
+
+	default:
+		smc_ret = SMC_UNK;
+		smc_resp = 0;
+	}
+
+	spin_unlock(&debugfs_access_lock);
+
+	SMC_RET2(handle, smc_ret, smc_resp);
+
+	/* Not reached */
+	return smc_ret;
+}
+
+int debugfs_smc_setup(void)
+{
+	debugfs_initialized = false;
+	debugfs_access_lock.lock = 0;
+
+	return 0;
+}
diff --git a/lib/debugfs/dev.c b/lib/debugfs/dev.c
new file mode 100644
index 0000000..0361437
--- /dev/null
+++ b/lib/debugfs/dev.c
@@ -0,0 +1,849 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <cdefs.h>
+#include <common/debug.h>
+#include <lib/debugfs.h>
+#include <string.h>
+
+#include "dev.h"
+
+#define NR_MOUNT_POINTS		4
+
+struct mount_point {
+	chan_t	*new;
+	chan_t	*old;
+};
+
+/* This array contains all the available channels of the filesystem.
+ * A file descriptor is the index of a specific channel in this array.
+ */
+static chan_t fdset[NR_CHANS];
+
+/* This array contains all the available mount points of the filesystem. */
+static struct mount_point mount_points[NR_MOUNT_POINTS];
+
+/* This variable stores the channel associated to the root directory. */
+static chan_t slash_channel;
+
+/* This function creates a channel from a device index and registers
+ * it to fdset.
+ */
+static chan_t *create_new_channel(unsigned char index)
+{
+	chan_t *channel = NULL;
+	int i;
+
+	for (i = 0; i < NR_CHANS; i++) {
+		if (fdset[i].index == NODEV) {
+			channel = &fdset[i];
+			channel->index = index;
+			break;
+		}
+	}
+
+	return channel;
+}
+
+/*******************************************************************************
+ * This function returns a pointer to an existing channel in fdset from a file
+ * descriptor.
+ ******************************************************************************/
+static chan_t *fd_to_channel(int fd)
+{
+	if ((fd < 0) || (fd >= NR_CHANS) || (fdset[fd].index == NODEV)) {
+		return NULL;
+	}
+
+	return &fdset[fd];
+}
+
+/*******************************************************************************
+ * This function returns a file descriptor from a channel.
+ * The caller must be sure that the channel is registered in fdset.
+ ******************************************************************************/
+static int channel_to_fd(chan_t *channel)
+{
+	return (channel == NULL) ? -1 : (channel - fdset);
+}
+
+/*******************************************************************************
+ * This function checks the validity of a mode.
+ ******************************************************************************/
+static bool is_valid_mode(int mode)
+{
+	if ((mode & O_READ) && (mode & (O_WRITE | O_RDWR))) {
+		return false;
+	}
+	if ((mode & O_WRITE) && (mode & (O_READ | O_RDWR))) {
+		return false;
+	}
+	if ((mode & O_RDWR) && (mode & (O_READ | O_WRITE))) {
+		return false;
+	}
+
+	return true;
+}
+
+/*******************************************************************************
+ * This function extracts the next part of the given path contained and puts it
+ * in token. It returns a pointer to the remainder of the path.
+ ******************************************************************************/
+static const char *next(const char *path, char *token)
+{
+	int index;
+	const char *cursor;
+
+	while (*path == '/') {
+		++path;
+	}
+
+	index = 0;
+	cursor = path;
+	if (*path != '\0') {
+		while (*cursor != '/' && *cursor != '\0') {
+			if (index == NAMELEN) {
+				return NULL;
+			}
+			token[index++] = *cursor++;
+		}
+	}
+	token[index] = '\0';
+
+	return cursor;
+}
+
+/*******************************************************************************
+ * This function returns the driver index in devtab of the driver
+ * identified by id.
+ ******************************************************************************/
+static int get_device_index(int id)
+{
+	int index;
+	dev_t * const *dp;
+
+	for (index = 0, dp = devtab; *dp && (*dp)->id != id; ++dp) {
+		index++;
+	}
+
+	if (*dp == NULL) {
+		return -1;
+	}
+
+	return index;
+}
+
+/*******************************************************************************
+ * This function clears a given channel fields
+ ******************************************************************************/
+static void channel_clear(chan_t *channel)
+{
+	channel->offset = 0;
+	channel->qid    = 0;
+	channel->index  = NODEV;
+	channel->dev    = 0;
+	channel->mode   = 0;
+}
+
+/*******************************************************************************
+ * This function closes the channel pointed to by c.
+ ******************************************************************************/
+void channel_close(chan_t *channel)
+{
+	if (channel != NULL) {
+		channel_clear(channel);
+	}
+}
+
+/*******************************************************************************
+ * This function copies data from src to dst after applying the offset of the
+ * channel c. nbytes bytes are expected to be copied unless the data goes over
+ * dst + len.
+ * It returns the actual number of bytes that were copied.
+ ******************************************************************************/
+int buf_to_channel(chan_t *channel, void *dst, void *src, int nbytes, long len)
+{
+	const char *addr = src;
+
+	if ((channel == NULL) || (dst == NULL) || (src == NULL)) {
+		return 0;
+	}
+
+	if (channel->offset >= len) {
+		return 0;
+	}
+
+	if ((channel->offset + nbytes) > len) {
+		nbytes = len - channel->offset;
+	}
+
+	memcpy(dst, addr + channel->offset, nbytes);
+
+	channel->offset += nbytes;
+
+	return nbytes;
+}
+
+/*******************************************************************************
+ * This function checks whether a channel (identified by its device index and
+ * qid) is registered as a mount point.
+ * Returns a pointer to the channel it is mounted to when found, NULL otherwise.
+ ******************************************************************************/
+static chan_t *mount_point_to_channel(int index, qid_t qid)
+{
+	chan_t *channel;
+	struct mount_point *mp;
+
+	for (mp = mount_points; mp < &mount_points[NR_MOUNT_POINTS]; mp++) {
+		channel = mp->new;
+		if (channel == NULL) {
+			continue;
+		}
+
+		if ((channel->index == index) && (channel->qid == qid)) {
+			return mp->old;
+		}
+	}
+
+	return NULL;
+}
+
+/*******************************************************************************
+ * This function calls the attach function of the driver identified by id.
+ ******************************************************************************/
+chan_t *attach(int id, int dev)
+{
+	/* Get the devtab index for the driver identified by id */
+	int index = get_device_index(id);
+
+	if (index < 0) {
+		return NULL;
+	}
+
+	return devtab[index]->attach(id, dev);
+}
+
+/*******************************************************************************
+ * This function is the default implementation of the driver attach function.
+ * It creates a new channel and returns a pointer to it.
+ ******************************************************************************/
+chan_t *devattach(int id, int dev)
+{
+	chan_t *channel;
+	int index;
+
+	index = get_device_index(id);
+	if (index < 0) {
+		return NULL;
+	}
+
+	channel = create_new_channel(index);
+	if (channel == NULL) {
+		return NULL;
+	}
+
+	channel->dev = dev;
+	channel->qid = CHDIR;
+
+	return channel;
+}
+
+/*******************************************************************************
+ * This function returns a channel given a path.
+ * It goes through the filesystem, from the root namespace ('/') or from a
+ * device namespace ('#'), switching channel on mount points.
+ ******************************************************************************/
+chan_t *path_to_channel(const char *path, int mode)
+{
+	int i, n;
+	const char *path_next;
+	chan_t *mnt, *channel;
+	char elem[NAMELEN];
+
+	if (path == NULL) {
+		return NULL;
+	}
+
+	switch (path[0]) {
+	case '/':
+		channel = clone(&slash_channel, NULL);
+		path_next = path;
+		break;
+	case '#':
+		path_next = next(path + 1, elem);
+		if (path_next == NULL) {
+			goto noent;
+		}
+
+		n = 0;
+		for (i = 1; (elem[i] >= '0') && (elem[i] <= '9'); i++) {
+			n += elem[i] - '0';
+		}
+
+		if (elem[i] != '\0') {
+			goto noent;
+		}
+
+		channel = attach(elem[0], n);
+		break;
+	default:
+		return NULL;
+	}
+
+	if (channel == NULL) {
+		return NULL;
+	}
+
+	for (path_next = next(path_next, elem); *elem;
+			path_next = next(path_next, elem)) {
+		if ((channel->qid & CHDIR) == 0) {
+			goto notfound;
+		}
+
+		if (devtab[channel->index]->walk(channel, elem) < 0) {
+			channel_close(channel);
+			goto notfound;
+		}
+
+		mnt = mount_point_to_channel(channel->index, channel->qid);
+		if (mnt != NULL) {
+			clone(mnt, channel);
+		}
+	}
+
+	if (path_next == NULL) {
+		goto notfound;
+	}
+
+	/* TODO: check mode */
+	return channel;
+
+notfound:
+	channel_close(channel);
+noent:
+	return NULL;
+}
+
+/*******************************************************************************
+ * This function calls the clone function of the driver associated to the
+ * channel c.
+ ******************************************************************************/
+chan_t *clone(chan_t *c, chan_t *nc)
+{
+	return devtab[c->index]->clone(c, nc);
+}
+
+/*******************************************************************************
+ * This function is the default implementation of the driver clone function.
+ * It creates a new channel and returns a pointer to it.
+ * It clones channel into new_channel.
+ ******************************************************************************/
+chan_t *devclone(chan_t *channel, chan_t *new_channel)
+{
+	if (channel == NULL) {
+		return NULL;
+	}
+
+	if (new_channel == NULL) {
+		new_channel = create_new_channel(channel->index);
+		if (new_channel == NULL) {
+			return NULL;
+		}
+	}
+
+	new_channel->qid    = channel->qid;
+	new_channel->dev    = channel->dev;
+	new_channel->mode   = channel->mode;
+	new_channel->offset = channel->offset;
+	new_channel->index  = channel->index;
+
+	return new_channel;
+}
+
+/*******************************************************************************
+ * This function is the default implementation of the driver walk function.
+ * It goes through all the elements of tab using the gen function until a match
+ * is found with name.
+ * If a match is found, it copies the qid of the new directory.
+ ******************************************************************************/
+int devwalk(chan_t *channel, const char *name, const dirtab_t *tab,
+	    int ntab, devgen_t *gen)
+{
+	int i;
+	dir_t dir;
+
+	if ((channel == NULL) || (name == NULL) || (gen == NULL)) {
+		return -1;
+	}
+
+	if ((name[0] == '.') && (name[1] == '\0')) {
+		return 1;
+	}
+
+	for (i = 0; ; i++) {
+		switch ((*gen)(channel, tab, ntab, i, &dir)) {
+		case 0:
+			/* Intentional fall-through */
+		case -1:
+			return -1;
+		case 1:
+			if (strncmp(name, dir.name, NAMELEN) != 0) {
+				continue;
+			}
+			channel->qid = dir.qid;
+			return 1;
+		}
+	}
+}
+
+/*******************************************************************************
+ * This is a helper function which exposes the content of a directory, element
+ * by element. It is meant to be called until the end of the directory is
+ * reached or an error occurs.
+ * It returns -1 on error, 0 on end of directory and 1 when a new file is found.
+ ******************************************************************************/
+int dirread(chan_t *channel, dir_t *dir, const dirtab_t *tab,
+	int ntab, devgen_t *gen)
+{
+	int i, ret;
+
+	if ((channel == NULL) || (dir == NULL) || (gen == NULL)) {
+		return -1;
+	}
+
+	i = channel->offset/sizeof(dir_t);
+	ret = (*gen)(channel, tab, ntab, i, dir);
+	if (ret == 1) {
+		channel->offset += sizeof(dir_t);
+	}
+
+	return ret;
+}
+
+/*******************************************************************************
+ * This function sets the elements of dir.
+ ******************************************************************************/
+void make_dir_entry(chan_t *channel, dir_t *dir,
+	     const char *name, long length, qid_t qid, unsigned int mode)
+{
+	if ((channel == NULL) || (dir == NULL) || (name == NULL)) {
+		return;
+	}
+
+	strlcpy(dir->name, name, sizeof(dir->name));
+	dir->length = length;
+	dir->qid = qid;
+	dir->mode = mode;
+
+	if ((qid & CHDIR) != 0) {
+		dir->mode |= O_DIR;
+	}
+
+	dir->index = channel->index;
+	dir->dev   = channel->dev;
+}
+
+/*******************************************************************************
+ * This function is the default implementation of the internal driver gen
+ * function.
+ * It copies and formats the information of the nth element of tab into dir.
+ ******************************************************************************/
+int devgen(chan_t *channel, const dirtab_t *tab, int ntab, int n, dir_t *dir)
+{
+	const dirtab_t *dp;
+
+	if ((channel == NULL) || (dir == NULL) || (tab == NULL) ||
+			(n >= ntab)) {
+		return 0;
+	}
+
+	dp = &tab[n];
+	make_dir_entry(channel, dir, dp->name, dp->length, dp->qid, dp->perm);
+	return 1;
+}
+
+/*******************************************************************************
+ * This function returns a file descriptor identifying the channel associated to
+ * the given path.
+ ******************************************************************************/
+int open(const char *path, int mode)
+{
+	chan_t *channel;
+
+	if (path == NULL) {
+		return -1;
+	}
+
+	if (is_valid_mode(mode) == false) {
+		return -1;
+	}
+
+	channel = path_to_channel(path, mode);
+
+	return channel_to_fd(channel);
+}
+
+/*******************************************************************************
+ * This function closes the channel identified by the file descriptor fd.
+ ******************************************************************************/
+int close(int fd)
+{
+	chan_t *channel;
+
+	channel = fd_to_channel(fd);
+	if (channel == NULL) {
+		return -1;
+	}
+
+	channel_close(channel);
+	return 0;
+}
+
+/*******************************************************************************
+ * This function is the default implementation of the driver stat function.
+ * It goes through all the elements of tab using the gen function until a match
+ * is found with file.
+ * If a match is found, dir contains the information file.
+ ******************************************************************************/
+int devstat(chan_t *dirc, const char *file, dir_t *dir,
+	    const dirtab_t *tab, int ntab, devgen_t *gen)
+{
+	int i, r = 0;
+	chan_t *c, *mnt;
+
+	if ((dirc == NULL) || (dir == NULL) || (gen == NULL)) {
+		return -1;
+	}
+
+	c = path_to_channel(file, O_STAT);
+	if (c == NULL) {
+		return -1;
+	}
+
+	for (i = 0; ; i++) {
+		switch ((*gen)(dirc, tab, ntab, i, dir)) {
+		case 0:
+			/* Intentional fall-through */
+		case -1:
+			r = -1;
+			goto leave;
+		case 1:
+			mnt = mount_point_to_channel(dir->index, dir->qid);
+			if (mnt != NULL) {
+				dir->qid = mnt->qid;
+				dir->index = mnt->index;
+			}
+
+			if ((dir->qid != c->qid) || (dir->index != c->index)) {
+				continue;
+			}
+
+			goto leave;
+		}
+	}
+
+leave:
+	channel_close(c);
+	return r;
+}
+
+/*******************************************************************************
+ * This function calls the stat function of the driver associated to the parent
+ * directory of the file in path.
+ * The result is stored in dir.
+ ******************************************************************************/
+int stat(const char *path, dir_t *dir)
+{
+	int r;
+	size_t len;
+	chan_t *channel;
+	char *p, dirname[PATHLEN];
+
+	if ((path == NULL) || (dir == NULL)) {
+		return -1;
+	}
+
+	len = strlen(path);
+	if ((len + 1) > sizeof(dirname)) {
+		return -1;
+	}
+
+	memcpy(dirname, path, len);
+	for (p = dirname + len; p > dirname; --p) {
+		if (*p != '/') {
+			break;
+		}
+	}
+
+	p = memrchr(dirname, '/', p - dirname);
+	if (p == NULL) {
+		return -1;
+	}
+
+	dirname[p - dirname + 1] = '\0';
+
+	channel = path_to_channel(dirname, O_STAT);
+	if (channel == NULL) {
+		return -1;
+	}
+
+	r = devtab[channel->index]->stat(channel, path, dir);
+	channel_close(channel);
+
+	return r;
+}
+
+/*******************************************************************************
+ * This function calls the read function of the driver associated to fd.
+ * It fills buf with at most n bytes.
+ * It returns the number of bytes that were actually read.
+ ******************************************************************************/
+int read(int fd, void *buf, int n)
+{
+	chan_t *channel;
+
+	if (buf == NULL) {
+		return -1;
+	}
+
+	channel = fd_to_channel(fd);
+	if (channel == NULL) {
+		return -1;
+	}
+
+	if (((channel->qid & CHDIR) != 0) && (n < sizeof(dir_t))) {
+		return -1;
+	}
+
+	return devtab[channel->index]->read(channel, buf, n);
+}
+
+/*******************************************************************************
+ * This function calls the write function of the driver associated to fd.
+ * It writes at most n bytes of buf.
+ * It returns the number of bytes that were actually written.
+ ******************************************************************************/
+int write(int fd, void *buf, int n)
+{
+	chan_t *channel;
+
+	if (buf == NULL) {
+		return -1;
+	}
+
+	channel = fd_to_channel(fd);
+	if (channel == NULL) {
+		return -1;
+	}
+
+	if ((channel->qid & CHDIR) != 0) {
+		return -1;
+	}
+
+	return devtab[channel->index]->write(channel, buf, n);
+}
+
+/*******************************************************************************
+ * This function calls the seek function of the driver associated to fd.
+ * It applies the offset off according to the strategy whence.
+ ******************************************************************************/
+int seek(int fd, long off, int whence)
+{
+	chan_t *channel;
+
+	channel = fd_to_channel(fd);
+	if (channel == NULL) {
+		return -1;
+	}
+
+	if ((channel->qid & CHDIR) != 0) {
+		return -1;
+	}
+
+	return devtab[channel->index]->seek(channel, off, whence);
+}
+
+/*******************************************************************************
+ * This function is the default error implementation of the driver mount
+ * function.
+ ******************************************************************************/
+chan_t *deverrmount(chan_t *channel, const char *spec)
+{
+	return NULL;
+}
+
+/*******************************************************************************
+ * This function is the default error implementation of the driver write
+ * function.
+ ******************************************************************************/
+int deverrwrite(chan_t *channel, void *buf, int n)
+{
+	return -1;
+}
+
+/*******************************************************************************
+ * This function is the default error implementation of the driver seek
+ * function.
+ ******************************************************************************/
+int deverrseek(chan_t *channel, long off, int whence)
+{
+	return -1;
+}
+
+/*******************************************************************************
+ * This function is the default implementation of the driver seek function.
+ * It applies the offset off according to the strategy whence to the channel c.
+ ******************************************************************************/
+int devseek(chan_t *channel, long off, int whence)
+{
+	switch (whence) {
+	case KSEEK_SET:
+		channel->offset = off;
+		break;
+	case KSEEK_CUR:
+		channel->offset += off;
+		break;
+	case KSEEK_END:
+		/* Not implemented */
+		return -1;
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
+ * This function registers the channel associated to the path new as a mount
+ * point for the channel c.
+ ******************************************************************************/
+static int add_mount_point(chan_t *channel, const char *new)
+{
+	int i;
+	chan_t *cn;
+	struct mount_point *mp;
+
+	if (new == NULL) {
+		goto err0;
+	}
+
+	cn = path_to_channel(new, O_READ);
+	if (cn == NULL) {
+		goto err0;
+	}
+
+	if ((cn->qid & CHDIR) == 0) {
+		goto err1;
+	}
+
+	for (i = NR_MOUNT_POINTS - 1; i >= 0; i--) {
+		mp = &mount_points[i];
+		if (mp->new == NULL) {
+			break;
+		}
+	}
+
+	if (i < 0) {
+		goto err1;
+	}
+
+	mp->new = cn;
+	mp->old = channel;
+
+	return 0;
+
+err1:
+	channel_close(cn);
+err0:
+	return -1;
+}
+
+/*******************************************************************************
+ * This function registers the path new as a mount point for the path old.
+ ******************************************************************************/
+int bind(const char *old, const char *new)
+{
+	chan_t *channel;
+
+	channel = path_to_channel(old, O_BIND);
+	if (channel == NULL) {
+		return -1;
+	}
+
+	if (add_mount_point(channel, new) < 0) {
+		channel_close(channel);
+		return -1;
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
+ * This function calls the mount function of the driver associated to the path
+ * srv.
+ * It mounts the path srv on the path where.
+ ******************************************************************************/
+int mount(const char *srv, const char *where, const char *spec)
+{
+	chan_t *channel, *mount_point_chan;
+	int ret;
+
+	channel = path_to_channel(srv, O_RDWR);
+	if (channel == NULL) {
+		goto err0;
+	}
+
+	mount_point_chan = devtab[channel->index]->mount(channel, spec);
+	if (mount_point_chan == NULL) {
+		goto err1;
+	}
+
+	ret = add_mount_point(mount_point_chan, where);
+	if (ret < 0) {
+		goto err2;
+	}
+
+	channel_close(channel);
+
+	return 0;
+
+err2:
+	channel_close(mount_point_chan);
+err1:
+	channel_close(channel);
+err0:
+	return -1;
+}
+
+/*******************************************************************************
+ * This function initializes the device environment.
+ * It creates the '/' channel.
+ * It links the device drivers to the physical drivers.
+ ******************************************************************************/
+void debugfs_init(void)
+{
+	chan_t *channel, *cloned_channel;
+
+	for (channel = fdset; channel < &fdset[NR_CHANS]; channel++) {
+		channel_clear(channel);
+	}
+
+	channel = devattach('/', 0);
+	if (channel == NULL) {
+		panic();
+	}
+
+	cloned_channel = clone(channel, &slash_channel);
+	if (cloned_channel == NULL) {
+		panic();
+	}
+
+	channel_close(channel);
+	devlink();
+}
+
+__dead2 void devpanic(const char *cause)
+{
+	panic();
+}
diff --git a/lib/debugfs/dev.h b/lib/debugfs/dev.h
new file mode 100644
index 0000000..c142651
--- /dev/null
+++ b/lib/debugfs/dev.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DEV_H
+#define DEV_H
+
+#include <cdefs.h>
+#include <lib/debugfs.h>
+#include <stddef.h>
+
+/* FIXME: need configurability */
+#define NR_CHANS  10
+#define NR_CONSS  1
+#define NR_BINDS  4
+#define NR_FILES  18
+
+#define NODEV     255
+#define CHDIR     (1 << 15)
+
+#define SYNCDEV   0
+#define SYNCALL   1
+
+typedef struct dev dev_t;
+typedef struct chan chan_t;
+typedef struct dirtab dirtab_t;
+typedef int devgen_t(chan_t *, const dirtab_t *, int, int, dir_t *);
+typedef struct attr attr_t;
+
+enum {
+	DEV_ROOT_QROOT,
+	DEV_ROOT_QDEV,
+	DEV_ROOT_QFIP,
+	DEV_ROOT_QBLOBS,
+	DEV_ROOT_QBLOBCTL,
+	DEV_ROOT_QPSCI
+};
+
+/*******************************************************************************
+ * This structure contains the necessary information to represent a directory
+ * of the filesystem.
+ ******************************************************************************/
+struct dirtab {
+	char		name[NAMELEN];
+	qid_t		qid;
+	long		length;
+	unsigned char	perm;
+	void		*data;
+};
+
+/*******************************************************************************
+ * This structure defines the interface of device drivers.
+ * Each driver must implement a subset of those functions.
+ * It is possible to redirect to default implementations defined in dev.c.
+ ******************************************************************************/
+/* FIXME: comments for the callbacks */
+struct dev {
+	char id;
+	int (*stat)(chan_t *c, const char *file, dir_t *dir);
+	int (*walk)(chan_t *c, const char *name);
+	int (*read)(chan_t *c, void *buf, int n);
+	int (*write)(chan_t *c, void *buf, int n);
+	int (*seek)(chan_t *c, long off, int whence);
+	chan_t *(*clone)(chan_t *c, chan_t *nc);
+	chan_t *(*attach)(int id, int dev);
+	chan_t *(*mount)(chan_t *c, const char *spec);
+};
+
+/*******************************************************************************
+ * This structure defines the channel structure.
+ * A channel is a handle on an element of the filesystem.
+ ******************************************************************************/
+struct chan {
+	long		offset;
+	qid_t		qid;
+	unsigned char	index;	/* device index in devtab */
+	unsigned char	dev;
+	unsigned char	mode;
+};
+
+/*******************************************************************************
+ * This structure defines an abstract argument passed to physical drivers from
+ * the configuration file.
+ ******************************************************************************/
+struct attr {
+	char	*key;
+	char	*value;
+};
+
+chan_t *path_to_channel(const char *path, int mode);
+chan_t *clone(chan_t *c, chan_t *nc);
+chan_t *attach(int id, int dev);
+void channel_close(chan_t *c);
+int buf_to_channel(chan_t *c, void *dst, void *src, int nbytes, long len);
+int dirread(chan_t *c, dir_t *dir, const dirtab_t *tab,
+	    int ntab, devgen_t *gen);
+void make_dir_entry(chan_t *c, dir_t *dir, const char *name, long length,
+		    qid_t qid, unsigned int mode);
+void devlink(void);
+
+chan_t *devattach(int id, int dev);
+int devseek(chan_t *c, long off, int whence);
+chan_t *devclone(chan_t *c, chan_t *nc);
+int devgen(chan_t *c, const dirtab_t *tab, int ntab, int n, dir_t *dir);
+int devwalk(chan_t *c, const char *name, const dirtab_t *tab, int ntab,
+		   devgen_t *gen);
+int devstat(chan_t *dirc, const char *file, dir_t *dir,
+		   const dirtab_t *tab, int ntab, devgen_t *gen);
+
+chan_t *deverrmount(chan_t *c, const char *spec);
+int deverrwrite(chan_t *c, void *buf, int n);
+int deverrseek(chan_t *c, long off, int whence);
+
+extern dev_t *const devtab[];
+
+void __dead2 devpanic(const char *cause);
+
+#endif /* DEV_H */
diff --git a/lib/debugfs/devc.c b/lib/debugfs/devc.c
new file mode 100644
index 0000000..1099a85
--- /dev/null
+++ b/lib/debugfs/devc.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+typedef struct dev dev_t;
+
+extern dev_t rootdevtab;
+extern dev_t fipdevtab;
+
+dev_t *const devtab[] = {
+	&rootdevtab,
+	&fipdevtab,
+	0
+};
+
+void devlink(void)
+{
+}
diff --git a/lib/debugfs/devfip.c b/lib/debugfs/devfip.c
new file mode 100644
index 0000000..5581b21
--- /dev/null
+++ b/lib/debugfs/devfip.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <lib/debugfs.h>
+#include <limits.h>
+#include <plat/arm/common/plat_arm.h>
+#include <stdlib.h>
+#include <string.h>
+#include <tools_share/firmware_image_package.h>
+
+#include "dev.h"
+
+#define NR_FIPS		1
+#define STOC_HEADER	(sizeof(fip_toc_header_t))
+#define STOC_ENTRY	(sizeof(fip_toc_entry_t))
+
+struct fipfile {
+	chan_t	*c;
+	long	offset[NR_FILES];
+	long	size[NR_FILES];
+};
+
+struct fip_entry {
+	uuid_t		uuid;
+	long long	offset_address;
+	long long	size;
+	long long	flags;
+};
+
+struct uuidnames {
+	const char   name[NAMELEN];
+	const uuid_t uuid;
+};
+
+/*******************************************************************************
+ * This array links the FIP file names to their UUID.
+ * The elements are ordered according to the image number stored in
+ * tbbr_img_def.h, starting at index 1.
+ *
+ * TODO: this name to uuid binding will preferably be done using
+ * the coming Property Access Layer / Firmware CONFiguration feature.
+ ******************************************************************************/
+static const struct uuidnames uuidnames[] = {
+	{"",			{ {0}, {0}, {0}, 0, 0, {0} } },
+	{"bl2.bin",		UUID_TRUSTED_BOOT_FIRMWARE_BL2},
+	{"scp-bl2.bin",		UUID_SCP_FIRMWARE_SCP_BL2},
+	{"bl31.bin",		UUID_EL3_RUNTIME_FIRMWARE_BL31},
+	{"bl32.bin",		UUID_SECURE_PAYLOAD_BL32},
+	{"bl33.bin",		UUID_NON_TRUSTED_FIRMWARE_BL33},
+	{"tb-fw.crt",		UUID_TRUSTED_BOOT_FW_CERT},
+	{"trstd-k.crt",		UUID_TRUSTED_KEY_CERT},
+	{"scp-fw-k.crt",	UUID_SCP_FW_KEY_CERT},
+	{"soc-fw-k.crt",	UUID_SOC_FW_KEY_CERT},
+	{"tos-fw-k.crt",	UUID_TRUSTED_OS_FW_KEY_CERT},
+	{"nt-fw-k.crt",		UUID_NON_TRUSTED_FW_KEY_CERT},
+	{"scp-fw-c.crt",	UUID_SCP_FW_CONTENT_CERT},
+	{"soc-fw-c.crt",	UUID_SOC_FW_CONTENT_CERT},
+	{"tos-fw-c.crt",	UUID_TRUSTED_OS_FW_CONTENT_CERT},
+	{"nt-fw-c.crt",		UUID_NON_TRUSTED_FW_CONTENT_CERT},
+	{ },
+	{"fwu.crt",		UUID_TRUSTED_FWU_CERT},
+	{"scp-bl2u.bin",	UUID_TRUSTED_UPDATE_FIRMWARE_SCP_BL2U},
+	{"bl2u.bin",		UUID_TRUSTED_UPDATE_FIRMWARE_BL2U},
+	{"ns-bl2u.bin",		UUID_TRUSTED_UPDATE_FIRMWARE_NS_BL2U},
+	{"bl32-xtr1.bin",	UUID_SECURE_PAYLOAD_BL32_EXTRA1},
+	{"bl32-xtr2.bin",	UUID_SECURE_PAYLOAD_BL32_EXTRA2},
+	{"hw.cfg",		UUID_HW_CONFIG},
+	{"tb-fw.cfg",		UUID_TB_FW_CONFIG},
+	{"soc-fw.cfg",		UUID_SOC_FW_CONFIG},
+	{"tos-fw.cfg",		UUID_TOS_FW_CONFIG},
+	{"nt-fw.cfg",		UUID_NT_FW_CONFIG},
+	{"rot-k.crt",		UUID_ROT_KEY_CERT},
+	{"nt-k.crt",		UUID_NON_TRUSTED_WORLD_KEY_CERT}
+};
+
+/*******************************************************************************
+ * This array contains all the available FIP files.
+ ******************************************************************************/
+static struct fipfile archives[NR_FIPS];
+
+/*******************************************************************************
+ * This variable stores the current number of registered FIP files.
+ ******************************************************************************/
+static int nfips;
+
+/*******************************************************************************
+ * This function parses the ToC of the FIP.
+ ******************************************************************************/
+static int get_entry(chan_t *c, struct fip_entry *entry)
+{
+	int n;
+
+	n = devtab[c->index]->read(c, entry, sizeof(struct fip_entry));
+	if (n <= 0) {
+		return n;
+	}
+
+	if (n != sizeof(struct fip_entry)) {
+		return -1;
+	}
+
+	if ((entry->size > LONG_MAX) || (entry->offset_address > LONG_MAX)) {
+		return -1;
+	}
+
+	if (entry->size == 0) {
+		return 0;
+	}
+
+	return 1;
+}
+
+/*******************************************************************************
+ * This function exposes the FIP images as files.
+ ******************************************************************************/
+static int fipgen(chan_t *c, const dirtab_t *tab, int ntab, int n, dir_t *dir)
+{
+	int i, r;
+	long off;
+	chan_t nc;
+	struct fip_entry entry;
+	struct fipfile *fip;
+	static const char unk[] = "unknown";
+
+	if (c->dev >= nfips) {
+		panic();
+	}
+
+	clone(archives[c->dev].c, &nc);
+	fip = &archives[nc.dev];
+
+	off = STOC_HEADER;
+	for (i = 0; i <= n; i++) {
+		if (fip->offset[i] == -1) {
+			return 0;
+		}
+
+		if (devtab[nc.index]->seek(&nc, off, KSEEK_SET) < 0) {
+			return -1;
+		}
+
+		r = get_entry(&nc, &entry);
+		if (r <= 0) {
+			return r;
+		}
+
+		off += sizeof(entry);
+	}
+
+	for (i = 1; i < NELEM(uuidnames); i++) {
+		if (memcmp(&uuidnames[i].uuid,
+			   &entry.uuid, sizeof(uuid_t)) == 0) {
+			break;
+		}
+	}
+
+	if (i < NELEM(uuidnames)) {
+		make_dir_entry(c, dir, uuidnames[i].name,
+			       entry.size, n, O_READ);
+	} else {
+		// TODO: set name depending on uuid node value
+		make_dir_entry(c, dir, unk, entry.size, n, O_READ);
+	}
+
+	return 1;
+}
+
+static int fipwalk(chan_t *c, const char *name)
+{
+	return devwalk(c, name, NULL, 0, fipgen);
+}
+
+static int fipstat(chan_t *c, const char *file, dir_t *dir)
+{
+	return devstat(c, file, dir, NULL, 0, fipgen);
+}
+
+/*******************************************************************************
+ * This function copies at most n bytes of the FIP image referred by c into
+ * buf.
+ ******************************************************************************/
+static int fipread(chan_t *c, void *buf, int n)
+{
+	long off;
+	chan_t cs;
+	struct fipfile *fip;
+	long size;
+
+	/* Only makes sense when using debug language */
+	assert(c->qid != CHDIR);
+
+	if ((c->dev >= nfips) || ((c->qid & CHDIR) != 0)) {
+		panic();
+	}
+
+	fip = &archives[c->dev];
+
+	if ((c->qid >= NR_FILES) || (fip->offset[c->qid] < 0)) {
+		panic();
+	}
+
+	clone(fip->c, &cs);
+
+	size = fip->size[c->qid];
+	if (c->offset >= size) {
+		return 0;
+	}
+
+	if (n < 0) {
+		return -1;
+	}
+
+	if (n > (size - c->offset)) {
+		n = size - c->offset;
+	}
+
+	off = fip->offset[c->qid] + c->offset;
+	if (devtab[cs.index]->seek(&cs, off, KSEEK_SET) < 0) {
+		return -1;
+	}
+
+	n = devtab[cs.index]->read(&cs, buf, n);
+	if (n > 0) {
+		c->offset += n;
+	}
+
+	return n;
+}
+
+/*******************************************************************************
+ * This function parses the FIP spec and registers its images in order to
+ * expose them as files in the driver namespace.
+ * It acts as an initialization function for the FIP driver.
+ * It returns a pointer to the newly created channel.
+ ******************************************************************************/
+static chan_t *fipmount(chan_t *c, const char *spec)
+{
+	int r, n, t;
+	chan_t *cspec;
+	uint32_t hname;
+	struct fip_entry entry;
+	struct fipfile *fip;
+	dir_t dir;
+
+	if (nfips == NR_FIPS) {
+		return NULL;
+	}
+
+	fip = &archives[nfips];
+
+	for (n = 0; n < NR_FILES; n++) {
+		fip->offset[n] = -1;
+	}
+
+	cspec = path_to_channel(spec, O_READ);
+	if (cspec == NULL) {
+		return NULL;
+	}
+
+	fip->c = cspec;
+
+	r = devtab[cspec->index]->read(cspec, &hname, sizeof(hname));
+	if (r < 0) {
+		goto err;
+	}
+
+	if ((r != sizeof(hname)) || (hname != TOC_HEADER_NAME)) {
+		goto err;
+	}
+
+	if (stat(spec, &dir) < 0) {
+		goto err;
+	}
+
+	t = cspec->index;
+	if (devtab[t]->seek(cspec, STOC_HEADER, KSEEK_SET) < 0) {
+		goto err;
+	}
+
+	for (n = 0; n < NR_FILES; n++) {
+		switch (get_entry(cspec, &entry)) {
+		case 0:
+			return attach('F', nfips++);
+		case -1:
+			goto err;
+		default:
+			if ((entry.offset_address + entry.size) > dir.length) {
+				goto err;
+			}
+
+			fip->offset[n] = entry.offset_address;
+			fip->size[n] = entry.size;
+			break;
+		}
+	}
+
+err:
+	channel_close(cspec);
+	return NULL;
+}
+
+const dev_t fipdevtab = {
+	.id = 'F',
+	.stat = fipstat,
+	.clone = devclone,
+	.attach = devattach,
+	.walk = fipwalk,
+	.read = fipread,
+	.write = deverrwrite,
+	.mount = fipmount,
+	.seek = devseek
+};
+
diff --git a/lib/debugfs/devroot.c b/lib/debugfs/devroot.c
new file mode 100644
index 0000000..9dd6c92
--- /dev/null
+++ b/lib/debugfs/devroot.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <common/debug.h>
+#include <lib/debugfs.h>
+
+#include "blobs.h"
+#include "dev.h"
+
+/*******************************************************************************
+ * This array contains the directories available from the root directory.
+ ******************************************************************************/
+static const dirtab_t dirtab[] = {
+	{"dev",   CHDIR | DEV_ROOT_QDEV,   0, O_READ},
+	{"blobs", CHDIR | DEV_ROOT_QBLOBS, 0, O_READ},
+	{"fip",   CHDIR | DEV_ROOT_QFIP,   0, O_READ}
+};
+
+static const dirtab_t devfstab[] = {
+};
+
+/*******************************************************************************
+ * This function exposes the elements of the root directory.
+ * It also exposes the content of the dev and blobs directories.
+ ******************************************************************************/
+static int rootgen(chan_t *channel, const dirtab_t *tab, int ntab,
+		   int n, dir_t *dir)
+{
+	switch (channel->qid & ~CHDIR) {
+	case DEV_ROOT_QROOT:
+		tab = dirtab;
+		ntab = NELEM(dirtab);
+		break;
+	case DEV_ROOT_QDEV:
+		tab = devfstab;
+		ntab = NELEM(devfstab);
+		break;
+	case DEV_ROOT_QBLOBS:
+		tab = blobtab;
+		ntab = NELEM(blobtab);
+		break;
+	default:
+		return 0;
+	}
+
+	return devgen(channel, tab, ntab, n, dir);
+}
+
+static int rootwalk(chan_t *channel, const char *name)
+{
+	return devwalk(channel, name, NULL, 0, rootgen);
+}
+
+/*******************************************************************************
+ * This function copies at most n bytes from the element referred by c into buf.
+ ******************************************************************************/
+static int rootread(chan_t *channel, void *buf, int size)
+{
+	const dirtab_t *dp;
+	dir_t *dir;
+
+	if ((channel->qid & CHDIR) != 0) {
+		if (size < sizeof(dir_t)) {
+			return -1;
+		}
+
+		dir = buf;
+		return dirread(channel, dir, NULL, 0, rootgen);
+	}
+
+	/* Only makes sense when using debug language */
+	assert(channel->qid != DEV_ROOT_QBLOBCTL);
+
+	dp = &blobtab[channel->qid - DEV_ROOT_QBLOBCTL];
+	return buf_to_channel(channel, buf, dp->data, size, dp->length);
+}
+
+static int rootstat(chan_t *channel, const char *file, dir_t *dir)
+{
+	return devstat(channel, file, dir, NULL, 0, rootgen);
+}
+
+const dev_t rootdevtab = {
+	.id = '/',
+	.stat = rootstat,
+	.clone = devclone,
+	.attach = devattach,
+	.walk = rootwalk,
+	.read = rootread,
+	.write = deverrwrite,
+	.mount = deverrmount,
+	.seek = devseek
+};
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 1101425..1bbd610 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -6,6 +6,7 @@
 
 #include <arch.h>
 #include <asm_macros.S>
+#include <assert_macros.S>
 #include <context.h>
 
 	.global	el1_sysregs_context_save
@@ -477,6 +478,13 @@
  * ------------------------------------------------------------------
  */
 func el3_exit
+#if ENABLE_ASSERTIONS
+	/* el3_exit assumes SP_EL0 on entry */
+	mrs	x17, spsel
+	cmp	x17, #MODE_SP_EL0
+	ASM_ASSERT(eq)
+#endif
+
 	/* ----------------------------------------------------------
 	 * Save the current SP_EL0 i.e. the EL3 runtime stack which
 	 * will be used for handling the next SMC.
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index d65e02d..b7908ad 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -181,6 +181,16 @@
 		scr_el3 |= SCR_HCE_BIT;
 	}
 
+	/* Enable S-EL2 if the next EL is EL2 and security state is secure */
+	if ((security_state == SECURE) && (GET_EL(ep->spsr) == MODE_EL2)) {
+		if (GET_RW(ep->spsr) != MODE_RW_64) {
+			ERROR("S-EL2 can not be used in AArch32.");
+			panic();
+		}
+
+		scr_el3 |= SCR_EEL2_BIT;
+	}
+
 	/*
 	 * Initialise SCTLR_EL1 to the reset value corresponding to the target
 	 * execution state setting all fields rather than relying of the hw.
diff --git a/lib/libc/libc.mk b/lib/libc/libc.mk
index e1b5560..93d30d0 100644
--- a/lib/libc/libc.mk
+++ b/lib/libc/libc.mk
@@ -12,6 +12,7 @@
 			memcmp.c			\
 			memcpy.c			\
 			memmove.c			\
+			memrchr.c			\
 			memset.c			\
 			printf.c			\
 			putchar.c			\
diff --git a/lib/libc/memrchr.c b/lib/libc/memrchr.c
new file mode 100644
index 0000000..01caef3
--- /dev/null
+++ b/lib/libc/memrchr.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+#undef memrchr
+
+void *memrchr(const void *src, int c, size_t len)
+{
+	const unsigned char *s = src + (len - 1);
+
+	while (len--) {
+		if (*s == (unsigned char)c) {
+			return (void*) s;
+		}
+
+		s--;
+	}
+
+	return NULL;
+}
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index 7c42be7..ea1a01d 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -43,6 +43,7 @@
 static plat_local_state_t
 	psci_req_local_pwr_states[PLAT_MAX_PWR_LVL][PLATFORM_CORE_COUNT];
 
+unsigned int psci_plat_core_count;
 
 /*******************************************************************************
  * Arrays that hold the platform's power domain tree information for state
@@ -161,7 +162,7 @@
 {
 	unsigned int cpu_idx, my_idx = plat_my_core_pos();
 
-	for (cpu_idx = 0; cpu_idx < (unsigned int)PLATFORM_CORE_COUNT;
+	for (cpu_idx = 0; cpu_idx < psci_plat_core_count;
 			cpu_idx++) {
 		if (cpu_idx == my_idx) {
 			assert(psci_get_aff_info_state() == AFF_STATE_ON);
@@ -208,7 +209,7 @@
 {
 	assert(pwrlvl > PSCI_CPU_PWR_LVL);
 	if ((pwrlvl > PSCI_CPU_PWR_LVL) && (pwrlvl <= PLAT_MAX_PWR_LVL) &&
-			(cpu_idx < (unsigned int) PLATFORM_CORE_COUNT)) {
+			(cpu_idx < psci_plat_core_count)) {
 		psci_req_local_pwr_states[pwrlvl - 1U][cpu_idx] = req_pwr_state;
 	}
 }
@@ -220,10 +221,10 @@
 {
 	/* Initialize the requested state of all non CPU power domains as OFF */
 	unsigned int pwrlvl;
-	int core;
+	unsigned int core;
 
 	for (pwrlvl = 0U; pwrlvl < PLAT_MAX_PWR_LVL; pwrlvl++) {
-		for (core = 0; core < PLATFORM_CORE_COUNT; core++) {
+		for (core = 0; core < psci_plat_core_count; core++) {
 			psci_req_local_pwr_states[pwrlvl][core] =
 				PLAT_MAX_OFF_STATE;
 		}
@@ -244,7 +245,7 @@
 	assert(pwrlvl > PSCI_CPU_PWR_LVL);
 
 	if ((pwrlvl > PSCI_CPU_PWR_LVL) && (pwrlvl <= PLAT_MAX_PWR_LVL) &&
-			(cpu_idx < (unsigned int) PLATFORM_CORE_COUNT)) {
+			(cpu_idx < psci_plat_core_count)) {
 		return &psci_req_local_pwr_states[pwrlvl - 1U][cpu_idx];
 	} else
 		return NULL;
@@ -888,7 +889,7 @@
 void psci_print_power_domain_map(void)
 {
 #if LOG_LEVEL >= LOG_LEVEL_INFO
-	int idx;
+	unsigned int idx;
 	plat_local_state_t state;
 	plat_local_state_type_t state_type;
 
@@ -900,7 +901,7 @@
 	};
 
 	INFO("PSCI Power Domain Map:\n");
-	for (idx = 0; idx < (PSCI_NUM_PWR_DOMAINS - PLATFORM_CORE_COUNT);
+	for (idx = 0; idx < (PSCI_NUM_PWR_DOMAINS - psci_plat_core_count);
 							idx++) {
 		state_type = find_local_state_type(
 				psci_non_cpu_pd_nodes[idx].local_state);
@@ -912,7 +913,7 @@
 				psci_non_cpu_pd_nodes[idx].local_state);
 	}
 
-	for (idx = 0; idx < PLATFORM_CORE_COUNT; idx++) {
+	for (idx = 0; idx < psci_plat_core_count; idx++) {
 		state = psci_get_cpu_local_state_by_idx(idx);
 		state_type = find_local_state_type(state);
 		INFO("  CPU Node : MPID 0x%llx, parent_node %d,"
diff --git a/lib/psci/psci_main.c b/lib/psci/psci_main.c
index 5c0e952..52a8b8a 100644
--- a/lib/psci/psci_main.c
+++ b/lib/psci/psci_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -219,16 +219,19 @@
 int psci_affinity_info(u_register_t target_affinity,
 		       unsigned int lowest_affinity_level)
 {
-	int target_idx;
+	int ret;
+	unsigned int target_idx;
 
 	/* We dont support level higher than PSCI_CPU_PWR_LVL */
 	if (lowest_affinity_level > PSCI_CPU_PWR_LVL)
 		return PSCI_E_INVALID_PARAMS;
 
 	/* Calculate the cpu index of the target */
-	target_idx = plat_core_pos_by_mpidr(target_affinity);
-	if (target_idx == -1)
+	ret = plat_core_pos_by_mpidr(target_affinity);
+	if (ret == -1) {
 		return PSCI_E_INVALID_PARAMS;
+	}
+	target_idx = (unsigned int)ret;
 
 	/*
 	 * Generic management:
@@ -245,7 +248,7 @@
 	 * target CPUs shutdown was not seen by the current CPU's cluster. And
 	 * so the cache may contain stale data for the target CPU.
 	 */
-	flush_cpu_data_by_index((unsigned int)target_idx,
+	flush_cpu_data_by_index(target_idx,
 				psci_svc_cpu_data.aff_info_state);
 
 	return psci_get_aff_info_state_by_idx(target_idx);
diff --git a/lib/psci/psci_off.c b/lib/psci/psci_off.c
index e8cd8fe..5447045 100644
--- a/lib/psci/psci_off.c
+++ b/lib/psci/psci_off.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -43,7 +43,7 @@
 int psci_do_cpu_off(unsigned int end_pwrlvl)
 {
 	int rc = PSCI_E_SUCCESS;
-	int idx = (int) plat_my_core_pos();
+	unsigned int idx = plat_my_core_pos();
 	psci_power_state_t state_info;
 	unsigned int parent_nodes[PLAT_MAX_PWR_LVL] = {0};
 
diff --git a/lib/psci/psci_on.c b/lib/psci/psci_on.c
index 470b4f3..dd48e10 100644
--- a/lib/psci/psci_on.c
+++ b/lib/psci/psci_on.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,12 +20,12 @@
 /*
  * Helper functions for the CPU level spinlocks
  */
-static inline void psci_spin_lock_cpu(int idx)
+static inline void psci_spin_lock_cpu(unsigned int idx)
 {
 	spin_lock(&psci_cpu_pd_nodes[idx].cpu_lock);
 }
 
-static inline void psci_spin_unlock_cpu(int idx)
+static inline void psci_spin_unlock_cpu(unsigned int idx)
 {
 	spin_unlock(&psci_cpu_pd_nodes[idx].cpu_lock);
 }
@@ -61,12 +61,14 @@
 {
 	int rc;
 	aff_info_state_t target_aff_state;
-	int target_idx = plat_core_pos_by_mpidr(target_cpu);
+	int ret = plat_core_pos_by_mpidr(target_cpu);
+	unsigned int target_idx = (unsigned int)ret;
 
 	/* Calling function must supply valid input arguments */
-	assert(target_idx >= 0);
+	assert(ret >= 0);
 	assert(ep != NULL);
 
+
 	/*
 	 * This function must only be called on platforms where the
 	 * CPU_ON platform hooks have been implemented.
@@ -93,7 +95,7 @@
 	 * target CPUs shutdown was not seen by the current CPU's cluster. And
 	 * so the cache may contain stale data for the target CPU.
 	 */
-	flush_cpu_data_by_index((unsigned int)target_idx,
+	flush_cpu_data_by_index(target_idx,
 				psci_svc_cpu_data.aff_info_state);
 	rc = cpu_on_validate_state(psci_get_aff_info_state_by_idx(target_idx));
 	if (rc != PSCI_E_SUCCESS)
@@ -113,7 +115,7 @@
 	 * turned OFF.
 	 */
 	psci_set_aff_info_state_by_idx(target_idx, AFF_STATE_ON_PENDING);
-	flush_cpu_data_by_index((unsigned int)target_idx,
+	flush_cpu_data_by_index(target_idx,
 				psci_svc_cpu_data.aff_info_state);
 
 	/*
@@ -126,7 +128,7 @@
 	if (target_aff_state != AFF_STATE_ON_PENDING) {
 		assert(target_aff_state == AFF_STATE_OFF);
 		psci_set_aff_info_state_by_idx(target_idx, AFF_STATE_ON_PENDING);
-		flush_cpu_data_by_index((unsigned int)target_idx,
+		flush_cpu_data_by_index(target_idx,
 					psci_svc_cpu_data.aff_info_state);
 
 		assert(psci_get_aff_info_state_by_idx(target_idx) ==
@@ -146,11 +148,11 @@
 
 	if (rc == PSCI_E_SUCCESS)
 		/* Store the re-entry information for the non-secure world. */
-		cm_init_context_by_index((unsigned int)target_idx, ep);
+		cm_init_context_by_index(target_idx, ep);
 	else {
 		/* Restore the state on error. */
 		psci_set_aff_info_state_by_idx(target_idx, AFF_STATE_OFF);
-		flush_cpu_data_by_index((unsigned int)target_idx,
+		flush_cpu_data_by_index(target_idx,
 					psci_svc_cpu_data.aff_info_state);
 	}
 
@@ -164,7 +166,7 @@
  * are called by the common finisher routine in psci_common.c. The `state_info`
  * is the psci_power_state from which this CPU has woken up from.
  ******************************************************************************/
-void psci_cpu_on_finish(int cpu_idx, const psci_power_state_t *state_info)
+void psci_cpu_on_finish(unsigned int cpu_idx, const psci_power_state_t *state_info)
 {
 	/*
 	 * Plat. management: Perform the platform specific actions
diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h
index b49847c..e2dcfa8 100644
--- a/lib/psci/psci_private.h
+++ b/lib/psci/psci_private.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -251,6 +251,7 @@
 extern non_cpu_pd_node_t psci_non_cpu_pd_nodes[PSCI_NUM_NON_CPU_PWR_DOMAINS];
 extern cpu_pd_node_t psci_cpu_pd_nodes[PLATFORM_CORE_COUNT];
 extern unsigned int psci_caps;
+extern unsigned int psci_plat_core_count;
 
 /*******************************************************************************
  * SPD's power management hooks registered with PSCI
@@ -300,7 +301,7 @@
 int psci_cpu_on_start(u_register_t target_cpu,
 		      const entry_point_info_t *ep);
 
-void psci_cpu_on_finish(int cpu_idx, const psci_power_state_t *state_info);
+void psci_cpu_on_finish(unsigned int cpu_idx, const psci_power_state_t *state_info);
 
 /* Private exported functions from psci_off.c */
 int psci_do_cpu_off(unsigned int end_pwrlvl);
@@ -311,7 +312,7 @@
 			psci_power_state_t *state_info,
 			unsigned int is_power_down_state);
 
-void psci_cpu_suspend_finish(int cpu_idx, const psci_power_state_t *state_info);
+void psci_cpu_suspend_finish(unsigned int cpu_idx, const psci_power_state_t *state_info);
 
 /* Private exported functions from psci_helpers.S */
 void psci_do_pwrdown_cache_maintenance(unsigned int pwr_level);
diff --git a/lib/psci/psci_setup.c b/lib/psci/psci_setup.c
index 853f915..d1ec998 100644
--- a/lib/psci/psci_setup.c
+++ b/lib/psci/psci_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -84,15 +84,16 @@
  *******************************************************************************/
 static void __init psci_update_pwrlvl_limits(void)
 {
-	int j, cpu_idx;
+	unsigned int cpu_idx;
+	int j;
 	unsigned int nodes_idx[PLAT_MAX_PWR_LVL] = {0};
 	unsigned int temp_index[PLAT_MAX_PWR_LVL];
 
-	for (cpu_idx = 0; cpu_idx < PLATFORM_CORE_COUNT; cpu_idx++) {
+	for (cpu_idx = 0; cpu_idx < psci_plat_core_count; cpu_idx++) {
 		psci_get_parent_pwr_domain_nodes(cpu_idx,
-						 (unsigned int)PLAT_MAX_PWR_LVL,
+						 PLAT_MAX_PWR_LVL,
 						 temp_index);
-		for (j = (int) PLAT_MAX_PWR_LVL - 1; j >= 0; j--) {
+		for (j = (int)PLAT_MAX_PWR_LVL - 1; j >= 0; j--) {
 			if (temp_index[j] != nodes_idx[j]) {
 				nodes_idx[j] = temp_index[j];
 				psci_non_cpu_pd_nodes[nodes_idx[j]].cpu_start_idx
@@ -109,12 +110,13 @@
  * informs the number of root power domains. The parent nodes of the root nodes
  * will point to an invalid entry(-1).
  ******************************************************************************/
-static void __init populate_power_domain_tree(const unsigned char *topology)
+static unsigned int __init populate_power_domain_tree(const unsigned char
+							*topology)
 {
 	unsigned int i, j = 0U, num_nodes_at_lvl = 1U, num_nodes_at_next_lvl;
 	unsigned int node_index = 0U, num_children;
-	int parent_node_index = 0;
-	int level = (int) PLAT_MAX_PWR_LVL;
+	unsigned int parent_node_index = 0U;
+	int level = (int)PLAT_MAX_PWR_LVL;
 
 	/*
 	 * For each level the inputs are:
@@ -143,8 +145,8 @@
 			for (j = node_index;
 				j < (node_index + num_children); j++)
 				psci_init_pwr_domain_node((unsigned char)j,
-							  parent_node_index - 1,
-							  (unsigned char)level);
+						  parent_node_index - 1U,
+						  (unsigned char)level);
 
 			node_index = j;
 			num_nodes_at_next_lvl += num_children;
@@ -160,7 +162,8 @@
 	}
 
 	/* Validate the sanity of array exported by the platform */
-	assert((int) j == PLATFORM_CORE_COUNT);
+	assert(j <= PLATFORM_CORE_COUNT);
+	return j;
 }
 
 /*******************************************************************************
@@ -199,7 +202,7 @@
 	topology_tree = plat_get_power_domain_tree_desc();
 
 	/* Populate the power domain arrays using the platform topology map */
-	populate_power_domain_tree(topology_tree);
+	psci_plat_core_count = populate_power_domain_tree(topology_tree);
 
 	/* Update the CPU limits for each node in psci_non_cpu_pd_nodes */
 	psci_update_pwrlvl_limits();
diff --git a/lib/psci/psci_stat.c b/lib/psci/psci_stat.c
index 772a184..ecef95a 100644
--- a/lib/psci/psci_stat.c
+++ b/lib/psci/psci_stat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -28,7 +28,7 @@
  * that goes to power down in non cpu power domains.
  */
 static int last_cpu_in_non_cpu_pd[PSCI_NUM_NON_CPU_PWR_DOMAINS] = {
-		[0 ... PSCI_NUM_NON_CPU_PWR_DOMAINS - 1] = -1};
+		[0 ... PSCI_NUM_NON_CPU_PWR_DOMAINS - 1U] = -1};
 
 /*
  * Following are used to store PSCI STAT values for
@@ -77,7 +77,7 @@
 			const psci_power_state_t *state_info)
 {
 	unsigned int lvl, parent_idx;
-	int cpu_idx = (int) plat_my_core_pos();
+	unsigned int cpu_idx = plat_my_core_pos();
 
 	assert(end_pwrlvl <= PLAT_MAX_PWR_LVL);
 	assert(state_info != NULL);
@@ -94,7 +94,7 @@
 		 * The power domain is entering a low power state, so this is
 		 * the last CPU for this power domain
 		 */
-		last_cpu_in_non_cpu_pd[parent_idx] = cpu_idx;
+		last_cpu_in_non_cpu_pd[parent_idx] = (int)cpu_idx;
 
 		parent_idx = psci_non_cpu_pd_nodes[parent_idx].parent_node;
 	}
@@ -110,7 +110,7 @@
 			const psci_power_state_t *state_info)
 {
 	unsigned int lvl, parent_idx;
-	int cpu_idx = (int) plat_my_core_pos();
+	unsigned int cpu_idx = plat_my_core_pos();
 	int stat_idx;
 	plat_local_state_t local_state;
 	u_register_t residency;
@@ -150,7 +150,7 @@
 
 		/* Call into platform interface to calculate residency. */
 		residency = plat_psci_stat_get_residency(lvl, state_info,
-					last_cpu_in_non_cpu_pd[parent_idx]);
+			(unsigned int)last_cpu_in_non_cpu_pd[parent_idx]);
 
 		/* Initialize back to reset value */
 		last_cpu_in_non_cpu_pd[parent_idx] = -1;
diff --git a/lib/psci/psci_suspend.c b/lib/psci/psci_suspend.c
index 98dd2d6..da9f328 100644
--- a/lib/psci/psci_suspend.c
+++ b/lib/psci/psci_suspend.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -25,7 +25,7 @@
  * This function does generic and platform specific operations after a wake-up
  * from standby/retention states at multiple power levels.
  ******************************************************************************/
-static void psci_suspend_to_standby_finisher(int cpu_idx,
+static void psci_suspend_to_standby_finisher(unsigned int cpu_idx,
 					     unsigned int end_pwrlvl)
 {
 	unsigned int parent_nodes[PLAT_MAX_PWR_LVL] = {0};
@@ -157,7 +157,7 @@
 			    unsigned int is_power_down_state)
 {
 	int skip_wfi = 0;
-	int idx = (int) plat_my_core_pos();
+	unsigned int idx = plat_my_core_pos();
 	unsigned int parent_nodes[PLAT_MAX_PWR_LVL] = {0};
 
 	/*
@@ -276,7 +276,7 @@
  * are called by the common finisher routine in psci_common.c. The `state_info`
  * is the psci_power_state from which this CPU has woken up from.
  ******************************************************************************/
-void psci_cpu_suspend_finish(int cpu_idx, const psci_power_state_t *state_info)
+void psci_cpu_suspend_finish(unsigned int cpu_idx, const psci_power_state_t *state_info)
 {
 	unsigned int counter_freq;
 	unsigned int max_off_lvl;
diff --git a/lib/sprt/sprt_host.c b/lib/sprt/sprt_host.c
deleted file mode 100644
index c4d436e..0000000
--- a/lib/sprt/sprt_host.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#include "sprt_common.h"
-#include "sprt_queue.h"
-
-void sprt_initialize_queues(void *buffer_base, size_t buffer_size)
-{
-	/* Initialize queue for blocking messages */
-
-	void *blocking_base = buffer_base;
-	uint32_t blocking_num = 4U;
-	size_t blocking_size = SPRT_QUEUE_HEADER_SIZE +
-			       SPRT_QUEUE_ENTRY_MSG_SIZE * blocking_num;
-
-	sprt_queue_init(blocking_base, blocking_num, SPRT_QUEUE_ENTRY_MSG_SIZE);
-
-	/* Initialize queue for non-blocking messages */
-
-	void *non_blocking_base = (void *)((uintptr_t)blocking_base + blocking_size);
-	size_t non_blocking_size = buffer_size - blocking_size;
-	uint32_t non_blocking_num = (non_blocking_size - SPRT_QUEUE_HEADER_SIZE) /
-		SPRT_QUEUE_ENTRY_MSG_SIZE;
-
-	sprt_queue_init(non_blocking_base, non_blocking_num, SPRT_QUEUE_ENTRY_MSG_SIZE);
-}
-
-int sprt_push_message(void *buffer_base,
-		      const struct sprt_queue_entry_message *message,
-		      int queue_num)
-{
-	struct sprt_queue *q = buffer_base;
-
-	while (queue_num-- > 0) {
-		uintptr_t next_addr = (uintptr_t)q + sizeof(struct sprt_queue) +
-				      q->entry_num * q->entry_size;
-		q = (struct sprt_queue *) next_addr;
-	}
-
-	return sprt_queue_push(q, message);
-}
diff --git a/lib/sprt/sprt_host.mk b/lib/sprt/sprt_host.mk
deleted file mode 100644
index abcfe5e..0000000
--- a/lib/sprt/sprt_host.mk
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Copyright (c) 2018, Arm Limited. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-SPRT_LIB_SOURCES	:=	$(addprefix lib/sprt/,			\
-					sprt_host.c			\
-					sprt_queue.c)
-
-SPRT_LIB_INCLUDES	:=	-Iinclude/lib/sprt/
diff --git a/lib/sprt/sprt_queue.c b/lib/sprt/sprt_queue.c
deleted file mode 100644
index 2bd4139..0000000
--- a/lib/sprt/sprt_queue.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <stdint.h>
-#include <string.h>
-
-#include "sprt_queue.h"
-
-void sprt_queue_init(void *queue_base, uint32_t entry_num, uint32_t entry_size)
-{
-	assert(queue_base != NULL);
-	assert(entry_size > 0U);
-	assert(entry_num > 0U);
-
-	struct sprt_queue *queue = (struct sprt_queue *)queue_base;
-
-	queue->entry_num = entry_num;
-	queue->entry_size = entry_size;
-	queue->idx_write = 0U;
-	queue->idx_read = 0U;
-
-	memset(queue->data, 0, entry_num * entry_size);
-}
-
-int sprt_queue_is_empty(void *queue_base)
-{
-	assert(queue_base != NULL);
-
-	struct sprt_queue *queue = (struct sprt_queue *)queue_base;
-
-	return (queue->idx_write == queue->idx_read);
-}
-
-int sprt_queue_is_full(void *queue_base)
-{
-	assert(queue_base != NULL);
-
-	struct sprt_queue *queue = (struct sprt_queue *)queue_base;
-
-	uint32_t idx_next_write = (queue->idx_write + 1) % queue->entry_num;
-
-	return (idx_next_write == queue->idx_read);
-}
-
-int sprt_queue_push(void *queue_base, const void *entry)
-{
-	assert(entry != NULL);
-	assert(queue_base != NULL);
-
-	if (sprt_queue_is_full(queue_base) != 0) {
-		return -ENOMEM;
-	}
-
-	struct sprt_queue *queue = (struct sprt_queue *)queue_base;
-
-	uint8_t *dst_entry = &queue->data[queue->entry_size * queue->idx_write];
-
-	memcpy(dst_entry, entry, queue->entry_size);
-
-	/*
-	 * Make sure that the message data is visible before increasing the
-	 * counter of available messages.
-	 */
-	__asm__ volatile("dmb st" ::: "memory");
-
-	queue->idx_write = (queue->idx_write + 1) % queue->entry_num;
-
-	__asm__ volatile("dmb st" ::: "memory");
-
-	return 0;
-}
-
-int sprt_queue_pop(void *queue_base, void *entry)
-{
-	assert(entry != NULL);
-	assert(queue_base != NULL);
-
-	if (sprt_queue_is_empty(queue_base) != 0) {
-		return -ENOENT;
-	}
-
-	struct sprt_queue *queue = (struct sprt_queue *)queue_base;
-
-	uint8_t *src_entry = &queue->data[queue->entry_size * queue->idx_read];
-
-	memcpy(entry, src_entry, queue->entry_size);
-
-	/*
-	 * Make sure that the message data is visible before increasing the
-	 * counter of read messages.
-	 */
-	__asm__ volatile("dmb st" ::: "memory");
-
-	queue->idx_read = (queue->idx_read + 1) % queue->entry_num;
-
-	__asm__ volatile("dmb st" ::: "memory");
-
-	return 0;
-}
diff --git a/lib/sprt/sprt_queue.h b/lib/sprt/sprt_queue.h
deleted file mode 100644
index 4ea1bc2..0000000
--- a/lib/sprt/sprt_queue.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPRT_QUEUE_H
-#define SPRT_QUEUE_H
-
-#include <stdint.h>
-
-/* Struct that defines a queue. Not to be used directly. */
-struct __attribute__((__packed__)) sprt_queue {
-	uint32_t entry_num;	/* Number of entries */
-	uint32_t entry_size;	/* Size of an entry */
-	uint32_t idx_write;	/* Index of first empty entry */
-	uint32_t idx_read;	/* Index of first entry to read */
-	uint8_t  data[0];	/* Start of data */
-};
-
-#define SPRT_QUEUE_HEADER_SIZE	(sizeof(struct sprt_queue))
-
-/*
- * Initializes a memory region to be used as a queue of the given number of
- * entries with the specified size.
- */
-void sprt_queue_init(void *queue_base, uint32_t entry_num, uint32_t entry_size);
-
-/* Returns 1 if the queue is empty, 0 otherwise */
-int sprt_queue_is_empty(void *queue_base);
-
-/* Returns 1 if the queue is full, 0 otherwise */
-int sprt_queue_is_full(void *queue_base);
-
-/*
- * Pushes a new entry intro the queue. Returns 0 on success, -ENOMEM if the
- * queue is full.
- */
-int sprt_queue_push(void *queue_base, const void *entry);
-
-/*
- * Pops an entry from the queue. Returns 0 on success, -ENOENT if the queue is
- * empty.
- */
-int sprt_queue_pop(void *queue_base, void *entry);
-
-#endif /* SPRT_QUEUE_H */
diff --git a/lib/stack_protector/stack_protector.mk b/lib/stack_protector/stack_protector.mk
index 94e804b..b5aba15 100644
--- a/lib/stack_protector/stack_protector.mk
+++ b/lib/stack_protector/stack_protector.mk
@@ -11,7 +11,9 @@
   ENABLE_STACK_PROTECTOR := none
 endif
 
-ifneq (${ENABLE_STACK_PROTECTOR},none)
+ifeq (${ENABLE_STACK_PROTECTOR},none)
+  TF_CFLAGS            +=      -fno-stack-protector
+else
   STACK_PROTECTOR_ENABLED := 1
   BL_COMMON_SOURCES	+=	lib/stack_protector/stack_protector.c	\
 				lib/stack_protector/${ARCH}/asm_stack_protector.S
diff --git a/lib/xlat_tables/aarch32/nonlpae_tables.c b/lib/xlat_tables/aarch32/nonlpae_tables.c
index bd6b152..b8c2686 100644
--- a/lib/xlat_tables/aarch32/nonlpae_tables.c
+++ b/lib/xlat_tables/aarch32/nonlpae_tables.c
@@ -284,10 +284,10 @@
 }
 
 /* map all memory as shared/global/domain0/no-usr access */
-static unsigned long mmap_desc(unsigned attr, unsigned long addr_pa,
-					unsigned int level)
+static uint32_t mmap_desc(unsigned attr, unsigned int addr_pa,
+		unsigned int level)
 {
-	unsigned long desc;
+	uint32_t desc;
 
 	switch (level) {
 	case 1:
@@ -380,14 +380,14 @@
 }
 
 static mmap_region_t *init_xlation_table_inner(mmap_region_t *mm,
-						unsigned long base_va,
-						unsigned long *table,
+						unsigned int base_va,
+						uint32_t *table,
 						unsigned int level)
 {
 	unsigned int level_size_shift = (level == 1) ?
 					ONE_MB_SHIFT : FOUR_KB_SHIFT;
 	unsigned int level_size = 1 << level_size_shift;
-	unsigned long level_index_mask = (level == 1) ?
+	unsigned int level_index_mask = (level == 1) ?
 					(NUM_1MB_IN_4GB - 1) << ONE_MB_SHIFT :
 					(NUM_4K_IN_1MB - 1) << FOUR_KB_SHIFT;
 
@@ -396,7 +396,7 @@
 	VERBOSE("init xlat table at %p (level%1d)\n", (void *)table, level);
 
 	do  {
-		unsigned long desc = MMU32B_UNSET_DESC;
+		uint32_t desc = MMU32B_UNSET_DESC;
 
 		if (mm->base_va + mm->size <= base_va) {
 			/* Area now after the region so skip it */
@@ -427,7 +427,7 @@
 		}
 
 		if (desc == MMU32B_UNSET_DESC) {
-			unsigned long xlat_table;
+			uintptr_t xlat_table;
 
 			/*
 			 * Area not covered by a region so need finer table
@@ -443,7 +443,7 @@
 						~(MMU32B_L1_TABLE_ALIGN - 1);
 				desc = *table;
 			} else {
-				xlat_table = (unsigned long)mmu_l2_base +
+				xlat_table = (uintptr_t)mmu_l2_base +
 					next_xlat * MMU32B_L2_TABLE_SIZE;
 				next_xlat++;
 				assert(next_xlat <= MAX_XLAT_TABLES);
@@ -456,7 +456,7 @@
 			}
 			/* Recurse to fill in new table */
 			mm = init_xlation_table_inner(mm, base_va,
-						(unsigned long *)xlat_table,
+						(uint32_t *)xlat_table,
 						level + 1);
 		}
 #if LOG_LEVEL >= LOG_LEVEL_VERBOSE
@@ -480,7 +480,7 @@
 
 	memset(mmu_l1_base, 0, MMU32B_L1_TABLE_SIZE);
 
-	init_xlation_table_inner(mmap, 0, (unsigned long *)mmu_l1_base, 1);
+	init_xlation_table_inner(mmap, 0, (uint32_t *)mmu_l1_base, 1);
 
 	VERBOSE("init xlat - max_va=%p, max_pa=%llx\n",
 			(void *)xlat_max_va, xlat_max_pa);
diff --git a/lib/xlat_tables_v2/xlat_tables_core.c b/lib/xlat_tables_v2/xlat_tables_core.c
index 4f62f46..3c0865b 100644
--- a/lib/xlat_tables_v2/xlat_tables_core.c
+++ b/lib/xlat_tables_v2/xlat_tables_core.c
@@ -607,7 +607,8 @@
 			}
 
 			/* Point to new subtable from this one. */
-			table_base[table_idx] = TABLE_DESC | (unsigned long)subtable;
+			table_base[table_idx] =
+				TABLE_DESC | (uintptr_t)subtable;
 
 			/* Recurse to write into subtable */
 			end_va = xlat_tables_map_region(ctx, mm, table_idx_va,
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index b89d87e..47f3ebd 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -236,7 +236,7 @@
 
 $(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | bl$(3)_dirs
 	$$(ECHO) "  CC      $$<"
-	$$(Q)$$(CC) $$(TF_CFLAGS) $$(CFLAGS) $(BL_CFLAGS) -D$(IMAGE) $(MAKE_DEP) -c $$< -o $$@
+	$$(Q)$$(CC) $$(LTO_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(BL_CFLAGS) -D$(IMAGE) $(MAKE_DEP) -c $$< -o $$@
 
 -include $(DEP)
 
@@ -433,6 +433,10 @@
 		--map --list="$(MAPFILE)" --scatter=${PLAT_DIR}/scat/bl${1}.scat \
 		$(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS) \
 		$(BUILD_DIR)/build_message.o $(OBJS)
+else ifneq ($(findstring gcc,$(notdir $(LD))),)
+	$$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) -Wl,-Map=$(MAPFILE) \
+		-Wl,-T$(LINKERFILE) $(BUILD_DIR)/build_message.o \
+		$(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS)
 else
 	$$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) -Map=$(MAPFILE) \
 		--script $(LINKERFILE) $(BUILD_DIR)/build_message.o \
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index b7fb173..53832c5 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -171,6 +171,10 @@
 # platform Makefile is free to override this value.
 SEPARATE_CODE_AND_RODATA	:= 0
 
+# Put NOBITS sections (.bss, stacks, page tables, and coherent memory) in a
+# separate memory region, which may be discontiguous from the rest of BL31.
+SEPARATE_NOBITS_REGION		:= 0
+
 # If the BL31 image initialisation code is recalimed after use for the secondary
 # cores stack
 RECLAIM_INIT_CODE		:= 0
@@ -178,11 +182,8 @@
 # SPD choice
 SPD				:= none
 
-# For including the Secure Partition Manager
-ENABLE_SPM			:= 0
-
-# Use the SPM based on MM
-SPM_MM				:= 1
+# Enable the Management Mode (MM)-based Secure Partition Manager implementation
+SPM_MM				:= 0
 
 # Flag to introduce an infinite loop in BL1 just before it exits into the next
 # image. This is meant to help debugging the post-BL2 phase.
@@ -194,6 +195,9 @@
 # Build option to choose whether Trusted Firmware uses Coherent memory or not.
 USE_COHERENT_MEM		:= 1
 
+# Build option to add debugfs support
+USE_DEBUGFS			:= 0
+
 # Build option to choose whether Trusted Firmware uses library at ROM
 USE_ROMLIB			:= 0
 
@@ -239,3 +243,6 @@
 # implementation variant using the ARMv8.1-LSE compare-and-swap instruction.
 # Default: disabled
 USE_SPINLOCK_CAS := 0
+
+# Enable Link Time Optimization
+ENABLE_LTO			:= 0
diff --git a/plat/allwinner/common/allwinner-common.mk b/plat/allwinner/common/allwinner-common.mk
index 6866bd6..98bcf3e 100644
--- a/plat/allwinner/common/allwinner-common.mk
+++ b/plat/allwinner/common/allwinner-common.mk
@@ -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,8 +8,7 @@
 
 AW_PLAT			:=	plat/allwinner
 
-PLAT_INCLUDES		:=	-Iinclude/plat/arm/common		\
-				-Iinclude/plat/arm/common/aarch64	\
+PLAT_INCLUDES		:=	-Iinclude/plat/arm/common/aarch64	\
 				-I${AW_PLAT}/common/include		\
 				-I${AW_PLAT}/${PLAT}/include
 
@@ -20,7 +19,8 @@
 				${AW_PLAT}/common/plat_helpers.S	\
 				${AW_PLAT}/common/sunxi_common.c
 
-BL31_SOURCES		+=	drivers/arm/gic/common/gic_common.c	\
+BL31_SOURCES		+=	drivers/allwinner/axp/common.c		\
+				drivers/arm/gic/common/gic_common.c	\
 				drivers/arm/gic/v2/gicv2_helpers.c	\
 				drivers/arm/gic/v2/gicv2_main.c		\
 				drivers/delay_timer/delay_timer.c	\
@@ -55,11 +55,11 @@
 # Allow mapping read-only data as execute-never.
 SEPARATE_CODE_AND_RODATA	:=	1
 
+# Put NOBITS memory in SRAM A1, overwriting U-Boot's SPL.
+SEPARATE_NOBITS_REGION		:=	1
+
 # BL31 gets loaded alongside BL33 (U-Boot) by U-Boot's SPL
 RESET_TO_BL31			:=	1
 
-# We are short on memory, so save 3.5KB by not having an extra coherent page.
-USE_COHERENT_MEM		:=	0
-
 # This platform is single-cluster and does not require coherency setup.
 WARMBOOT_ENABLE_DCACHE_EARLY	:=	1
diff --git a/plat/allwinner/common/include/platform_def.h b/plat/allwinner/common/include/platform_def.h
index ede3881..0a00076 100644
--- a/plat/allwinner/common/include/platform_def.h
+++ b/plat/allwinner/common/include/platform_def.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
  */
@@ -16,6 +16,10 @@
 #define BL31_BASE			SUNXI_SRAM_A2_BASE
 #define BL31_LIMIT			(SUNXI_SRAM_A2_BASE + SUNXI_SRAM_A2_SIZE)
 
+/* Overwrite U-Boot SPL, but reserve the first page for the SPL header. */
+#define BL31_NOBITS_BASE		(SUNXI_SRAM_A1_BASE + 0x1000)
+#define BL31_NOBITS_LIMIT		(SUNXI_SRAM_A1_BASE + SUNXI_SRAM_A1_SIZE)
+
 /* The traditional U-Boot load address is 160MB into DRAM, so at 0x4a000000 */
 #define PLAT_SUNXI_NS_IMAGE_OFFSET	(SUNXI_DRAM_BASE + (160U << 20))
 
@@ -28,7 +32,7 @@
 #define CACHE_WRITEBACK_SHIFT		6
 #define CACHE_WRITEBACK_GRANULE		(1 << CACHE_WRITEBACK_SHIFT)
 
-#define MAX_MMAP_REGIONS		(3 + PLATFORM_MMAP_REGIONS)
+#define MAX_MMAP_REGIONS		(4 + PLATFORM_MMAP_REGIONS)
 #define MAX_XLAT_TABLES			1
 
 #define PLAT_MAX_PWR_LVL_STATES		U(2)
diff --git a/plat/allwinner/common/include/sunxi_private.h b/plat/allwinner/common/include/sunxi_private.h
index 1166879..dcf3dc9 100644
--- a/plat/allwinner/common/include/sunxi_private.h
+++ b/plat/allwinner/common/include/sunxi_private.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
  */
@@ -12,7 +12,7 @@
 void sunxi_cpu_on(u_register_t mpidr);
 void sunxi_cpu_off(u_register_t mpidr);
 void sunxi_disable_secondary_cpus(u_register_t primary_mpidr);
-void __dead2 sunxi_power_down(void);
+void sunxi_power_down(void);
 
 int sunxi_pmic_setup(uint16_t socid, const void *fdt);
 void sunxi_security_setup(void);
@@ -20,7 +20,6 @@
 uint16_t sunxi_read_soc_id(void);
 void sunxi_set_gpio_out(char port, int pin, bool level_high);
 int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb);
-void sunxi_execute_arisc_code(uint32_t *code, size_t size,
-			      int patch_offset, uint16_t param);
+void sunxi_execute_arisc_code(uint32_t *code, size_t size, uint16_t param);
 
 #endif /* SUNXI_PRIVATE_H */
diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c
index 3b44aab..cff8268 100644
--- a/plat/allwinner/common/sunxi_common.c
+++ b/plat/allwinner/common/sunxi_common.c
@@ -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
  */
@@ -57,6 +57,10 @@
 	mmap_add_region(BL_RO_DATA_BASE, BL_RO_DATA_BASE,
 			BL_RO_DATA_END - BL_RO_DATA_BASE,
 			MT_RO_DATA | MT_SECURE);
+	mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE,
+			BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
+			MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER);
+
 	mmap_add(sunxi_mmap);
 	init_xlat_tables();
 
@@ -150,16 +154,16 @@
 	/* set both pins to pull-up */
 	mmio_clrsetbits_32(SUNXI_R_PIO_BASE + 0x1c, 0x0fU, 0x5U);
 
-	/* assert, then de-assert reset of I2C/RSB controller */
-	mmio_clrbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit);
-	mmio_setbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit);
-
 	/* un-gate clock */
 	if (socid != SUNXI_SOC_H6)
 		mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x28, device_bit);
 	else
 		mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x19c, device_bit | BIT(0));
 
+	/* assert, then de-assert reset of I2C/RSB controller */
+	mmio_clrbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit);
+	mmio_setbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit);
+
 	return 0;
 }
 
@@ -172,8 +176,7 @@
  * in SRAM, put the address of that into the reset vector and release the
  * arisc reset line. The SCP will execute that code and pull the line up again.
  */
-void sunxi_execute_arisc_code(uint32_t *code, size_t size,
-			      int patch_offset, uint16_t param)
+void sunxi_execute_arisc_code(uint32_t *code, size_t size, uint16_t param)
 {
 	uintptr_t arisc_reset_vec = SUNXI_SRAM_A2_BASE - 0x4000 + 0x100;
 
@@ -187,8 +190,7 @@
 	} while (1);
 
 	/* Patch up the code to feed in an input parameter. */
-	if (patch_offset >= 0 && patch_offset <= (size - 4))
-		code[patch_offset] = (code[patch_offset] & ~0xffff) | param;
+	code[0] = (code[0] & ~0xffff) | param;
 	clean_dcache_range((uintptr_t)code, size);
 
 	/*
diff --git a/plat/allwinner/common/sunxi_cpu_ops.c b/plat/allwinner/common/sunxi_cpu_ops.c
index b4c9fcc..6e29b69 100644
--- a/plat/allwinner/common/sunxi_cpu_ops.c
+++ b/plat/allwinner/common/sunxi_cpu_ops.c
@@ -78,7 +78,7 @@
 	 * patched into the first instruction.
 	 */
 	sunxi_execute_arisc_code(arisc_core_off, sizeof(arisc_core_off),
-				 0, BIT_32(core));
+				 BIT_32(core));
 }
 
 void sunxi_cpu_on(u_register_t mpidr)
diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c
index 13e1353..9b074d2 100644
--- a/plat/allwinner/common/sunxi_pm.c
+++ b/plat/allwinner/common/sunxi_pm.c
@@ -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
  */
@@ -65,6 +65,11 @@
 	sunxi_disable_secondary_cpus(read_mpidr());
 
 	sunxi_power_down();
+
+	udelay(1000);
+	ERROR("PSCI: Cannot turn off system, halting\n");
+	wfi();
+	panic();
 }
 
 static void __dead2 sunxi_system_reset(void)
diff --git a/plat/allwinner/sun50i_a64/platform.mk b/plat/allwinner/sun50i_a64/platform.mk
index b46fbc2..f6d5aa9 100644
--- a/plat/allwinner/sun50i_a64/platform.mk
+++ b/plat/allwinner/sun50i_a64/platform.mk
@@ -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
 #
@@ -7,4 +7,5 @@
 # The differences between the platform are covered by the include files.
 include plat/allwinner/common/allwinner-common.mk
 
-PLAT_BL_COMMON_SOURCES	+=	drivers/allwinner/sunxi_rsb.c
+BL31_SOURCES		+=	drivers/allwinner/axp/axp803.c		\
+				drivers/allwinner/sunxi_rsb.c
diff --git a/plat/allwinner/sun50i_a64/sunxi_power.c b/plat/allwinner/sun50i_a64/sunxi_power.c
index 07a3716..5b7d76a 100644
--- a/plat/allwinner/sun50i_a64/sunxi_power.c
+++ b/plat/allwinner/sun50i_a64/sunxi_power.c
@@ -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.
  * Copyright (c) 2018, Icenowy Zheng <icenowy@aosc.io>
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -7,14 +7,11 @@
 
 #include <errno.h>
 
-#include <libfdt.h>
-
 #include <platform_def.h>
 
-#include <arch_helpers.h>
 #include <common/debug.h>
+#include <drivers/allwinner/axp.h>
 #include <drivers/allwinner/sunxi_rsb.h>
-#include <drivers/delay_timer.h>
 #include <lib/mmio.h>
 
 #include <sunxi_def.h>
@@ -22,6 +19,7 @@
 #include <sunxi_private.h>
 
 static enum pmic_type {
+	UNKNOWN,
 	GENERIC_H5,
 	GENERIC_A64,
 	REF_DESIGN_H5,	/* regulators controlled by GPIO pins on port L */
@@ -38,7 +36,7 @@
  * disabled.
  * This function only cares about peripherals.
  */
-void sunxi_turn_off_soc(uint16_t socid)
+static void sunxi_turn_off_soc(uint16_t socid)
 {
 	int i;
 
@@ -113,174 +111,22 @@
 		return ret;
 
 	/* Associate the 8-bit runtime address with the 12-bit bus address. */
-	return rsb_assign_runtime_address(AXP803_HW_ADDR,
-					  AXP803_RT_ADDR);
-}
-
-static int axp_write(uint8_t reg, uint8_t val)
-{
-	return rsb_write(AXP803_RT_ADDR, reg, val);
-}
-
-static int axp_clrsetbits(uint8_t reg, uint8_t clr_mask, uint8_t set_mask)
-{
-	uint8_t regval;
-	int ret;
-
-	ret = rsb_read(AXP803_RT_ADDR, reg);
-	if (ret < 0)
+	ret = rsb_assign_runtime_address(AXP803_HW_ADDR,
+					 AXP803_RT_ADDR);
+	if (ret)
 		return ret;
 
-	regval = (ret & ~clr_mask) | set_mask;
-
-	return rsb_write(AXP803_RT_ADDR, reg, regval);
-}
-
-#define axp_clrbits(reg, clr_mask) axp_clrsetbits(reg, clr_mask, 0)
-#define axp_setbits(reg, set_mask) axp_clrsetbits(reg, 0, set_mask)
-
-static bool should_enable_regulator(const void *fdt, int node)
-{
-	if (fdt_getprop(fdt, node, "phandle", NULL) != NULL)
-		return true;
-	if (fdt_getprop(fdt, node, "regulator-always-on", NULL) != NULL)
-		return true;
-	return false;
+	return axp_check_id();
 }
 
-/*
- * Retrieve the voltage from a given regulator DTB node.
- * Both the regulator-{min,max}-microvolt properties must be present and
- * have the same value. Return that value in millivolts.
- */
-static int fdt_get_regulator_millivolt(const void *fdt, int node)
+int axp_read(uint8_t reg)
 {
-	const fdt32_t *prop;
-	uint32_t min_volt;
-
-	prop = fdt_getprop(fdt, node, "regulator-min-microvolt", NULL);
-	if (prop == NULL)
-		return -EINVAL;
-	min_volt = fdt32_to_cpu(*prop);
-
-	prop = fdt_getprop(fdt, node, "regulator-max-microvolt", NULL);
-	if (prop == NULL)
-		return -EINVAL;
-
-	if (fdt32_to_cpu(*prop) != min_volt)
-		return -EINVAL;
-
-	return min_volt / 1000;
+	return rsb_read(AXP803_RT_ADDR, reg);
 }
 
-#define NO_SPLIT 0xff
-
-static const struct axp_regulator {
-	char *dt_name;
-	uint16_t min_volt;
-	uint16_t max_volt;
-	uint16_t step;
-	unsigned char split;
-	unsigned char volt_reg;
-	unsigned char switch_reg;
-	unsigned char switch_bit;
-} regulators[] = {
-	{"dcdc1", 1600, 3400, 100, NO_SPLIT, 0x20, 0x10, 0},
-	{"dcdc5",  800, 1840,  10,       32, 0x24, 0x10, 4},
-	{"dcdc6",  600, 1520,  10,       50, 0x25, 0x10, 5},
-	{"dldo1",  700, 3300, 100, NO_SPLIT, 0x15, 0x12, 3},
-	{"dldo2",  700, 4200, 100,       27, 0x16, 0x12, 4},
-	{"dldo3",  700, 3300, 100, NO_SPLIT, 0x17, 0x12, 5},
-	{"fldo1",  700, 1450,  50, NO_SPLIT, 0x1c, 0x13, 2},
-	{}
-};
-
-static int setup_regulator(const void *fdt, int node,
-			   const struct axp_regulator *reg)
+int axp_write(uint8_t reg, uint8_t val)
 {
-	int mvolt;
-	uint8_t regval;
-
-	if (!should_enable_regulator(fdt, node))
-		return -ENOENT;
-
-	mvolt = fdt_get_regulator_millivolt(fdt, node);
-	if (mvolt < reg->min_volt || mvolt > reg->max_volt)
-		return -EINVAL;
-
-	regval = (mvolt / reg->step) - (reg->min_volt / reg->step);
-	if (regval > reg->split)
-		regval = ((regval - reg->split) / 2) + reg->split;
-
-	axp_write(reg->volt_reg, regval);
-	if (reg->switch_reg < 0xff)
-		axp_setbits(reg->switch_reg, BIT(reg->switch_bit));
-
-	INFO("PMIC: AXP803: %s voltage: %d.%03dV\n", reg->dt_name,
-	     mvolt / 1000, mvolt % 1000);
-
-	return 0;
-}
-
-static void setup_axp803_rails(const void *fdt)
-{
-	int node;
-	bool dc1sw = false;
-
-	/* locate the PMIC DT node, bail out if not found */
-	node = fdt_node_offset_by_compatible(fdt, -1, "x-powers,axp803");
-	if (node < 0) {
-		WARN("BL31: PMIC: Cannot find AXP803 DT node, skipping initial setup.\n");
-		return;
-	}
-
-	if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL)) {
-		axp_clrbits(0x8f, BIT(4));
-		axp_setbits(0x30, BIT(2));
-		INFO("PMIC: AXP803: Enabling DRIVEVBUS\n");
-	}
-
-	/* descend into the "regulators" subnode */
-	node = fdt_subnode_offset(fdt, node, "regulators");
-	if (node < 0) {
-		WARN("BL31: PMIC: Cannot find regulators subnode, skipping initial setup.\n");
-		return;
-	}
-
-	/* iterate over all regulators to find used ones */
-	for (node = fdt_first_subnode(fdt, node);
-	     node >= 0;
-	     node = fdt_next_subnode(fdt, node)) {
-		const struct axp_regulator *reg;
-		const char *name;
-		int length;
-
-		/* We only care if it's always on or referenced. */
-		if (!should_enable_regulator(fdt, node))
-			continue;
-
-		name = fdt_get_name(fdt, node, &length);
-		for (reg = regulators; reg->dt_name; reg++) {
-			if (!strncmp(name, reg->dt_name, length)) {
-				setup_regulator(fdt, node, reg);
-				break;
-			}
-		}
-
-		if (!strncmp(name, "dc1sw", length)) {
-			/* Delay DC1SW enablement to avoid overheating. */
-			dc1sw = true;
-			continue;
-		}
-	}
-	/*
-	 * If DLDO2 is enabled after DC1SW, the PMIC overheats and shuts
-	 * down. So always enable DC1SW as the very last regulator.
-	 */
-	if (dc1sw) {
-		INFO("PMIC: AXP803: Enabling DC1SW\n");
-		axp_setbits(0x12, BIT(7));
-	}
+	return rsb_write(AXP803_RT_ADDR, reg, val);
 }
 
 int sunxi_pmic_setup(uint16_t socid, const void *fdt)
@@ -289,11 +135,16 @@
 
 	switch (socid) {
 	case SUNXI_SOC_H5:
+		NOTICE("PMIC: Assuming H5 reference regulator design\n");
+
 		pmic = REF_DESIGN_H5;
-		NOTICE("BL31: PMIC: Defaulting to PortL GPIO according to H5 reference design.\n");
+
 		break;
 	case SUNXI_SOC_A64:
 		pmic = GENERIC_A64;
+
+		INFO("PMIC: Probing AXP803 on RSB\n");
+
 		ret = sunxi_init_platform_r_twi(socid, true);
 		if (ret)
 			return ret;
@@ -303,20 +154,16 @@
 			return ret;
 
 		pmic = AXP803_RSB;
-		NOTICE("BL31: PMIC: Detected AXP803 on RSB.\n");
-
-		if (fdt)
-			setup_axp803_rails(fdt);
+		axp_setup_regulators(fdt);
 
 		break;
 	default:
-		NOTICE("BL31: PMIC: No support for Allwinner %x SoC.\n", socid);
 		return -ENODEV;
 	}
 	return 0;
 }
 
-void __dead2 sunxi_power_down(void)
+void sunxi_power_down(void)
 {
 	switch (pmic) {
 	case GENERIC_H5:
@@ -354,16 +201,10 @@
 		/* (Re-)init RSB in case the rich OS has disabled it. */
 		sunxi_init_platform_r_twi(SUNXI_SOC_A64, true);
 		rsb_init();
-
-		/* Set "power disable control" bit */
-		axp_setbits(0x32, BIT(7));
+		axp_power_off();
 		break;
 	default:
 		break;
 	}
 
-	udelay(1000);
-	ERROR("PSCI: Cannot turn off system, halting.\n");
-	wfi();
-	panic();
 }
diff --git a/plat/allwinner/sun50i_h6/platform.mk b/plat/allwinner/sun50i_h6/platform.mk
index 5c21ead..4ecc57c 100644
--- a/plat/allwinner/sun50i_h6/platform.mk
+++ b/plat/allwinner/sun50i_h6/platform.mk
@@ -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
 #
@@ -7,4 +7,5 @@
 # The differences between the platform are covered by the include files.
 include plat/allwinner/common/allwinner-common.mk
 
-PLAT_BL_COMMON_SOURCES	+=	drivers/mentor/i2c/mi2cv.c
+BL31_SOURCES		+=	drivers/allwinner/axp/axp805.c		\
+				drivers/mentor/i2c/mi2cv.c
diff --git a/plat/allwinner/sun50i_h6/sunxi_power.c b/plat/allwinner/sun50i_h6/sunxi_power.c
index 5b5bad1..443015b 100644
--- a/plat/allwinner/sun50i_h6/sunxi_power.c
+++ b/plat/allwinner/sun50i_h6/sunxi_power.c
@@ -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.
  * Copyright (c) 2018, Icenowy Zheng <icenowy@aosc.io>
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -10,6 +10,7 @@
 
 #include <arch_helpers.h>
 #include <common/debug.h>
+#include <drivers/allwinner/axp.h>
 #include <drivers/delay_timer.h>
 #include <drivers/mentor/mi2cv.h>
 #include <lib/mmio.h>
@@ -19,53 +20,51 @@
 #include <sunxi_private.h>
 
 #define AXP805_ADDR	0x36
-#define AXP805_ID	0x03
 
-enum pmic_type {
-	NO_PMIC,
+static enum pmic_type {
+	UNKNOWN,
 	AXP805,
-};
+} pmic;
 
-enum pmic_type pmic;
-
-int axp_i2c_read(uint8_t chip, uint8_t reg, uint8_t *val)
+int axp_read(uint8_t reg)
 {
+	uint8_t val;
 	int ret;
 
-	ret = i2c_write(chip, 0, 0, &reg, 1);
-	if (ret)
+	ret = i2c_write(AXP805_ADDR, 0, 0, &reg, 1);
+	if (ret == 0)
+		ret = i2c_read(AXP805_ADDR, 0, 0, &val, 1);
+	if (ret) {
+		ERROR("PMIC: Cannot read AXP805 register %02x\n", reg);
 		return ret;
+	}
 
-	return i2c_read(chip, 0, 0, val, 1);
+	return val;
 }
 
-int axp_i2c_write(uint8_t chip, uint8_t reg, uint8_t val)
+int axp_write(uint8_t reg, uint8_t val)
 {
-	return i2c_write(chip, reg, 1, &val, 1);
+	int ret;
+
+	ret = i2c_write(AXP805_ADDR, reg, 1, &val, 1);
+	if (ret)
+		ERROR("PMIC: Cannot write AXP805 register %02x\n", reg);
+
+	return ret;
 }
 
 static int axp805_probe(void)
 {
 	int ret;
-	uint8_t val;
 
-	ret = axp_i2c_write(AXP805_ADDR, 0xff, 0x0);
-	if (ret) {
-		ERROR("PMIC: Cannot put AXP805 to master mode.\n");
-		return -EPERM;
-	}
-
-	ret = axp_i2c_read(AXP805_ADDR, AXP805_ID, &val);
+	/* Switch the AXP805 to master/single-PMIC mode. */
+	ret = axp_write(0xff, 0x0);
+	if (ret)
+		return ret;
 
-	if (!ret && ((val & 0xcf) == 0x40))
-		NOTICE("PMIC: AXP805 detected\n");
-	else if (ret) {
-		ERROR("PMIC: Cannot communicate with AXP805.\n");
-		return -EPERM;
-	} else {
-		ERROR("PMIC: Non-AXP805 chip attached at AXP805's address.\n");
-		return -EINVAL;
-	}
+	ret = axp_check_id();
+	if (ret)
+		return ret;
 
 	return 0;
 }
@@ -74,41 +73,36 @@
 {
 	int ret;
 
+	INFO("PMIC: Probing AXP805 on I2C\n");
+
-	sunxi_init_platform_r_twi(SUNXI_SOC_H6, false);
+	ret = sunxi_init_platform_r_twi(SUNXI_SOC_H6, false);
+	if (ret)
+		return ret;
+
 	/* initialise mi2cv driver */
 	i2c_init((void *)SUNXI_R_I2C_BASE);
 
-	NOTICE("PMIC: Probing AXP805\n");
-	pmic = AXP805;
-
 	ret = axp805_probe();
 	if (ret)
-		pmic = NO_PMIC;
-	else
-		pmic = AXP805;
+		return ret;
+
+	pmic = AXP805;
+	axp_setup_regulators(fdt);
 
 	return 0;
 }
 
-void __dead2 sunxi_power_down(void)
+void sunxi_power_down(void)
 {
-	uint8_t val;
-
 	switch (pmic) {
 	case AXP805:
 		/* Re-initialise after rich OS might have used it. */
 		sunxi_init_platform_r_twi(SUNXI_SOC_H6, false);
 		/* initialise mi2cv driver */
 		i2c_init((void *)SUNXI_R_I2C_BASE);
-		axp_i2c_read(AXP805_ADDR, 0x32, &val);
-		axp_i2c_write(AXP805_ADDR, 0x32, val | 0x80);
+		axp_power_off();
 		break;
 	default:
 		break;
 	}
-
-	udelay(1000);
-	ERROR("PSCI: Cannot communicate with PMIC, halting\n");
-	wfi();
-	panic();
 }
diff --git a/plat/arm/board/a5ds/a5ds_common.c b/plat/arm/board/a5ds/a5ds_common.c
index e462fa1..a4a0cff 100644
--- a/plat/arm/board/a5ds/a5ds_common.c
+++ b/plat/arm/board/a5ds/a5ds_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,18 +23,18 @@
 #ifdef IMAGE_BL1
 const mmap_region_t plat_arm_mmap[] = {
 	ARM_MAP_SHARED_RAM,
-	MAP_FLASH1_RW,
 	MAP_PERIPHBASE,
 	MAP_A5_PERIPHERALS,
+	MAP_BOOT_RW,
 	{0}
 };
 #endif
 #ifdef IMAGE_BL2
 const mmap_region_t plat_arm_mmap[] = {
 	ARM_MAP_SHARED_RAM,
-	MAP_FLASH1_RW,
 	MAP_PERIPHBASE,
 	MAP_A5_PERIPHERALS,
+	MAP_BOOT_RW,
 	ARM_MAP_NS_DRAM1,
 	{0}
 };
diff --git a/plat/arm/board/a5ds/a5ds_pm.c b/plat/arm/board/a5ds/a5ds_pm.c
index cc734b0..7774002 100644
--- a/plat/arm/board/a5ds/a5ds_pm.c
+++ b/plat/arm/board/a5ds/a5ds_pm.c
@@ -4,11 +4,10 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 #include <assert.h>
-
+#include <drivers/arm/gicv2.h>
 #include <lib/psci/psci.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
-#include <drivers/arm/gicv2.h>
 
 /*******************************************************************************
  * Platform handler called when a power domain is about to be turned on. The
diff --git a/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts b/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts
index 9ab2d96..7b3aa11 100644
--- a/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts
+++ b/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,7 +10,7 @@
 	/* Platform Config */
 	plat_arm_bl2 {
 		compatible = "arm,tb_fw";
-		hw_config_addr = <0x0 0x82000000>;
+		hw_config_addr = <0x0 0x83000000>;
 		hw_config_max_size = <0x01000000>;
 		/* Disable authentication for development */
 		disable_auth = <0x0>;
diff --git a/plat/arm/board/a5ds/include/platform_def.h b/plat/arm/board/a5ds/include/platform_def.h
index e9e4b9a..31dfb1c 100644
--- a/plat/arm/board/a5ds/include/platform_def.h
+++ b/plat/arm/board/a5ds/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,14 +21,6 @@
 #define ARM_DRAM1_END			(ARM_DRAM1_BASE +		\
 					 ARM_DRAM1_SIZE - 1)
 
-#define ARM_NS_DRAM1_BASE		ARM_DRAM1_BASE
-/*
- * The last 2MB is meant to be NOLOAD and will not be zero
- * initialized.
- */
-#define ARM_NS_DRAM1_SIZE		(ARM_DRAM1_SIZE -		\
-					 0x00200000)
-
 #define SRAM_BASE	0x2000000
 #define SRAM_SIZE	0x200000
 
@@ -47,7 +39,7 @@
 #define A5_PERIPHERALS_BASE 0x1c000000
 #define A5_PERIPHERALS_SIZE  0x10000
 
-#define ARM_CACHE_WRITEBACK_SHIFT	6
+#define ARM_CACHE_WRITEBACK_SHIFT	5
 
 #define ARM_IRQ_SEC_PHY_TIMER		29
 
@@ -89,28 +81,34 @@
 #define A5DS_IRQ_SEC_SYS_TIMER		57
 
 /* Default cluster count for A5DS */
-#define A5DS_CLUSTER_COUNT	1
+#define A5DS_CLUSTER_COUNT	U(1)
 
 /* Default number of CPUs per cluster on A5DS */
-#define A5DS_MAX_CPUS_PER_CLUSTER	4
+#define A5DS_MAX_CPUS_PER_CLUSTER	U(4)
 
 /* Default number of threads per CPU on A5DS */
-#define A5DS_MAX_PE_PER_CPU	1
+#define A5DS_MAX_PE_PER_CPU	U(1)
 
-#define A5DS_CORE_COUNT		4
+#define A5DS_CORE_COUNT		U(4)
 
 #define A5DS_PRIMARY_CPU	0x0
 
-#define FLASH1_BASE			UL(0x8000000)
-#define FLASH1_SIZE			UL(0x2800000)
+#define BOOT_BASE			ARM_DRAM1_BASE
+#define BOOT_SIZE			UL(0x2800000)
 
-#define MAP_FLASH1_RW		MAP_REGION_FLAT(FLASH1_BASE,\
-						FLASH1_SIZE,	\
-						MT_DEVICE | MT_RW | MT_SECURE)
+#define ARM_NS_DRAM1_BASE		(ARM_DRAM1_BASE + BOOT_SIZE)
+/*
+ * The last 2MB is meant to be NOLOAD and will not be zero
+ * initialized.
+ */
+#define ARM_NS_DRAM1_SIZE		(ARM_DRAM1_SIZE -		\
+					 BOOT_SIZE -			\
+					 0x00200000)
 
-#define MAP_FLASH1_RO		MAP_REGION_FLAT(FLASH1_BASE,\
-						FLASH1_SIZE,	\
-						MT_RO_DATA | MT_SECURE)
+#define MAP_BOOT_RW          		MAP_REGION_FLAT(		\
+						BOOT_BASE,		\
+						BOOT_SIZE,    		\
+						MT_DEVICE | MT_RW | MT_SECURE)
 
 #define ARM_MAP_SHARED_RAM		MAP_REGION_FLAT(		\
 						A5DS_SHARED_RAM_BASE,	\
@@ -122,9 +120,9 @@
 						ARM_NS_DRAM1_SIZE,	\
 						MT_MEMORY | MT_RW | MT_NS)
 
-#define ARM_MAP_SRAM		MAP_REGION_FLAT(		\
-						SRAM_BASE,	\
-						SRAM_SIZE,	\
+#define ARM_MAP_SRAM			MAP_REGION_FLAT(		\
+						SRAM_BASE,		\
+						SRAM_SIZE,		\
 						MT_MEMORY | MT_RW | MT_NS)
 
 /*
@@ -162,7 +160,7 @@
 					 ARM_BL_REGIONS)
 
 /* Memory mapped Generic timer interfaces  */
-#define A5DS_TIMER_BASE_FREQUENCY		UL(24000000)
+#define A5DS_TIMER_BASE_FREQUENCY		UL(7500000)
 
 #define ARM_CONSOLE_BAUDRATE		115200
 
@@ -231,7 +229,7 @@
 /* Required platform porting definitions */
 #define PLATFORM_CORE_COUNT	A5DS_CORE_COUNT
 #define PLAT_NUM_PWR_DOMAINS	(A5DS_CLUSTER_COUNT + \
-					PLATFORM_CORE_COUNT) + 1
+				PLATFORM_CORE_COUNT) + U(1)
 
 #define PLAT_MAX_PWR_LVL	2
 
@@ -300,25 +298,25 @@
 #define MAX_IO_HANDLES			4
 
 /* Reserve the last block of flash for PSCI MEM PROTECT flag */
-#define PLAT_ARM_FIP_BASE		FLASH1_BASE
-#define PLAT_ARM_FIP_MAX_SIZE		(FLASH1_SIZE - V2M_FLASH_BLOCK_SIZE)
+#define PLAT_ARM_FIP_BASE		BOOT_BASE
+#define PLAT_ARM_FIP_MAX_SIZE		(BOOT_SIZE - V2M_FLASH_BLOCK_SIZE)
 
-#define PLAT_ARM_NVM_BASE		FLASH1_BASE
-#define PLAT_ARM_NVM_SIZE		(FLASH1_SIZE - V2M_FLASH_BLOCK_SIZE)
+#define PLAT_ARM_NVM_BASE		BOOT_BASE
+#define PLAT_ARM_NVM_SIZE		(BOOT_SIZE - V2M_FLASH_BLOCK_SIZE)
 
 /*
  * PL011 related constants
  */
 #define PLAT_ARM_BOOT_UART_BASE		0x1A200000
-#define PLAT_ARM_BOOT_UART_CLK_IN_HZ	24000000
+#define PLAT_ARM_BOOT_UART_CLK_IN_HZ	UL(7500000)
 
 #define PLAT_ARM_RUN_UART_BASE		0x1A210000
-#define PLAT_ARM_RUN_UART_CLK_IN_HZ	24000000
+#define PLAT_ARM_RUN_UART_CLK_IN_HZ	UL(7500000)
 
 #define PLAT_ARM_CRASH_UART_BASE	PLAT_ARM_RUN_UART_BASE
 #define PLAT_ARM_CRASH_UART_CLK_IN_HZ	PLAT_ARM_RUN_UART_CLK_IN_HZ
 
-#define A5DS_TIMER_BASE_FREQUENCY	UL(24000000)
+#define A5DS_TIMER_BASE_FREQUENCY	UL(7500000)
 
 /* System timer related constants */
 #define PLAT_ARM_NSTIMER_FRAME_ID		1
@@ -334,6 +332,9 @@
 #define A5DS_HOLD_STATE_WAIT	0
 #define A5DS_HOLD_STATE_GO	1
 
+/* Snoop Control Unit base address */
+#define A5DS_SCU_BASE			0x1C000000
+
 /*
  * GIC related constants to cater for GICv2
  */
diff --git a/plat/arm/board/a5ds/sp_min/a5ds_sp_min_setup.c b/plat/arm/board/a5ds/sp_min/a5ds_sp_min_setup.c
index 8b45af8..a951dc7 100644
--- a/plat/arm/board/a5ds/sp_min/a5ds_sp_min_setup.c
+++ b/plat/arm/board/a5ds/sp_min/a5ds_sp_min_setup.c
@@ -4,12 +4,17 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <drivers/arm/scu.h>
 #include <plat/arm/common/plat_arm.h>
 
+
 void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1,
 			u_register_t arg2, u_register_t arg3)
 {
 	arm_sp_min_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
+
+	/* enable snoop control unit */
+	enable_snoop_ctrl_unit(A5DS_SCU_BASE);
 }
 
 /*
diff --git a/plat/arm/board/a5ds/sp_min/sp_min-a5ds.mk b/plat/arm/board/a5ds/sp_min/sp_min-a5ds.mk
index da1d785..4b0c97d 100644
--- a/plat/arm/board/a5ds/sp_min/sp_min-a5ds.mk
+++ b/plat/arm/board/a5ds/sp_min/sp_min-a5ds.mk
@@ -5,7 +5,8 @@
 #
 
 # SP_MIN source files specific to A5DS platform
-BL32_SOURCES	+=	drivers/cfi/v2m/v2m_flash.c			\
+BL32_SOURCES	+=	drivers/arm/scu/scu.c                           \
+			drivers/cfi/v2m/v2m_flash.c			\
 			lib/utils/mem_region.c				\
 			lib/aarch32/arm32_aeabi_divmod.c		\
 			lib/aarch32/arm32_aeabi_divmod_a32.S		\
diff --git a/plat/arm/board/corstone700/include/platform_def.h b/plat/arm/board/corstone700/include/platform_def.h
index de99b06..8dff3ec 100644
--- a/plat/arm/board/corstone700/include/platform_def.h
+++ b/plat/arm/board/corstone700/include/platform_def.h
@@ -14,9 +14,9 @@
 #include <plat/common/common_def.h>
 
 /* Core/Cluster/Thread counts for Corstone700 */
-#define CORSTONE700_CLUSTER_COUNT		1
-#define CORSTONE700_MAX_CPUS_PER_CLUSTER	4
-#define CORSTONE700_MAX_PE_PER_CPU		1
+#define CORSTONE700_CLUSTER_COUNT		U(1)
+#define CORSTONE700_MAX_CPUS_PER_CLUSTER	U(4)
+#define CORSTONE700_MAX_PE_PER_CPU		U(1)
 #define CORSTONE700_CORE_COUNT		(CORSTONE700_CLUSTER_COUNT *	\
 					CORSTONE700_MAX_CPUS_PER_CLUSTER * \
 					CORSTONE700_MAX_PE_PER_CPU)
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index a948796..ffaa93d 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -18,7 +18,7 @@
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 #include <platform_def.h>
-#include <services/secure_partition.h>
+#include <services/spm_mm_partition.h>
 
 #include "fvp_private.h"
 
@@ -96,12 +96,9 @@
 	ARM_MAP_BL1_RW,
 #endif
 #endif /* TRUSTED_BOARD_BOOT */
-#if ENABLE_SPM && SPM_MM
+#if SPM_MM
 	ARM_SP_IMAGE_MMAP,
 #endif
-#if ENABLE_SPM && !SPM_MM
-	PLAT_MAP_SP_PACKAGE_MEM_RW,
-#endif
 #if ARM_BL31_IN_DRAM
 	ARM_MAP_BL31_SEC_DRAM,
 #endif
@@ -122,21 +119,22 @@
 #ifdef IMAGE_BL31
 const mmap_region_t plat_arm_mmap[] = {
 	ARM_MAP_SHARED_RAM,
+#if USE_DEBUGFS
+	/* Required by devfip, can be removed if devfip is not used */
+	V2M_MAP_FLASH0_RW,
+#endif /* USE_DEBUGFS */
 	ARM_MAP_EL3_TZC_DRAM,
 	V2M_MAP_IOFPGA,
 	MAP_DEVICE0,
 	MAP_DEVICE1,
 	ARM_V2M_MAP_MEM_PROTECT,
-#if ENABLE_SPM && SPM_MM
+#if SPM_MM
 	ARM_SPM_BUF_EL3_MMAP,
 #endif
-#if ENABLE_SPM && !SPM_MM
-	PLAT_MAP_SP_PACKAGE_MEM_RO,
-#endif
 	{0}
 };
 
-#if ENABLE_SPM && defined(IMAGE_BL31) && SPM_MM
+#if defined(IMAGE_BL31) && SPM_MM
 const mmap_region_t plat_arm_secure_partition_mmap[] = {
 	V2M_MAP_IOFPGA_EL0, /* for the UART */
 	MAP_REGION_FLAT(DEVICE0_BASE,				\
@@ -190,12 +188,12 @@
 }
 #endif
 
-#if ENABLE_SPM && defined(IMAGE_BL31) && SPM_MM
+#if defined(IMAGE_BL31) && SPM_MM
 /*
  * Boot information passed to a secure partition during initialisation. Linear
  * indices in MP information will be filled at runtime.
  */
-static secure_partition_mp_info_t sp_mp_info[] = {
+static spm_mm_mp_info_t sp_mp_info[] = {
 	[0] = {0x80000000, 0},
 	[1] = {0x80000001, 0},
 	[2] = {0x80000002, 0},
@@ -206,10 +204,10 @@
 	[7] = {0x80000103, 0},
 };
 
-const secure_partition_boot_info_t plat_arm_secure_partition_boot_info = {
+const spm_mm_boot_info_t plat_arm_secure_partition_boot_info = {
 	.h.type              = PARAM_SP_IMAGE_BOOT_INFO,
 	.h.version           = VERSION_1,
-	.h.size              = sizeof(secure_partition_boot_info_t),
+	.h.size              = sizeof(spm_mm_boot_info_t),
 	.h.attr              = 0,
 	.sp_mem_base         = ARM_SP_IMAGE_BASE,
 	.sp_mem_limit        = ARM_SP_IMAGE_LIMIT,
@@ -233,7 +231,7 @@
 	return plat_arm_secure_partition_mmap;
 }
 
-const struct secure_partition_boot_info *plat_get_secure_partition_boot_info(
+const struct spm_mm_boot_info *plat_get_secure_partition_boot_info(
 		void *cookie)
 {
 	return &plat_arm_secure_partition_boot_info;
diff --git a/plat/arm/board/fvp/fvp_def.h b/plat/arm/board/fvp/fvp_def.h
index 1b9f84b..347ba2e 100644
--- a/plat/arm/board/fvp/fvp_def.h
+++ b/plat/arm/board/fvp/fvp_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,15 +10,15 @@
 #include <lib/utils_def.h>
 
 #ifndef FVP_CLUSTER_COUNT
-#define FVP_CLUSTER_COUNT		2
+#error "FVP_CLUSTER_COUNT is not set in makefile"
 #endif
 
 #ifndef FVP_MAX_CPUS_PER_CLUSTER
-#define FVP_MAX_CPUS_PER_CLUSTER	4
+#error "FVP_MAX_CPUS_PER_CLUSTER is not set in makefile"
 #endif
 
 #ifndef FVP_MAX_PE_PER_CPU
-# define FVP_MAX_PE_PER_CPU		1
+#error "FVP_MAX_PE_PER_CPU is not set in makefile"
 #endif
 
 #define FVP_PRIMARY_CPU			0x0
diff --git a/plat/arm/board/fvp/fvp_topology.c b/plat/arm/board/fvp/fvp_topology.c
index 9823fb3..24e79b4 100644
--- a/plat/arm/board/fvp/fvp_topology.c
+++ b/plat/arm/board/fvp/fvp_topology.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -36,7 +36,8 @@
 	fvp_power_domain_tree_desc[1] = FVP_CLUSTER_COUNT;
 
 	for (i = 0; i < FVP_CLUSTER_COUNT; i++)
-		fvp_power_domain_tree_desc[i + 2] = FVP_MAX_CPUS_PER_CLUSTER;
+		fvp_power_domain_tree_desc[i + 2] =
+			FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU;
 
 
 	return fvp_power_domain_tree_desc;
diff --git a/plat/arm/board/fvp/include/plat.ld.S b/plat/arm/board/fvp/include/plat.ld.S
index f024f55..7c8bf06 100644
--- a/plat/arm/board/fvp/include/plat.ld.S
+++ b/plat/arm/board/fvp/include/plat.ld.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,9 @@
 #define PLAT_LD_S
 
 #include <plat/arm/common/arm_tzc_dram.ld.S>
+
+#if RECLAIM_INIT_CODE
 #include <plat/arm/common/arm_reclaim_init.ld.S>
+#endif /* RECLAIM_INIT_CODE */
 
 #endif /* PLAT_LD_S */
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 4f26277..c2b7b98 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -17,11 +17,12 @@
 #include "../fvp_def.h"
 
 /* Required platform porting definitions */
-#define PLATFORM_CORE_COUNT \
-	(FVP_CLUSTER_COUNT * FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU)
+#define PLATFORM_CORE_COUNT  (U(FVP_CLUSTER_COUNT) * \
+			      U(FVP_MAX_CPUS_PER_CLUSTER) * \
+			      U(FVP_MAX_PE_PER_CPU))
 
-#define PLAT_NUM_PWR_DOMAINS		(FVP_CLUSTER_COUNT + \
-					PLATFORM_CORE_COUNT) + 1
+#define PLAT_NUM_PWR_DOMAINS (U(FVP_CLUSTER_COUNT) + \
+			      PLATFORM_CORE_COUNT + U(1))
 
 #define PLAT_MAX_PWR_LVL		ARM_PWR_LVL2
 
@@ -32,7 +33,7 @@
 /*
  * Required ARM standard platform porting definitions
  */
-#define PLAT_ARM_CLUSTER_COUNT		FVP_CLUSTER_COUNT
+#define PLAT_ARM_CLUSTER_COUNT		U(FVP_CLUSTER_COUNT)
 
 #define PLAT_ARM_TRUSTED_SRAM_SIZE	UL(0x00040000)	/* 256 KB */
 
@@ -61,14 +62,18 @@
  * plat_arm_mmap array defined for each BL stage.
  */
 #if defined(IMAGE_BL31)
-# if ENABLE_SPM
+# if SPM_MM
 #  define PLAT_ARM_MMAP_ENTRIES		9
 #  define MAX_XLAT_TABLES		9
 #  define PLAT_SP_IMAGE_MMAP_REGIONS	30
 #  define PLAT_SP_IMAGE_MAX_XLAT_TABLES	10
 # else
 #  define PLAT_ARM_MMAP_ENTRIES		8
-#  define MAX_XLAT_TABLES		5
+#  if USE_DEBUGFS
+#   define MAX_XLAT_TABLES		6
+#  else
+#   define MAX_XLAT_TABLES		5
+#  endif
 # endif
 #elif defined(IMAGE_BL32)
 # define PLAT_ARM_MMAP_ENTRIES		8
@@ -94,9 +99,11 @@
 #if USE_ROMLIB
 #define PLAT_ARM_MAX_ROMLIB_RW_SIZE	UL(0x1000)
 #define PLAT_ARM_MAX_ROMLIB_RO_SIZE	UL(0xe000)
+#define FVP_BL2_ROMLIB_OPTIMIZATION UL(0x6000)
 #else
 #define PLAT_ARM_MAX_ROMLIB_RW_SIZE	UL(0)
 #define PLAT_ARM_MAX_ROMLIB_RO_SIZE	UL(0)
+#define FVP_BL2_ROMLIB_OPTIMIZATION UL(0)
 #endif
 
 /*
@@ -104,9 +111,9 @@
  * little space for growth.
  */
 #if TRUSTED_BOARD_BOOT
-# define PLAT_ARM_MAX_BL2_SIZE		UL(0x1D000)
+# define PLAT_ARM_MAX_BL2_SIZE	(UL(0x1D000) - FVP_BL2_ROMLIB_OPTIMIZATION)
 #else
-# define PLAT_ARM_MAX_BL2_SIZE		UL(0x11000)
+# define PLAT_ARM_MAX_BL2_SIZE	(UL(0x11000) - FVP_BL2_ROMLIB_OPTIMIZATION)
 #endif
 
 /*
@@ -114,11 +121,7 @@
  * calculated using the current BL31 PROGBITS debug size plus the sizes of
  * BL2 and BL1-RW
  */
-#if ENABLE_SPM && !SPM_MM
-#define PLAT_ARM_MAX_BL31_SIZE		UL(0x60000)
-#else
 #define PLAT_ARM_MAX_BL31_SIZE		UL(0x3B000)
-#endif
 
 #ifndef __aarch64__
 /*
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 317f0ba..97a326c 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -244,15 +244,12 @@
 # Enable dynamic mitigation support by default
 DYNAMIC_WORKAROUND_CVE_2018_3639	:=	1
 
+# Enable reclaiming of BL31 initialisation code for secondary cores
+# stacks for FVP. However, don't enable reclaiming for clang.
 ifneq (${RESET_TO_BL31},1)
-# Enable reclaiming of BL31 initialisation code for secondary cores stacks for
-# FVP. We cannot enable PIE for this case because the overlayed init section
-# creates some dynamic relocations which cannot be handled by the fixup
-# logic currently.
+ifeq ($(findstring clang,$(notdir $(CC))),)
 RECLAIM_INIT_CODE	:=	1
-else
-# Enable PIE support when RESET_TO_BL31=1
-ENABLE_PIE		:=	1
+endif
 endif
 
 ifeq (${ENABLE_AMU},1)
@@ -286,16 +283,15 @@
     ifeq (${RESET_TO_BL31},1)
         BL31_CFLAGS	+=	-DPLAT_XLAT_TABLES_DYNAMIC=1
     endif
-    ifeq (${ENABLE_SPM},1)
-        ifeq (${SPM_MM},0)
-            BL31_CFLAGS	+=	-DPLAT_XLAT_TABLES_DYNAMIC=1
-        endif
-    endif
     ifeq (${SPD},trusty)
         BL31_CFLAGS	+=	-DPLAT_XLAT_TABLES_DYNAMIC=1
     endif
 endif
 
+ifeq (${USE_DEBUGFS},1)
+    BL31_CFLAGS	+=	-DPLAT_XLAT_TABLES_DYNAMIC=1
+endif
+
 # Add support for platform supplied linker script for BL31 build
 $(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
 
diff --git a/plat/arm/board/fvp_ve/fvp_ve_def.h b/plat/arm/board/fvp_ve/fvp_ve_def.h
index 565753a..98de5f6 100644
--- a/plat/arm/board/fvp_ve/fvp_ve_def.h
+++ b/plat/arm/board/fvp_ve/fvp_ve_def.h
@@ -10,17 +10,17 @@
 #include <lib/utils_def.h>
 
 /* Default cluster count for FVP VE */
-#define FVP_VE_CLUSTER_COUNT	1
+#define FVP_VE_CLUSTER_COUNT		U(1)
 
 /* Default number of CPUs per cluster on FVP VE */
-#define FVP_VE_MAX_CPUS_PER_CLUSTER	1
+#define FVP_VE_MAX_CPUS_PER_CLUSTER	U(1)
 
 /* Default number of threads per CPU on FVP VE */
-#define FVP_VE_MAX_PE_PER_CPU	1
+#define FVP_VE_MAX_PE_PER_CPU		U(1)
 
-#define FVP_VE_CORE_COUNT 1
+#define FVP_VE_CORE_COUNT		U(1)
 
-#define FVP_VE_PRIMARY_CPU			0x0
+#define FVP_VE_PRIMARY_CPU		0x0
 
 /*******************************************************************************
  * FVP memory map related constants
diff --git a/plat/arm/board/fvp_ve/include/platform_def.h b/plat/arm/board/fvp_ve/include/platform_def.h
index 4e575e1..1b07a9b 100644
--- a/plat/arm/board/fvp_ve/include/platform_def.h
+++ b/plat/arm/board/fvp_ve/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -211,9 +211,9 @@
 #define BL32_LIMIT			(ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)
 
 /* Required platform porting definitions */
-#define PLATFORM_CORE_COUNT		1
+#define PLATFORM_CORE_COUNT		FVP_VE_CLUSTER_COUNT
 #define PLAT_NUM_PWR_DOMAINS		((FVP_VE_CLUSTER_COUNT + \
-					PLATFORM_CORE_COUNT) + 1)
+					PLATFORM_CORE_COUNT) + U(1))
 
 #define PLAT_MAX_PWR_LVL		2
 
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index 83aeeb4..16bb33d 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -60,9 +60,11 @@
 #if USE_ROMLIB
 #define PLAT_ARM_MAX_ROMLIB_RW_SIZE	UL(0x1000)
 #define PLAT_ARM_MAX_ROMLIB_RO_SIZE	UL(0xe000)
+#define JUNO_BL2_ROMLIB_OPTIMIZATION UL(0x8000)
 #else
 #define PLAT_ARM_MAX_ROMLIB_RW_SIZE	UL(0)
 #define PLAT_ARM_MAX_ROMLIB_RO_SIZE	UL(0)
+#define JUNO_BL2_ROMLIB_OPTIMIZATION UL(0)
 #endif
 
 /*
@@ -127,14 +129,14 @@
  */
 #if TRUSTED_BOARD_BOOT
 #if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA
-# define PLAT_ARM_MAX_BL2_SIZE		UL(0x1F000)
+# define PLAT_ARM_MAX_BL2_SIZE	(UL(0x1F000) - JUNO_BL2_ROMLIB_OPTIMIZATION)
 #elif TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA
-# define PLAT_ARM_MAX_BL2_SIZE		UL(0x1D000)
+# define PLAT_ARM_MAX_BL2_SIZE	(UL(0x1D000) - JUNO_BL2_ROMLIB_OPTIMIZATION)
 #else
-# define PLAT_ARM_MAX_BL2_SIZE		UL(0x1D000)
+# define PLAT_ARM_MAX_BL2_SIZE	(UL(0x1D000) - JUNO_BL2_ROMLIB_OPTIMIZATION)
 #endif
 #else
-# define PLAT_ARM_MAX_BL2_SIZE		UL(0xF000)
+# define PLAT_ARM_MAX_BL2_SIZE	(UL(0xF000) - JUNO_BL2_ROMLIB_OPTIMIZATION)
 #endif
 
 /*
diff --git a/plat/arm/board/juno/juno_def.h b/plat/arm/board/juno/juno_def.h
index 7a8bedf..3b34a9f 100644
--- a/plat/arm/board/juno/juno_def.h
+++ b/plat/arm/board/juno/juno_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -32,9 +32,9 @@
 /*******************************************************************************
  * Juno topology related constants
  ******************************************************************************/
-#define JUNO_CLUSTER_COUNT		2
-#define JUNO_CLUSTER0_CORE_COUNT	2
-#define JUNO_CLUSTER1_CORE_COUNT	4
+#define JUNO_CLUSTER_COUNT		U(2)
+#define JUNO_CLUSTER0_CORE_COUNT	U(2)
+#define JUNO_CLUSTER1_CORE_COUNT	U(4)
 
 /*******************************************************************************
  * TZC-400 related constants
diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
index 79a0a79..b150b89 100644
--- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
+++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
@@ -6,10 +6,11 @@
 
 #include <platform_def.h>
 
+#include <common/debug.h>
 #include <drivers/arm/css/css_mhu_doorbell.h>
 #include <drivers/arm/css/scmi.h>
 #include <drivers/arm/css/sds.h>
-#include <common/debug.h>
+#include <drivers/arm/gic600_multichip.h>
 #include <lib/mmio.h>
 #include <lib/utils.h>
 #include <plat/arm/common/plat_arm.h>
@@ -53,6 +54,26 @@
 	.ring_doorbell = &mhu_ring_doorbell
 };
 
+static struct gic600_multichip_data n1sdp_multichip_data __init = {
+	.rt_owner_base = PLAT_ARM_GICD_BASE,
+	.rt_owner = 0,
+	.chip_count = 1,
+	.chip_addrs = {
+		PLAT_ARM_GICD_BASE >> 16,
+		PLAT_ARM_GICD_BASE >> 16
+	},
+	.spi_ids = {
+		{32, 255},
+		{0, 0}
+	}
+};
+
+static uintptr_t n1sdp_multichip_gicr_frames[3] = {
+	PLAT_ARM_GICR_BASE,
+	PLAT_ARM_GICR_BASE + PLAT_ARM_REMOTE_CHIP_OFFSET,
+	0
+};
+
 scmi_channel_plat_info_t *plat_css_get_scmi_info()
 {
 	return &n1sdp_scmi_plat_info;
@@ -149,14 +170,18 @@
 	}
 }
 
+void n1sdp_bl31_multichip_setup(void)
+{
+	plat_arm_override_gicr_frames(n1sdp_multichip_gicr_frames);
+	gic600_multichip_init(&n1sdp_multichip_data);
+}
+
 void bl31_platform_setup(void)
 {
 	int ret;
 	struct n1sdp_plat_info plat_info;
 	struct n1sdp_bl33_info bl33_info;
 
-	arm_bl31_platform_setup();
-
 	ret = sds_init();
 	if (ret != SDS_OK) {
 		ERROR("SDS initialization failed\n");
@@ -181,6 +206,12 @@
 		panic();
 	}
 
+	if (plat_info.multichip_mode) {
+		n1sdp_multichip_data.chip_count = plat_info.slave_count + 1;
+		n1sdp_bl31_multichip_setup();
+	}
+	arm_bl31_platform_setup();
+
 	dmc_ecc_setup(plat_info.local_ddr_size);
 
 	/* Check if remote memory is present */
diff --git a/plat/arm/board/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk
index 986bd70..8816670 100644
--- a/plat/arm/board/n1sdp/platform.mk
+++ b/plat/arm/board/n1sdp/platform.mk
@@ -18,6 +18,7 @@
 N1SDP_GIC_SOURCES	:=	drivers/arm/gic/common/gic_common.c	\
 				drivers/arm/gic/v3/gicv3_main.c		\
 				drivers/arm/gic/v3/gicv3_helpers.c	\
+				drivers/arm/gic/v3/gic600_multichip.c	\
 				plat/common/plat_gicv3.c		\
 				plat/arm/common/arm_gicv3.c		\
 				drivers/arm/gic/v3/gic600.c
diff --git a/plat/arm/board/rde1edge/include/platform_def.h b/plat/arm/board/rde1edge/include/platform_def.h
index 50b04f0..2be3f88 100644
--- a/plat/arm/board/rde1edge/include/platform_def.h
+++ b/plat/arm/board/rde1edge/include/platform_def.h
@@ -11,9 +11,9 @@
 
 #include <sgi_base_platform_def.h>
 
-#define PLAT_ARM_CLUSTER_COUNT		2
-#define CSS_SGI_MAX_CPUS_PER_CLUSTER	8
-#define CSS_SGI_MAX_PE_PER_CPU		2
+#define PLAT_ARM_CLUSTER_COUNT		U(2)
+#define CSS_SGI_MAX_CPUS_PER_CLUSTER	U(8)
+#define CSS_SGI_MAX_PE_PER_CPU		U(2)
 
 #define PLAT_CSS_MHU_BASE		UL(0x45400000)
 #define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
diff --git a/plat/arm/board/rdn1edge/include/platform_def.h b/plat/arm/board/rdn1edge/include/platform_def.h
index 580ab8e..c635faa 100644
--- a/plat/arm/board/rdn1edge/include/platform_def.h
+++ b/plat/arm/board/rdn1edge/include/platform_def.h
@@ -11,9 +11,9 @@
 
 #include <sgi_base_platform_def.h>
 
-#define PLAT_ARM_CLUSTER_COUNT		2
-#define CSS_SGI_MAX_CPUS_PER_CLUSTER	4
-#define CSS_SGI_MAX_PE_PER_CPU		1
+#define PLAT_ARM_CLUSTER_COUNT		U(2)
+#define CSS_SGI_MAX_CPUS_PER_CLUSTER	U(4)
+#define CSS_SGI_MAX_PE_PER_CPU		U(1)
 
 #define PLAT_CSS_MHU_BASE		UL(0x45400000)
 #define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
diff --git a/plat/arm/board/sgi575/include/platform_def.h b/plat/arm/board/sgi575/include/platform_def.h
index f00146f..fd59e52 100644
--- a/plat/arm/board/sgi575/include/platform_def.h
+++ b/plat/arm/board/sgi575/include/platform_def.h
@@ -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,9 +11,9 @@
 
 #include <sgi_base_platform_def.h>
 
-#define PLAT_ARM_CLUSTER_COUNT		2
-#define CSS_SGI_MAX_CPUS_PER_CLUSTER	4
-#define CSS_SGI_MAX_PE_PER_CPU		1
+#define PLAT_ARM_CLUSTER_COUNT		U(2)
+#define CSS_SGI_MAX_CPUS_PER_CLUSTER	U(4)
+#define CSS_SGI_MAX_PE_PER_CPU		U(1)
 
 #define PLAT_CSS_MHU_BASE		UL(0x45000000)
 #define PLAT_MHUV2_BASE			PLAT_CSS_MHU_BASE
diff --git a/plat/arm/board/sgm775/include/platform_def.h b/plat/arm/board/sgm775/include/platform_def.h
index 27d1b33..d165ff9 100644
--- a/plat/arm/board/sgm775/include/platform_def.h
+++ b/plat/arm/board/sgm775/include/platform_def.h
@@ -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
  */
@@ -9,8 +9,8 @@
 
 #include <sgm_base_platform_def.h>
 
-#define PLAT_MAX_CPUS_PER_CLUSTER	8
-#define PLAT_MAX_PE_PER_CPU		1
+#define PLAT_MAX_CPUS_PER_CLUSTER	U(8)
+#define PLAT_MAX_PE_PER_CPU		U(1)
 
 /*
  * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
diff --git a/plat/arm/common/aarch64/arm_ehf.c b/plat/arm/common/aarch64/arm_ehf.c
index 4ae992c..69ebd79 100644
--- a/plat/arm/common/aarch64/arm_ehf.c
+++ b/plat/arm/common/aarch64/arm_ehf.c
@@ -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
  */
@@ -24,7 +24,7 @@
 	/* Normal priority SDEI */
 	EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SDEI_NORMAL_PRI),
 #endif
-#if ENABLE_SPM
+#if SPM_MM
 	EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SP_PRI),
 #endif
 };
diff --git a/plat/arm/common/execution_state_switch.c b/plat/arm/common/aarch64/execution_state_switch.c
similarity index 96%
rename from plat/arm/common/execution_state_switch.c
rename to plat/arm/common/aarch64/execution_state_switch.c
index 00ac16e..8835fa1 100644
--- a/plat/arm/common/execution_state_switch.c
+++ b/plat/arm/common/aarch64/execution_state_switch.c
@@ -39,8 +39,6 @@
 		uint32_t cookie_lo,
 		void *handle)
 {
-	/* Execution state can be switched only if EL3 is AArch64 */
-#ifdef __aarch64__
 	bool caller_64, thumb = false, from_el2;
 	unsigned int el, endianness;
 	u_register_t spsr, pc, scr, sctlr;
@@ -48,6 +46,11 @@
 	cpu_context_t *ctx = (cpu_context_t *) handle;
 	el3_state_t *el3_ctx = get_el3state_ctx(ctx);
 
+	/* Validate supplied entry point */
+	pc = (u_register_t) (((uint64_t) pc_hi << 32) | pc_lo);
+	if (arm_validate_ns_entrypoint(pc) != 0)
+		goto invalid_param;
+
 	/* That the SMC originated from NS is already validated by the caller */
 
 	/*
@@ -173,7 +176,6 @@
 	SMC_RET1(handle, STATE_SW_E_PARAM);
 
 exec_denied:
-#endif /* __aarch64__ */
 	/* State switch denied */
 	SMC_RET1(handle, STATE_SW_E_DENIED);
 }
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index ab90f46..939885f 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,6 +11,7 @@
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <drivers/console.h>
+#include <lib/debugfs.h>
 #include <lib/extensions/ras.h>
 #include <lib/mmio.h>
 #include <lib/utils.h>
@@ -231,6 +232,10 @@
 #if RAS_EXTENSION
 	ras_init();
 #endif
+
+#if USE_DEBUGFS
+	debugfs_init();
+#endif /* USE_DEBUGFS */
 }
 
 /*******************************************************************************
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index bc0cf9a..03d842a 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -16,7 +16,7 @@
 #include <lib/xlat_tables/xlat_tables_compat.h>
 #include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
-#include <services/secure_partition.h>
+#include <services/spm_mm_partition.h>
 
 /* Weak definitions may be overridden in specific ARM standard platform */
 #pragma weak plat_get_ns_image_entrypoint
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index a4a29bf..9d4f05e 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -130,6 +130,11 @@
 $(eval $(call assert_boolean,ARM_CRYPTOCELL_INTEG))
 $(eval $(call add_define,ARM_CRYPTOCELL_INTEG))
 
+# Enable PIE support for RESET_TO_BL31 case
+ifeq (${RESET_TO_BL31},1)
+    ENABLE_PIE			:=	1
+endif
+
 # CryptoCell integration relies on coherent buffers for passing data from
 # the AP CPU to the CryptoCell
 ifeq (${ARM_CRYPTOCELL_INTEG},1)
@@ -210,13 +215,18 @@
 BL31_SOURCES		+=	plat/arm/common/arm_bl31_setup.c		\
 				plat/arm/common/arm_pm.c			\
 				plat/arm/common/arm_topology.c			\
-				plat/arm/common/execution_state_switch.c	\
 				plat/common/plat_psci_common.c
 
 ifeq (${ENABLE_PMF}, 1)
-BL31_SOURCES		+=	plat/arm/common/arm_sip_svc.c			\
+ifeq (${ARCH}, aarch64)
+BL31_SOURCES		+=	plat/arm/common/aarch64/execution_state_switch.c\
+				plat/arm/common/arm_sip_svc.c			\
+				lib/pmf/pmf_smc.c
+else
+BL32_SOURCES		+=	plat/arm/common/arm_sip_svc.c			\
 				lib/pmf/pmf_smc.c
 endif
+endif
 
 ifeq (${EL3_EXCEPTION_HANDLING},1)
 BL31_SOURCES		+=	plat/arm/common/aarch64/arm_ehf.c
@@ -238,16 +248,6 @@
 				lib/extensions/pauth/pauth_helpers.S
 endif
 
-# SPM uses libfdt in Arm platforms
-ifeq (${SPM_MM},0)
-ifeq (${ENABLE_SPM},1)
-BL31_SOURCES		+=	common/fdt_wrappers.c			\
-				plat/common/plat_spm_rd.c		\
-				plat/common/plat_spm_sp.c		\
-				${LIBFDT_SRCS}
-endif
-endif
-
 ifneq (${TRUSTED_BOARD_BOOT},0)
 
     # Include common TBB sources
diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c
index 9a53649..e6c5a73 100644
--- a/plat/arm/common/arm_dyn_cfg.c
+++ b/plat/arm/common/arm_dyn_cfg.c
@@ -1,11 +1,12 @@
 /*
- * 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
  */
 
 #include <assert.h>
 #include <string.h>
+#include <libfdt.h>
 
 #include <platform_def.h>
 
@@ -21,8 +22,6 @@
 
 /* Variable to store the address to TB_FW_CONFIG passed from BL1 */
 static void *tb_fw_cfg_dtb;
-static size_t tb_fw_cfg_dtb_size;
-
 
 #if TRUSTED_BOARD_BOOT
 
@@ -110,7 +109,7 @@
 		 * without the heap info.
 		 */
 		flush_dcache_range((uintptr_t)tb_fw_cfg_dtb,
-			tb_fw_cfg_dtb_size);
+			fdt_totalsize(tb_fw_cfg_dtb));
 	}
 }
 
@@ -146,7 +145,6 @@
 	/* At this point we know that a DTB is indeed available */
 	config_base = arm_tb_fw_info.image_info.image_base;
 	tb_fw_cfg_dtb = (void *)config_base;
-	tb_fw_cfg_dtb_size = (size_t)arm_tb_fw_info.image_info.image_max_size;
 
 	/* The BL2 ep_info arg0 is modified to point to TB_FW_CONFIG */
 	desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
@@ -245,7 +243,8 @@
 
 #ifdef	BL31_BASE
 			/* Ensure the configs don't overlap with BL31 */
-			if ((image_base > BL31_BASE) || ((image_base + image_size) > BL31_BASE))
+			if ((image_base >= BL31_BASE) &&
+			    (image_base <= BL31_LIMIT))
 				continue;
 #endif
 			/* Ensure the configs are loaded in a valid address */
@@ -256,7 +255,8 @@
 			 * If BL32 is present, ensure that the configs don't
 			 * overlap with it.
 			 */
-			if (image_base >= BL32_BASE && image_base <= BL32_LIMIT)
+			if ((image_base >= BL32_BASE) &&
+			    (image_base <= BL32_LIMIT))
 				continue;
 #endif
 		}
@@ -265,7 +265,10 @@
 		cfg_mem_params->image_info.image_base = (uintptr_t)image_base;
 		cfg_mem_params->image_info.image_max_size = image_size;
 
-		/* Remove the IMAGE_ATTRIB_SKIP_LOADING attribute from HW_CONFIG node */
+		/*
+		 * Remove the IMAGE_ATTRIB_SKIP_LOADING attribute from
+		 * HW_CONFIG or FW_CONFIG nodes
+		 */
 		cfg_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
 	}
 
diff --git a/plat/arm/common/arm_gicv3.c b/plat/arm/common/arm_gicv3.c
index fef5376..4a3a22e 100644
--- a/plat/arm/common/arm_gicv3.c
+++ b/plat/arm/common/arm_gicv3.c
@@ -28,6 +28,15 @@
 /* The GICv3 driver only needs to be initialized in EL3 */
 static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
 
+/* Default GICR base address to be used for GICR probe. */
+static const uintptr_t gicr_base_addrs[2] = {
+	PLAT_ARM_GICR_BASE,	/* GICR Base address of the primary CPU */
+	0U			/* Zero Termination */
+};
+
+/* List of zero terminated GICR frame addresses which CPUs will probe */
+static const uintptr_t *gicr_frames = gicr_base_addrs;
+
 static const interrupt_prop_t arm_interrupt_props[] = {
 	PLAT_ARM_G1S_IRQ_PROPS(INTR_GROUP1S),
 	PLAT_ARM_G0_IRQ_PROPS(INTR_GROUP0)
@@ -35,12 +44,11 @@
 
 /*
  * We save and restore the GICv3 context on system suspend. Allocate the
- * data in the designated EL3 Secure carve-out memory. The `volatile`
- * is used to prevent the compiler from removing the gicv3 contexts even
- * though the DEFINE_LOAD_SYM_ADDR creates a dummy reference to it.
+ * data in the designated EL3 Secure carve-out memory. The `used` attribute
+ * is used to prevent the compiler from removing the gicv3 contexts.
  */
-static volatile gicv3_redist_ctx_t rdist_ctx __section("arm_el3_tzc_dram");
-static volatile gicv3_dist_ctx_t dist_ctx __section("arm_el3_tzc_dram");
+static gicv3_redist_ctx_t rdist_ctx __section("arm_el3_tzc_dram") __used;
+static gicv3_dist_ctx_t dist_ctx __section("arm_el3_tzc_dram") __used;
 
 /* Define accessor function to get reference to the GICv3 context */
 DEFINE_LOAD_SYM_ADDR(rdist_ctx)
@@ -76,6 +84,18 @@
 	.mpidr_to_core_pos = arm_gicv3_mpidr_hash
 };
 
+/*
+ * By default, gicr_frames will be pointing to gicr_base_addrs. If
+ * the platform supports a non-contiguous GICR frames (GICR frames located
+ * at uneven offset), plat_arm_override_gicr_frames function can be used by
+ * such platform to override the gicr_frames.
+ */
+void plat_arm_override_gicr_frames(const uintptr_t *plat_gicr_frames)
+{
+	assert(plat_gicr_frames != NULL);
+	gicr_frames = plat_gicr_frames;
+}
+
 void __init plat_arm_gic_driver_init(void)
 {
 	/*
@@ -88,7 +108,7 @@
 	(defined(__aarch64__) && defined(IMAGE_BL31))
 	gicv3_driver_init(&arm_gic_data);
 
-	if (gicv3_rdistif_probe(PLAT_ARM_GICR_BASE) == -1) {
+	if (gicv3_rdistif_probe(gicr_base_addrs[0]) == -1) {
 		ERROR("No GICR base frame found for Primary CPU\n");
 		panic();
 	}
@@ -124,14 +144,23 @@
 /******************************************************************************
  * ARM common helper function to iterate over all GICR frames and discover the
  * corresponding per-cpu redistributor frame as well as initialize the
- * corresponding interface in GICv3. At the moment, Arm platforms do not have
- * non-contiguous GICR frames.
+ * corresponding interface in GICv3.
  *****************************************************************************/
 void plat_arm_gic_pcpu_init(void)
 {
 	int result;
+	const uintptr_t *plat_gicr_frames = gicr_frames;
+
+	do {
+		result = gicv3_rdistif_probe(*plat_gicr_frames);
+
+		/* If the probe is successful, no need to proceed further */
+		if (result == 0)
+			break;
+
+		plat_gicr_frames++;
+	} while (*plat_gicr_frames != 0U);
 
-	result = gicv3_rdistif_probe(PLAT_ARM_GICR_BASE);
 	if (result == -1) {
 		ERROR("No GICR base frame found for CPU 0x%lx\n", read_mpidr());
 		panic();
diff --git a/plat/arm/common/arm_sip_svc.c b/plat/arm/common/arm_sip_svc.c
index 3d308a3..9f5d455 100644
--- a/plat/arm/common/arm_sip_svc.c
+++ b/plat/arm/common/arm_sip_svc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,6 +8,7 @@
 
 #include <common/debug.h>
 #include <common/runtime_svc.h>
+#include <lib/debugfs.h>
 #include <lib/pmf/pmf.h>
 #include <plat/arm/common/arm_sip_svc.h>
 #include <plat/arm/common/plat_arm.h>
@@ -20,8 +21,18 @@
 
 static int arm_sip_setup(void)
 {
-	if (pmf_setup() != 0)
+	if (pmf_setup() != 0) {
 		return 1;
+	}
+
+#if USE_DEBUGFS
+
+	if (debugfs_smc_setup() != 0) {
+		return 1;
+	}
+
+#endif /* USE_DEBUGFS */
+
 	return 0;
 }
 
@@ -48,25 +59,33 @@
 				handle, flags);
 	}
 
+#if USE_DEBUGFS
+
+	if (is_debugfs_fid(smc_fid)) {
+		return debugfs_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
+					   handle, flags);
+	}
+
+#endif /* USE_DEBUGFS */
+
 	switch (smc_fid) {
 	case ARM_SIP_SVC_EXE_STATE_SWITCH: {
-		u_register_t pc;
-
+		/* Execution state can be switched only if EL3 is AArch64 */
+#ifdef __aarch64__
 		/* Allow calls from non-secure only */
 		if (!is_caller_non_secure(flags))
 			SMC_RET1(handle, STATE_SW_E_DENIED);
 
-		/* Validate supplied entry point */
-		pc = (u_register_t) ((x1 << 32) | (uint32_t) x2);
-		if (arm_validate_ns_entrypoint(pc) != 0)
-			SMC_RET1(handle, STATE_SW_E_PARAM);
-
 		/*
 		 * Pointers used in execution state switch are all 32 bits wide
 		 */
 		return (uintptr_t) arm_execution_state_switch(smc_fid,
 				(uint32_t) x1, (uint32_t) x2, (uint32_t) x3,
 				(uint32_t) x4, handle);
+#else
+		/* State switch denied */
+		SMC_RET1(handle, STATE_SW_E_DENIED);
+#endif /* __aarch64__ */
 		}
 
 	case ARM_SIP_SVC_CALL_COUNT:
diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h
index a9cc852..e214573 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -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
  */
@@ -28,7 +28,7 @@
  * plat_arm_mmap array defined for each BL stage.
  */
 #if defined(IMAGE_BL31)
-# if ENABLE_SPM
+# if SPM_MM
 #  define PLAT_ARM_MMAP_ENTRIES		9
 #  define MAX_XLAT_TABLES		7
 #  define PLAT_SP_IMAGE_MMAP_REGIONS	7
@@ -101,7 +101,7 @@
 #elif defined(IMAGE_BL2U)
 # define PLATFORM_STACK_SIZE 0x400
 #elif defined(IMAGE_BL31)
-# if ENABLE_SPM
+# if SPM_MM
 #  define PLATFORM_STACK_SIZE 0x500
 # else
 #  define PLATFORM_STACK_SIZE 0x400
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index b736b0b..7160111 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -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
 #
@@ -10,8 +10,6 @@
 
 RAS_EXTENSION			:=	0
 
-ENABLE_SPM			:=	0
-
 SDEI_SUPPORT			:=	0
 
 EL3_EXCEPTION_HANDLING		:=	0
diff --git a/plat/arm/css/sgi/sgi_plat.c b/plat/arm/css/sgi/sgi_plat.c
index 3e207ec..b611eaf 100644
--- a/plat/arm/css/sgi/sgi_plat.c
+++ b/plat/arm/css/sgi/sgi_plat.c
@@ -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
  */
@@ -15,7 +15,7 @@
 #include <plat/common/platform.h>
 #include <drivers/arm/sbsa.h>
 #include <sgi_base_platform_def.h>
-#include <services/secure_partition.h>
+#include <services/spm_mm_partition.h>
 
 #define SGI_MAP_FLASH0_RO	MAP_REGION_FLAT(V2M_FLASH0_BASE,\
 						V2M_FLASH0_SIZE,	\
@@ -46,7 +46,7 @@
 #if ARM_BL31_IN_DRAM
 	ARM_MAP_BL31_SEC_DRAM,
 #endif
-#if ENABLE_SPM
+#if SPM_MM
 	ARM_SP_IMAGE_MMAP,
 #endif
 #if TRUSTED_BOARD_BOOT && !BL2_AT_EL3
@@ -61,13 +61,13 @@
 	V2M_MAP_IOFPGA,
 	CSS_SGI_MAP_DEVICE,
 	SOC_CSS_MAP_DEVICE,
-#if ENABLE_SPM
+#if SPM_MM
 	ARM_SPM_BUF_EL3_MMAP,
 #endif
 	{0}
 };
 
-#if ENABLE_SPM && defined(IMAGE_BL31)
+#if SPM_MM && defined(IMAGE_BL31)
 const mmap_region_t plat_arm_secure_partition_mmap[] = {
 	PLAT_ARM_SECURE_MAP_DEVICE,
 	ARM_SP_IMAGE_MMAP,
@@ -77,17 +77,17 @@
 	ARM_SPM_BUF_EL0_MMAP,
 	{0}
 };
-#endif /* ENABLE_SPM && defined(IMAGE_BL31) */
+#endif /* SPM_MM && defined(IMAGE_BL31) */
 #endif
 
 ARM_CASSERT_MMAP
 
-#if ENABLE_SPM && defined(IMAGE_BL31)
+#if SPM_MM && defined(IMAGE_BL31)
 /*
  * Boot information passed to a secure partition during initialisation. Linear
  * indices in MP information will be filled at runtime.
  */
-static secure_partition_mp_info_t sp_mp_info[] = {
+static spm_mm_mp_info_t sp_mp_info[] = {
 	[0] = {0x81000000, 0},
 	[1] = {0x81000100, 0},
 	[2] = {0x81000200, 0},
@@ -98,10 +98,10 @@
 	[7] = {0x81010300, 0},
 };
 
-const secure_partition_boot_info_t plat_arm_secure_partition_boot_info = {
+const spm_mm_boot_info_t plat_arm_secure_partition_boot_info = {
 	.h.type              = PARAM_SP_IMAGE_BOOT_INFO,
 	.h.version           = VERSION_1,
-	.h.size              = sizeof(secure_partition_boot_info_t),
+	.h.size              = sizeof(spm_mm_boot_info_t),
 	.h.attr              = 0,
 	.sp_mem_base         = ARM_SP_IMAGE_BASE,
 	.sp_mem_limit        = ARM_SP_IMAGE_LIMIT,
@@ -125,12 +125,12 @@
 	return plat_arm_secure_partition_mmap;
 }
 
-const struct secure_partition_boot_info *plat_get_secure_partition_boot_info(
+const struct spm_mm_boot_info *plat_get_secure_partition_boot_info(
 		void *cookie)
 {
 	return &plat_arm_secure_partition_boot_info;
 }
-#endif /* ENABLE_SPM && defined(IMAGE_BL31) */
+#endif /* SPM_MM && defined(IMAGE_BL31) */
 
 #if TRUSTED_BOARD_BOOT
 int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
diff --git a/plat/arm/css/sgi/sgi_ras.c b/plat/arm/css/sgi/sgi_ras.c
index 0001ffd..f56544e 100644
--- a/plat/arm/css/sgi/sgi_ras.c
+++ b/plat/arm/css/sgi/sgi_ras.c
@@ -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
  */
@@ -12,9 +12,8 @@
 #include <lib/extensions/ras.h>
 #include <plat/arm/common/arm_spm_def.h>
 #include <plat/common/platform.h>
-#include <services/mm_svc.h>
 #include <services/sdei.h>
-#include <services/spm_svc.h>
+#include <services/spm_mm_svc.h>
 
 #include <sgi_ras.h>
 
@@ -142,11 +141,11 @@
 	       sizeof(ras_map->ras_ev_num));
 	header->message_len = 4;
 
-	spm_sp_call(MM_COMMUNICATE_AARCH64, (uint64_t)header, 0,
-		    plat_my_core_pos());
+	spm_mm_sp_call(MM_COMMUNICATE_AARCH64, (uint64_t)header, 0,
+		       plat_my_core_pos());
 
 	/*
-	 * Do an EOI of the RAS interuupt. This allows the
+	 * Do an EOI of the RAS interrupt. This allows the
 	 * sdei event to be dispatched at the SDEI event's
 	 * priority.
 	 */
diff --git a/plat/arm/css/sgm/include/sgm_base_platform_def.h b/plat/arm/css/sgm/include/sgm_base_platform_def.h
index f349c19..24bbed5 100644
--- a/plat/arm/css/sgm/include/sgm_base_platform_def.h
+++ b/plat/arm/css/sgm/include/sgm_base_platform_def.h
@@ -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
  */
@@ -17,8 +17,8 @@
 #include <plat/common/common_def.h>
 
 /* CPU topology */
-#define PLAT_ARM_CLUSTER_COUNT		1
-#define PLAT_ARM_CLUSTER_CORE_COUNT	8
+#define PLAT_ARM_CLUSTER_COUNT		U(1)
+#define PLAT_ARM_CLUSTER_CORE_COUNT	U(8)
 #define PLATFORM_CORE_COUNT		PLAT_ARM_CLUSTER_CORE_COUNT
 
 #define PLAT_MAX_PWR_LVL		ARM_PWR_LVL2
diff --git a/plat/common/plat_psci_common.c b/plat/common/plat_psci_common.c
index 16bec79..80ed819 100644
--- a/plat/common/plat_psci_common.c
+++ b/plat/common/plat_psci_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -31,6 +31,8 @@
 #define PSCI_STAT_ID_EXIT_LOW_PWR		1
 #define PSCI_STAT_TOTAL_IDS			2
 
+PMF_DECLARE_CAPTURE_TIMESTAMP(psci_svc)
+PMF_DECLARE_GET_TIMESTAMP(psci_svc)
 PMF_REGISTER_SERVICE(psci_svc, PMF_PSCI_STAT_SVC_ID, PSCI_STAT_TOTAL_IDS,
 	PMF_STORE_ENABLE)
 
@@ -92,7 +94,7 @@
  */
 u_register_t plat_psci_stat_get_residency(unsigned int lvl,
 	const psci_power_state_t *state_info,
-	int last_cpu_idx)
+	unsigned int last_cpu_idx)
 {
 	plat_local_state_t state;
 	unsigned long long pwrup_ts = 0, pwrdn_ts = 0;
@@ -103,7 +105,7 @@
 	assert(last_cpu_idx <= PLATFORM_CORE_COUNT);
 
 	if (lvl == PSCI_CPU_PWR_LVL)
-		assert((unsigned int)last_cpu_idx == plat_my_core_pos());
+		assert(last_cpu_idx == plat_my_core_pos());
 
 	/*
 	 * If power down is requested, then timestamp capture will
diff --git a/plat/common/plat_spm_rd.c b/plat/common/plat_spm_rd.c
deleted file mode 100644
index ebd3e6d..0000000
--- a/plat/common/plat_spm_rd.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include <libfdt.h>
-
-#include <platform_def.h>
-
-#include <common/debug.h>
-#include <common/fdt_wrappers.h>
-#include <lib/object_pool.h>
-#include <plat/common/platform.h>
-#include <services/sp_res_desc.h>
-
-/*******************************************************************************
- * Resource pool
- ******************************************************************************/
-static struct sp_rd_sect_mem_region rd_mem_regions[PLAT_SPM_MEM_REGIONS_MAX];
-static OBJECT_POOL_ARRAY(rd_mem_regions_pool, rd_mem_regions);
-
-static struct sp_rd_sect_notification rd_notifs[PLAT_SPM_NOTIFICATIONS_MAX];
-static OBJECT_POOL_ARRAY(rd_notifs_pool, rd_notifs);
-
-static struct sp_rd_sect_service rd_services[PLAT_SPM_SERVICES_MAX];
-static OBJECT_POOL_ARRAY(rd_services_pool, rd_services);
-
-/*******************************************************************************
- * Attribute section handler
- ******************************************************************************/
-static void rd_parse_attribute(struct sp_rd_sect_attribute *attr,
-			       const void *fdt, int node)
-{
-	int rc = 0;
-
-	/* The minimum size that can be read from the DTB is 32-bit. */
-	uint32_t version, sp_type, runtime_el, exec_type;
-	uint32_t panic_policy, xlat_granule;
-
-	rc |= fdtw_read_cells(fdt, node, "version", 1, &version);
-
-	if (version != 1) {
-		ERROR("Unsupported resource description version: 0x%x\n",
-		      version);
-		panic();
-	}
-
-	rc |= fdtw_read_cells(fdt, node, "sp_type", 1, &sp_type);
-	rc |= fdtw_read_cells(fdt, node, "pe_mpidr", 1, &attr->pe_mpidr);
-	rc |= fdtw_read_cells(fdt, node, "runtime_el", 1, &runtime_el);
-	rc |= fdtw_read_cells(fdt, node, "exec_type", 1, &exec_type);
-	rc |= fdtw_read_cells(fdt, node, "panic_policy", 1, &panic_policy);
-	rc |= fdtw_read_cells(fdt, node, "xlat_granule", 1, &xlat_granule);
-	rc |= fdtw_read_cells(fdt, node, "binary_size", 1, &attr->binary_size);
-	rc |= fdtw_read_cells(fdt, node, "load_address", 2, &attr->load_address);
-	rc |= fdtw_read_cells(fdt, node, "entrypoint", 2, &attr->entrypoint);
-
-	attr->version = version;
-	attr->sp_type = sp_type;
-	attr->runtime_el = runtime_el;
-	attr->exec_type = exec_type;
-	attr->panic_policy = panic_policy;
-	attr->xlat_granule = xlat_granule;
-
-	VERBOSE(" Attribute Section:\n");
-	VERBOSE("  version: 0x%x\n", version);
-	VERBOSE("  sp_type: 0x%x\n", sp_type);
-	VERBOSE("  pe_mpidr: 0x%x\n", attr->pe_mpidr);
-	VERBOSE("  runtime_el: 0x%x\n", runtime_el);
-	VERBOSE("  exec_type: 0x%x\n", exec_type);
-	VERBOSE("  panic_policy: 0x%x\n", panic_policy);
-	VERBOSE("  xlat_granule: 0x%x\n", xlat_granule);
-	VERBOSE("  binary_size: 0x%x\n", attr->binary_size);
-	VERBOSE("  load_address: 0x%llx\n", attr->load_address);
-	VERBOSE("  entrypoint: 0x%llx\n", attr->entrypoint);
-
-	if (rc) {
-		ERROR("Failed to read attribute node elements.\n");
-		panic();
-	}
-}
-
-/*******************************************************************************
- * Memory regions section handlers
- ******************************************************************************/
-static void rd_parse_memory_region(struct sp_rd_sect_mem_region *rdmem,
-				   const void *fdt, int node)
-{
-	int rc = 0;
-	char name[RD_MEM_REGION_NAME_LEN];
-
-	rc |= fdtw_read_string(fdt, node, "str", (char *)&name, sizeof(name));
-	rc |= fdtw_read_cells(fdt, node, "attr", 1, &rdmem->attr);
-	rc |= fdtw_read_cells(fdt, node, "base", 2, &rdmem->base);
-	rc |= fdtw_read_cells(fdt, node, "size", 2, &rdmem->size);
-
-	size_t len = strlcpy(rdmem->name, name, RD_MEM_REGION_NAME_LEN);
-
-	if (len >= RD_MEM_REGION_NAME_LEN) {
-		WARN("Memory region name truncated: '%s'\n", name);
-	}
-
-	VERBOSE(" Memory Region:\n");
-	VERBOSE("  name: '%s'\n", rdmem->name);
-	VERBOSE("  attr: 0x%x\n", rdmem->attr);
-	VERBOSE("  base: 0x%llx\n", rdmem->base);
-	VERBOSE("  size: 0x%llx\n", rdmem->size);
-
-	if (rc) {
-		ERROR("Failed to read mem_region node elements.\n");
-		panic();
-	}
-}
-
-static void rd_parse_memory_regions(struct sp_res_desc *rd, const void *fdt,
-				    int node)
-{
-	int child;
-	struct sp_rd_sect_mem_region *rdmem, *old_rdmem;
-
-	fdt_for_each_subnode(child, fdt, node) {
-		rdmem = pool_alloc(&rd_mem_regions_pool);
-
-		/* Add element to the start of the list */
-		old_rdmem = rd->mem_region;
-		rd->mem_region = rdmem;
-		rdmem->next = old_rdmem;
-
-		rd_parse_memory_region(rdmem, fdt, child);
-	}
-
-	if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) {
-		ERROR("%d: fdt_for_each_subnode(): %d\n", __LINE__, node);
-		panic();
-	}
-}
-
-/*******************************************************************************
- * Notifications section handlers
- ******************************************************************************/
-static void rd_parse_notification(struct sp_rd_sect_notification *rdnot,
-				   const void *fdt, int node)
-{
-	int rc = 0;
-
-	rc |= fdtw_read_cells(fdt, node, "attr", 1, &rdnot->attr);
-	rc |= fdtw_read_cells(fdt, node, "pe", 1, &rdnot->pe);
-
-	VERBOSE(" Notification:\n");
-	VERBOSE("  attr: 0x%x\n", rdnot->attr);
-	VERBOSE("  pe: 0x%x\n", rdnot->pe);
-
-	if (rc) {
-		ERROR("Failed to read notification node elements.\n");
-		panic();
-	}
-}
-
-static void rd_parse_notifications(struct sp_res_desc *rd, const void *fdt, int node)
-{
-	int child;
-	struct sp_rd_sect_notification *rdnot, *old_rdnot;
-
-	fdt_for_each_subnode(child, fdt, node) {
-		rdnot = pool_alloc(&rd_notifs_pool);
-
-		/* Add element to the start of the list */
-		old_rdnot = rd->notification;
-		rd->notification = rdnot;
-		rdnot->next = old_rdnot;
-
-		rd_parse_notification(rdnot, fdt, child);
-	}
-
-	if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) {
-		ERROR("%d: fdt_for_each_subnode(): %d\n", __LINE__, child);
-		panic();
-	}
-}
-
-/*******************************************************************************
- * Services section handlers
- ******************************************************************************/
-static void rd_parse_service(struct sp_rd_sect_service *rdsvc, const void *fdt,
-			     int node)
-{
-	int rc = 0;
-
-	/* The minimum size that can be read from the DTB is 32-bit. */
-	uint32_t accessibility, request_type, connection_quota;
-
-	rc |= fdtw_read_array(fdt, node, "uuid", 4, &rdsvc->uuid);
-	rc |= fdtw_read_cells(fdt, node, "accessibility", 1, &accessibility);
-	rc |= fdtw_read_cells(fdt, node, "request_type", 1, &request_type);
-	rc |= fdtw_read_cells(fdt, node, "connection_quota", 1, &connection_quota);
-	rc |= fdtw_read_cells(fdt, node, "sec_mem_size", 1, &rdsvc->secure_mem_size);
-	rc |= fdtw_read_cells(fdt, node, "interrupt_num", 1, &rdsvc->interrupt_num);
-
-	rdsvc->accessibility = accessibility;
-	rdsvc->request_type = request_type;
-	rdsvc->connection_quota = connection_quota;
-
-	VERBOSE(" Service:\n");
-	VERBOSE("  uuid: 0x%08x 0x%08x 0x%08x 0x%08x\n", rdsvc->uuid[0],
-		rdsvc->uuid[1], rdsvc->uuid[2], rdsvc->uuid[3]);
-	VERBOSE("  accessibility: 0x%x\n", accessibility);
-	VERBOSE("  request_type: 0x%x\n", request_type);
-	VERBOSE("  connection_quota: 0x%x\n", connection_quota);
-	VERBOSE("  secure_memory_size: 0x%x\n", rdsvc->secure_mem_size);
-	VERBOSE("  interrupt_num: 0x%x\n", rdsvc->interrupt_num);
-
-	if (rc) {
-		ERROR("Failed to read attribute node elements.\n");
-		panic();
-	}
-}
-
-static void rd_parse_services(struct sp_res_desc *rd, const void *fdt, int node)
-{
-	int child;
-	struct sp_rd_sect_service *rdsvc, *old_rdsvc;
-
-	fdt_for_each_subnode(child, fdt, node) {
-		rdsvc = pool_alloc(&rd_services_pool);
-
-		/* Add element to the start of the list */
-		old_rdsvc = rd->service;
-		rd->service = rdsvc;
-		rdsvc->next = old_rdsvc;
-
-		rd_parse_service(rdsvc, fdt, child);
-	}
-
-	if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) {
-		ERROR("%d: fdt_for_each_subnode(): %d\n", __LINE__, node);
-		panic();
-	}
-}
-
-/*******************************************************************************
- * Root node handler
- ******************************************************************************/
-static void rd_parse_root(struct sp_res_desc *rd, const void *fdt, int root)
-{
-	int node;
-	char *str;
-
-	str = "attribute";
-	node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str));
-	if (node < 0) {
-		ERROR("Root node doesn't contain subnode '%s'\n", str);
-		panic();
-	} else {
-		rd_parse_attribute(&rd->attribute, fdt, node);
-	}
-
-	str = "memory_regions";
-	node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str));
-	if (node < 0) {
-		ERROR("Root node doesn't contain subnode '%s'\n", str);
-		panic();
-	} else {
-		rd_parse_memory_regions(rd, fdt, node);
-	}
-
-	str = "notifications";
-	node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str));
-	if (node < 0) {
-		WARN("Root node doesn't contain subnode '%s'\n", str);
-	} else {
-		rd_parse_notifications(rd, fdt, node);
-	}
-
-	str = "services";
-	node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str));
-	if (node < 0) {
-		WARN("Root node doesn't contain subnode '%s'\n", str);
-	} else {
-		rd_parse_services(rd, fdt, node);
-	}
-}
-
-/*******************************************************************************
- * Platform handler to load resource descriptor blobs into the active Secure
- * Partition context.
- ******************************************************************************/
-int plat_spm_sp_rd_load(struct sp_res_desc *rd, const void *ptr, size_t size)
-{
-	int rc;
-	int root_node;
-
-	assert(rd != NULL);
-	assert(ptr != NULL);
-
-	INFO("Reading RD blob at address %p\n", ptr);
-
-	rc = fdt_check_header(ptr);
-	if (rc != 0) {
-		ERROR("Wrong format for resource descriptor blob (%d).\n", rc);
-		return -1;
-	}
-
-	root_node = fdt_node_offset_by_compatible(ptr, -1, "arm,sp_rd");
-	if (root_node < 0) {
-		ERROR("Unrecognized resource descriptor blob (%d)\n", rc);
-		return -1;
-	}
-
-	rd_parse_root(rd, ptr, root_node);
-
-	return 0;
-}
diff --git a/plat/common/plat_spm_sp.c b/plat/common/plat_spm_sp.c
deleted file mode 100644
index bc3d6a0..0000000
--- a/plat/common/plat_spm_sp.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-
-#include <platform_def.h>
-
-#include <common/debug.h>
-#include <plat/common/platform.h>
-#include <tools_share/sptool.h>
-
-static unsigned int sp_next;
-
-/*******************************************************************************
- * Platform handler get the address of a Secure Partition and its resource
- * description blob. It iterates through all SPs detected by the platform. If
- * there is information for another SP, it returns 0. If there are no more SPs,
- * it returns -1.
- ******************************************************************************/
-int plat_spm_sp_get_next_address(void **sp_base, size_t *sp_size,
-				 void **rd_base, size_t *rd_size)
-{
-	assert((sp_base != NULL) && (sp_size != NULL));
-	assert((rd_base != NULL) && (rd_base != NULL));
-
-	const uint64_t *pkg_base = (uint64_t *)PLAT_SP_PACKAGE_BASE;
-
-	struct sp_pkg_header *pkg_header = (struct sp_pkg_header *)pkg_base;
-
-	if (sp_next == 0) {
-		if (pkg_header->version != 0x1) {
-			ERROR("SP package has an unsupported version 0x%llx\n",
-			      pkg_header->version);
-			panic();
-		}
-	}
-
-	if (sp_next >= pkg_header->number_of_sp) {
-		/* No more partitions in the package */
-		return -1;
-	}
-
-	const struct sp_pkg_entry *entry_list =
-		(const struct sp_pkg_entry *)((uintptr_t)pkg_base
-					       + sizeof(struct sp_pkg_header));
-
-	const struct sp_pkg_entry *entry = &(entry_list[sp_next]);
-
-	uint64_t sp_offset = entry->sp_offset;
-	uint64_t rd_offset = entry->rd_offset;
-
-	uintptr_t pkg_sp_base = ((uintptr_t)PLAT_SP_PACKAGE_BASE + sp_offset);
-	uintptr_t pkg_rd_base = ((uintptr_t)PLAT_SP_PACKAGE_BASE + rd_offset);
-
-	uint64_t pkg_sp_size = entry->sp_size;
-	uint64_t pkg_rd_size = entry->rd_size;
-
-	uintptr_t pkg_end = (uintptr_t)PLAT_SP_PACKAGE_BASE
-			  + (uintptr_t)PLAT_SP_PACKAGE_SIZE - 1U;
-
-	/*
-	 * Check for overflows. The package header isn't trusted, so assert()
-	 * can't be used here.
-	 */
-
-	uintptr_t pkg_sp_end = pkg_sp_base + pkg_sp_size - 1U;
-	uintptr_t pkg_rd_end = pkg_rd_base + pkg_rd_size - 1U;
-
-	if ((pkg_sp_end > pkg_end) || (pkg_sp_end < pkg_sp_base)) {
-		ERROR("Invalid Secure Partition size (0x%llx)\n", pkg_sp_size);
-		panic();
-	}
-
-	if ((pkg_rd_end > pkg_end) || (pkg_rd_end < pkg_rd_base)) {
-		ERROR("Invalid Resource Description blob size (0x%llx)\n",
-		      pkg_rd_size);
-		panic();
-	}
-
-	/* Return location of the binaries. */
-
-	*sp_base = (void *)pkg_sp_base;
-	*sp_size = pkg_sp_size;
-	*rd_base = (void *)pkg_rd_base;
-	*rd_size = pkg_rd_size;
-
-	sp_next++;
-
-	return 0;
-}
diff --git a/plat/imx/common/include/imx_caam.h b/plat/imx/common/include/imx_caam.h
index 335bd0f..61005b5 100644
--- a/plat/imx/common/include/imx_caam.h
+++ b/plat/imx/common/include/imx_caam.h
@@ -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
  */
@@ -7,6 +7,7 @@
 #ifndef IMX_CAAM_H
 #define IMX_CAAM_H
 
+#include <cdefs.h>
 #include <stdint.h>
 #include <arch.h>
 #include <imx_regs.h>
diff --git a/plat/imx/common/include/imx_snvs.h b/plat/imx/common/include/imx_snvs.h
index 0b3d108..565c451 100644
--- a/plat/imx/common/include/imx_snvs.h
+++ b/plat/imx/common/include/imx_snvs.h
@@ -1,11 +1,12 @@
 /*
- * 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
  */
 #ifndef IMX_SNVS_H
 #define IMX_SNVS_H
 
+#include <cdefs.h>
 #include <stdint.h>
 
 #include <arch.h>
diff --git a/plat/imx/common/include/sci/sci_ipc.h b/plat/imx/common/include/sci/sci_ipc.h
index 1167ea3..39e9012 100644
--- a/plat/imx/common/include/sci/sci_ipc.h
+++ b/plat/imx/common/include/sci/sci_ipc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -62,6 +62,6 @@
  */
 void sc_ipc_write(sc_ipc_t ipc, void *data);
 
-sc_ipc_t ipc_handle;
+extern sc_ipc_t ipc_handle;
 
 #endif /* SCI_IPC_H */
diff --git a/plat/imx/common/sci/ipc.c b/plat/imx/common/sci/ipc.c
index 6491ca5..5769119 100644
--- a/plat/imx/common/sci/ipc.c
+++ b/plat/imx/common/sci/ipc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,6 +13,8 @@
 #include <sci/sci_rpc.h>
 #include "imx8_mu.h"
 
+sc_ipc_t ipc_handle;
+
 DEFINE_BAKERY_LOCK(sc_ipc_bakery_lock);
 #define sc_ipc_lock_init()	bakery_lock_init(&sc_ipc_bakery_lock)
 #define sc_ipc_lock()		bakery_lock_get(&sc_ipc_bakery_lock)
diff --git a/plat/imx/imx8m/include/imx8m_psci.h b/plat/imx/imx8m/include/imx8m_psci.h
index 4966403..c33d25e 100644
--- a/plat/imx/imx8m/include/imx8m_psci.h
+++ b/plat/imx/imx8m/include/imx8m_psci.h
@@ -15,13 +15,9 @@
 void imx_pwr_domain_on_finish(const psci_power_state_t *target_state);
 void imx_pwr_domain_off(const psci_power_state_t *target_state);
 int imx_validate_ns_entrypoint(uintptr_t ns_entrypoint);
-int imx_validate_power_state(unsigned int power_state, psci_power_state_t *rq_state);
 void imx_cpu_standby(plat_local_state_t cpu_state);
 void imx_domain_suspend(const psci_power_state_t *target_state);
 void imx_domain_suspend_finish(const psci_power_state_t *target_state);
-void imx_get_sys_suspend_power_state(psci_power_state_t *req_state);
-void __dead2 imx_system_reset(void);
-void __dead2 imx_system_off(void);
 void __dead2 imx_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state);
 
 #endif /* IMX8M_PSCI_H */
diff --git a/plat/intel/soc/agilex/bl2_plat_setup.c b/plat/intel/soc/agilex/bl2_plat_setup.c
index e9ab928..86b7ab8 100644
--- a/plat/intel/soc/agilex/bl2_plat_setup.c
+++ b/plat/intel/soc/agilex/bl2_plat_setup.c
@@ -14,20 +14,17 @@
 #include <drivers/synopsys/dw_mmc.h>
 #include <drivers/ti/uart/uart_16550.h>
 #include <lib/xlat_tables/xlat_tables.h>
-#include <platform_def.h>
-#include <socfpga_private.h>
 
 #include "agilex_clock_manager.h"
-#include "agilex_handoff.h"
-#include "agilex_mailbox.h"
 #include "agilex_memory_controller.h"
 #include "agilex_pinmux.h"
-#include "agilex_private.h"
 #include "agilex_reset_manager.h"
 #include "agilex_system_manager.h"
-
 #include "ccu/ncore_ccu.h"
 #include "qspi/cadence_qspi.h"
+#include "socfpga_handoff.h"
+#include "socfpga_mailbox.h"
+#include "socfpga_private.h"
 #include "wdt/watchdog.h"
 
 
@@ -59,7 +56,7 @@
 
 	generic_delay_timer_init();
 
-	if (agilex_get_handoff(&reverse_handoff_ptr))
+	if (socfpga_get_handoff(&reverse_handoff_ptr))
 		return;
 	config_pinmux(&reverse_handoff_ptr);
 	boot_source = reverse_handoff_ptr.boot_source;
diff --git a/plat/intel/soc/agilex/bl31_plat_setup.c b/plat/intel/soc/agilex/bl31_plat_setup.c
index c8765e8..375483d 100644
--- a/plat/intel/soc/agilex/bl31_plat_setup.c
+++ b/plat/intel/soc/agilex/bl31_plat_setup.c
@@ -12,7 +12,6 @@
 #include <drivers/arm/gicv2.h>
 #include <drivers/ti/uart/uart_16550.h>
 #include <lib/xlat_tables/xlat_tables.h>
-#include <platform_def.h>
 
 
 static entry_point_info_t bl32_image_ep_info;
@@ -67,15 +66,15 @@
 }
 
 static const interrupt_prop_t s10_interrupt_props[] = {
-	PLAT_INTEL_AGX_G1S_IRQ_PROPS(GICV2_INTR_GROUP0),
-	PLAT_INTEL_AGX_G0_IRQ_PROPS(GICV2_INTR_GROUP0)
+	PLAT_INTEL_SOCFPGA_G1S_IRQ_PROPS(GICV2_INTR_GROUP0),
+	PLAT_INTEL_SOCFPGA_G0_IRQ_PROPS(GICV2_INTR_GROUP0)
 };
 
 static unsigned int target_mask_array[PLATFORM_CORE_COUNT];
 
 static const gicv2_driver_data_t plat_gicv2_gic_data = {
-	.gicd_base = PLAT_INTEL_AGX_GICD_BASE,
-	.gicc_base = PLAT_INTEL_AGX_GICC_BASE,
+	.gicd_base = PLAT_INTEL_SOCFPGA_GICD_BASE,
+	.gicc_base = PLAT_INTEL_SOCFPGA_GICC_BASE,
 	.interrupt_props = s10_interrupt_props,
 	.interrupt_props_num = ARRAY_SIZE(s10_interrupt_props),
 	.target_masks = target_mask_array,
@@ -104,7 +103,7 @@
 		MT_DEVICE | MT_RW | MT_SECURE),
 	MAP_REGION_FLAT(MEM64_BASE, MEM64_SIZE, MT_DEVICE | MT_RW | MT_NS),
 	MAP_REGION_FLAT(DEVICE4_BASE, DEVICE4_SIZE, MT_DEVICE | MT_RW | MT_NS),
-	{0},
+	{0}
 };
 
 /*******************************************************************************
@@ -126,7 +125,7 @@
 			BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
 			MT_DEVICE | MT_RW | MT_SECURE),
 #endif
-		{0},
+		{0}
 	};
 
 	setup_page_tables(bl_regions, plat_agilex_mmap);
diff --git a/plat/intel/soc/agilex/include/agilex_clock_manager.h b/plat/intel/soc/agilex/include/agilex_clock_manager.h
index 0822290..8af6a60 100644
--- a/plat/intel/soc/agilex/include/agilex_clock_manager.h
+++ b/plat/intel/soc/agilex/include/agilex_clock_manager.h
@@ -7,7 +7,7 @@
 #ifndef CLOCKMANAGER_H
 #define CLOCKMANAGER_H
 
-#include "agilex_handoff.h"
+#include "socfpga_handoff.h"
 
 /* Clock Manager Registers */
 #define CLKMGR_OFFSET				0xffd10000
diff --git a/plat/intel/soc/agilex/include/agilex_pinmux.h b/plat/intel/soc/agilex/include/agilex_pinmux.h
index e6a7b34..fe01062 100644
--- a/plat/intel/soc/agilex/include/agilex_pinmux.h
+++ b/plat/intel/soc/agilex/include/agilex_pinmux.h
@@ -12,7 +12,7 @@
 #define AGX_PINMUX_PINMUX_EMAC0_USEFPGA	0xffd13300
 #define AGX_PINMUX_IO0_DELAY		0xffd13400
 
-#include "agilex_handoff.h"
+#include "socfpga_handoff.h"
 
 void config_pinmux(handoff *handoff);
 
diff --git a/plat/intel/soc/agilex/include/agilex_private.h b/plat/intel/soc/agilex/include/agilex_private.h
deleted file mode 100644
index fc0e9fd..0000000
--- a/plat/intel/soc/agilex/include/agilex_private.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef AGX_PRIVATE_H
-#define AGX_PRIVATE_H
-
-#define AGX_MMC_REG_BASE	0xff808000
-
-#define EMMC_DESC_SIZE		(1<<20)
-#define EMMC_INIT_PARAMS(base, clk)		\
-	{	.bus_width = MMC_BUS_WIDTH_4,	\
-		.clk_rate = (clk),		\
-		.desc_base = (base),		\
-		.desc_size = EMMC_DESC_SIZE,	\
-		.flags = 0,			\
-		.reg_base = AGX_MMC_REG_BASE	\
-	}
-
-typedef enum {
-	BOOT_SOURCE_FPGA = 0,
-	BOOT_SOURCE_SDMMC,
-	BOOT_SOURCE_NAND,
-	BOOT_SOURCE_RSVD,
-	BOOT_SOURCE_QSPI
-} boot_source_type;
-
-void enable_nonsecure_access(void);
-void socfpga_io_setup(int boot_source);
-
-#endif
diff --git a/plat/intel/soc/agilex/include/agilex_system_manager.h b/plat/intel/soc/agilex/include/agilex_system_manager.h
index 381c2d3..be29536 100644
--- a/plat/intel/soc/agilex/include/agilex_system_manager.h
+++ b/plat/intel/soc/agilex/include/agilex_system_manager.h
@@ -73,7 +73,6 @@
 #define DISABLE_BRIDGE_FIREWALL			0x0ffe0101
 #define DISABLE_L4_FIREWALL	(BIT(0) | BIT(16) | BIT(24))
 
-void enable_nonsecure_access(void);
 void enable_ns_bridge_access(void);
 
 #endif
diff --git a/plat/intel/soc/agilex/include/socfpga_plat_def.h b/plat/intel/soc/agilex/include/socfpga_plat_def.h
new file mode 100644
index 0000000..a346cb5
--- /dev/null
+++ b/plat/intel/soc/agilex/include/socfpga_plat_def.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_SOCFPGA_DEF_H
+#define PLAT_SOCFPGA_DEF_H
+
+#include <platform_def.h>
+
+/* Platform Setting */
+#define PLATFORM_MODEL				PLAT_SOCFPGA_AGILEX
+
+/* Register Mapping */
+#define SOCFPGA_MMC_REG_BASE			0xff808000
+
+#define SOCFPGA_RSTMGR_OFST			0xffd11000
+#define SOCFPGA_RSTMGR_MPUMODRST_OFST		0xffd11020
+
+#endif /* PLAT_SOCFPGA_DEF_H */
+
diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk
index d1ea629..ef02a8d 100644
--- a/plat/intel/soc/agilex/platform.mk
+++ b/plat/intel/soc/agilex/platform.mk
@@ -4,7 +4,7 @@
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
-#
+
 PLAT_INCLUDES		:=	\
 			-Iplat/intel/soc/agilex/include/		\
 			-Iplat/intel/soc/common/drivers/		\
@@ -25,48 +25,41 @@
 
 BL2_SOURCES     +=	\
 		common/desc_image_load.c				\
-		drivers/partition/partition.c				\
-		drivers/partition/gpt.c					\
-		drivers/arm/pl061/pl061_gpio.c				\
 		drivers/mmc/mmc.c					\
-		drivers/synopsys/emmc/dw_mmc.c				\
+		drivers/intel/soc/stratix10/io/s10_memmap_qspi.c	\
 		drivers/io/io_storage.c					\
 		drivers/io/io_block.c					\
 		drivers/io/io_fip.c					\
-		drivers/gpio/gpio.c					\
-		drivers/intel/soc/stratix10/io/s10_memmap_qspi.c	\
+		drivers/partition/partition.c				\
+		drivers/partition/gpt.c					\
+		drivers/synopsys/emmc/dw_mmc.c				\
 		lib/cpus/aarch64/cortex_a53.S				\
 		plat/intel/soc/agilex/bl2_plat_setup.c			\
-		plat/intel/soc/agilex/socfpga_storage.c			\
-                plat/intel/soc/common/bl2_plat_mem_params_desc.c	\
-		plat/intel/soc/agilex/soc/agilex_reset_manager.c	\
-		plat/intel/soc/agilex/soc/agilex_handoff.c		\
 		plat/intel/soc/agilex/soc/agilex_clock_manager.c	\
-		plat/intel/soc/agilex/soc/agilex_pinmux.c		\
 		plat/intel/soc/agilex/soc/agilex_memory_controller.c	\
+		plat/intel/soc/agilex/soc/agilex_pinmux.c		\
+		plat/intel/soc/agilex/soc/agilex_reset_manager.c	\
+		plat/intel/soc/agilex/soc/agilex_system_manager.c	\
+                plat/intel/soc/common/bl2_plat_mem_params_desc.c	\
 		plat/intel/soc/common/socfpga_delay_timer.c		\
 		plat/intel/soc/common/socfpga_image_load.c		\
-		plat/intel/soc/agilex/soc/agilex_system_manager.c	\
-		plat/intel/soc/agilex/soc/agilex_mailbox.c		\
+		plat/intel/soc/common/socfpga_storage.c			\
+		plat/intel/soc/common/soc/socfpga_handoff.c		\
+		plat/intel/soc/common/soc/socfpga_mailbox.c		\
 		plat/intel/soc/common/drivers/qspi/cadence_qspi.c	\
 		plat/intel/soc/common/drivers/wdt/watchdog.c		\
 		plat/intel/soc/common/drivers/ccu/ncore_ccu.c
 
 BL31_SOURCES	+=	\
 		drivers/arm/cci/cci.c					\
-		lib/cpus/aarch64/cortex_a53.S				\
 		lib/cpus/aarch64/aem_generic.S				\
+		lib/cpus/aarch64/cortex_a53.S				\
 		plat/common/plat_psci_common.c				\
-		plat/intel/soc/agilex/socfpga_sip_svc.c			\
 		plat/intel/soc/agilex/bl31_plat_setup.c 		\
-		plat/intel/soc/agilex/socfpga_psci.c			\
+		plat/intel/soc/common/socfpga_psci.c			\
+		plat/intel/soc/common/socfpga_sip_svc.c			\
 		plat/intel/soc/common/socfpga_topology.c		\
-		plat/intel/soc/common/socfpga_delay_timer.c		\
-		plat/intel/soc/agilex/soc/agilex_reset_manager.c	\
-		plat/intel/soc/agilex/soc/agilex_pinmux.c		\
-		plat/intel/soc/agilex/soc/agilex_clock_manager.c	\
-		plat/intel/soc/agilex/soc/agilex_handoff.c		\
-		plat/intel/soc/agilex/soc/agilex_mailbox.c
+		plat/intel/soc/common/soc/socfpga_mailbox.c		\
 
 PROGRAMMABLE_RESET_ADDRESS	:= 0
 BL2_AT_EL3			:= 1
diff --git a/plat/intel/soc/agilex/soc/agilex_clock_manager.c b/plat/intel/soc/agilex/soc/agilex_clock_manager.c
index 06891ff..96b669c 100644
--- a/plat/intel/soc/agilex/soc/agilex_clock_manager.c
+++ b/plat/intel/soc/agilex/soc/agilex_clock_manager.c
@@ -11,8 +11,8 @@
 #include <lib/mmio.h>
 
 #include "agilex_clock_manager.h"
-#include "agilex_handoff.h"
 #include "agilex_system_manager.h"
+#include "socfpga_handoff.h"
 
 
 uint32_t wait_pll_lock(void)
diff --git a/plat/intel/soc/agilex/soc/agilex_memory_controller.c b/plat/intel/soc/agilex/soc/agilex_memory_controller.c
index 5f3cae7..2aabe87 100644
--- a/plat/intel/soc/agilex/soc/agilex_memory_controller.c
+++ b/plat/intel/soc/agilex/soc/agilex_memory_controller.c
@@ -20,9 +20,8 @@
 #define PRE_CALIBRATION_DELAY		1
 #define POST_CALIBRATION_DELAY		1
 #define TIMEOUT_EMIF_CALIBRATION	1000
-#define CLEAR_EMIF_DELAY		50000
-#define CLEAR_EMIF_TIMEOUT		0x100000
-#define TIMEOUT_INT_RESP		10000
+#define CLEAR_EMIF_DELAY		1000
+#define CLEAR_EMIF_TIMEOUT		1000
 
 #define DDR_CONFIG(A, B, C, R)	(((A) << 24) | ((B) << 16) | ((C) << 8) | (R))
 #define DDR_CONFIG_ELEMENTS	(sizeof(ddr_config)/sizeof(uint32_t))
@@ -125,7 +124,7 @@
 			data = mmio_read_32(AGX_MPFE_HMC_ADP_DDRCALSTAT);
 			if (AGX_MPFE_HMC_ADP_DDRCALSTAT_CAL(data) == 1)
 				break;
-			mdelay(1);
+			udelay(500);
 		} while (++timeout < TIMEOUT_EMIF_CALIBRATION);
 
 		if (AGX_MPFE_HMC_ADP_DDRCALSTAT_CAL(data) == 0) {
diff --git a/plat/intel/soc/agilex/socfpga_sip_svc.c b/plat/intel/soc/agilex/socfpga_sip_svc.c
deleted file mode 100644
index 6a1c957..0000000
--- a/plat/intel/soc/agilex/socfpga_sip_svc.c
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <common/debug.h>
-#include <common/runtime_svc.h>
-#include <tools_share/uuid.h>
-
-#include "agilex_mailbox.h"
-
-/* Number of SiP Calls implemented */
-#define SIP_NUM_CALLS		0x3
-
-/* Total buffer the driver can hold */
-#define FPGA_CONFIG_BUFFER_SIZE 4
-
-int current_block;
-int current_buffer;
-int current_id = 1;
-int max_blocks;
-uint32_t bytes_per_block;
-uint32_t blocks_submitted;
-uint32_t blocks_completed;
-
-struct fpga_config_info {
-	uint32_t addr;
-	int size;
-	int size_written;
-	uint32_t write_requested;
-	int subblocks_sent;
-	int block_number;
-};
-
-/*  SiP Service UUID */
-DEFINE_SVC_UUID2(intl_svc_uid,
-		0xa85273b0, 0xe85a, 0x4862, 0xa6, 0x2a,
-		0xfa, 0x88, 0x88, 0x17, 0x68, 0x81);
-
-uint64_t socfpga_sip_handler(uint32_t smc_fid,
-				   uint64_t x1,
-				   uint64_t x2,
-				   uint64_t x3,
-				   uint64_t x4,
-				   void *cookie,
-				   void *handle,
-				   uint64_t flags)
-{
-	ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
-	SMC_RET1(handle, SMC_UNK);
-}
-
-struct fpga_config_info fpga_config_buffers[FPGA_CONFIG_BUFFER_SIZE];
-
-static void intel_fpga_sdm_write_buffer(struct fpga_config_info *buffer)
-{
-	uint32_t args[3];
-
-	while (max_blocks > 0 && buffer->size > buffer->size_written) {
-		if (buffer->size - buffer->size_written <=
-			bytes_per_block) {
-			args[0] = (1<<8);
-			args[1] = buffer->addr + buffer->size_written;
-			args[2] = buffer->size - buffer->size_written;
-			buffer->size_written +=
-				buffer->size - buffer->size_written;
-			buffer->subblocks_sent++;
-			mailbox_send_cmd_async(0x4,
-				MBOX_RECONFIG_DATA,
-				args, 3, 0);
-			current_buffer++;
-			current_buffer %= FPGA_CONFIG_BUFFER_SIZE;
-		} else {
-			args[0] = (1<<8);
-			args[1] = buffer->addr + buffer->size_written;
-			args[2] = bytes_per_block;
-			buffer->size_written += bytes_per_block;
-			mailbox_send_cmd_async(0x4,
-				MBOX_RECONFIG_DATA,
-				args, 3, 0);
-			buffer->subblocks_sent++;
-		}
-		max_blocks--;
-	}
-}
-
-static int intel_fpga_sdm_write_all(void)
-{
-	int i;
-
-	for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++)
-		intel_fpga_sdm_write_buffer(
-			&fpga_config_buffers[current_buffer]);
-
-	return 0;
-}
-
-uint32_t intel_mailbox_fpga_config_isdone(void)
-{
-	uint32_t args[2];
-	uint32_t response[6];
-	int status;
-
-	status = mailbox_send_cmd(1, MBOX_RECONFIG_STATUS, args, 0, 0,
-				response);
-
-	if (status < 0)
-		return INTEL_SIP_SMC_STATUS_ERROR;
-
-	if (response[RECONFIG_STATUS_STATE] &&
-		response[RECONFIG_STATUS_STATE] != MBOX_CFGSTAT_STATE_CONFIG)
-		return INTEL_SIP_SMC_STATUS_ERROR;
-
-	if (!(response[RECONFIG_STATUS_PIN_STATUS] & PIN_STATUS_NSTATUS))
-		return INTEL_SIP_SMC_STATUS_ERROR;
-
-	if (response[RECONFIG_STATUS_SOFTFUNC_STATUS] &
-		SOFTFUNC_STATUS_SEU_ERROR)
-		return INTEL_SIP_SMC_STATUS_ERROR;
-
-	if ((response[RECONFIG_STATUS_SOFTFUNC_STATUS] &
-		SOFTFUNC_STATUS_CONF_DONE) &&
-		(response[RECONFIG_STATUS_SOFTFUNC_STATUS] &
-		SOFTFUNC_STATUS_INIT_DONE))
-		return INTEL_SIP_SMC_STATUS_OK;
-
-	return INTEL_SIP_SMC_STATUS_ERROR;
-}
-
-static int mark_last_buffer_xfer_completed(uint32_t *buffer_addr_completed)
-{
-	int i;
-
-	for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
-		if (fpga_config_buffers[i].block_number == current_block) {
-			fpga_config_buffers[i].subblocks_sent--;
-			if (fpga_config_buffers[i].subblocks_sent == 0
-			&& fpga_config_buffers[i].size <=
-			fpga_config_buffers[i].size_written) {
-				fpga_config_buffers[i].write_requested = 0;
-				current_block++;
-				*buffer_addr_completed =
-					fpga_config_buffers[i].addr;
-				return 0;
-			}
-		}
-	}
-
-	return -1;
-}
-
-unsigned int address_in_ddr(uint32_t *addr)
-{
-	if (((unsigned long long)addr > DRAM_BASE) &&
-		((unsigned long long)addr < DRAM_BASE + DRAM_SIZE))
-		return 0;
-
-	return -1;
-}
-
-int intel_fpga_config_completed_write(uint32_t *completed_addr,
-					uint32_t *count)
-{
-	uint32_t status = INTEL_SIP_SMC_STATUS_OK;
-	*count = 0;
-	int resp_len = 0;
-	uint32_t resp[5];
-	int all_completed = 1;
-	int count_check = 0;
-
-	if (address_in_ddr(completed_addr) != 0 || address_in_ddr(count) != 0)
-		return INTEL_SIP_SMC_STATUS_ERROR;
-
-	for (count_check = 0; count_check < 3; count_check++)
-		if (address_in_ddr(&completed_addr[*count + count_check]) != 0)
-			return INTEL_SIP_SMC_STATUS_ERROR;
-
-	resp_len = mailbox_read_response(0x4, resp);
-
-	while (resp_len >= 0 && *count < 3) {
-		max_blocks++;
-		if (mark_last_buffer_xfer_completed(
-			&completed_addr[*count]) == 0)
-			*count = *count + 1;
-		else
-			break;
-		resp_len = mailbox_read_response(0x4, resp);
-	}
-
-	if (*count <= 0) {
-		if (resp_len != MBOX_NO_RESPONSE &&
-			resp_len != MBOX_TIMEOUT && resp_len != 0) {
-			return INTEL_SIP_SMC_STATUS_ERROR;
-		}
-
-		*count = 0;
-	}
-
-	intel_fpga_sdm_write_all();
-
-	if (*count > 0)
-		status = INTEL_SIP_SMC_STATUS_OK;
-	else if (*count == 0)
-		status = INTEL_SIP_SMC_STATUS_BUSY;
-
-	for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
-		if (fpga_config_buffers[i].write_requested != 0) {
-			all_completed = 0;
-			break;
-		}
-	}
-
-	if (all_completed == 1)
-		return INTEL_SIP_SMC_STATUS_OK;
-
-	return status;
-}
-
-int intel_fpga_config_start(uint32_t config_type)
-{
-	uint32_t response[3];
-	int status = 0;
-
-	status = mailbox_send_cmd(2, MBOX_RECONFIG, 0, 0, 0,
-			response);
-
-	if (status < 0)
-		return status;
-
-	max_blocks = response[0];
-	bytes_per_block = response[1];
-
-	for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
-		fpga_config_buffers[i].size = 0;
-		fpga_config_buffers[i].size_written = 0;
-		fpga_config_buffers[i].addr = 0;
-		fpga_config_buffers[i].write_requested = 0;
-		fpga_config_buffers[i].block_number = 0;
-		fpga_config_buffers[i].subblocks_sent = 0;
-	}
-
-	blocks_submitted = 0;
-	current_block = 0;
-	current_buffer = 0;
-
-	return 0;
-}
-
-
-uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size)
-{
-	int i = 0;
-	uint32_t status = INTEL_SIP_SMC_STATUS_OK;
-
-	if (mem < DRAM_BASE || mem > DRAM_BASE + DRAM_SIZE)
-		status = INTEL_SIP_SMC_STATUS_REJECTED;
-
-	if (mem + size > DRAM_BASE + DRAM_SIZE)
-		status = INTEL_SIP_SMC_STATUS_REJECTED;
-
-	for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
-		if (!fpga_config_buffers[i].write_requested) {
-			fpga_config_buffers[i].addr = mem;
-			fpga_config_buffers[i].size = size;
-			fpga_config_buffers[i].size_written = 0;
-			fpga_config_buffers[i].write_requested = 1;
-			fpga_config_buffers[i].block_number =
-				blocks_submitted++;
-			fpga_config_buffers[i].subblocks_sent = 0;
-			break;
-		}
-	}
-
-
-	if (i == FPGA_CONFIG_BUFFER_SIZE) {
-		status = INTEL_SIP_SMC_STATUS_REJECTED;
-		return status;
-	} else if (i == FPGA_CONFIG_BUFFER_SIZE - 1) {
-		status = INTEL_SIP_SMC_STATUS_BUSY;
-	}
-
-	intel_fpga_sdm_write_all();
-
-	return status;
-}
-
-/*
- * This function is responsible for handling all SiP calls from the NS world
- */
-
-uintptr_t sip_smc_handler(uint32_t smc_fid,
-			 u_register_t x1,
-			 u_register_t x2,
-			 u_register_t x3,
-			 u_register_t x4,
-			 void *cookie,
-			 void *handle,
-			 u_register_t flags)
-{
-	uint32_t status = INTEL_SIP_SMC_STATUS_OK;
-	uint32_t completed_addr[3];
-	uint32_t count = 0;
-
-	switch (smc_fid) {
-	case SIP_SVC_UID:
-		/* Return UID to the caller */
-		SMC_UUID_RET(handle, intl_svc_uid);
-		break;
-	case INTEL_SIP_SMC_FPGA_CONFIG_ISDONE:
-		status = intel_mailbox_fpga_config_isdone();
-		SMC_RET4(handle, status, 0, 0, 0);
-		break;
-	case INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM:
-		SMC_RET3(handle, INTEL_SIP_SMC_STATUS_OK,
-			INTEL_SIP_SMC_FPGA_CONFIG_ADDR,
-			INTEL_SIP_SMC_FPGA_CONFIG_SIZE -
-				INTEL_SIP_SMC_FPGA_CONFIG_ADDR);
-		break;
-	case INTEL_SIP_SMC_FPGA_CONFIG_START:
-		status = intel_fpga_config_start(x1);
-		SMC_RET4(handle, status, 0, 0, 0);
-		break;
-	case INTEL_SIP_SMC_FPGA_CONFIG_WRITE:
-		status = intel_fpga_config_write(x1, x2);
-		SMC_RET4(handle, status, 0, 0, 0);
-		break;
-	case INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE:
-		status = intel_fpga_config_completed_write(completed_addr,
-								&count);
-		switch (count) {
-		case 1:
-			SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK,
-				completed_addr[0], 0, 0);
-			break;
-		case 2:
-			SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK,
-				completed_addr[0],
-				completed_addr[1], 0);
-			break;
-		case 3:
-			SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK,
-				completed_addr[0],
-				completed_addr[1],
-				completed_addr[2]);
-			break;
-		case 0:
-			SMC_RET4(handle, status, 0, 0, 0);
-			break;
-		default:
-			SMC_RET1(handle, INTEL_SIP_SMC_STATUS_ERROR);
-		}
-		break;
-
-	default:
-		return socfpga_sip_handler(smc_fid, x1, x2, x3, x4,
-			cookie, handle, flags);
-	}
-}
-
-DECLARE_RT_SVC(
-	agilex_sip_svc,
-	OEN_SIP_START,
-	OEN_SIP_END,
-	SMC_TYPE_FAST,
-	NULL,
-	sip_smc_handler
-);
-
-DECLARE_RT_SVC(
-	agilex_sip_svc_std,
-	OEN_SIP_START,
-	OEN_SIP_END,
-	SMC_TYPE_YIELD,
-	NULL,
-	sip_smc_handler
-);
diff --git a/plat/intel/soc/common/aarch64/plat_helpers.S b/plat/intel/soc/common/aarch64/plat_helpers.S
index 00fe2d9..5cb9b69 100644
--- a/plat/intel/soc/common/aarch64/plat_helpers.S
+++ b/plat/intel/soc/common/aarch64/plat_helpers.S
@@ -8,6 +8,7 @@
 #include <asm_macros.S>
 #include <cpu_macros.S>
 #include <platform_def.h>
+#include <el3_common_macros.S>
 
 	.globl	plat_secondary_cold_boot_setup
 	.globl	platform_is_primary_cpu
@@ -17,6 +18,7 @@
 	.globl	plat_crash_console_putc
 	.globl  plat_crash_console_flush
 	.globl	platform_mem_init
+	.globl	plat_secondary_cpus_bl31_entry
 
 	.globl plat_get_my_entrypoint
 
@@ -33,7 +35,6 @@
 	/* Wait until the it gets reset signal from rstmgr gets populated */
 poll_mailbox:
 	wfi
-
 	mov_imm	x0, PLAT_SEC_ENTRY
 	ldr	x1, [x0]
 	mov_imm	x2, PLAT_CPUID_RELEASE
@@ -65,12 +66,34 @@
 	ret
 endfunc plat_my_core_pos
 
+func warm_reset_req
+	str	xzr, [x4]
+	bl	plat_is_my_cpu_primary
+	cbz	x0, cpu_in_wfi
+	mov_imm x1, PLAT_SEC_ENTRY
+	str	xzr, [x1]
+	mrs	x1, rmr_el3
+	orr	x1, x1, #0x02
+	msr	rmr_el3, x1
+	isb
+	dsb	sy
+cpu_in_wfi:
+	wfi
+	b	cpu_in_wfi
+endfunc warm_reset_req
+
 func plat_get_my_entrypoint
+	ldr	x4, =L2_RESET_DONE_REG
+	ldr	x5, [x4]
+	ldr	x1, =L2_RESET_DONE_STATUS
+	cmp	x1, x5
+	b.eq	warm_reset_req
 	mov_imm	x1, PLAT_SEC_ENTRY
 	ldr	x0, [x1]
 	ret
 endfunc plat_get_my_entrypoint
 
+
 	/* ---------------------------------------------
 	 * int plat_crash_console_init(void)
 	 * Function to initialize the crash console
@@ -114,3 +137,14 @@
 	mov	x0, #0
 	ret
 endfunc platform_mem_init
+
+func plat_secondary_cpus_bl31_entry
+	el3_entrypoint_common                                   \
+		_init_sctlr=0                                   \
+		_warm_boot_mailbox=!PROGRAMMABLE_RESET_ADDRESS  \
+		_secondary_cold_boot=!COLD_BOOT_SINGLE_CPU      \
+		_init_memory=1                                  \
+		_init_c_runtime=1                               \
+		_exception_vectors=runtime_exceptions		\
+		_pie_fixup_size=BL31_LIMIT - BL31_BASE
+endfunc plat_secondary_cpus_bl31_entry
diff --git a/plat/intel/soc/common/aarch64/platform_common.c b/plat/intel/soc/common/aarch64/platform_common.c
index 6d3d817..b79a63c 100644
--- a/plat/intel/soc/common/aarch64/platform_common.c
+++ b/plat/intel/soc/common/aarch64/platform_common.c
@@ -8,7 +8,8 @@
 #include <arch_helpers.h>
 #include <platform_def.h>
 #include <plat/common/platform.h>
-#include <socfpga_private.h>
+
+#include "socfpga_private.h"
 
 
 unsigned int plat_get_syscnt_freq2(void)
diff --git a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
index ac8218e..fce816b 100644
--- a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
+++ b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
@@ -10,7 +10,6 @@
 #include <lib/mmio.h>
 
 #include "ncore_ccu.h"
-#include <platform_def.h>
 
 uint32_t poll_active_bit(uint32_t dir);
 
diff --git a/plat/intel/soc/common/drivers/qspi/cadence_qspi.c b/plat/intel/soc/common/drivers/qspi/cadence_qspi.c
index 0fd11ec..cecf560 100644
--- a/plat/intel/soc/common/drivers/qspi/cadence_qspi.c
+++ b/plat/intel/soc/common/drivers/qspi/cadence_qspi.c
@@ -13,7 +13,6 @@
 #include <drivers/console.h>
 
 #include "cadence_qspi.h"
-#include <platform_def.h>
 
 #define LESS(a, b)   (((a) < (b)) ? (a) : (b))
 #define MORE(a, b)   (((a) > (b)) ? (a) : (b))
@@ -689,10 +688,7 @@
 
 	if ((offset >= qspi_device_size) ||
 			(offset + size - 1 >= qspi_device_size) ||
-			(size == 0) ||
-			((long) ((int *)buffer) & 0x3)  ||
-			(offset & 0x3) ||
-			(size & 0x3)) {
+			(size == 0)) {
 		ERROR("Invalid read parameter\n");
 		return -1;
 	}
@@ -767,11 +763,9 @@
 
 	if ((offset >= qspi_device_size) ||
 			(offset + size - 1 >= qspi_device_size) ||
-			(size == 0) ||
-			((long)buffer & 0x3)  ||
-			(offset & 0x3) ||
-			(size & 0x3))
+			(size == 0)) {
 		return -2;
+	}
 
 	if (CAD_QSPI_INDWR_RDSTAT(mmio_read_32(CAD_QSPI_OFFSET +
 						CAD_QSPI_INDWR))) {
diff --git a/plat/intel/soc/common/drivers/wdt/watchdog.c b/plat/intel/soc/common/drivers/wdt/watchdog.c
index 0f89b4f..651189b 100644
--- a/plat/intel/soc/common/drivers/wdt/watchdog.c
+++ b/plat/intel/soc/common/drivers/wdt/watchdog.c
@@ -6,7 +6,6 @@
 
 #include <common/debug.h>
 #include <lib/mmio.h>
-#include <platform_def.h>
 
 #include "watchdog.h"
 
diff --git a/plat/intel/soc/agilex/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h
similarity index 64%
rename from plat/intel/soc/agilex/include/platform_def.h
rename to plat/intel/soc/common/include/platform_def.h
index 277862a..8d04479 100644
--- a/plat/intel/soc/agilex/include/platform_def.h
+++ b/plat/intel/soc/common/include/platform_def.h
@@ -13,12 +13,23 @@
 #include <common/tbbr/tbbr_img_def.h>
 #include <plat/common/common_def.h>
 
+#define PLAT_SOCFPGA_STRATIX10			1
+#define PLAT_SOCFPGA_AGILEX			2
 
-#define PLAT_CPUID_RELEASE			0xffe1b000
-#define PLAT_SEC_ENTRY				0xffe1b008
+/* sysmgr.boot_scratch_cold4 & 5 used for CPU release address for SPL */
+#define PLAT_CPU_RELEASE_ADDR			0xffd12210
+
+/*
+ * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
+ * is done and HPS should trigger warm reset via RMR_EL3.
+ */
+#define L2_RESET_DONE_REG			0xFFD12218
+
+/* Magic word to indicate L2 reset is completed */
+#define L2_RESET_DONE_STATUS			0x1228E5E7
 
 /* Define next boot image name and offset */
-#define PLAT_NS_IMAGE_OFFSET			0x50000
+#define PLAT_NS_IMAGE_OFFSET			0x10000000
 #define PLAT_HANDOFF_OFFSET			0xFFE3F000
 
 /*******************************************************************************
@@ -27,7 +38,7 @@
 #define PLATFORM_LINKER_FORMAT			"elf64-littleaarch64"
 #define PLATFORM_LINKER_ARCH			aarch64
 
-/* Agilex supports up to 124GB RAM */
+/* SoCFPGA supports up to 124GB RAM */
 #define PLAT_PHY_ADDR_SPACE_SIZE		(1ULL << 39)
 #define PLAT_VIRT_ADDR_SPACE_SIZE		(1ULL << 39)
 
@@ -56,18 +67,18 @@
 
 /* Interrupt related constant */
 
-#define INTEL_AGX_IRQ_SEC_PHY_TIMER		29
+#define INTEL_SOCFPGA_IRQ_SEC_PHY_TIMER		29
 
-#define INTEL_AGX_IRQ_SEC_SGI_0			8
-#define INTEL_AGX_IRQ_SEC_SGI_1			9
-#define INTEL_AGX_IRQ_SEC_SGI_2			10
-#define INTEL_AGX_IRQ_SEC_SGI_3			11
-#define INTEL_AGX_IRQ_SEC_SGI_4			12
-#define INTEL_AGX_IRQ_SEC_SGI_5			13
-#define INTEL_AGX_IRQ_SEC_SGI_6			14
-#define INTEL_AGX_IRQ_SEC_SGI_7			15
+#define INTEL_SOCFPGA_IRQ_SEC_SGI_0			8
+#define INTEL_SOCFPGA_IRQ_SEC_SGI_1			9
+#define INTEL_SOCFPGA_IRQ_SEC_SGI_2			10
+#define INTEL_SOCFPGA_IRQ_SEC_SGI_3			11
+#define INTEL_SOCFPGA_IRQ_SEC_SGI_4			12
+#define INTEL_SOCFPGA_IRQ_SEC_SGI_5			13
+#define INTEL_SOCFPGA_IRQ_SEC_SGI_6			14
+#define INTEL_SOCFPGA_IRQ_SEC_SGI_7			15
 
-#define TSP_IRQ_SEC_PHY_TIMER		INTEL_AGX_IRQ_SEC_PHY_TIMER
+#define TSP_IRQ_SEC_PHY_TIMER		INTEL_SOCFPGA_IRQ_SEC_PHY_TIMER
 #define TSP_SEC_MEM_BASE		BL32_BASE
 #define TSP_SEC_MEM_SIZE		(BL32_LIMIT - BL32_BASE + 1)
 /*******************************************************************************
@@ -104,19 +115,24 @@
  */
 
 
-#define FIRMWARE_WELCOME_STR		"Booting Trusted Firmware\n"
+#define FIRMWARE_WELCOME_STR	"Booting Trusted Firmware\n"
 
-#define BL1_RO_BASE	(0xffe00000)
-#define BL1_RO_LIMIT	(0xffe0f000)
-#define BL1_RW_BASE	(0xffe10000)
-#define BL1_RW_LIMIT	(0xffe1ffff)
-#define BL1_RW_SIZE	(0x14000)
+#define BL1_RO_BASE		(0xffe00000)
+#define BL1_RO_LIMIT		(0xffe0f000)
+#define BL1_RW_BASE		(0xffe10000)
+#define BL1_RW_LIMIT		(0xffe1ffff)
+#define BL1_RW_SIZE		(0x14000)
 
-#define BL2_BASE	(0xffe00000)
-#define BL2_LIMIT	(0xffe1b000)
+#define BL2_BASE		(0xffe00000)
+#define BL2_LIMIT		(0xffe1b000)
 
-#define BL31_BASE	(0xffe1c000)
-#define BL31_LIMIT	(0xffe3bfff)
+#define BL31_BASE		(0x1000)
+#define BL31_LIMIT		(0x81000)
+
+#define BL_DATA_LIMIT		PLAT_HANDOFF_OFFSET
+
+#define PLAT_CPUID_RELEASE	(BL_DATA_LIMIT - 16)
+#define PLAT_SEC_ENTRY		(BL_DATA_LIMIT - 8)
 
 /*******************************************************************************
  * Platform specific page table and MMU setup constants
@@ -158,39 +174,50 @@
 #define PLAT_SYS_COUNTER_FREQ_IN_TICKS	(400000000)
 #define PLAT_SYS_COUNTER_FREQ_IN_MHZ	(400)
 
-#define PLAT_INTEL_AGX_GICD_BASE	PLAT_GICD_BASE
-#define PLAT_INTEL_AGX_GICC_BASE	PLAT_GICC_BASE
+#define PLAT_INTEL_SOCFPGA_GICD_BASE	PLAT_GICD_BASE
+#define PLAT_INTEL_SOCFPGA_GICC_BASE	PLAT_GICC_BASE
 
 /*
  * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
  * terminology. On a GICv2 system or mode, the lists will be merged and treated
  * as Group 0 interrupts.
  */
-#define PLAT_INTEL_AGX_G1S_IRQ_PROPS(grp) \
-	INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \
-			grp, GIC_INTR_CFG_LEVEL), \
-	INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, grp, \
-			GIC_INTR_CFG_EDGE), \
-	INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \
-			GIC_INTR_CFG_EDGE), \
-	INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, grp, \
-			GIC_INTR_CFG_EDGE), \
-	INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, grp, \
-			GIC_INTR_CFG_EDGE), \
-	INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, grp, \
-			GIC_INTR_CFG_EDGE), \
-	INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, grp, \
-			GIC_INTR_CFG_EDGE), \
-	INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \
-			GIC_INTR_CFG_EDGE), \
-	INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \
-			GIC_INTR_CFG_EDGE)
+#define PLAT_INTEL_SOCFPGA_G1S_IRQ_PROPS(grp) \
+	INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_PHY_TIMER, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+	INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_SGI_0, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_EDGE), \
+	INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_SGI_1, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_EDGE), \
+	INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_SGI_2, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_EDGE), \
+	INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_SGI_3, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_EDGE), \
+	INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_SGI_4, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_EDGE), \
+	INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_SGI_5, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_EDGE), \
+	INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_SGI_6, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_EDGE), \
+	INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_SGI_7, \
+			GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_EDGE)
 
-#define PLAT_INTEL_AGX_G0_IRQ_PROPS(grp)
+#define PLAT_INTEL_SOCFPGA_G0_IRQ_PROPS(grp)
 
 #define MAX_IO_HANDLES			4
 #define MAX_IO_DEVICES			4
 #define MAX_IO_BLOCK_DEVICES		2
 
+#ifndef __ASSEMBLER__
+struct socfpga_bl31_params {
+	param_header_t h;
+	image_info_t *bl31_image_info;
+	entry_point_info_t *bl32_ep_info;
+	image_info_t *bl32_image_info;
+	entry_point_info_t *bl33_ep_info;
+	image_info_t *bl33_image_info;
+};
+#endif
+
 #endif /* PLATFORM_DEF_H */
 
diff --git a/plat/intel/soc/agilex/include/agilex_handoff.h b/plat/intel/soc/common/include/socfpga_handoff.h
similarity index 68%
rename from plat/intel/soc/agilex/include/agilex_handoff.h
rename to plat/intel/soc/common/include/socfpga_handoff.h
index 2016406..889d137 100644
--- a/plat/intel/soc/agilex/include/agilex_handoff.h
+++ b/plat/intel/soc/common/include/socfpga_handoff.h
@@ -15,6 +15,8 @@
 #define HANDOFF_MAGIC_CLOCK		0x434c4b53	/* CLKS */
 #define HANDOFF_MAGIC_MISC		0x4d495343	/* MISC */
 
+#include <socfpga_plat_def.h>
+
 typedef struct handoff_t {
 	/* header */
 	uint32_t	header_magic;
@@ -47,16 +49,54 @@
 	uint32_t	pinmux_iodelay_array[96];	/* offset, value */
 
 	/* clock configuration */
+
+#if PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10
 	uint32_t	clock_magic;
 	uint32_t	clock_length;
 	uint32_t	_pad_0x588_0x590[2];
 	uint32_t	main_pll_mpuclk;
 	uint32_t	main_pll_nocclk;
+	uint32_t	main_pll_cntr2clk;
+	uint32_t	main_pll_cntr3clk;
+	uint32_t	main_pll_cntr4clk;
+	uint32_t	main_pll_cntr5clk;
+	uint32_t	main_pll_cntr6clk;
+	uint32_t	main_pll_cntr7clk;
+	uint32_t	main_pll_cntr8clk;
+	uint32_t	main_pll_cntr9clk;
 	uint32_t	main_pll_nocdiv;
 	uint32_t	main_pll_pllglob;
 	uint32_t	main_pll_fdbck;
 	uint32_t	main_pll_pllc0;
 	uint32_t	main_pll_pllc1;
+	uint32_t	_pad_0x5cc_0x5d0[1];
+	uint32_t	per_pll_cntr2clk;
+	uint32_t	per_pll_cntr3clk;
+	uint32_t	per_pll_cntr4clk;
+	uint32_t	per_pll_cntr5clk;
+	uint32_t	per_pll_cntr6clk;
+	uint32_t	per_pll_cntr7clk;
+	uint32_t	per_pll_cntr8clk;
+	uint32_t	per_pll_cntr9clk;
+	uint32_t	per_pll_emacctl;
+	uint32_t	per_pll_gpiodiv;
+	uint32_t	per_pll_pllglob;
+	uint32_t	per_pll_fdbck;
+	uint32_t	per_pll_pllc0;
+	uint32_t	per_pll_pllc1;
+	uint32_t	hps_osc_clk_h;
+	uint32_t	fpga_clk_hz;
+#elif PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX
+	uint32_t	clock_magic;
+	uint32_t	clock_length;
+	uint32_t	_pad_0x588_0x590[2];
+	uint32_t	main_pll_mpuclk;
+	uint32_t	main_pll_nocclk;
+	uint32_t	main_pll_nocdiv;
+	uint32_t	main_pll_pllglob;
+	uint32_t	main_pll_fdbck;
+	uint32_t	main_pll_pllc0;
+	uint32_t	main_pll_pllc1;
 	uint32_t	main_pll_pllc2;
 	uint32_t	main_pll_pllc3;
 	uint32_t	main_pll_pllm;
@@ -80,7 +120,7 @@
 	uint32_t	hps_osc_clk_h;
 	uint32_t	fpga_clk_hz;
 	uint32_t	_pad_0x604_0x610[3];
-
+#endif
 	/* misc configuration */
 	uint32_t	misc_magic;
 	uint32_t	misc_length;
@@ -89,7 +129,7 @@
 } handoff;
 
 int verify_handoff_image(handoff *hoff_ptr, handoff *reverse_hoff_ptr);
-int agilex_get_handoff(handoff *hoff_ptr);
+int socfpga_get_handoff(handoff *hoff_ptr);
 
 #endif
 
diff --git a/plat/intel/soc/agilex/include/agilex_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h
similarity index 65%
rename from plat/intel/soc/agilex/include/agilex_mailbox.h
rename to plat/intel/soc/common/include/socfpga_mailbox.h
index cd8be28..c5f2fbe 100644
--- a/plat/intel/soc/agilex/include/agilex_mailbox.h
+++ b/plat/intel/soc/common/include/socfpga_mailbox.h
@@ -4,13 +4,14 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef AGX_MBOX_H
-#define AGX_MBOX_H
+#ifndef SOCFPGA_MBOX_H
+#define SOCFPGA_MBOX_H
 
 #include <lib/utils_def.h>
 
 #define MBOX_OFFSET			0xffa30000
 
+#define MBOX_MAX_JOB_ID			0xf
 #define MBOX_ATF_CLIENT_ID		0x1
 #define MBOX_JOB_ID			0x1
 
@@ -66,6 +67,9 @@
 #define MBOX_CMD_GET_IDCODE		16
 #define MBOX_CMD_QSPI_SET_CS		52
 
+/* Mailbox CANCEL command */
+#define MBOX_CMD_CANCEL			0x3
+
 /* Mailbox REBOOT commands */
 #define MBOX_CMD_REBOOT_HPS		71
 
@@ -75,41 +79,31 @@
 #define MBOX_WRONG_ID			-3
 
 /* Mailbox status */
-#define RECONFIG_STATUS_STATE		0
-#define RECONFIG_STATUS_PIN_STATUS	2
-#define RECONFIG_STATUS_SOFTFUNC_STATUS 3
-#define PIN_STATUS_NSTATUS		(U(1) << 31)
-#define SOFTFUNC_STATUS_SEU_ERROR	(1 << 3)
-#define SOFTFUNC_STATUS_INIT_DONE	(1 << 1)
-#define SOFTFUNC_STATUS_CONF_DONE	(1 << 0)
-#define MBOX_CFGSTAT_STATE_CONFIG	0x10000000
-
-/* SMC function IDs for SiP Service queries */
-#define SIP_SVC_CALL_COUNT	0x8200ff00
-#define SIP_SVC_UID		0x8200ff01
-#define SIP_SVC_VERSION		0x8200ff03
-
-/* SiP Service Calls version numbers */
-#define SIP_SVC_VERSION_MAJOR	0
-#define SIP_SVC_VERSION_MINOR	1
+#define RECONFIG_STATUS_STATE				0
+#define RECONFIG_STATUS_PIN_STATUS			2
+#define RECONFIG_STATUS_SOFTFUNC_STATUS			3
+#define PIN_STATUS_NSTATUS				(U(1) << 31)
+#define SOFTFUNC_STATUS_SEU_ERROR			(1 << 3)
+#define SOFTFUNC_STATUS_INIT_DONE			(1 << 1)
+#define SOFTFUNC_STATUS_CONF_DONE			(1 << 0)
+#define MBOX_CFGSTAT_STATE_IDLE				0x00000000
+#define MBOX_CFGSTAT_STATE_CONFIG			0x10000000
+#define MBOX_CFGSTAT_STATE_FAILACK			0x08000000
+#define MBOX_CFGSTAT_STATE_ERROR_INVALID		0xf0000001
+#define MBOX_CFGSTAT_STATE_ERROR_CORRUPT		0xf0000002
+#define MBOX_CFGSTAT_STATE_ERROR_AUTH			0xf0000003
+#define MBOX_CFGSTAT_STATE_ERROR_CORE_IO		0xf0000004
+#define MBOX_CFGSTAT_STATE_ERROR_HARDWARE		0xf0000005
+#define MBOX_CFGSTAT_STATE_ERROR_FAKE			0xf0000006
+#define MBOX_CFGSTAT_STATE_ERROR_BOOT_INFO		0xf0000007
+#define MBOX_CFGSTAT_STATE_ERROR_QSPI_ERROR		0xf0000008
 
 /* Mailbox reconfiguration commands */
+#define MBOX_CONFIG_STATUS	4
 #define MBOX_RECONFIG		6
 #define MBOX_RECONFIG_DATA	8
 #define MBOX_RECONFIG_STATUS	9
 
-/* Sip get memory */
-#define INTEL_SIP_SMC_FPGA_CONFIG_START			0xC2000001
-#define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM		0xC2000005
-#define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE		0xC2000004
-#define INTEL_SIP_SMC_FPGA_CONFIG_WRITE			0x42000002
-#define INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE	0xC2000003
-#define INTEL_SIP_SMC_STATUS_OK				0
-#define INTEL_SIP_SMC_STATUS_ERROR			0x4
-#define INTEL_SIP_SMC_STATUS_BUSY			0x1
-#define INTEL_SIP_SMC_STATUS_REJECTED			0x2
-#define INTEL_SIP_SMC_FPGA_CONFIG_ADDR			0x1000
-#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE			16777216
 
 void mailbox_set_int(int interrupt_input);
 int mailbox_init(void);
@@ -117,11 +111,14 @@
 void mailbox_set_qspi_open(void);
 void mailbox_set_qspi_direct(void);
 int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args,
-				int len, int urgent, uint32_t *response);
-void mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args,
+			int len, int urgent, uint32_t *response, int resp_len);
+int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args,
 				int len, int urgent);
-int mailbox_read_response(int job_id, uint32_t *response);
+int mailbox_read_response(int job_id, uint32_t *response, int resp_len);
 int mailbox_get_qspi_clock(void);
 void mailbox_reset_cold(void);
+void mailbox_clear_response(void);
+
+uint32_t intel_mailbox_get_config_status(uint32_t cmd);
 
-#endif
+#endif /* SOCFPGA_MBOX_H */
diff --git a/plat/intel/soc/common/include/socfpga_private.h b/plat/intel/soc/common/include/socfpga_private.h
index 6ab1409..ca38f62 100644
--- a/plat/intel/soc/common/include/socfpga_private.h
+++ b/plat/intel/soc/common/include/socfpga_private.h
@@ -4,12 +4,38 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef PLATFORM_PRIVATE_H
-#define PLATFORM_PRIVATE_H
+#ifndef SOCFPGA_PRIVATE_H
+#define SOCFPGA_PRIVATE_H
+
+#include "socfpga_plat_def.h"
+
+#define EMMC_DESC_SIZE		(1<<20)
+
+#define EMMC_INIT_PARAMS(base, clk)			\
+	{	.bus_width = MMC_BUS_WIDTH_4,		\
+		.clk_rate = (clk),			\
+		.desc_base = (base),			\
+		.desc_size = EMMC_DESC_SIZE,		\
+		.flags = 0,				\
+		.reg_base = SOCFPGA_MMC_REG_BASE	\
+	}
+
+typedef enum {
+	BOOT_SOURCE_FPGA = 0,
+	BOOT_SOURCE_SDMMC,
+	BOOT_SOURCE_NAND,
+	BOOT_SOURCE_RSVD,
+	BOOT_SOURCE_QSPI
+} boot_source_type;
 
 /*******************************************************************************
  * Function and variable prototypes
  ******************************************************************************/
+
+void enable_nonsecure_access(void);
+
+void socfpga_io_setup(int boot_source);
+
 void socfgpa_configure_mmu_el3(unsigned long total_base,
 			unsigned long total_size,
 			unsigned long ro_start,
@@ -35,5 +61,6 @@
 
 unsigned long socfpga_get_ns_image_entrypoint(void);
 
+void plat_secondary_cpus_bl31_entry(void);
 
-#endif /* PLATFORM_PRIVATE_H */
+#endif /* SOCFPGA_PRIVATE_H */
diff --git a/plat/intel/soc/common/include/socfpga_reset_manager.h b/plat/intel/soc/common/include/socfpga_reset_manager.h
new file mode 100644
index 0000000..3fbf242
--- /dev/null
+++ b/plat/intel/soc/common/include/socfpga_reset_manager.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOCFPGA_RESETMANAGER_H
+#define SOCFPGA_RESETMANAGER_H
+
+#define SOCFPGA_RSTMGR_STAT				0xffd11000
+#define SOCFPGA_RSTMGR_HDSKEN				0xffd11010
+#define SOCFPGA_RSTMGR_COLDMODRST			0xffd11034
+#define SOCFPGA_RSTMGR_HDSKTIMEOUT			0xffd11064
+
+#define SOCFPGA_RSTMGR_HDSKEN_SET			0x0000010D
+#define SOCFPGA_RSTMGR_SDMWARMRST			0x00000002
+
+#endif /* SOCFPGA_RESETMANAGER_H */
diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h
new file mode 100644
index 0000000..6bb41f3
--- /dev/null
+++ b/plat/intel/soc/common/include/socfpga_sip_svc.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOCFPGA_SIP_SVC_H
+#define SOCFPGA_SIP_SVC_H
+
+
+/* SiP status response */
+#define INTEL_SIP_SMC_STATUS_OK				0
+#define INTEL_SIP_SMC_STATUS_ERROR			0x4
+#define INTEL_SIP_SMC_STATUS_BUSY			0x1
+#define INTEL_SIP_SMC_STATUS_REJECTED			0x2
+
+/* SMC SiP service function identifier */
+#define INTEL_SIP_SMC_FPGA_CONFIG_START			0xC2000001
+#define INTEL_SIP_SMC_FPGA_CONFIG_WRITE			0x42000002
+#define INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE	0xC2000003
+#define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE		0xC2000004
+#define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM		0xC2000005
+#define INTEL_SIP_SMC_REG_READ				0xC2000007
+#define INTEL_SIP_SMC_REG_WRITE				0xC2000008
+#define INTEL_SIP_SMC_REG_UPDATE			0xC2000009
+#define INTEL_SIP_SMC_RSU_STATUS			0xC200000B
+#define INTEL_SIP_SMC_RSU_UPDATE			0xC200000C
+#define INTEL_SIP_LEGACY_SMC_ECC_DBE			0xC200000D
+#define INTEL_SIP_SMC_RSU_NOTIFY			0xC200000E
+#define INTEL_SIP_SMC_RSU_RETRY_COUNTER			0xC200000F
+
+/* FPGA config helpers */
+#define INTEL_SIP_SMC_FPGA_CONFIG_ADDR			0x400000
+#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE			16777216
+
+/* SMC function IDs for SiP Service queries */
+#define SIP_SVC_CALL_COUNT	0x8200ff00
+#define SIP_SVC_UID		0x8200ff01
+#define SIP_SVC_VERSION		0x8200ff03
+
+/* SiP Service Calls version numbers */
+#define SIP_SVC_VERSION_MAJOR	0
+#define SIP_SVC_VERSION_MINOR	1
+
+#endif /* SOCFPGA_SIP_SVC_H */
diff --git a/plat/intel/soc/agilex/soc/agilex_handoff.c b/plat/intel/soc/common/soc/socfpga_handoff.c
similarity index 89%
rename from plat/intel/soc/agilex/soc/agilex_handoff.c
rename to plat/intel/soc/common/soc/socfpga_handoff.c
index a458686..4bb3a96 100644
--- a/plat/intel/soc/agilex/soc/agilex_handoff.c
+++ b/plat/intel/soc/common/soc/socfpga_handoff.c
@@ -4,15 +4,14 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <platform_def.h>
 #include <string.h>
 
-#include "agilex_handoff.h"
+#include "socfpga_handoff.h"
 
 #define SWAP_UINT32(x) (((x) >> 24) | (((x) & 0x00FF0000) >> 8) |	\
 				(((x) & 0x0000FF00) << 8) | ((x) << 24))
 
-int agilex_get_handoff(handoff *reverse_hoff_ptr)
+int socfpga_get_handoff(handoff *reverse_hoff_ptr)
 {
 	int i;
 	uint32_t *buffer;
diff --git a/plat/intel/soc/agilex/soc/agilex_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c
similarity index 70%
rename from plat/intel/soc/agilex/soc/agilex_mailbox.c
rename to plat/intel/soc/common/soc/socfpga_mailbox.c
index ebfea61..eb35c4a 100644
--- a/plat/intel/soc/agilex/soc/agilex_mailbox.c
+++ b/plat/intel/soc/common/soc/socfpga_mailbox.c
@@ -6,8 +6,10 @@
 
 #include <lib/mmio.h>
 #include <common/debug.h>
+#include <drivers/delay_timer.h>
 
-#include "agilex_mailbox.h"
+#include "socfpga_mailbox.h"
+#include "socfpga_sip_svc.h"
 
 static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args,
 					int len)
@@ -17,12 +19,6 @@
 
 	cmd_free_offset = mmio_read_32(MBOX_OFFSET + MBOX_CIN);
 
-	if (cmd_free_offset >= MBOX_CMD_BUFFER_SIZE) {
-		INFO("Insufficient buffer in mailbox\n");
-		return MBOX_INSUFFICIENT_BUFFER;
-	}
-
-
 	mmio_write_32(MBOX_OFFSET + MBOX_CMD_BUFFER + (cmd_free_offset++ * 4),
 			header_cmd);
 
@@ -39,28 +35,21 @@
 	return 0;
 }
 
-int mailbox_read_response(int job_id, uint32_t *response)
+int mailbox_read_response(int job_id, uint32_t *response, int resp_len)
 {
 	int rin = 0;
 	int rout = 0;
 	int response_length = 0;
 	int resp = 0;
 	int total_resp_len = 0;
-	int timeout = 100000;
-
-	mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1);
 
-	while (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) != 1) {
-		if (timeout-- < 0)
-			return MBOX_NO_RESPONSE;
-	}
-
-	mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0);
+	if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM))
+		mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0);
 
 	rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
 	rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
 
-	while (rout != rin) {
+	if (rout != rin) {
 		resp = mmio_read_32(MBOX_OFFSET +
 				    MBOX_RESP_BUFFER + ((rout++)*4));
 
@@ -84,8 +73,9 @@
 			resp = mmio_read_32(MBOX_OFFSET +
 						MBOX_RESP_BUFFER +
 						(rout)*4);
-			if (response) {
+			if (response && resp_len) {
 				*(response + total_resp_len) = resp;
+				resp_len--;
 				total_resp_len++;
 			}
 			rout++;
@@ -99,25 +89,25 @@
 }
 
 
-int mailbox_poll_response(int job_id, int urgent, uint32_t *response)
+int mailbox_poll_response(int job_id, int urgent, uint32_t *response,
+				int resp_len)
 {
-	int timeout = 80000;
+	int timeout = 0xFFFFFF;
 	int rin = 0;
 	int rout = 0;
 	int response_length = 0;
 	int resp = 0;
 	int total_resp_len = 0;
 
-	mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1);
-
 	while (1) {
+
 		while (timeout > 0 &&
-			mmio_read_32(MBOX_OFFSET +
-				MBOX_DOORBELL_FROM_SDM) != 1) {
+			!(mmio_read_32(MBOX_OFFSET +
+				MBOX_DOORBELL_FROM_SDM) & 1)) {
 			timeout--;
 		}
 
-		if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) != 1) {
+		if (!timeout) {
 			INFO("Timed out waiting for SDM");
 			return MBOX_TIMEOUT;
 		}
@@ -125,6 +115,7 @@
 		mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0);
 
 		if (urgent & 1) {
+			mdelay(5);
 			if ((mmio_read_32(MBOX_OFFSET + MBOX_STATUS) &
 				MBOX_STATUS_UA_MASK) ^
 				(urgent & MBOX_STATUS_UA_MASK)) {
@@ -158,13 +149,13 @@
 			response_length = MBOX_RESP_LEN(resp);
 
 			while (response_length) {
-
 				response_length--;
 				resp = mmio_read_32(MBOX_OFFSET +
 							MBOX_RESP_BUFFER +
 							(rout)*4);
-				if (response) {
+				if (response && resp_len) {
 					*(response + total_resp_len) = resp;
+					resp_len--;
 					total_resp_len++;
 				}
 				rout++;
@@ -176,7 +167,7 @@
 	}
 }
 
-void mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args,
+int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args,
 			  int len, int urgent)
 {
 	if (urgent)
@@ -187,29 +178,44 @@
 					MBOX_CMD_LEN_CMD(len) |
 					MBOX_INDIRECT |
 					cmd, args, len);
+
+	mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1);
+
+	return 0;
 }
 
 int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args,
-			  int len, int urgent, uint32_t *response)
+			int len, int urgent, uint32_t *response, int resp_len)
 {
-	int status;
+	int status = 0;
 
 	if (urgent) {
 		urgent |= mmio_read_32(MBOX_OFFSET + MBOX_STATUS) &
 					MBOX_STATUS_UA_MASK;
 		mmio_write_32(MBOX_OFFSET + MBOX_URG, cmd);
-		status = 0;
-	} else {
+	}
+
+	else {
 		status = fill_mailbox_circular_buffer(
 			MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) |
 			MBOX_JOB_ID_CMD(job_id) |
+			MBOX_CMD_LEN_CMD(len) |
 			cmd, args, len);
 	}
 
 	if (status)
 		return status;
 
-	return mailbox_poll_response(job_id, urgent, response);
+	mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1);
+	status = mailbox_poll_response(job_id, urgent, response, resp_len);
+
+	return status;
+}
+
+void mailbox_clear_response(void)
+{
+	mmio_write_32(MBOX_OFFSET + MBOX_ROUT,
+		mmio_read_32(MBOX_OFFSET + MBOX_RIN));
 }
 
 void mailbox_set_int(int interrupt)
@@ -223,24 +229,25 @@
 void mailbox_set_qspi_open(void)
 {
 	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
-	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_OPEN, 0, 0, 0, 0);
+	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_OPEN, 0, 0, 0, NULL, 0);
 }
 
 void mailbox_set_qspi_direct(void)
 {
-	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, 0, 0, 0, 0);
+	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, 0, 0, 0, NULL, 0);
 }
 
 void mailbox_set_qspi_close(void)
 {
 	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
-	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_CLOSE, 0, 0, 0, 0);
+	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_CLOSE, 0, 0, 0, NULL, 0);
 }
 
 int mailbox_get_qspi_clock(void)
 {
 	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
-	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, 0, 0, 0, 0);
+	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, 0, 0, 0,
+				NULL, 0);
 }
 
 void mailbox_qspi_set_cs(int device_select)
@@ -251,13 +258,13 @@
 	cs_setting = (cs_setting << 28);
 	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
 	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_SET_CS, &cs_setting,
-		1, 0, 0);
+				1, 0, NULL, 0);
 }
 
 void mailbox_reset_cold(void)
 {
 	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
-	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, 0, 0, 0, 0);
+	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, 0, 0, 0, NULL, 0);
 }
 
 int mailbox_init(void)
@@ -268,13 +275,44 @@
 			MBOX_INT_FLAG_UAE);
 	mmio_write_32(MBOX_OFFSET + MBOX_URG, 0);
 	mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0);
-	status = mailbox_send_cmd(0, MBOX_CMD_RESTART, 0, 0, 1, 0);
+
+	status = mailbox_send_cmd(0, MBOX_CMD_RESTART, 0, 0, 1, NULL, 0);
 
 	if (status)
 		return status;
 
-	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
+	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE |
+			MBOX_INT_FLAG_UAE);
 
 	return 0;
 }
 
+uint32_t intel_mailbox_get_config_status(uint32_t cmd)
+{
+	uint32_t status, res;
+	uint32_t response[6];
+
+	status = mailbox_send_cmd(1, cmd, NULL, 0, 0, response,
+		sizeof(response) / sizeof(response[0]));
+
+	if (status < 0)
+		return status;
+
+	res = response[RECONFIG_STATUS_STATE];
+	if (res && res != MBOX_CFGSTAT_STATE_CONFIG)
+		return res;
+
+	res = response[RECONFIG_STATUS_PIN_STATUS];
+	if (!(res & PIN_STATUS_NSTATUS))
+		return MBOX_CFGSTAT_STATE_ERROR_HARDWARE;
+
+	res = response[RECONFIG_STATUS_SOFTFUNC_STATUS];
+	if (res & SOFTFUNC_STATUS_SEU_ERROR)
+		return MBOX_CFGSTAT_STATE_ERROR_HARDWARE;
+
+	if ((res & SOFTFUNC_STATUS_CONF_DONE) &&
+		(res & SOFTFUNC_STATUS_INIT_DONE))
+		return 0;
+
+	return MBOX_CFGSTAT_STATE_CONFIG;
+}
diff --git a/plat/intel/soc/common/socfpga_image_load.c b/plat/intel/soc/common/socfpga_image_load.c
index 67c02bc..a5c3279 100644
--- a/plat/intel/soc/common/socfpga_image_load.c
+++ b/plat/intel/soc/common/socfpga_image_load.c
@@ -28,5 +28,31 @@
  ******************************************************************************/
 bl_params_t *plat_get_next_bl_params(void)
 {
+	unsigned int count;
+	unsigned int img_id = 0U;
+	unsigned int link_index = 0U;
+	bl_params_node_t *bl_exec_node = NULL;
+	bl_mem_params_node_t *desc_ptr;
+
+	/* If there is no image to start with, return NULL */
+	if (bl_mem_params_desc_num == 0U)
+		return NULL;
+
+	/* Clean next_params_info in BL image node */
+	for (count = 0U; count < bl_mem_params_desc_num; count++) {
+
+		desc_ptr = &bl_mem_params_desc_ptr[link_index];
+		bl_exec_node = &desc_ptr->params_node_mem;
+		bl_exec_node->next_params_info = NULL;
+
+		/* If no next hand-off image then break out */
+		img_id = desc_ptr->next_handoff_image_id;
+		if (img_id == INVALID_IMAGE_ID)
+			break;
+
+		/* Get the index for the next hand-off image */
+		link_index = get_bl_params_node_index(img_id);
+	}
+
 	return get_next_bl_params_from_mem_params_desc();
 }
diff --git a/plat/intel/soc/agilex/socfpga_psci.c b/plat/intel/soc/common/socfpga_psci.c
similarity index 86%
rename from plat/intel/soc/agilex/socfpga_psci.c
rename to plat/intel/soc/common/socfpga_psci.c
index 12060ef..1ba48ea 100644
--- a/plat/intel/soc/agilex/socfpga_psci.c
+++ b/plat/intel/soc/common/socfpga_psci.c
@@ -11,14 +11,11 @@
 #include <lib/psci/psci.h>
 #include <plat/common/platform.h>
 
-#include "agilex_reset_manager.h"
-#include "agilex_mailbox.h"
+#include "socfpga_mailbox.h"
+#include "socfpga_plat_def.h"
+#include "socfpga_reset_manager.h"
 
-#define AGX_RSTMGR_OFST			0xffd11000
-#define AGX_RSTMGR_MPUMODRST_OFST	0x20
 
-uintptr_t *agilex_sec_entry = (uintptr_t *) PLAT_SEC_ENTRY;
-uintptr_t *cpuid_release = (uintptr_t *) PLAT_CPUID_RELEASE;
 
 /*******************************************************************************
  * plat handler called when a CPU is about to enter standby.
@@ -47,11 +44,10 @@
 	if (cpu_id == -1)
 		return PSCI_E_INTERN_FAIL;
 
-	*cpuid_release = cpu_id;
+	mmio_write_64(PLAT_CPUID_RELEASE, cpu_id);
 
 	/* release core reset */
-	mmio_setbits_32(AGX_RSTMGR_OFST + AGX_RSTMGR_MPUMODRST_OFST,
-		1 << cpu_id);
+	mmio_setbits_32(SOCFPGA_RSTMGR_MPUMODRST_OFST, 1 << cpu_id);
 	return PSCI_E_SUCCESS;
 }
 
@@ -80,9 +76,9 @@
 	for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
 		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
 			__func__, i, target_state->pwr_domain_state[i]);
+
 	/* assert core reset */
-	mmio_setbits_32(AGX_RSTMGR_OFST + AGX_RSTMGR_MPUMODRST_OFST,
-		1 << cpu_id);
+	mmio_setbits_32(SOCFPGA_RSTMGR_MPUMODRST_OFST, 1 << cpu_id);
 
 }
 
@@ -121,8 +117,7 @@
 			__func__, i, target_state->pwr_domain_state[i]);
 
 	/* release core reset */
-	mmio_clrbits_32(AGX_RSTMGR_OFST + AGX_RSTMGR_MPUMODRST_OFST,
-		1 << cpu_id);
+	mmio_clrbits_32(SOCFPGA_RSTMGR_MPUMODRST_OFST, 1 << cpu_id);
 }
 
 /*******************************************************************************
@@ -137,13 +132,35 @@
 
 static void __dead2 socfpga_system_reset(void)
 {
-	INFO("assert Peripheral from Reset\r\n");
-
-	deassert_peripheral_reset();
 	mailbox_reset_cold();
 
 	while (1)
 		wfi();
+}
+
+static int socfpga_system_reset2(int is_vendor, int reset_type,
+					u_register_t cookie)
+{
+	/* disable cpuif */
+	gicv2_cpuif_disable();
+
+	/* Store magic number */
+	mmio_write_32(L2_RESET_DONE_REG, L2_RESET_DONE_STATUS);
+
+	/* Increase timeout */
+	mmio_write_32(SOCFPGA_RSTMGR_HDSKTIMEOUT, 0xffffff);
+
+	/* Enable handshakes */
+	mmio_setbits_32(SOCFPGA_RSTMGR_HDSKEN, SOCFPGA_RSTMGR_HDSKEN_SET);
+
+	/* Reset L2 module */
+	mmio_setbits_32(SOCFPGA_RSTMGR_COLDMODRST, 0x100);
+
+	while (1)
+		wfi();
+
+	/* Should not reach here */
+	return 0;
 }
 
 int socfpga_validate_power_state(unsigned int power_state,
@@ -179,6 +196,7 @@
 	.pwr_domain_suspend_finish = socfpga_pwr_domain_suspend_finish,
 	.system_off = socfpga_system_off,
 	.system_reset = socfpga_system_reset,
+	.system_reset2 = socfpga_system_reset2,
 	.validate_power_state = socfpga_validate_power_state,
 	.validate_ns_entrypoint = socfpga_validate_ns_entrypoint,
 	.get_sys_suspend_power_state = socfpga_get_sys_suspend_power_state
@@ -191,8 +209,8 @@
 			const struct plat_psci_ops **psci_ops)
 {
 	/* Save warm boot entrypoint.*/
-	*agilex_sec_entry = sec_entrypoint;
-
+	mmio_write_64(PLAT_SEC_ENTRY, sec_entrypoint);
 	*psci_ops = &socfpga_psci_pm_ops;
+
 	return 0;
 }
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
new file mode 100644
index 0000000..ce88fb4
--- /dev/null
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -0,0 +1,450 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/mmio.h>
+#include <tools_share/uuid.h>
+
+#include "socfpga_mailbox.h"
+#include "socfpga_sip_svc.h"
+
+/* Number of SiP Calls implemented */
+#define SIP_NUM_CALLS		0x3
+
+/* Total buffer the driver can hold */
+#define FPGA_CONFIG_BUFFER_SIZE 4
+
+static int current_block;
+static int read_block;
+static int current_buffer;
+static int send_id;
+static int rcv_id;
+static int max_blocks;
+static uint32_t bytes_per_block;
+static uint32_t blocks_submitted;
+
+struct fpga_config_info {
+	uint32_t addr;
+	int size;
+	int size_written;
+	uint32_t write_requested;
+	int subblocks_sent;
+	int block_number;
+};
+
+/*  SiP Service UUID */
+DEFINE_SVC_UUID2(intl_svc_uid,
+		0xa85273b0, 0xe85a, 0x4862, 0xa6, 0x2a,
+		0xfa, 0x88, 0x88, 0x17, 0x68, 0x81);
+
+static uint64_t socfpga_sip_handler(uint32_t smc_fid,
+				   uint64_t x1,
+				   uint64_t x2,
+				   uint64_t x3,
+				   uint64_t x4,
+				   void *cookie,
+				   void *handle,
+				   uint64_t flags)
+{
+	ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
+	SMC_RET1(handle, SMC_UNK);
+}
+
+struct fpga_config_info fpga_config_buffers[FPGA_CONFIG_BUFFER_SIZE];
+
+static int intel_fpga_sdm_write_buffer(struct fpga_config_info *buffer)
+{
+	uint32_t args[3];
+
+	while (max_blocks > 0 && buffer->size > buffer->size_written) {
+		args[0] = (1<<8);
+		args[1] = buffer->addr + buffer->size_written;
+		if (buffer->size - buffer->size_written <= bytes_per_block) {
+			args[2] = buffer->size - buffer->size_written;
+			current_buffer++;
+			current_buffer %= FPGA_CONFIG_BUFFER_SIZE;
+		} else
+			args[2] = bytes_per_block;
+
+		buffer->size_written += args[2];
+		mailbox_send_cmd_async(
+			send_id++ % MBOX_MAX_JOB_ID,
+			MBOX_RECONFIG_DATA,
+			args, 3, 0);
+
+		buffer->subblocks_sent++;
+		max_blocks--;
+	}
+
+	return !max_blocks;
+}
+
+static int intel_fpga_sdm_write_all(void)
+{
+	for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++)
+		if (intel_fpga_sdm_write_buffer(
+			&fpga_config_buffers[current_buffer]))
+			break;
+	return 0;
+}
+
+static uint32_t intel_mailbox_fpga_config_isdone(void)
+{
+	uint32_t ret = intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS);
+
+	if (ret) {
+		if (ret == MBOX_CFGSTAT_STATE_CONFIG)
+			return INTEL_SIP_SMC_STATUS_BUSY;
+		else
+			return INTEL_SIP_SMC_STATUS_ERROR;
+	}
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
+static int mark_last_buffer_xfer_completed(uint32_t *buffer_addr_completed)
+{
+	int i;
+
+	for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
+		if (fpga_config_buffers[i].block_number == current_block) {
+			fpga_config_buffers[i].subblocks_sent--;
+			if (fpga_config_buffers[i].subblocks_sent == 0
+			&& fpga_config_buffers[i].size <=
+			fpga_config_buffers[i].size_written) {
+				fpga_config_buffers[i].write_requested = 0;
+				current_block++;
+				*buffer_addr_completed =
+					fpga_config_buffers[i].addr;
+				return 0;
+			}
+		}
+	}
+
+	return -1;
+}
+
+static int intel_fpga_config_completed_write(uint32_t *completed_addr,
+					uint32_t *count)
+{
+	uint32_t status = INTEL_SIP_SMC_STATUS_OK;
+	*count = 0;
+	int resp_len = 0;
+	uint32_t resp[5];
+	int all_completed = 1;
+
+	while (*count < 3) {
+
+		resp_len = mailbox_read_response(rcv_id % MBOX_MAX_JOB_ID,
+				resp, sizeof(resp) / sizeof(resp[0]));
+
+		if (resp_len < 0)
+			break;
+
+		max_blocks++;
+		rcv_id++;
+
+		if (mark_last_buffer_xfer_completed(
+			&completed_addr[*count]) == 0)
+			*count = *count + 1;
+		else
+			break;
+	}
+
+	if (*count <= 0) {
+		if (resp_len != MBOX_NO_RESPONSE &&
+			resp_len != MBOX_TIMEOUT && resp_len != 0) {
+			mailbox_clear_response();
+			return INTEL_SIP_SMC_STATUS_ERROR;
+		}
+
+		*count = 0;
+	}
+
+	intel_fpga_sdm_write_all();
+
+	if (*count > 0)
+		status = INTEL_SIP_SMC_STATUS_OK;
+	else if (*count == 0)
+		status = INTEL_SIP_SMC_STATUS_BUSY;
+
+	for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
+		if (fpga_config_buffers[i].write_requested != 0) {
+			all_completed = 0;
+			break;
+		}
+	}
+
+	if (all_completed == 1)
+		return INTEL_SIP_SMC_STATUS_OK;
+
+	return status;
+}
+
+static int intel_fpga_config_start(uint32_t config_type)
+{
+	uint32_t response[3];
+	int status = 0;
+
+	mailbox_clear_response();
+
+	mailbox_send_cmd(1, MBOX_CMD_CANCEL, 0, 0, 0, NULL, 0);
+
+	status = mailbox_send_cmd(1, MBOX_RECONFIG, 0, 0, 0,
+			response, sizeof(response) / sizeof(response[0]));
+
+	if (status < 0)
+		return status;
+
+	max_blocks = response[0];
+	bytes_per_block = response[1];
+
+	for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
+		fpga_config_buffers[i].size = 0;
+		fpga_config_buffers[i].size_written = 0;
+		fpga_config_buffers[i].addr = 0;
+		fpga_config_buffers[i].write_requested = 0;
+		fpga_config_buffers[i].block_number = 0;
+		fpga_config_buffers[i].subblocks_sent = 0;
+	}
+
+	blocks_submitted = 0;
+	current_block = 0;
+	read_block = 0;
+	current_buffer = 0;
+	send_id = 0;
+	rcv_id = 0;
+
+	return 0;
+}
+
+static bool is_fpga_config_buffer_full(void)
+{
+	for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++)
+		if (!fpga_config_buffers[i].write_requested)
+			return false;
+	return true;
+}
+
+static bool is_address_in_ddr_range(uint64_t addr)
+{
+	if (addr >= DRAM_BASE && addr <= DRAM_BASE + DRAM_SIZE)
+		return true;
+
+	return false;
+}
+
+static uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size)
+{
+	int i;
+
+	intel_fpga_sdm_write_all();
+
+	if (!is_address_in_ddr_range(mem) ||
+		!is_address_in_ddr_range(mem + size) ||
+		is_fpga_config_buffer_full())
+		return INTEL_SIP_SMC_STATUS_REJECTED;
+
+	for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
+		int j = (i + current_buffer) % FPGA_CONFIG_BUFFER_SIZE;
+
+		if (!fpga_config_buffers[j].write_requested) {
+			fpga_config_buffers[j].addr = mem;
+			fpga_config_buffers[j].size = size;
+			fpga_config_buffers[j].size_written = 0;
+			fpga_config_buffers[j].write_requested = 1;
+			fpga_config_buffers[j].block_number =
+				blocks_submitted++;
+			fpga_config_buffers[j].subblocks_sent = 0;
+			break;
+		}
+	}
+
+	if (is_fpga_config_buffer_full())
+		return INTEL_SIP_SMC_STATUS_BUSY;
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
+static int is_out_of_sec_range(uint64_t reg_addr)
+{
+	switch (reg_addr) {
+	case(0xF8011100):	/* ECCCTRL1 */
+	case(0xF8011104):	/* ECCCTRL2 */
+	case(0xF8011110):	/* ERRINTEN */
+	case(0xF8011114):	/* ERRINTENS */
+	case(0xF8011118):	/* ERRINTENR */
+	case(0xF801111C):	/* INTMODE */
+	case(0xF8011120):	/* INTSTAT */
+	case(0xF8011124):	/* DIAGINTTEST */
+	case(0xF801112C):	/* DERRADDRA */
+	case(0xFFD12028):	/* SDMMCGRP_CTRL */
+	case(0xFFD12044):	/* EMAC0 */
+	case(0xFFD12048):	/* EMAC1 */
+	case(0xFFD1204C):	/* EMAC2 */
+	case(0xFFD12090):	/* ECC_INT_MASK_VALUE */
+	case(0xFFD12094):	/* ECC_INT_MASK_SET */
+	case(0xFFD12098):	/* ECC_INT_MASK_CLEAR */
+	case(0xFFD1209C):	/* ECC_INTSTATUS_SERR */
+	case(0xFFD120A0):	/* ECC_INTSTATUS_DERR */
+	case(0xFFD120C0):	/* NOC_TIMEOUT */
+	case(0xFFD120C4):	/* NOC_IDLEREQ_SET */
+	case(0xFFD120C8):	/* NOC_IDLEREQ_CLR */
+	case(0xFFD120D0):	/* NOC_IDLEACK */
+	case(0xFFD120D4):	/* NOC_IDLESTATUS */
+	case(0xFFD12200):	/* BOOT_SCRATCH_COLD0 */
+	case(0xFFD12204):	/* BOOT_SCRATCH_COLD1 */
+	case(0xFFD12220):	/* BOOT_SCRATCH_COLD8 */
+	case(0xFFD12224):	/* BOOT_SCRATCH_COLD9 */
+		return 0;
+
+	default:
+		break;
+	}
+
+	return -1;
+}
+
+/* Secure register access */
+uint32_t intel_secure_reg_read(uint64_t reg_addr, uint32_t *retval)
+{
+	if (is_out_of_sec_range(reg_addr))
+		return INTEL_SIP_SMC_STATUS_ERROR;
+
+	*retval = mmio_read_32(reg_addr);
+
+	return INTEL_SIP_SMC_STATUS_OK;
+}
+
+uint32_t intel_secure_reg_write(uint64_t reg_addr, uint32_t val,
+				uint32_t *retval)
+{
+	if (is_out_of_sec_range(reg_addr))
+		return INTEL_SIP_SMC_STATUS_ERROR;
+
+	mmio_write_32(reg_addr, val);
+
+	return intel_secure_reg_read(reg_addr, retval);
+}
+
+uint32_t intel_secure_reg_update(uint64_t reg_addr, uint32_t mask,
+				 uint32_t val, uint32_t *retval)
+{
+	if (!intel_secure_reg_read(reg_addr, retval)) {
+		*retval &= ~mask;
+		*retval |= val;
+		return intel_secure_reg_write(reg_addr, *retval, retval);
+	}
+
+	return INTEL_SIP_SMC_STATUS_ERROR;
+}
+
+/*
+ * This function is responsible for handling all SiP calls from the NS world
+ */
+
+uintptr_t sip_smc_handler(uint32_t smc_fid,
+			 u_register_t x1,
+			 u_register_t x2,
+			 u_register_t x3,
+			 u_register_t x4,
+			 void *cookie,
+			 void *handle,
+			 u_register_t flags)
+{
+	uint32_t val = 0;
+	uint32_t status = INTEL_SIP_SMC_STATUS_OK;
+	uint32_t completed_addr[3];
+	uint32_t count = 0;
+
+	switch (smc_fid) {
+	case SIP_SVC_UID:
+		/* Return UID to the caller */
+		SMC_UUID_RET(handle, intl_svc_uid);
+
+	case INTEL_SIP_SMC_FPGA_CONFIG_ISDONE:
+		status = intel_mailbox_fpga_config_isdone();
+		SMC_RET4(handle, status, 0, 0, 0);
+
+	case INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM:
+		SMC_RET3(handle, INTEL_SIP_SMC_STATUS_OK,
+			INTEL_SIP_SMC_FPGA_CONFIG_ADDR,
+			INTEL_SIP_SMC_FPGA_CONFIG_SIZE -
+				INTEL_SIP_SMC_FPGA_CONFIG_ADDR);
+
+	case INTEL_SIP_SMC_FPGA_CONFIG_START:
+		status = intel_fpga_config_start(x1);
+		SMC_RET4(handle, status, 0, 0, 0);
+
+	case INTEL_SIP_SMC_FPGA_CONFIG_WRITE:
+		status = intel_fpga_config_write(x1, x2);
+		SMC_RET4(handle, status, 0, 0, 0);
+
+	case INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE:
+		status = intel_fpga_config_completed_write(completed_addr,
+								&count);
+		switch (count) {
+		case 1:
+			SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK,
+				completed_addr[0], 0, 0);
+
+		case 2:
+			SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK,
+				completed_addr[0],
+				completed_addr[1], 0);
+
+		case 3:
+			SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK,
+				completed_addr[0],
+				completed_addr[1],
+				completed_addr[2]);
+
+		case 0:
+			SMC_RET4(handle, status, 0, 0, 0);
+
+		default:
+			mailbox_clear_response();
+			SMC_RET1(handle, INTEL_SIP_SMC_STATUS_ERROR);
+		}
+
+	case INTEL_SIP_SMC_REG_READ:
+		status = intel_secure_reg_read(x1, &val);
+		SMC_RET3(handle, status, val, x1);
+
+	case INTEL_SIP_SMC_REG_WRITE:
+		status = intel_secure_reg_write(x1, (uint32_t)x2, &val);
+		SMC_RET3(handle, status, val, x1);
+
+	case INTEL_SIP_SMC_REG_UPDATE:
+		status = intel_secure_reg_update(x1, (uint32_t)x2,
+						 (uint32_t)x3, &val);
+		SMC_RET3(handle, status, val, x1);
+
+	default:
+		return socfpga_sip_handler(smc_fid, x1, x2, x3, x4,
+			cookie, handle, flags);
+	}
+}
+
+DECLARE_RT_SVC(
+	socfpga_sip_svc,
+	OEN_SIP_START,
+	OEN_SIP_END,
+	SMC_TYPE_FAST,
+	NULL,
+	sip_smc_handler
+);
+
+DECLARE_RT_SVC(
+	socfpga_sip_svc_std,
+	OEN_SIP_START,
+	OEN_SIP_END,
+	SMC_TYPE_YIELD,
+	NULL,
+	sip_smc_handler
+);
diff --git a/plat/intel/soc/agilex/socfpga_storage.c b/plat/intel/soc/common/socfpga_storage.c
similarity index 99%
rename from plat/intel/soc/agilex/socfpga_storage.c
rename to plat/intel/soc/common/socfpga_storage.c
index 76dd81f..a2f2c18 100644
--- a/plat/intel/soc/agilex/socfpga_storage.c
+++ b/plat/intel/soc/common/socfpga_storage.c
@@ -19,7 +19,7 @@
 #include <lib/mmio.h>
 #include <tools_share/firmware_image_package.h>
 
-#include "agilex_private.h"
+#include "socfpga_private.h"
 
 #define PLAT_FIP_BASE		(0)
 #define PLAT_FIP_MAX_SIZE	(0x1000000)
diff --git a/plat/intel/soc/stratix10/bl2_plat_setup.c b/plat/intel/soc/stratix10/bl2_plat_setup.c
index f24bbde..85a60d6 100644
--- a/plat/intel/soc/stratix10/bl2_plat_setup.c
+++ b/plat/intel/soc/stratix10/bl2_plat_setup.c
@@ -1,37 +1,29 @@
 /*
  * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <arch.h>
 #include <arch_helpers.h>
-#include <drivers/arm/gicv2.h>
-
-#include <drivers/generic_delay_timer.h>
-#include <drivers/console.h>
-#include <drivers/ti/uart/uart_16550.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <common/desc_image_load.h>
-#include <errno.h>
-#include <drivers/io/io_storage.h>
-#include <common/image_decompress.h>
-#include <plat/common/platform.h>
-#include <platform_def.h>
-#include <socfpga_private.h>
+#include <drivers/generic_delay_timer.h>
 #include <drivers/synopsys/dw_mmc.h>
-#include <lib/mmio.h>
+#include <drivers/ti/uart/uart_16550.h>
 #include <lib/xlat_tables/xlat_tables.h>
 
-#include "s10_memory_controller.h"
-#include "s10_reset_manager.h"
+#include "qspi/cadence_qspi.h"
+#include "socfpga_handoff.h"
+#include "socfpga_mailbox.h"
+#include "socfpga_private.h"
 #include "s10_clock_manager.h"
-#include "s10_handoff.h"
+#include "s10_memory_controller.h"
 #include "s10_pinmux.h"
-#include "stratix10_private.h"
-#include "include/s10_mailbox.h"
-#include "qspi/cadence_qspi.h"
+#include "s10_reset_manager.h"
+#include "s10_system_manager.h"
 #include "wdt/watchdog.h"
 
 
@@ -63,7 +55,7 @@
 
 	generic_delay_timer_init();
 
-	if (s10_get_handoff(&reverse_handoff_ptr))
+	if (socfpga_get_handoff(&reverse_handoff_ptr))
 		return;
 	config_pinmux(&reverse_handoff_ptr);
 	boot_source = reverse_handoff_ptr.boot_source;
@@ -115,7 +107,7 @@
 	switch (boot_source) {
 	case BOOT_SOURCE_SDMMC:
 		dw_mmc_init(&params, &info);
-		stratix10_io_setup(boot_source);
+		socfpga_io_setup(boot_source);
 		break;
 
 	case BOOT_SOURCE_QSPI:
@@ -124,7 +116,7 @@
 		cad_qspi_init(0, QSPI_CONFIG_CPHA, QSPI_CONFIG_CPOL,
 			QSPI_CONFIG_CSDA, QSPI_CONFIG_CSDADS,
 			QSPI_CONFIG_CSEOT, QSPI_CONFIG_CSSOT, 0);
-		stratix10_io_setup(boot_source);
+		socfpga_io_setup(boot_source);
 		break;
 
 	default:
diff --git a/plat/intel/soc/stratix10/bl31_plat_setup.c b/plat/intel/soc/stratix10/bl31_plat_setup.c
index 7c9833b..29bd176 100644
--- a/plat/intel/soc/stratix10/bl31_plat_setup.c
+++ b/plat/intel/soc/stratix10/bl31_plat_setup.c
@@ -1,29 +1,22 @@
 /*
  * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019, Intel Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <assert.h>
 #include <arch.h>
 #include <arch_helpers.h>
+#include <assert.h>
 #include <common/bl_common.h>
-#include <common/debug.h>
-#include <drivers/console.h>
-#include <drivers/delay_timer.h>
-#include <drivers/arm/gic_common.h>
 #include <drivers/arm/gicv2.h>
 #include <drivers/ti/uart/uart_16550.h>
-#include <drivers/generic_delay_timer.h>
-#include <drivers/arm/gicv2.h>
-#include <s10_mailbox.h>
 #include <lib/xlat_tables/xlat_tables.h>
 #include <lib/mmio.h>
 #include <plat/common/platform.h>
 #include <platform_def.h>
 
-#include "stratix10_private.h"
-#include "s10_handoff.h"
+#include "socfpga_private.h"
 #include "s10_reset_manager.h"
 #include "s10_memory_controller.h"
 #include "s10_pinmux.h"
@@ -60,37 +53,47 @@
 	void *from_bl2 = (void *) arg0;
 
 	bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
-
 	assert(params_from_bl2 != NULL);
-	assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
-	assert(params_from_bl2->h.version >= VERSION_2);
 
 	/*
 	 * Copy BL32 (if populated by BL31) and BL33 entry point information.
 	 * They are stored in Secure RAM, in BL31's address space.
 	 */
 
-	bl_params_node_t *bl_params = params_from_bl2->head;
+	if (params_from_bl2->h.type == PARAM_BL_PARAMS &&
+		params_from_bl2->h.version >= VERSION_2) {
 
-	while (bl_params) {
-		if (bl_params->image_id == BL33_IMAGE_ID)
-			bl33_image_ep_info = *bl_params->ep_info;
+		bl_params_node_t *bl_params = params_from_bl2->head;
 
-		bl_params = bl_params->next_params_info;
+		while (bl_params) {
+			if (bl_params->image_id == BL33_IMAGE_ID)
+				bl33_image_ep_info = *bl_params->ep_info;
+
+			bl_params = bl_params->next_params_info;
+		}
+	} else {
+		struct socfpga_bl31_params *arg_from_bl2 =
+			(struct socfpga_bl31_params *) from_bl2;
+
+		assert(arg_from_bl2->h.type == PARAM_BL31);
+		assert(arg_from_bl2->h.version >= VERSION_1);
+
+		bl32_image_ep_info = *arg_from_bl2->bl32_ep_info;
+		bl33_image_ep_info = *arg_from_bl2->bl33_ep_info;
 	}
 	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
 }
 
 static const interrupt_prop_t s10_interrupt_props[] = {
-	PLAT_INTEL_S10_G1S_IRQ_PROPS(GICV2_INTR_GROUP0),
-	PLAT_INTEL_S10_G0_IRQ_PROPS(GICV2_INTR_GROUP0)
+	PLAT_INTEL_SOCFPGA_G1S_IRQ_PROPS(GICV2_INTR_GROUP0),
+	PLAT_INTEL_SOCFPGA_G0_IRQ_PROPS(GICV2_INTR_GROUP0)
 };
 
 static unsigned int target_mask_array[PLATFORM_CORE_COUNT];
 
 static const gicv2_driver_data_t plat_gicv2_gic_data = {
-	.gicd_base = PLAT_INTEL_S10_GICD_BASE,
-	.gicc_base = PLAT_INTEL_S10_GICC_BASE,
+	.gicd_base = PLAT_INTEL_SOCFPGA_GICD_BASE,
+	.gicc_base = PLAT_INTEL_SOCFPGA_GICC_BASE,
 	.interrupt_props = s10_interrupt_props,
 	.interrupt_props_num = ARRAY_SIZE(s10_interrupt_props),
 	.target_masks = target_mask_array,
@@ -107,6 +110,10 @@
 	gicv2_distif_init();
 	gicv2_pcpu_distif_init();
 	gicv2_cpuif_enable();
+
+	/* Signal secondary CPUs to jump to BL31 (BL2 = U-boot SPL) */
+	mmio_write_64(PLAT_CPU_RELEASE_ADDR,
+		(uint64_t)plat_secondary_cpus_bl31_entry);
 }
 
 const mmap_region_t plat_stratix10_mmap[] = {
diff --git a/plat/intel/soc/stratix10/include/platform_def.h b/plat/intel/soc/stratix10/include/platform_def.h
deleted file mode 100644
index a753acd..0000000
--- a/plat/intel/soc/stratix10/include/platform_def.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
-
-#include <arch.h>
-#include <common/bl_common.h>
-#include <common/interrupt_props.h>
-#include <common/tbbr/tbbr_img_def.h>
-#include <drivers/arm/gic_common.h>
-#include <plat/common/common_def.h>
-
-
-#define PLAT_CPUID_RELEASE			0xffe1b000
-#define PLAT_SEC_ENTRY				0xffe1b008
-
-/* Define next boot image name and offset */
-#define PLAT_NS_IMAGE_OFFSET			0x50000
-#define PLAT_HANDOFF_OFFSET			0xFFE3F000
-
-/*******************************************************************************
- * Platform binary types for linking
- ******************************************************************************/
-#define PLATFORM_LINKER_FORMAT			"elf64-littleaarch64"
-#define PLATFORM_LINKER_ARCH			aarch64
-
-/* Stratix 10 supports up to 124GB RAM */
-#define PLAT_PHY_ADDR_SPACE_SIZE		(1ULL << 39)
-#define PLAT_VIRT_ADDR_SPACE_SIZE		(1ULL << 39)
-
-
-/*******************************************************************************
- * Generic platform constants
- ******************************************************************************/
-#define PLAT_PRIMARY_CPU			0
-#define PLAT_SECONDARY_ENTRY_BASE		0x01f78bf0
-
-/* Size of cacheable stacks */
-#define PLATFORM_STACK_SIZE			0x2000
-
-/* PSCI related constant */
-#define PLAT_NUM_POWER_DOMAINS		5
-#define PLAT_MAX_PWR_LVL		1
-#define PLAT_MAX_RET_STATE		1
-#define PLAT_MAX_OFF_STATE		2
-#define PLATFORM_SYSTEM_COUNT			1
-#define PLATFORM_CLUSTER_COUNT			1
-#define PLATFORM_CLUSTER0_CORE_COUNT		4
-#define PLATFORM_CLUSTER1_CORE_COUNT		0
-#define PLATFORM_CORE_COUNT		(PLATFORM_CLUSTER1_CORE_COUNT + \
-					PLATFORM_CLUSTER0_CORE_COUNT)
-#define PLATFORM_MAX_CPUS_PER_CLUSTER		4
-
-/* Interrupt related constant */
-
-#define INTEL_S10_IRQ_SEC_PHY_TIMER		29
-
-#define INTEL_S10_IRQ_SEC_SGI_0		8
-#define INTEL_S10_IRQ_SEC_SGI_1		9
-#define INTEL_S10_IRQ_SEC_SGI_2		10
-#define INTEL_S10_IRQ_SEC_SGI_3		11
-#define INTEL_S10_IRQ_SEC_SGI_4		12
-#define INTEL_S10_IRQ_SEC_SGI_5		13
-#define INTEL_S10_IRQ_SEC_SGI_6		14
-#define INTEL_S10_IRQ_SEC_SGI_7		15
-
-#define TSP_IRQ_SEC_PHY_TIMER		INTEL_S10_IRQ_SEC_PHY_TIMER
-#define TSP_SEC_MEM_BASE		BL32_BASE
-#define TSP_SEC_MEM_SIZE		(BL32_LIMIT - BL32_BASE + 1)
-/*******************************************************************************
- * Platform memory map related constants
- ******************************************************************************/
-#define DRAM_BASE				(0x0)
-#define DRAM_SIZE				(0x80000000)
-
-#define OCRAM_BASE				(0xFFE00000)
-#define OCRAM_SIZE				(0x00040000)
-
-#define MEM64_BASE				(0x0100000000)
-#define MEM64_SIZE				(0x1F00000000)
-
-#define DEVICE1_BASE				(0x80000000)
-#define DEVICE1_SIZE				(0x60000000)
-
-#define DEVICE2_BASE				(0xF7000000)
-#define DEVICE2_SIZE				(0x08E00000)
-
-#define DEVICE3_BASE				(0xFFFC0000)
-#define DEVICE3_SIZE				(0x00008000)
-
-#define DEVICE4_BASE				(0x2000000000)
-#define DEVICE4_SIZE				(0x0100000000)
-
-/*******************************************************************************
- * BL31 specific defines.
- ******************************************************************************/
-/*
- * Put BL3-1 at the top of the Trusted SRAM (just below the shared memory, if
- * present). BL31_BASE is calculated using the current BL3-1 debug size plus a
- * little space for growth.
- */
-
-
-#define FIRMWARE_WELCOME_STR		"Booting Trusted Firmware\n"
-
-#define BL1_RO_BASE	(0xffe00000)
-#define BL1_RO_LIMIT	(0xffe0f000)
-#define BL1_RW_BASE	(0xffe10000)
-#define BL1_RW_LIMIT	(0xffe1ffff)
-#define BL1_RW_SIZE	(0x14000)
-
-#define BL2_BASE	(0xffe00000)
-#define BL2_LIMIT	(0xffe1b000)
-
-#define BL31_BASE	(0xffe1c000)
-#define BL31_LIMIT	(0xffe3bfff)
-
-/*******************************************************************************
- * Platform specific page table and MMU setup constants
- ******************************************************************************/
-#define MAX_XLAT_TABLES			8
-#define MAX_MMAP_REGIONS		16
-
-/*******************************************************************************
- * Declarations and constants to access the mailboxes safely. Each mailbox is
- * aligned on the biggest cache line size in the platform. This is known only
- * to the platform as it might have a combination of integrated and external
- * caches. Such alignment ensures that two maiboxes do not sit on the same cache
- * line at any cache level. They could belong to different cpus/clusters &
- * get written while being protected by different locks causing corruption of
- * a valid mailbox address.
- ******************************************************************************/
-#define CACHE_WRITEBACK_SHIFT			6
-#define CACHE_WRITEBACK_GRANULE		(1 << CACHE_WRITEBACK_SHIFT)
-
-#define PLAT_GIC_BASE			(0xFFFC0000)
-#define PLAT_GICC_BASE			(PLAT_GIC_BASE + 0x2000)
-#define PLAT_GICD_BASE			(PLAT_GIC_BASE + 0x1000)
-#define PLAT_GICR_BASE			0
-
-/*******************************************************************************
- * UART related constants
- ******************************************************************************/
-#define PLAT_UART0_BASE		(0xFFC02000)
-#define PLAT_UART1_BASE		(0xFFC02100)
-
-#define CRASH_CONSOLE_BASE	PLAT_UART0_BASE
-
-#define PLAT_BAUDRATE			(115200)
-#define PLAT_UART_CLOCK		(100000000)
-
-/*******************************************************************************
- * System counter frequency related constants
- ******************************************************************************/
-#define PLAT_SYS_COUNTER_FREQ_IN_TICKS	(400000000)
-#define PLAT_SYS_COUNTER_FREQ_IN_MHZ	(400)
-
-#define PLAT_INTEL_S10_GICD_BASE	PLAT_GICD_BASE
-#define PLAT_INTEL_S10_GICC_BASE	PLAT_GICC_BASE
-
-/*
- * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
- * terminology. On a GICv2 system or mode, the lists will be merged and treated
- * as Group 0 interrupts.
- */
-#define PLAT_INTEL_S10_G1S_IRQ_PROPS(grp) \
-	INTR_PROP_DESC(INTEL_S10_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \
-			grp, GIC_INTR_CFG_LEVEL), \
-	INTR_PROP_DESC(INTEL_S10_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, grp, \
-			GIC_INTR_CFG_EDGE), \
-	INTR_PROP_DESC(INTEL_S10_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \
-			GIC_INTR_CFG_EDGE), \
-	INTR_PROP_DESC(INTEL_S10_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, grp, \
-			GIC_INTR_CFG_EDGE), \
-	INTR_PROP_DESC(INTEL_S10_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, grp, \
-			GIC_INTR_CFG_EDGE), \
-	INTR_PROP_DESC(INTEL_S10_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, grp, \
-			GIC_INTR_CFG_EDGE), \
-	INTR_PROP_DESC(INTEL_S10_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, grp, \
-			GIC_INTR_CFG_EDGE), \
-	INTR_PROP_DESC(INTEL_S10_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \
-			GIC_INTR_CFG_EDGE), \
-	INTR_PROP_DESC(INTEL_S10_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \
-			GIC_INTR_CFG_EDGE)
-
-#define PLAT_INTEL_S10_G0_IRQ_PROPS(grp)
-
-#define MAX_IO_HANDLES                   4
-#define MAX_IO_DEVICES                  4
-#define MAX_IO_BLOCK_DEVICES             2
-
-
-#endif /* __PLATFORM_DEF_H__ */
-
diff --git a/plat/intel/soc/stratix10/include/s10_clock_manager.h b/plat/intel/soc/stratix10/include/s10_clock_manager.h
index c800b9c..acc700a 100644
--- a/plat/intel/soc/stratix10/include/s10_clock_manager.h
+++ b/plat/intel/soc/stratix10/include/s10_clock_manager.h
@@ -7,7 +7,7 @@
 #ifndef __CLOCKMANAGER_H__
 #define __CLOCKMANAGER_H__
 
-#include "s10_handoff.h"
+#include "socfpga_handoff.h"
 
 #define ALT_CLKMGR				0xffd10000
 
diff --git a/plat/intel/soc/stratix10/include/s10_handoff.h b/plat/intel/soc/stratix10/include/s10_handoff.h
deleted file mode 100644
index 1cc8d09..0000000
--- a/plat/intel/soc/stratix10/include/s10_handoff.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef	_HANDOFF_H_
-#define	_HANDOFF_H_
-
-#define HANDOFF_MAGIC_HEADER	0x424f4f54	/* BOOT */
-#define HANDOFF_MAGIC_PINMUX_SEL	0x504d5558	/* PMUX */
-#define HANDOFF_MAGIC_IOCTLR	0x494f4354	/* IOCT */
-#define HANDOFF_MAGIC_FPGA		0x46504741	/* FPGA */
-#define HANDOFF_MAGIC_IODELAY	0x444c4159	/* DLAY */
-#define HANDOFF_MAGIC_CLOCK		0x434c4b53	/* CLKS */
-#define HANDOFF_MAGIC_MISC		0x4d495343	/* MISC */
-
-typedef struct handoff_t {
-	/* header */
-	uint32_t	header_magic;
-	uint32_t	header_device;
-	uint32_t	_pad_0x08_0x10[2];
-
-	/* pinmux configuration - select */
-	uint32_t	pinmux_sel_magic;
-	uint32_t	pinmux_sel_length;
-	uint32_t	_pad_0x18_0x20[2];
-	uint32_t	pinmux_sel_array[96];	/* offset, value */
-
-	/* pinmux configuration - io control */
-	uint32_t	pinmux_io_magic;
-	uint32_t	pinmux_io_length;
-	uint32_t	_pad_0x1a8_0x1b0[2];
-	uint32_t	pinmux_io_array[96];	/* offset, value */
-
-	/* pinmux configuration - use fpga switch */
-	uint32_t	pinmux_fpga_magic;
-	uint32_t	pinmux_fpga_length;
-	uint32_t	_pad_0x338_0x340[2];
-	uint32_t	pinmux_fpga_array[42];	/* offset, value */
-	uint32_t	_pad_0x3e8_0x3f0[2];
-
-	/* pinmux configuration - io delay */
-	uint32_t	pinmux_delay_magic;
-	uint32_t	pinmux_delay_length;
-	uint32_t	_pad_0x3f8_0x400[2];
-	uint32_t	pinmux_iodelay_array[96];	/* offset, value */
-
-	/* clock configuration */
-	uint32_t	clock_magic;
-	uint32_t	clock_length;
-	uint32_t	_pad_0x588_0x590[2];
-	uint32_t	main_pll_mpuclk;
-	uint32_t	main_pll_nocclk;
-	uint32_t	main_pll_cntr2clk;
-	uint32_t	main_pll_cntr3clk;
-	uint32_t	main_pll_cntr4clk;
-	uint32_t	main_pll_cntr5clk;
-	uint32_t	main_pll_cntr6clk;
-	uint32_t	main_pll_cntr7clk;
-	uint32_t	main_pll_cntr8clk;
-	uint32_t	main_pll_cntr9clk;
-	uint32_t	main_pll_nocdiv;
-	uint32_t	main_pll_pllglob;
-	uint32_t	main_pll_fdbck;
-	uint32_t	main_pll_pllc0;
-	uint32_t	main_pll_pllc1;
-	uint32_t	_pad_0x5cc_0x5d0[1];
-	uint32_t	per_pll_cntr2clk;
-	uint32_t	per_pll_cntr3clk;
-	uint32_t	per_pll_cntr4clk;
-	uint32_t	per_pll_cntr5clk;
-	uint32_t	per_pll_cntr6clk;
-	uint32_t	per_pll_cntr7clk;
-	uint32_t	per_pll_cntr8clk;
-	uint32_t	per_pll_cntr9clk;
-	uint32_t	per_pll_emacctl;
-	uint32_t	per_pll_gpiodiv;
-	uint32_t	per_pll_pllglob;
-	uint32_t	per_pll_fdbck;
-	uint32_t	per_pll_pllc0;
-	uint32_t	per_pll_pllc1;
-	uint32_t	hps_osc_clk_h;
-	uint32_t	fpga_clk_hz;
-
-	/* misc configuration */
-	uint32_t	misc_magic;
-	uint32_t	misc_length;
-	uint32_t	_pad_0x618_0x620[2];
-	uint32_t	boot_source;
-} handoff;
-
-int verify_handoff_image(handoff *hoff_ptr, handoff *reverse_hoff_ptr);
-int s10_get_handoff(handoff *hoff_ptr);
-
-#endif
-
-
diff --git a/plat/intel/soc/stratix10/include/s10_mailbox.h b/plat/intel/soc/stratix10/include/s10_mailbox.h
deleted file mode 100644
index 554c265..0000000
--- a/plat/intel/soc/stratix10/include/s10_mailbox.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef __S10_MBOX__
-#define __S10_MBOX__
-
-#define MBOX_OFFSET		0xffa30000
-
-#define MBOX_ATF_CLIENT_ID	0x1
-#define MBOX_JOB_ID		0x1
-
-/* Mailbox interrupt flags and masks */
-#define MBOX_INT_FLAG_COE	0x1
-#define MBOX_INT_FLAG_RIE	0x2
-#define MBOX_INT_FLAG_UAE	0x100
-#define MBOX_COE_BIT(INTERRUPT)	((INTERRUPT) & 0x3)
-#define MBOX_UAE_BIT(INTERRUPT)	(((INTERRUPT) & (1<<4)))
-
-/* Mailbox response and status */
-#define MBOX_RESP_BUFFER_SIZE	16
-#define MBOX_RESP_ERR(BUFFER)	((BUFFER) & 0x00000fff)
-#define MBOX_RESP_LEN(BUFFER)	(((BUFFER) & 0x007ff000) >> 12)
-#define MBOX_RESP_CLIENT_ID(BUFFER)	(((BUFFER) & 0xf0000000) >> 28)
-#define MBOX_RESP_JOB_ID(BUFFER)	(((BUFFER) & 0x0f000000) >> 24)
-#define MBOX_STATUS_UA_MASK	(1<<8)
-
-/* Mailbox command and response */
-#define MBOX_CMD_FREE_OFFSET	0x14
-#define MBOX_CMD_BUFFER_SIZE	32
-#define MBOX_CLIENT_ID_CMD(CLIENT_ID)	((CLIENT_ID) << 28)
-#define MBOX_JOB_ID_CMD(JOB_ID)	(JOB_ID<<24)
-#define MBOX_CMD_LEN_CMD(CMD_LEN)	((CMD_LEN) << 12)
-#define MBOX_INDIRECT			(1 << 11)
-#define MBOX_INSUFFICIENT_BUFFER	-2
-#define MBOX_CIN			0x00
-#define MBOX_ROUT			0x04
-#define MBOX_URG			0x08
-#define MBOX_INT			0x0C
-#define MBOX_COUT			0x20
-#define MBOX_RIN			0x24
-#define MBOX_STATUS			0x2C
-#define MBOX_CMD_BUFFER			0x40
-#define MBOX_RESP_BUFFER		0xC0
-
-#define MBOX_RESP_BUFFER_SIZE		16
-#define MBOX_RESP_OK			0
-#define MBOX_RESP_INVALID_CMD		1
-#define MBOX_RESP_UNKNOWN_BR		2
-#define MBOX_RESP_UNKNOWN		3
-#define MBOX_RESP_NOT_CONFIGURED	256
-
-/* Mailbox SDM doorbell */
-#define MBOX_DOORBELL_TO_SDM		0x400
-#define MBOX_DOORBELL_FROM_SDM		0x480
-
-/* Mailbox QSPI commands */
-#define MBOX_CMD_RESTART		2
-#define MBOX_CMD_QSPI_OPEN		50
-#define MBOX_CMD_QSPI_CLOSE		51
-#define MBOX_CMD_QSPI_DIRECT		59
-#define MBOX_CMD_GET_IDCODE		16
-#define MBOX_CMD_QSPI_SET_CS		52
-
-/* Mailbox REBOOT commands */
-#define MBOX_CMD_REBOOT_HPS		71
-
-/* Generic error handling */
-#define MBOX_TIMEOUT			-2047
-#define MBOX_NO_RESPONSE		-2
-#define MBOX_WRONG_ID			-3
-
-/* Mailbox status */
-#define RECONFIG_STATUS_STATE		0
-#define RECONFIG_STATUS_PIN_STATUS	2
-#define RECONFIG_STATUS_SOFTFUNC_STATUS 3
-#define PIN_STATUS_NSTATUS		(1U << 31)
-#define SOFTFUNC_STATUS_SEU_ERROR	(1 << 3)
-#define SOFTFUNC_STATUS_INIT_DONE	(1 << 1)
-#define SOFTFUNC_STATUS_CONF_DONE	(1 << 0)
-#define MBOX_CFGSTAT_STATE_CONFIG	0x10000000
-
-/* SMC function IDs for SiP Service queries */
-#define SIP_SVC_CALL_COUNT	0x8200ff00
-#define SIP_SVC_UID		0x8200ff01
-#define SIP_SVC_VERSION		0x8200ff03
-
-/* SiP Service Calls version numbers */
-#define SIP_SVC_VERSION_MAJOR	0
-#define SIP_SVC_VERSION_MINOR	1
-
-/* Mailbox reconfiguration commands */
-#define MBOX_RECONFIG		6
-#define MBOX_RECONFIG_DATA	8
-#define MBOX_RECONFIG_STATUS	9
-
-/* Sip get memory */
-#define INTEL_SIP_SMC_FPGA_CONFIG_START			0xC2000001
-#define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM		0xC2000005
-#define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE		0xC2000004
-#define INTEL_SIP_SMC_FPGA_CONFIG_WRITE			0x42000002
-#define INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE	0xC2000003
-#define INTEL_SIP_SMC_STATUS_OK				0
-#define INTEL_SIP_SMC_STATUS_ERROR			0x4
-#define INTEL_SIP_SMC_STATUS_BUSY			0x1
-#define INTEL_SIP_SMC_STATUS_REJECTED			0x2
-#define INTEL_SIP_SMC_FPGA_CONFIG_ADDR			0x1000
-#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE			16777216
-
-void mailbox_set_int(int interrupt_input);
-int mailbox_init(void);
-void mailbox_set_qspi_close(void);
-void mailbox_set_qspi_open(void);
-void mailbox_set_qspi_direct(void);
-int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args,
-				int len, int urgent, uint32_t *response);
-void mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args,
-				int len, int urgent);
-int mailbox_read_response(int job_id, uint32_t *response);
-int mailbox_get_qspi_clock(void);
-void mailbox_reset_cold(void);
-
-#endif
diff --git a/plat/intel/soc/stratix10/include/s10_pinmux.h b/plat/intel/soc/stratix10/include/s10_pinmux.h
index a1ba29e..82367d7 100644
--- a/plat/intel/soc/stratix10/include/s10_pinmux.h
+++ b/plat/intel/soc/stratix10/include/s10_pinmux.h
@@ -12,7 +12,7 @@
 #define S10_PINMUX_PINMUX_EMAC0_USEFPGA	0xffd13300
 #define S10_PINMUX_IO0_DELAY		0xffd13400
 
-#include "s10_handoff.h"
+#include "socfpga_handoff.h"
 
 void config_pinmux(handoff *handoff);
 
diff --git a/plat/intel/soc/stratix10/include/s10_system_manager.h b/plat/intel/soc/stratix10/include/s10_system_manager.h
index a67d689..4abfedb 100644
--- a/plat/intel/soc/stratix10/include/s10_system_manager.h
+++ b/plat/intel/soc/stratix10/include/s10_system_manager.h
@@ -69,5 +69,3 @@
 
 #define DISABLE_L4_FIREWALL	(BIT(0) | BIT(16) | BIT(24))
 
-void enable_nonsecure_access(void);
-
diff --git a/plat/intel/soc/stratix10/include/socfpga_plat_def.h b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
new file mode 100644
index 0000000..ab723f7
--- /dev/null
+++ b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_SOCFPGA_DEF_H
+#define PLAT_SOCFPGA_DEF_H
+
+#include <platform_def.h>
+
+/* Platform Setting */
+#define PLATFORM_MODEL		PLAT_SOCFPGA_STRATIX10
+
+/* Register Mapping */
+#define SOCFPGA_MMC_REG_BASE                    0xff808000
+
+#define SOCFPGA_RSTMGR_OFST                     0xffd11000
+#define SOCFPGA_RSTMGR_MPUMODRST_OFST           0xffd11020
+
+#endif /* PLATSOCFPGA_DEF_H */
+
diff --git a/plat/intel/soc/stratix10/include/stratix10_private.h b/plat/intel/soc/stratix10/include/stratix10_private.h
deleted file mode 100644
index 85aff3a..0000000
--- a/plat/intel/soc/stratix10/include/stratix10_private.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef __S10_PRIVATE_H__
-#define __S10_PRIVATE_H__
-
-#define S10_MMC_REG_BASE	0xff808000
-
-#define EMMC_DESC_SIZE		(1<<20)
-#define EMMC_INIT_PARAMS(base, clk)			\
-	{	.bus_width = MMC_BUS_WIDTH_4,	\
-		.clk_rate = (clk),		\
-		.desc_base = (base),		\
-		.desc_size = EMMC_DESC_SIZE,	\
-		.flags = 0,			\
-		.reg_base = S10_MMC_REG_BASE,	\
-		\
-	}
-
-typedef enum {
-	BOOT_SOURCE_FPGA = 0,
-	BOOT_SOURCE_SDMMC,
-	BOOT_SOURCE_NAND,
-	BOOT_SOURCE_RSVD,
-	BOOT_SOURCE_QSPI,
-} boot_source_type;
-
-void enable_nonsecure_access(void);
-void stratix10_io_setup(int boot_source);
-
-#endif
diff --git a/plat/intel/soc/stratix10/plat_psci.c b/plat/intel/soc/stratix10/plat_psci.c
deleted file mode 100644
index f4a970e..0000000
--- a/plat/intel/soc/stratix10/plat_psci.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch_helpers.h>
-#include <assert.h>
-#include <common/debug.h>
-#include <errno.h>
-#include <lib/mmio.h>
-#include <drivers/arm/gic_common.h>
-#include <drivers/arm/gicv2.h>
-#include <plat/common/platform.h>
-#include <lib/psci/psci.h>
-
-#include "platform_def.h"
-#include "s10_reset_manager.h"
-#include "s10_mailbox.h"
-
-#define S10_RSTMGR_OFST			0xffd11000
-#define S10_RSTMGR_MPUMODRST_OFST	0x20
-
-uintptr_t *stratix10_sec_entry = (uintptr_t *) PLAT_SEC_ENTRY;
-uintptr_t *cpuid_release = (uintptr_t *) PLAT_CPUID_RELEASE;
-
-/*******************************************************************************
- * plat handler called when a CPU is about to enter standby.
- ******************************************************************************/
-void plat_cpu_standby(plat_local_state_t cpu_state)
-{
-	/*
-	 * Enter standby state
-	 * dsb is good practice before using wfi to enter low power states
-	 */
-	VERBOSE("%s: cpu_state: 0x%x\n", __func__, cpu_state);
-	dsb();
-	wfi();
-}
-
-/*******************************************************************************
- * plat handler called when a power domain is about to be turned on. The
- * mpidr determines the CPU to be turned on.
- ******************************************************************************/
-int plat_pwr_domain_on(u_register_t mpidr)
-{
-	unsigned int cpu_id = plat_core_pos_by_mpidr(mpidr);
-
-	VERBOSE("%s: mpidr: 0x%lx\n", __func__, mpidr);
-
-	if (cpu_id == -1)
-		return PSCI_E_INTERN_FAIL;
-
-	*cpuid_release = cpu_id;
-
-	/* release core reset */
-	mmio_setbits_32(S10_RSTMGR_OFST + S10_RSTMGR_MPUMODRST_OFST,
-		1 << cpu_id);
-	return PSCI_E_SUCCESS;
-}
-
-/*******************************************************************************
- * plat handler called when a power domain is about to be turned off. The
- * target_state encodes the power state that each level should transition to.
- ******************************************************************************/
-void plat_pwr_domain_off(const psci_power_state_t *target_state)
-{
-	unsigned int cpu_id = plat_my_core_pos();
-
-	for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
-		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
-			__func__, i, target_state->pwr_domain_state[i]);
-
-	/* TODO: Prevent interrupts from spuriously waking up this cpu */
-	/* gicv2_cpuif_disable(); */
-
-	/* assert core reset */
-	mmio_setbits_32(S10_RSTMGR_OFST + S10_RSTMGR_MPUMODRST_OFST,
-		1 << cpu_id);
-}
-
-/*******************************************************************************
- * plat handler called when a power domain is about to be suspended. The
- * target_state encodes the power state that each level should transition to.
- ******************************************************************************/
-void plat_pwr_domain_suspend(const psci_power_state_t *target_state)
-{
-	unsigned int cpu_id = plat_my_core_pos();
-
-	for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
-		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
-			__func__, i, target_state->pwr_domain_state[i]);
-	/* assert core reset */
-	mmio_setbits_32(S10_RSTMGR_OFST + S10_RSTMGR_MPUMODRST_OFST,
-		1 << cpu_id);
-
-}
-
-/*******************************************************************************
- * plat handler called when a power domain has just been powered on after
- * being turned off earlier. The target_state encodes the low power state that
- * each level has woken up from.
- ******************************************************************************/
-void plat_pwr_domain_on_finish(const psci_power_state_t *target_state)
-{
-	for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
-		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
-			__func__, i, target_state->pwr_domain_state[i]);
-
-	/* Program the gic per-cpu distributor or re-distributor interface */
-	gicv2_pcpu_distif_init();
-	gicv2_set_pe_target_mask(plat_my_core_pos());
-
-	/* Enable the gic cpu interface */
-	gicv2_cpuif_enable();
-}
-
-/*******************************************************************************
- * plat handler called when a power domain has just been powered on after
- * having been suspended earlier. The target_state encodes the low power state
- * that each level has woken up from.
- * TODO: At the moment we reuse the on finisher and reinitialize the secure
- * context. Need to implement a separate suspend finisher.
- ******************************************************************************/
-void plat_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
-{
-	unsigned int cpu_id = plat_my_core_pos();
-
-	for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
-		VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
-			__func__, i, target_state->pwr_domain_state[i]);
-
-	/* release core reset */
-	mmio_clrbits_32(S10_RSTMGR_OFST + S10_RSTMGR_MPUMODRST_OFST,
-		1 << cpu_id);
-}
-
-/*******************************************************************************
- * plat handlers to shutdown/reboot the system
- ******************************************************************************/
-static void __dead2 plat_system_off(void)
-{
-	wfi();
-	ERROR("System Off: operation not handled.\n");
-	panic();
-}
-
-static void __dead2 plat_system_reset(void)
-{
-	INFO("assert Peripheral from Reset\r\n");
-
-	deassert_peripheral_reset();
-	mailbox_reset_cold();
-
-	while (1)
-		wfi();
-}
-
-int plat_validate_power_state(unsigned int power_state,
-				psci_power_state_t *req_state)
-{
-	VERBOSE("%s: power_state: 0x%x\n", __func__, power_state);
-
-	return PSCI_E_SUCCESS;
-}
-
-int plat_validate_ns_entrypoint(unsigned long ns_entrypoint)
-{
-	VERBOSE("%s: ns_entrypoint: 0x%lx\n", __func__, ns_entrypoint);
-	return PSCI_E_SUCCESS;
-}
-
-void plat_get_sys_suspend_power_state(psci_power_state_t *req_state)
-{
-	req_state->pwr_domain_state[PSCI_CPU_PWR_LVL] = PLAT_MAX_OFF_STATE;
-	req_state->pwr_domain_state[1] = PLAT_MAX_OFF_STATE;
-}
-
-/*******************************************************************************
- * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard
- * platform layer will take care of registering the handlers with PSCI.
- ******************************************************************************/
-const plat_psci_ops_t plat_psci_pm_ops = {
-	.cpu_standby = plat_cpu_standby,
-	.pwr_domain_on = plat_pwr_domain_on,
-	.pwr_domain_off = plat_pwr_domain_off,
-	.pwr_domain_suspend = plat_pwr_domain_suspend,
-	.pwr_domain_on_finish = plat_pwr_domain_on_finish,
-	.pwr_domain_suspend_finish = plat_pwr_domain_suspend_finish,
-	.system_off = plat_system_off,
-	.system_reset = plat_system_reset,
-	.validate_power_state = plat_validate_power_state,
-	.validate_ns_entrypoint = plat_validate_ns_entrypoint,
-	.get_sys_suspend_power_state = plat_get_sys_suspend_power_state
-};
-
-/*******************************************************************************
- * Export the platform specific power ops.
- ******************************************************************************/
-int plat_setup_psci_ops(uintptr_t sec_entrypoint,
-			const struct plat_psci_ops **psci_ops)
-{
-	/* Save warm boot entrypoint.*/
-	*stratix10_sec_entry = sec_entrypoint;
-
-	*psci_ops = &plat_psci_pm_ops;
-	return 0;
-}
diff --git a/plat/intel/soc/stratix10/plat_sip_svc.c b/plat/intel/soc/stratix10/plat_sip_svc.c
deleted file mode 100644
index 2c2332b..0000000
--- a/plat/intel/soc/stratix10/plat_sip_svc.c
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <common/debug.h>
-#include <common/runtime_svc.h>
-#include <lib/mmio.h>
-#include <s10_mailbox.h>
-#include <tools_share/uuid.h>
-
-/* Number of SiP Calls implemented */
-#define SIP_NUM_CALLS		0x3
-
-/* Total buffer the driver can hold */
-#define FPGA_CONFIG_BUFFER_SIZE 4
-
-int current_block;
-int current_buffer;
-int current_id = 1;
-int max_blocks;
-uint32_t bytes_per_block;
-uint32_t blocks_submitted;
-uint32_t blocks_completed;
-
-struct fpga_config_info {
-	uint32_t addr;
-	int size;
-	int size_written;
-	uint32_t write_requested;
-	int subblocks_sent;
-	int block_number;
-};
-
-/*  SiP Service UUID */
-DEFINE_SVC_UUID2(intl_svc_uid,
-		0xa85273b0, 0xe85a, 0x4862, 0xa6, 0x2a,
-		0xfa, 0x88, 0x88, 0x17, 0x68, 0x81);
-
-uint64_t plat_sip_handler(uint32_t smc_fid,
-				   uint64_t x1,
-				   uint64_t x2,
-				   uint64_t x3,
-				   uint64_t x4,
-				   void *cookie,
-				   void *handle,
-				   uint64_t flags)
-{
-	ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
-	SMC_RET1(handle, SMC_UNK);
-}
-
-struct fpga_config_info fpga_config_buffers[FPGA_CONFIG_BUFFER_SIZE];
-
-static void intel_fpga_sdm_write_buffer(struct fpga_config_info *buffer)
-{
-	uint32_t args[3];
-
-	while (max_blocks > 0 && buffer->size > buffer->size_written) {
-		if (buffer->size - buffer->size_written <=
-			bytes_per_block) {
-			args[0] = (1<<8);
-			args[1] = buffer->addr + buffer->size_written;
-			args[2] = buffer->size - buffer->size_written;
-			buffer->size_written +=
-				buffer->size - buffer->size_written;
-			buffer->subblocks_sent++;
-			mailbox_send_cmd_async(0x4,
-				MBOX_RECONFIG_DATA,
-				args, 3, 0);
-			current_buffer++;
-			current_buffer %= FPGA_CONFIG_BUFFER_SIZE;
-		} else {
-			args[0] = (1<<8);
-			args[1] = buffer->addr + buffer->size_written;
-			args[2] = bytes_per_block;
-			buffer->size_written += bytes_per_block;
-			mailbox_send_cmd_async(0x4,
-				MBOX_RECONFIG_DATA,
-				args, 3, 0);
-			buffer->subblocks_sent++;
-		}
-		max_blocks--;
-	}
-}
-
-static int intel_fpga_sdm_write_all(void)
-{
-	int i;
-
-	for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++)
-		intel_fpga_sdm_write_buffer(
-			&fpga_config_buffers[current_buffer]);
-
-	return 0;
-}
-
-uint32_t intel_mailbox_fpga_config_isdone(void)
-{
-	uint32_t args[2];
-	uint32_t response[6];
-	int status;
-
-	status = mailbox_send_cmd(1, MBOX_RECONFIG_STATUS, args, 0, 0,
-				response);
-
-	if (status < 0)
-		return INTEL_SIP_SMC_STATUS_ERROR;
-
-	if (response[RECONFIG_STATUS_STATE] &&
-		response[RECONFIG_STATUS_STATE] != MBOX_CFGSTAT_STATE_CONFIG)
-		return INTEL_SIP_SMC_STATUS_ERROR;
-
-	if (!(response[RECONFIG_STATUS_PIN_STATUS] & PIN_STATUS_NSTATUS))
-		return INTEL_SIP_SMC_STATUS_ERROR;
-
-	if (response[RECONFIG_STATUS_SOFTFUNC_STATUS] &
-		SOFTFUNC_STATUS_SEU_ERROR)
-		return INTEL_SIP_SMC_STATUS_ERROR;
-
-	if ((response[RECONFIG_STATUS_SOFTFUNC_STATUS] &
-		SOFTFUNC_STATUS_CONF_DONE) &&
-		(response[RECONFIG_STATUS_SOFTFUNC_STATUS] &
-		SOFTFUNC_STATUS_INIT_DONE))
-		return INTEL_SIP_SMC_STATUS_OK;
-
-	return INTEL_SIP_SMC_STATUS_ERROR;
-}
-
-static int mark_last_buffer_xfer_completed(uint32_t *buffer_addr_completed)
-{
-	int i;
-
-	for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
-		if (fpga_config_buffers[i].block_number == current_block) {
-			fpga_config_buffers[i].subblocks_sent--;
-			if (fpga_config_buffers[i].subblocks_sent == 0
-			&& fpga_config_buffers[i].size <=
-			fpga_config_buffers[i].size_written) {
-				fpga_config_buffers[i].write_requested = 0;
-				current_block++;
-				*buffer_addr_completed =
-					fpga_config_buffers[i].addr;
-				return 0;
-			}
-		}
-	}
-
-	return -1;
-}
-
-unsigned int address_in_ddr(uint32_t *addr)
-{
-	if (((unsigned long long)addr > DRAM_BASE) &&
-		((unsigned long long)addr < DRAM_BASE + DRAM_SIZE))
-		return 0;
-
-	return -1;
-}
-
-int intel_fpga_config_completed_write(uint32_t *completed_addr,
-					uint32_t *count)
-{
-	uint32_t status = INTEL_SIP_SMC_STATUS_OK;
-	*count = 0;
-	int resp_len = 0;
-	uint32_t resp[5];
-	int all_completed = 1;
-	int count_check = 0;
-
-	if (address_in_ddr(completed_addr) != 0 || address_in_ddr(count) != 0)
-		return INTEL_SIP_SMC_STATUS_ERROR;
-
-	for (count_check = 0; count_check < 3; count_check++)
-		if (address_in_ddr(&completed_addr[*count + count_check]) != 0)
-			return INTEL_SIP_SMC_STATUS_ERROR;
-
-	resp_len = mailbox_read_response(0x4, resp);
-
-	while (resp_len >= 0 && *count < 3) {
-		max_blocks++;
-		if (mark_last_buffer_xfer_completed(
-			&completed_addr[*count]) == 0)
-			*count = *count + 1;
-		else
-			break;
-		resp_len = mailbox_read_response(0x4, resp);
-	}
-
-	if (*count <= 0) {
-		if (resp_len != MBOX_NO_RESPONSE &&
-			resp_len != MBOX_TIMEOUT && resp_len != 0) {
-			return INTEL_SIP_SMC_STATUS_ERROR;
-		}
-
-		*count = 0;
-	}
-
-	intel_fpga_sdm_write_all();
-
-	if (*count > 0)
-		status = INTEL_SIP_SMC_STATUS_OK;
-	else if (*count == 0)
-		status = INTEL_SIP_SMC_STATUS_BUSY;
-
-	for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
-		if (fpga_config_buffers[i].write_requested != 0) {
-			all_completed = 0;
-			break;
-		}
-	}
-
-	if (all_completed == 1)
-		return INTEL_SIP_SMC_STATUS_OK;
-
-	return status;
-}
-
-int intel_fpga_config_start(uint32_t config_type)
-{
-	uint32_t response[3];
-	int status = 0;
-
-	status = mailbox_send_cmd(2, MBOX_RECONFIG, 0, 0, 0,
-			response);
-
-	if (status < 0)
-		return status;
-
-	max_blocks = response[0];
-	bytes_per_block = response[1];
-
-	for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
-		fpga_config_buffers[i].size = 0;
-		fpga_config_buffers[i].size_written = 0;
-		fpga_config_buffers[i].addr = 0;
-		fpga_config_buffers[i].write_requested = 0;
-		fpga_config_buffers[i].block_number = 0;
-		fpga_config_buffers[i].subblocks_sent = 0;
-	}
-
-	blocks_submitted = 0;
-	current_block = 0;
-	current_buffer = 0;
-
-	return 0;
-}
-
-
-uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size)
-{
-	int i = 0;
-	uint32_t status = INTEL_SIP_SMC_STATUS_OK;
-
-	if (mem < DRAM_BASE || mem > DRAM_BASE + DRAM_SIZE)
-		status = INTEL_SIP_SMC_STATUS_REJECTED;
-
-	if (mem + size > DRAM_BASE + DRAM_SIZE)
-		status = INTEL_SIP_SMC_STATUS_REJECTED;
-
-	for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
-		if (!fpga_config_buffers[i].write_requested) {
-			fpga_config_buffers[i].addr = mem;
-			fpga_config_buffers[i].size = size;
-			fpga_config_buffers[i].size_written = 0;
-			fpga_config_buffers[i].write_requested = 1;
-			fpga_config_buffers[i].block_number =
-				blocks_submitted++;
-			fpga_config_buffers[i].subblocks_sent = 0;
-			break;
-		}
-	}
-
-
-	if (i == FPGA_CONFIG_BUFFER_SIZE) {
-		status = INTEL_SIP_SMC_STATUS_REJECTED;
-		return status;
-	} else if (i == FPGA_CONFIG_BUFFER_SIZE - 1) {
-		status = INTEL_SIP_SMC_STATUS_BUSY;
-	}
-
-	intel_fpga_sdm_write_all();
-
-	return status;
-}
-
-/*
- * This function is responsible for handling all SiP calls from the NS world
- */
-
-uintptr_t sip_smc_handler(uint32_t smc_fid,
-			 u_register_t x1,
-			 u_register_t x2,
-			 u_register_t x3,
-			 u_register_t x4,
-			 void *cookie,
-			 void *handle,
-			 u_register_t flags)
-{
-	uint32_t status = INTEL_SIP_SMC_STATUS_OK;
-	uint32_t completed_addr[3];
-	uint32_t count = 0;
-
-	switch (smc_fid) {
-	case SIP_SVC_UID:
-		/* Return UID to the caller */
-		SMC_UUID_RET(handle, intl_svc_uid);
-		break;
-	case INTEL_SIP_SMC_FPGA_CONFIG_ISDONE:
-		status = intel_mailbox_fpga_config_isdone();
-		SMC_RET4(handle, status, 0, 0, 0);
-		break;
-	case INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM:
-		SMC_RET3(handle, INTEL_SIP_SMC_STATUS_OK,
-			INTEL_SIP_SMC_FPGA_CONFIG_ADDR,
-			INTEL_SIP_SMC_FPGA_CONFIG_SIZE -
-				INTEL_SIP_SMC_FPGA_CONFIG_ADDR);
-		break;
-	case INTEL_SIP_SMC_FPGA_CONFIG_START:
-		status = intel_fpga_config_start(x1);
-		SMC_RET4(handle, status, 0, 0, 0);
-		break;
-	case INTEL_SIP_SMC_FPGA_CONFIG_WRITE:
-		status = intel_fpga_config_write(x1, x2);
-		SMC_RET4(handle, status, 0, 0, 0);
-		break;
-	case INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE:
-		status = intel_fpga_config_completed_write(completed_addr,
-								&count);
-		switch (count) {
-		case 1:
-			SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK,
-				completed_addr[0], 0, 0);
-			break;
-		case 2:
-			SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK,
-				completed_addr[0],
-				completed_addr[1], 0);
-			break;
-		case 3:
-			SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK,
-				completed_addr[0],
-				completed_addr[1],
-				completed_addr[2]);
-			break;
-		case 0:
-			SMC_RET4(handle, status, 0, 0, 0);
-			break;
-		default:
-			SMC_RET1(handle, INTEL_SIP_SMC_STATUS_ERROR);
-		}
-		break;
-
-	default:
-		return plat_sip_handler(smc_fid, x1, x2, x3, x4,
-			cookie, handle, flags);
-	}
-}
-
-DECLARE_RT_SVC(
-	s10_sip_svc,
-	OEN_SIP_START,
-	OEN_SIP_END,
-	SMC_TYPE_FAST,
-	NULL,
-	sip_smc_handler
-);
-
-DECLARE_RT_SVC(
-	s10_sip_svc_std,
-	OEN_SIP_START,
-	OEN_SIP_END,
-	SMC_TYPE_YIELD,
-	NULL,
-	sip_smc_handler
-);
diff --git a/plat/intel/soc/stratix10/plat_storage.c b/plat/intel/soc/stratix10/plat_storage.c
deleted file mode 100644
index 0b8b9cd..0000000
--- a/plat/intel/soc/stratix10/plat_storage.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch_helpers.h>
-#include <assert.h>
-#include <common/debug.h>
-#include <drivers/mmc.h>
-#include <tools_share/firmware_image_package.h>
-#include <drivers/io/io_block.h>
-#include <drivers/io/io_driver.h>
-#include <drivers/io/io_fip.h>
-#include <drivers/io/io_memmap.h>
-#include <drivers/io/io_storage.h>
-#include <lib/mmio.h>
-#include <drivers/partition/partition.h>
-#include <lib/semihosting.h>
-#include <string.h>
-#include <lib/utils.h>
-#include <common/tbbr/tbbr_img_def.h>
-#include "platform_def.h"
-#include "stratix10_private.h"
-
-#define STRATIX10_FIP_BASE		(0)
-#define STRATIX10_FIP_MAX_SIZE		(0x1000000)
-#define STRATIX10_MMC_DATA_BASE		(0xffe3c000)
-#define STRATIX10_MMC_DATA_SIZE		(0x2000)
-#define STRATIX10_QSPI_DATA_BASE	(0x3C00000)
-#define STRATIX10_QSPI_DATA_SIZE	(0x1000000)
-
-
-static const io_dev_connector_t *fip_dev_con;
-static const io_dev_connector_t *boot_dev_con;
-
-static uintptr_t fip_dev_handle;
-static uintptr_t boot_dev_handle;
-
-static const io_uuid_spec_t bl2_uuid_spec = {
-	.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
-};
-
-static const io_uuid_spec_t bl31_uuid_spec = {
-	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
-};
-
-static const io_uuid_spec_t bl33_uuid_spec = {
-	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
-};
-
-uintptr_t a2_lba_offset;
-const char a2[] = {0xa2, 0x0};
-
-static const io_block_spec_t gpt_block_spec = {
-	.offset = 0,
-	.length = MMC_BLOCK_SIZE
-};
-
-static int check_fip(const uintptr_t spec);
-static int check_dev(const uintptr_t spec);
-
-static io_block_dev_spec_t boot_dev_spec;
-static int (*register_io_dev)(const io_dev_connector_t **);
-
-static io_block_spec_t fip_spec = {
-	.offset		= STRATIX10_FIP_BASE,
-	.length		= STRATIX10_FIP_MAX_SIZE,
-};
-
-struct plat_io_policy {
-	uintptr_t       *dev_handle;
-	uintptr_t       image_spec;
-	int             (*check)(const uintptr_t spec);
-};
-
-static const struct plat_io_policy policies[] = {
-	[FIP_IMAGE_ID] = {
-		&boot_dev_handle,
-		(uintptr_t)&fip_spec,
-		check_dev
-	},
-	[BL2_IMAGE_ID] = {
-	  &fip_dev_handle,
-	  (uintptr_t)&bl2_uuid_spec,
-	  check_fip
-	},
-	[BL31_IMAGE_ID] = {
-		&fip_dev_handle,
-		(uintptr_t)&bl31_uuid_spec,
-		check_fip
-	},
-	[BL33_IMAGE_ID] = {
-		&fip_dev_handle,
-		(uintptr_t) &bl33_uuid_spec,
-		check_fip
-	},
-	[GPT_IMAGE_ID] = {
-		&boot_dev_handle,
-		(uintptr_t) &gpt_block_spec,
-		check_dev
-	},
-};
-
-static int check_dev(const uintptr_t spec)
-{
-	int result;
-	uintptr_t local_handle;
-
-	result = io_dev_init(boot_dev_handle, (uintptr_t)NULL);
-	if (result == 0) {
-		result = io_open(boot_dev_handle, spec, &local_handle);
-		if (result == 0)
-			io_close(local_handle);
-	}
-	return result;
-}
-
-static int check_fip(const uintptr_t spec)
-{
-	int result;
-	uintptr_t local_image_handle;
-
-	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
-	if (result == 0) {
-		result = io_open(fip_dev_handle, spec, &local_image_handle);
-		if (result == 0)
-			io_close(local_image_handle);
-	}
-	return result;
-}
-
-void stratix10_io_setup(int boot_source)
-{
-	int result;
-
-	switch (boot_source) {
-	case BOOT_SOURCE_SDMMC:
-		register_io_dev = &register_io_dev_block;
-		boot_dev_spec.buffer.offset	= STRATIX10_MMC_DATA_BASE;
-		boot_dev_spec.buffer.length	= MMC_BLOCK_SIZE;
-		boot_dev_spec.ops.read		= mmc_read_blocks;
-		boot_dev_spec.ops.write		= mmc_write_blocks;
-		boot_dev_spec.block_size	= MMC_BLOCK_SIZE;
-		break;
-
-	case BOOT_SOURCE_QSPI:
-		register_io_dev = &register_io_dev_memmap;
-		fip_spec.offset = fip_spec.offset + STRATIX10_QSPI_DATA_BASE;
-		break;
-
-	default:
-		ERROR("Unsupported boot source\n");
-		panic();
-		break;
-	}
-
-	result = (*register_io_dev)(&boot_dev_con);
-	assert(result == 0);
-
-	result = register_io_dev_fip(&fip_dev_con);
-	assert(result == 0);
-
-	result = io_dev_open(boot_dev_con, (uintptr_t)&boot_dev_spec,
-			&boot_dev_handle);
-	assert(result == 0);
-
-	result = io_dev_open(fip_dev_con, (uintptr_t)NULL, &fip_dev_handle);
-	assert(result == 0);
-
-	if (boot_source == BOOT_SOURCE_SDMMC) {
-		partition_init(GPT_IMAGE_ID);
-		fip_spec.offset = get_partition_entry(a2)->start;
-	}
-
-	(void)result;
-}
-
-int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
-			uintptr_t *image_spec)
-{
-	int result;
-	const struct plat_io_policy *policy;
-
-	assert(image_id < ARRAY_SIZE(policies));
-
-	policy = &policies[image_id];
-	result = policy->check(policy->image_spec);
-	assert(result == 0);
-
-	*image_spec = policy->image_spec;
-	*dev_handle = *(policy->dev_handle);
-
-	return result;
-}
diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk
index 34674b0..e7251c4 100644
--- a/plat/intel/soc/stratix10/platform.mk
+++ b/plat/intel/soc/stratix10/platform.mk
@@ -1,5 +1,6 @@
 #
 # Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2019, Intel Corporation. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -10,61 +11,54 @@
 			-Iplat/intel/soc/common/include/
 
 PLAT_BL_COMMON_SOURCES	:=	\
-			lib/xlat_tables/xlat_tables_common.c 		\
-			lib/xlat_tables/aarch64/xlat_tables.c 		\
 			drivers/arm/gic/common/gic_common.c		\
 			drivers/arm/gic/v2/gicv2_main.c			\
 			drivers/arm/gic/v2/gicv2_helpers.c		\
-			plat/common/plat_gicv2.c			\
 			drivers/delay_timer/delay_timer.c		\
 			drivers/delay_timer/generic_delay_timer.c  	\
 			drivers/ti/uart/aarch64/16550_console.S		\
+			lib/xlat_tables/aarch64/xlat_tables.c 		\
+			lib/xlat_tables/xlat_tables_common.c 		\
+			plat/common/plat_gicv2.c			\
 			plat/intel/soc/common/aarch64/platform_common.c \
 			plat/intel/soc/common/aarch64/plat_helpers.S
 
 BL2_SOURCES     +=	\
-		drivers/partition/partition.c				\
-		drivers/partition/gpt.c					\
-		drivers/arm/pl061/pl061_gpio.c				\
+		common/desc_image_load.c				\
 		drivers/mmc/mmc.c					\
-		drivers/synopsys/emmc/dw_mmc.c				\
+		drivers/intel/soc/stratix10/io/s10_memmap_qspi.c	\
 		drivers/io/io_storage.c					\
 		drivers/io/io_block.c					\
 		drivers/io/io_fip.c					\
-		drivers/gpio/gpio.c					\
-		drivers/intel/soc/stratix10/io/s10_memmap_qspi.c	\
+		drivers/partition/partition.c				\
+		drivers/partition/gpt.c					\
+		drivers/synopsys/emmc/dw_mmc.c				\
+		lib/cpus/aarch64/cortex_a53.S				\
 		plat/intel/soc/stratix10/bl2_plat_setup.c		\
-		plat/intel/soc/stratix10/plat_storage.c			\
-                plat/intel/soc/common/bl2_plat_mem_params_desc.c	\
-		plat/intel/soc/stratix10/soc/s10_reset_manager.c	\
-		plat/intel/soc/stratix10/soc/s10_handoff.c		\
 		plat/intel/soc/stratix10/soc/s10_clock_manager.c	\
-		plat/intel/soc/stratix10/soc/s10_pinmux.c		\
 		plat/intel/soc/stratix10/soc/s10_memory_controller.c	\
+		plat/intel/soc/stratix10/soc/s10_pinmux.c		\
+		plat/intel/soc/stratix10/soc/s10_reset_manager.c	\
+		plat/intel/soc/stratix10/soc/s10_system_manager.c	\
+                plat/intel/soc/common/bl2_plat_mem_params_desc.c	\
 		plat/intel/soc/common/socfpga_delay_timer.c		\
-		lib/cpus/aarch64/cortex_a53.S				\
 		plat/intel/soc/common/socfpga_image_load.c		\
-		plat/intel/soc/stratix10/soc/s10_system_manager.c	\
-		common/desc_image_load.c				\
-		plat/intel/soc/stratix10/soc/s10_mailbox.c		\
+		plat/intel/soc/common/socfpga_storage.c			\
+		plat/intel/soc/common/soc/socfpga_handoff.c		\
+		plat/intel/soc/common/soc/socfpga_mailbox.c		\
 		plat/intel/soc/common/drivers/qspi/cadence_qspi.c	\
 		plat/intel/soc/common/drivers/wdt/watchdog.c
 
-BL31_SOURCES	+=	drivers/arm/cci/cci.c				\
+BL31_SOURCES	+=	\
+		drivers/arm/cci/cci.c					\
+		lib/cpus/aarch64/aem_generic.S				\
 		lib/cpus/aarch64/cortex_a53.S				\
-			lib/cpus/aarch64/aem_generic.S			\
-			lib/cpus/aarch64/cortex_a53.S			\
-			plat/common/plat_psci_common.c			\
-			plat/intel/soc/stratix10/plat_sip_svc.c		\
-			plat/intel/soc/stratix10/bl31_plat_setup.c 	\
-			plat/intel/soc/stratix10/plat_psci.c		\
-			plat/intel/soc/common/socfpga_topology.c	\
-			plat/intel/soc/common/socfpga_delay_timer.c	\
-			plat/intel/soc/stratix10/soc/s10_reset_manager.c\
-			plat/intel/soc/stratix10/soc/s10_pinmux.c	\
-			plat/intel/soc/stratix10/soc/s10_clock_manager.c\
-			plat/intel/soc/stratix10/soc/s10_handoff.c	\
-			plat/intel/soc/stratix10/soc/s10_mailbox.c
+		plat/common/plat_psci_common.c				\
+		plat/intel/soc/stratix10/bl31_plat_setup.c	 	\
+		plat/intel/soc/common/socfpga_psci.c			\
+		plat/intel/soc/common/socfpga_sip_svc.c			\
+		plat/intel/soc/common/socfpga_topology.c		\
+		plat/intel/soc/common/soc/socfpga_mailbox.c		\
 
 PROGRAMMABLE_RESET_ADDRESS	:= 0
 BL2_AT_EL3			:= 1
diff --git a/plat/intel/soc/stratix10/soc/s10_clock_manager.c b/plat/intel/soc/stratix10/soc/s10_clock_manager.c
index ed65c2b..e4ff7ac 100644
--- a/plat/intel/soc/stratix10/soc/s10_clock_manager.c
+++ b/plat/intel/soc/stratix10/soc/s10_clock_manager.c
@@ -12,8 +12,8 @@
 #include <platform_def.h>
 
 #include "s10_clock_manager.h"
-#include "s10_handoff.h"
 #include "s10_system_manager.h"
+#include "socfpga_handoff.h"
 
 
 void wait_pll_lock(void)
diff --git a/plat/intel/soc/stratix10/soc/s10_handoff.c b/plat/intel/soc/stratix10/soc/s10_handoff.c
deleted file mode 100644
index 1a4d5c3..0000000
--- a/plat/intel/soc/stratix10/soc/s10_handoff.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <arch_helpers.h>
-#include <drivers/arm/gicv2.h>
-#include <assert.h>
-#include <common/bl_common.h>
-#include <lib/mmio.h>
-#include <string.h>
-#include <plat/common/platform.h>
-#include <platform_def.h>
-
-#include "s10_handoff.h"
-
-#define SWAP_UINT32(x) (((x) >> 24) | (((x) & 0x00FF0000) >> 8) |	\
-				(((x) & 0x0000FF00) << 8) | ((x) << 24))
-
-int s10_get_handoff(handoff *reverse_hoff_ptr)
-{
-	int i;
-	uint32_t *buffer;
-	handoff *handoff_ptr = (handoff *) PLAT_HANDOFF_OFFSET;
-
-	memcpy(reverse_hoff_ptr, handoff_ptr, sizeof(handoff));
-	buffer = (uint32_t *)reverse_hoff_ptr;
-
-	/* convert big indian to little indian */
-	for (i = 0; i < sizeof(handoff) / 4; i++)
-		buffer[i] = SWAP_UINT32(buffer[i]);
-
-	if (reverse_hoff_ptr->header_magic != HANDOFF_MAGIC_HEADER)
-		return -1;
-	if (reverse_hoff_ptr->pinmux_sel_magic != HANDOFF_MAGIC_PINMUX_SEL)
-		return -1;
-	if (reverse_hoff_ptr->pinmux_io_magic != HANDOFF_MAGIC_IOCTLR)
-		return -1;
-	if (reverse_hoff_ptr->pinmux_fpga_magic != HANDOFF_MAGIC_FPGA)
-		return -1;
-	if (reverse_hoff_ptr->pinmux_delay_magic != HANDOFF_MAGIC_IODELAY)
-		return -1;
-
-	return 0;
-}
diff --git a/plat/intel/soc/stratix10/soc/s10_mailbox.c b/plat/intel/soc/stratix10/soc/s10_mailbox.c
deleted file mode 100644
index 00a07f3..0000000
--- a/plat/intel/soc/stratix10/soc/s10_mailbox.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <lib/mmio.h>
-#include <common/debug.h>
-#include "s10_mailbox.h"
-
-static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args,
-					int len)
-{
-	uint32_t cmd_free_offset;
-	int i;
-
-	cmd_free_offset = mmio_read_32(MBOX_OFFSET + MBOX_CIN);
-
-	if (cmd_free_offset >= MBOX_CMD_BUFFER_SIZE) {
-		INFO("Insufficient buffer in mailbox\n");
-		return MBOX_INSUFFICIENT_BUFFER;
-	}
-
-
-	mmio_write_32(MBOX_OFFSET + MBOX_CMD_BUFFER + (cmd_free_offset++ * 4),
-			header_cmd);
-
-
-	for (i = 0; i < len; i++) {
-		cmd_free_offset %= MBOX_CMD_BUFFER_SIZE;
-		mmio_write_32(MBOX_OFFSET + MBOX_CMD_BUFFER +
-				(cmd_free_offset++ * 4), args[i]);
-	}
-
-	cmd_free_offset %= MBOX_CMD_BUFFER_SIZE;
-	mmio_write_32(MBOX_OFFSET + MBOX_CIN, cmd_free_offset);
-
-	return 0;
-}
-
-int mailbox_read_response(int job_id, uint32_t *response)
-{
-	int rin = 0;
-	int rout = 0;
-	int response_length = 0;
-	int resp = 0;
-	int total_resp_len = 0;
-	int timeout = 100000;
-
-	mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1);
-
-	while (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) != 1) {
-		if (timeout-- < 0)
-			return MBOX_NO_RESPONSE;
-	}
-
-	mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0);
-
-	rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
-	rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
-
-	while (rout != rin) {
-		resp = mmio_read_32(MBOX_OFFSET +
-				    MBOX_RESP_BUFFER + ((rout++)*4));
-
-		rout %= MBOX_RESP_BUFFER_SIZE;
-		mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
-
-		if (MBOX_RESP_CLIENT_ID(resp) != MBOX_ATF_CLIENT_ID ||
-		   MBOX_RESP_JOB_ID(resp) != job_id) {
-			return MBOX_WRONG_ID;
-		}
-
-		if (MBOX_RESP_ERR(resp) > 0) {
-			INFO("Error in response: %x\n", resp);
-			return -resp;
-		}
-		response_length = MBOX_RESP_LEN(resp);
-
-		while (response_length) {
-
-			response_length--;
-			resp = mmio_read_32(MBOX_OFFSET +
-						MBOX_RESP_BUFFER +
-						(rout)*4);
-			if (response) {
-				*(response + total_resp_len) = resp;
-				total_resp_len++;
-			}
-			rout++;
-			rout %= MBOX_RESP_BUFFER_SIZE;
-			mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
-		}
-		return total_resp_len;
-	}
-
-	return MBOX_NO_RESPONSE;
-}
-
-
-int mailbox_poll_response(int job_id, int urgent, uint32_t *response)
-{
-	int timeout = 80000;
-	int rin = 0;
-	int rout = 0;
-	int response_length = 0;
-	int resp = 0;
-	int total_resp_len = 0;
-
-	mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1);
-
-	while (1) {
-		while (timeout > 0 &&
-			mmio_read_32(MBOX_OFFSET +
-				MBOX_DOORBELL_FROM_SDM) != 1) {
-			timeout--;
-		}
-
-		if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) != 1) {
-			INFO("Timed out waiting for SDM");
-			return MBOX_TIMEOUT;
-		}
-
-		mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0);
-
-		if (urgent & 1) {
-			if ((mmio_read_32(MBOX_OFFSET + MBOX_STATUS) &
-				MBOX_STATUS_UA_MASK) ^
-				(urgent & MBOX_STATUS_UA_MASK)) {
-				mmio_write_32(MBOX_OFFSET + MBOX_URG, 0);
-				return 0;
-			}
-
-			mmio_write_32(MBOX_OFFSET + MBOX_URG, 0);
-			INFO("Error: Mailbox did not get UA");
-			return -1;
-		}
-
-		rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
-		rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
-
-		while (rout != rin) {
-			resp = mmio_read_32(MBOX_OFFSET +
-					    MBOX_RESP_BUFFER + ((rout++)*4));
-
-			rout %= MBOX_RESP_BUFFER_SIZE;
-			mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
-
-			if (MBOX_RESP_CLIENT_ID(resp) != MBOX_ATF_CLIENT_ID ||
-			   MBOX_RESP_JOB_ID(resp) != job_id)
-				continue;
-
-			if (MBOX_RESP_ERR(resp) > 0) {
-				INFO("Error in response: %x\n", resp);
-				return -MBOX_RESP_ERR(resp);
-			}
-			response_length = MBOX_RESP_LEN(resp);
-
-			while (response_length) {
-
-				response_length--;
-				resp = mmio_read_32(MBOX_OFFSET +
-							MBOX_RESP_BUFFER +
-							(rout)*4);
-				if (response) {
-					*(response + total_resp_len) = resp;
-					total_resp_len++;
-				}
-				rout++;
-				rout %= MBOX_RESP_BUFFER_SIZE;
-				mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
-			}
-			return total_resp_len;
-		}
-	}
-}
-
-void mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args,
-			  int len, int urgent)
-{
-	if (urgent)
-		mmio_write_32(MBOX_OFFSET + MBOX_URG, 1);
-
-	fill_mailbox_circular_buffer(MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) |
-					MBOX_JOB_ID_CMD(job_id) |
-					MBOX_CMD_LEN_CMD(len) |
-					MBOX_INDIRECT |
-					cmd, args, len);
-}
-
-int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args,
-			  int len, int urgent, uint32_t *response)
-{
-	int status;
-
-	if (urgent) {
-		urgent |= mmio_read_32(MBOX_OFFSET + MBOX_STATUS) &
-					MBOX_STATUS_UA_MASK;
-		mmio_write_32(MBOX_OFFSET + MBOX_URG, 1);
-	}
-
-	status = fill_mailbox_circular_buffer(
-			MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) |
-			MBOX_JOB_ID_CMD(job_id) |
-			cmd, args, len);
-
-	if (status)
-		return status;
-
-	return mailbox_poll_response(job_id, urgent, response);
-}
-
-void mailbox_set_int(int interrupt)
-{
-
-	mmio_write_32(MBOX_OFFSET+MBOX_INT, MBOX_COE_BIT(interrupt) |
-			MBOX_UAE_BIT(interrupt));
-}
-
-
-void mailbox_set_qspi_open(void)
-{
-	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
-	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_OPEN, 0, 0, 0, 0);
-}
-
-void mailbox_set_qspi_direct(void)
-{
-	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, 0, 0, 0, 0);
-}
-
-void mailbox_set_qspi_close(void)
-{
-	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
-	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_CLOSE, 0, 0, 0, 0);
-}
-
-int mailbox_get_qspi_clock(void)
-{
-	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
-	return mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, 0, 0, 0, 0);
-}
-
-void mailbox_qspi_set_cs(int device_select)
-{
-	uint32_t cs_setting = device_select;
-
-	/* QSPI device select settings at 31:28 */
-	cs_setting = (cs_setting << 28);
-	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
-	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_SET_CS, &cs_setting,
-		1, 0, 0);
-}
-
-void mailbox_reset_cold(void)
-{
-	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
-	mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, 0, 0, 0, 0);
-}
-
-int mailbox_init(void)
-{
-	int status = 0;
-
-	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
-	status = mailbox_send_cmd(0, MBOX_CMD_RESTART, 0, 0, 1, 0);
-
-	if (status)
-		return status;
-
-	mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
-
-	return 0;
-}
-
diff --git a/plat/intel/soc/stratix10/soc/s10_memory_controller.c b/plat/intel/soc/stratix10/soc/s10_memory_controller.c
index ed06f54..cb45251 100644
--- a/plat/intel/soc/stratix10/soc/s10_memory_controller.c
+++ b/plat/intel/soc/stratix10/soc/s10_memory_controller.c
@@ -22,10 +22,9 @@
 #define MAX_MEM_CAL_RETRY		3
 #define PRE_CALIBRATION_DELAY		1
 #define POST_CALIBRATION_DELAY		1
-#define TIMEOUT_EMIF_CALIBRATION	100
-#define CLEAR_EMIF_DELAY		50000
-#define CLEAR_EMIF_TIMEOUT		0x100000
-#define TIMEOUT_INT_RESP		10000
+#define TIMEOUT_EMIF_CALIBRATION	1000
+#define CLEAR_EMIF_DELAY		1000
+#define CLEAR_EMIF_TIMEOUT		1000
 
 #define DDR_CONFIG(A, B, C, R)	(((A) << 24) | ((B) << 16) | ((C) << 8) | (R))
 #define DDR_CONFIG_ELEMENTS	(sizeof(ddr_config)/sizeof(uint32_t))
@@ -128,13 +127,13 @@
 			data = mmio_read_32(S10_MPFE_HMC_ADP_DDRCALSTAT);
 			if (S10_MPFE_HMC_ADP_DDRCALSTAT_CAL(data) == 1)
 				break;
-			udelay(1);
+			udelay(500);
 		} while (++timeout < TIMEOUT_EMIF_CALIBRATION);
 
 		if (S10_MPFE_HMC_ADP_DDRCALSTAT_CAL(data) == 0) {
 			status = clear_emif();
-		if (status)
-			ERROR("Failed to clear Emif\n");
+			if (status)
+				ERROR("Failed to clear Emif\n");
 		} else {
 			break;
 		}
diff --git a/plat/layerscape/common/ns_access.c b/plat/layerscape/common/ns_access.c
index b84fdbd..9717c72 100644
--- a/plat/layerscape/common/ns_access.c
+++ b/plat/layerscape/common/ns_access.c
@@ -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
  */
@@ -13,7 +13,7 @@
 
 #include "ns_access.h"
 
-static void enable_devices_ns_access(struct csu_ns_dev *ns_dev, uint32_t num)
+static void enable_devices_ns_access(struct csu_ns_dev *_ns_dev, uint32_t num)
 {
 	uint32_t *base = (uint32_t *)CONFIG_SYS_FSL_CSU_ADDR;
 	uint32_t *reg;
@@ -21,14 +21,14 @@
 	int i;
 
 	for (i = 0; i < num; i++) {
-		reg = base + ns_dev[i].ind / 2;
+		reg = base + _ns_dev[i].ind / 2;
 		val = be32toh(mmio_read_32((uintptr_t)reg));
-		if (ns_dev[i].ind % 2 == 0) {
+		if (_ns_dev[i].ind % 2 == 0) {
 			val &= 0x0000ffff;
-			val |= ns_dev[i].val << 16;
+			val |= _ns_dev[i].val << 16;
 		} else {
 			val &= 0xffff0000;
-			val |= ns_dev[i].val;
+			val |= _ns_dev[i].val;
 		}
 		mmio_write_32((uintptr_t)reg, htobe32(val));
 	}
diff --git a/plat/marvell/a8k/common/a8k_common.mk b/plat/marvell/a8k/common/a8k_common.mk
index ccb662b..bf79ebe 100644
--- a/plat/marvell/a8k/common/a8k_common.mk
+++ b/plat/marvell/a8k/common/a8k_common.mk
@@ -37,6 +37,13 @@
 ROM_BIN_EXT ?= $(BUILD_PLAT)/ble.bin
 DOIMAGE_FLAGS	+= -b $(ROM_BIN_EXT) $(NAND_DOIMAGE_FLAGS) $(DOIMAGE_SEC_FLAGS)
 
+# Check whether to build system_power.c for the platform
+ifneq ("$(wildcard $(PLAT_FAMILY_BASE)/$(PLAT)/board/system_power.c)","")
+SYSTEM_POWER_SUPPORT = 1
+else
+SYSTEM_POWER_SUPPORT = 0
+endif
+
 # This define specifies DDR type for BLE
 $(eval $(call add_define,CONFIG_DDR4))
 
@@ -82,6 +89,10 @@
 
 BL31_PORTING_SOURCES	:=	$(PLAT_FAMILY_BASE)/$(PLAT)/board/marvell_plat_config.c
 
+ifeq ($(SYSTEM_POWER_SUPPORT),1)
+BL31_PORTING_SOURCES	+=	$(PLAT_FAMILY_BASE)/$(PLAT)/board/system_power.c
+endif
+
 BL31_SOURCES		+=	lib/cpus/aarch64/cortex_a72.S		       \
 				$(PLAT_COMMON_BASE)/aarch64/plat_helpers.S     \
 				$(PLAT_COMMON_BASE)/aarch64/plat_arch_config.c \
diff --git a/plat/marvell/a8k/common/plat_pm.c b/plat/marvell/a8k/common/plat_pm.c
index d07601a..96e95c2 100644
--- a/plat/marvell/a8k/common/plat_pm.c
+++ b/plat/marvell/a8k/common/plat_pm.c
@@ -792,8 +792,20 @@
  * A8K handlers to shutdown/reboot the system
  *****************************************************************************
  */
+
+/* Set a weak stub for platforms that don't configure system power off */
+#pragma weak system_power_off
+int system_power_off(void)
+{
+	return 0;
+}
+
 static void __dead2 a8k_system_off(void)
 {
+	/* Call the platform specific system power off function */
+	system_power_off();
+
+	/* board doesn't have a system off implementation */
 	ERROR("%s:  needs to be implemented\n", __func__);
 	panic();
 }
diff --git a/plat/mediatek/mt8173/drivers/spm/spm.h b/plat/mediatek/mt8173/drivers/spm/spm.h
index 403303a..0c05410 100644
--- a/plat/mediatek/mt8173/drivers/spm/spm.h
+++ b/plat/mediatek/mt8173/drivers/spm/spm.h
@@ -320,7 +320,6 @@
 void spm_go_to_hotplug(void);
 void spm_init_event_vector(const struct pcm_desc *pcmdesc);
 void spm_kick_im_to_fetch(const struct pcm_desc *pcmdesc);
-void spm_set_sysclk_settle(void);
 int is_mcdi_ready(void);
 int is_hotplug_ready(void);
 int is_suspend_ready(void);
diff --git a/plat/mediatek/mt8173/drivers/spm/spm_suspend.c b/plat/mediatek/mt8173/drivers/spm/spm_suspend.c
index 5021695..838455d 100644
--- a/plat/mediatek/mt8173/drivers/spm/spm_suspend.c
+++ b/plat/mediatek/mt8173/drivers/spm/spm_suspend.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -239,13 +239,13 @@
 /*
  * go_to_sleep_before_wfi() - trigger SPM to enter suspend scenario
  */
-static void go_to_sleep_before_wfi(const unsigned int spm_flags)
+static void go_to_sleep_before_wfi(const unsigned int flags_spm)
 {
 	struct pwr_ctrl *pwrctrl;
 
 	pwrctrl = &spm_ctrl;
 
-	set_pwrctrl_pcm_flags(pwrctrl, spm_flags);
+	set_pwrctrl_pcm_flags(pwrctrl, flags_spm);
 
 	spm_set_sysclk_settle();
 
diff --git a/plat/mediatek/mt8183/drivers/spm/spm.c b/plat/mediatek/mt8183/drivers/spm/spm.c
index dcafd55..d6d2344 100644
--- a/plat/mediatek/mt8183/drivers/spm/spm.c
+++ b/plat/mediatek/mt8183/drivers/spm/spm.c
@@ -12,6 +12,27 @@
 
 DEFINE_BAKERY_LOCK(spm_lock);
 
+/* SPM_DVS_LEVEL */
+#define SPM_VMODEM_LEVEL_MASK	(0xff << 16)
+#define SPM_VMODEM_LEVEL	(1U << 18)
+#define SPM_VCORE_LEVEL_MASK	(0xff)
+#define SPM_VCORE_LEVEL		(1U << 1)
+
+/* CLK_SCP_CFG_0 */
+#define SPM_CK_OFF_CONTROL	(0x3FF)
+
+/* CLK_SCP_CFG_1 */
+#define SPM_AXI_26M_SEL		(0x1)
+
+/* AP_PLL_CON3 */
+#define SPM_PLL_CONTROL		(0x7FAAAAF)
+
+/* AP_PLL_CON4 */
+#define SPM_PLL_OUT_OFF_CONTROL	(0xFA0A)
+
+/* AP_PLL_CON6 */
+#define PLL_DLY			(0x20000)
+
 const char *wakeup_src_str[32] = {
 	[0] = "R12_PCM_TIMER",
 	[1] = "R12_SSPM_WDT_EVENT_B",
@@ -324,5 +345,19 @@
 	spm_lock_init();
 	mt_spm_pmic_wrap_set_phase(PMIC_WRAP_PHASE_ALLINONE);
 
+	/* Set Vmodem / Vcore DVS init level */
+	mmio_clrsetbits_32(SPM_DVS_LEVEL,
+			   SPM_VMODEM_LEVEL_MASK | SPM_VCORE_LEVEL_MASK,
+			   SPM_VMODEM_LEVEL | SPM_VCORE_LEVEL);
+
+	/* switch ck_off/axi_26m control to SPM */
+	mmio_setbits_32(CLK_SCP_CFG_0, SPM_CK_OFF_CONTROL);
+	mmio_setbits_32(CLK_SCP_CFG_1, SPM_AXI_26M_SEL);
+
+	/* switch PLL/CLKSQ control to SPM */
+	mmio_clrbits_32(AP_PLL_CON3, SPM_PLL_CONTROL);
+	mmio_clrbits_32(AP_PLL_CON4, SPM_PLL_OUT_OFF_CONTROL);
+	mmio_clrbits_32(AP_PLL_CON6, PLL_DLY);
+
 	NOTICE("%s() end\n", __func__);
 }
diff --git a/plat/mediatek/mt8183/include/mt_gic_v3.h b/plat/mediatek/mt8183/include/mt_gic_v3.h
index 9d78ddb..b6fc29b 100644
--- a/plat/mediatek/mt8183/include/mt_gic_v3.h
+++ b/plat/mediatek/mt8183/include/mt_gic_v3.h
@@ -15,15 +15,19 @@
 #define GIC500_ACTIVE_CPU_SHIFT 16
 #define GIC500_ACTIVE_CPU_MASK (0xff << GIC500_ACTIVE_CPU_SHIFT)
 
+#define NR_INT_POL_CTL 20
+
 void mt_gic_driver_init(void);
 void mt_gic_init(void);
 void mt_gic_set_pending(uint32_t irq);
 uint32_t mt_gic_get_pending(uint32_t irq);
 void mt_gic_cpuif_enable(void);
 void mt_gic_cpuif_disable(void);
-void mt_gic_pcpu_init(void);
-void mt_gic_irq_save(void);
-void mt_gic_irq_restore(void);
+void mt_gic_rdistif_init(void);
+void mt_gic_distif_save(void);
+void mt_gic_distif_restore(void);
+void mt_gic_rdistif_save(void);
+void mt_gic_rdistif_restore(void);
 void mt_gic_sync_dcm_enable(void);
 void mt_gic_sync_dcm_disable(void);
 
diff --git a/plat/mediatek/mt8183/include/platform_def.h b/plat/mediatek/mt8183/include/platform_def.h
index 0a1e038..ad81a33 100644
--- a/plat/mediatek/mt8183/include/platform_def.h
+++ b/plat/mediatek/mt8183/include/platform_def.h
@@ -39,7 +39,14 @@
 
 #define INFRACFG_AO_BASE   (IO_PHYS + 0x1000)
 
+#define TOPCKGEN_BASE      (IO_PHYS + 0x0)
+#define CLK_SCP_CFG_0      (TOPCKGEN_BASE + 0x200)
+#define CLK_SCP_CFG_1      (TOPCKGEN_BASE + 0x204)
+
 #define APMIXEDSYS         (IO_PHYS + 0xC000)
+#define AP_PLL_CON3        (APMIXEDSYS + 0xC)
+#define AP_PLL_CON4        (APMIXEDSYS + 0x10)
+#define AP_PLL_CON6        (APMIXEDSYS + 0x18)
 #define ARMPLL_LL_CON0     (APMIXEDSYS + 0x200)
 #define ARMPLL_L_CON0      (APMIXEDSYS + 0x210)
 #define ARMPLL_L_PWR_CON0  (APMIXEDSYS + 0x21c)
diff --git a/plat/mediatek/mt8183/plat_mt_gic.c b/plat/mediatek/mt8183/plat_mt_gic.c
index ccb72be..35792b2 100644
--- a/plat/mediatek/mt8183/plat_mt_gic.c
+++ b/plat/mediatek/mt8183/plat_mt_gic.c
@@ -11,18 +11,17 @@
 #include <bl31/interrupt_mgmt.h>
 #include <mt_gic_v3.h>
 #include <mtk_plat_common.h>
+#include "../drivers/arm/gic/v3/gicv3_private.h"
 #include "plat_private.h"
 #include <plat/common/platform.h>
 #include <platform_def.h>
 #include <stdint.h>
 #include <stdio.h>
 
-#define NR_INT_POL_CTL         20
-
 uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
+static uint32_t rdist_has_saved[PLATFORM_CORE_COUNT];
 
 /* we save and restore the GICv3 context on system suspend */
-gicv3_redist_ctx_t rdist_ctx;
 gicv3_dist_ctx_t dist_ctx;
 
 static unsigned int mt_mpidr_to_core_pos(u_register_t mpidr)
@@ -38,6 +37,16 @@
 	.mpidr_to_core_pos = mt_mpidr_to_core_pos,
 };
 
+struct gic_chip_data {
+	unsigned int saved_group;
+	unsigned int saved_enable;
+	unsigned int saved_conf0;
+	unsigned int saved_conf1;
+	unsigned int saved_grpmod;
+};
+
+static struct gic_chip_data gic_data;
+
 void clear_sec_pol_ctl_en(void)
 {
 	unsigned int i;
@@ -54,15 +63,6 @@
 	gicv3_driver_init(&mt_gicv3_data);
 }
 
-void mt_gic_init(void)
-{
-	gicv3_distif_init();
-	gicv3_rdistif_init(plat_my_core_pos());
-	gicv3_cpuif_enable(plat_my_core_pos());
-
-	clear_sec_pol_ctl_en();
-}
-
 void mt_gic_set_pending(uint32_t irq)
 {
 	gicv3_set_interrupt_pending(irq, plat_my_core_pos());
@@ -78,35 +78,83 @@
 	gicv3_cpuif_disable(plat_my_core_pos());
 }
 
-void mt_gic_pcpu_init(void)
+void mt_gic_rdistif_init(void)
 {
-	gicv3_rdistif_init(plat_my_core_pos());
+	unsigned int proc_num;
+	unsigned int index;
+	uintptr_t gicr_base;
+
+	proc_num = plat_my_core_pos();
+	gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
+
+	/* set all SGI/PPI as non-secure GROUP1 by default */
+	mmio_write_32(gicr_base + GICR_IGROUPR0, ~0U);
+	mmio_write_32(gicr_base + GICR_IGRPMODR0, 0x0);
+
+	/* setup the default PPI/SGI priorities */
+	for (index = 0; index < TOTAL_PCPU_INTR_NUM; index += 4U)
+		gicr_write_ipriorityr(gicr_base, index,
+				GICD_IPRIORITYR_DEF_VAL);
 }
 
-void mt_gic_irq_save(void)
+void mt_gic_distif_save(void)
 {
-	gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx);
 	gicv3_distif_save(&dist_ctx);
 }
 
-void mt_gic_irq_restore(void)
+void mt_gic_distif_restore(void)
 {
 	gicv3_distif_init_restore(&dist_ctx);
-	gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx);
 }
 
-void mt_gic_sync_dcm_enable(void)
+void mt_gic_rdistif_save(void)
+{
+	unsigned int proc_num;
+	uintptr_t gicr_base;
+
+	proc_num = plat_my_core_pos();
+	gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
+
+	gic_data.saved_group = mmio_read_32(gicr_base + GICR_IGROUPR0);
+	gic_data.saved_enable = mmio_read_32(gicr_base + GICR_ISENABLER0);
+	gic_data.saved_conf0 = mmio_read_32(gicr_base + GICR_ICFGR0);
+	gic_data.saved_conf1 = mmio_read_32(gicr_base + GICR_ICFGR1);
+	gic_data.saved_grpmod = mmio_read_32(gicr_base + GICR_IGRPMODR0);
+
+	rdist_has_saved[proc_num] = 1;
+}
+
+void mt_gic_rdistif_restore(void)
 {
-	unsigned int val = mmio_read_32(GIC_SYNC_DCM);
+	unsigned int proc_num;
+	uintptr_t gicr_base;
 
-	val &= ~GIC_SYNC_DCM_MASK;
-	mmio_write_32(GIC_SYNC_DCM, val | GIC_SYNC_DCM_ON);
+	proc_num = plat_my_core_pos();
+	if (rdist_has_saved[proc_num] == 1) {
+		gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
+		mmio_write_32(gicr_base + GICR_IGROUPR0, gic_data.saved_group);
+		mmio_write_32(gicr_base + GICR_ISENABLER0, gic_data.saved_enable);
+		mmio_write_32(gicr_base + GICR_ICFGR0, gic_data.saved_conf0);
+		mmio_write_32(gicr_base + GICR_ICFGR1, gic_data.saved_conf1);
+		mmio_write_32(gicr_base + GICR_IGRPMODR0, gic_data.saved_grpmod);
+	}
 }
 
+void mt_gic_sync_dcm_enable(void)
+{
+	mmio_clrsetbits_32(GIC_SYNC_DCM, GIC_SYNC_DCM_MASK, GIC_SYNC_DCM_ON);
+}
+
 void mt_gic_sync_dcm_disable(void)
 {
+	mmio_clrsetbits_32(GIC_SYNC_DCM, GIC_SYNC_DCM_MASK, GIC_SYNC_DCM_OFF);
+}
+
+void mt_gic_init(void)
+{
-	unsigned int val = mmio_read_32(GIC_SYNC_DCM);
+	gicv3_distif_init();
+	gicv3_cpuif_enable(plat_my_core_pos());
+	mt_gic_rdistif_init();
 
-	val &= ~GIC_SYNC_DCM_MASK;
-	mmio_write_32(GIC_SYNC_DCM, val | GIC_SYNC_DCM_OFF);
+	clear_sec_pol_ctl_en();
 }
diff --git a/plat/mediatek/mt8183/plat_pm.c b/plat/mediatek/mt8183/plat_pm.c
index 555b389..2358ec6 100644
--- a/plat/mediatek/mt8183/plat_pm.c
+++ b/plat/mediatek/mt8183/plat_pm.c
@@ -152,6 +152,21 @@
 	return !(on_stat & (cpu_mask[cluster] & ~BIT(my_idx)));
 }
 
+static void plat_cpu_pwrdwn_common(void)
+{
+	/* Prevent interrupts from spuriously waking up this cpu */
+	mt_gic_rdistif_save();
+	mt_gic_cpuif_disable();
+}
+
+static void plat_cpu_pwron_common(void)
+{
+	/* Enable the gic cpu interface */
+	mt_gic_cpuif_enable();
+	mt_gic_rdistif_init();
+	mt_gic_rdistif_restore();
+}
+
 static void plat_cluster_pwrdwn_common(uint64_t mpidr, int cluster)
 {
 	if (cluster > 0)
@@ -289,13 +304,19 @@
 {
 	int cpu = MPIDR_AFFLVL0_VAL(mpidr);
 	int cluster = MPIDR_AFFLVL1_VAL(mpidr);
+	int clst_pwr = spm_get_cluster_powerstate(cluster);
+	unsigned int i;
 
 	mcdi_ctrl_before_hotplug_on(cluster, cpu);
 	hotplug_ctrl_cluster_on(cluster, cpu);
 
-	/* init cpu reset arch as AARCH64 */
-	mcucfg_init_archstate(cluster, cpu, 1);
-	mcucfg_set_bootaddr(cluster, cpu, secure_entrypoint);
+	if (clst_pwr == 0) {
+		/* init cpu reset arch as AARCH64 of cluster */
+		for (i = 0; i < PLATFORM_MAX_CPUS_PER_CLUSTER; i++) {
+			mcucfg_init_archstate(cluster, i, 1);
+			mcucfg_set_bootaddr(cluster, i, secure_entrypoint);
+		}
+	}
 
 	hotplug_ctrl_cpu_on(cluster, cpu);
 
@@ -312,7 +333,7 @@
 	bool cluster_off = (HP_CLUSTER_OFF && afflvl1 &&
 					clst_single_on(cluster, cpu));
 
-	mt_gic_cpuif_disable();
+	plat_cpu_pwrdwn_common();
 
 	if (cluster_off)
 		plat_cluster_pwrdwn_common(mpidr, cluster);
@@ -332,8 +353,7 @@
 	if (afflvl1)
 		plat_cluster_pwron_common(mpidr, cluster);
 
-	mt_gic_pcpu_init();
-	mt_gic_cpuif_enable();
+	plat_cpu_pwron_common();
 
 	hotplug_ctrl_cpu_on_finish(cluster, cpu);
 }
@@ -348,12 +368,8 @@
 	bool afflvl2 = (pds[MPIDR_AFFLVL2] == MTK_LOCAL_STATE_OFF);
 	bool cluster_off = MCDI_C2 && afflvl1 && clst_single_pwr(cluster, cpu);
 
-	/* init cpu reset arch as AARCH64 */
-	mcucfg_init_archstate(cluster, cpu, 1);
-	mcucfg_set_bootaddr(cluster, cpu, secure_entrypoint);
+	plat_cpu_pwrdwn_common();
 
-	mt_gic_cpuif_disable();
-	mt_gic_irq_save();
 	plat_dcm_mcsi_a_backup();
 
 	if (cluster_off || afflvl2)
@@ -376,6 +392,8 @@
 		if (MCDI_SSPM)
 			while (sspm_ipi_recv_non_blocking(IPI_ID_SUSPEND, d, l))
 				;
+
+		mt_gic_distif_save();
 	} else {
 		mcdi_ctrl_cluster_cpu_off(cluster, cpu, cluster_off);
 	}
@@ -394,7 +412,9 @@
 		uint32_t l = sizeof(spm_d) / sizeof(uint32_t);
 
 		mt_gic_init();
-		mt_gic_irq_restore();
+		mt_gic_distif_restore();
+		mt_gic_rdistif_restore();
+
 		mmio_write_32(EMI_WFIFO, 0xf);
 
 		if (MCDI_SSPM)
@@ -407,6 +427,8 @@
 				;
 
 		mcdi_ctrl_resume();
+	} else {
+		plat_cpu_pwron_common();
 	}
 
 	plat_cluster_pwron_common(mpidr, cluster);
@@ -541,15 +563,23 @@
 	.system_off			= plat_mtk_system_off,
 	.system_reset			= plat_mtk_system_reset,
 	.validate_power_state		= plat_mtk_validate_power_state,
-	.get_sys_suspend_power_state	= plat_mtk_get_sys_suspend_power_state,
+	.get_sys_suspend_power_state	= plat_mtk_get_sys_suspend_power_state
 };
 
 int plat_setup_psci_ops(uintptr_t sec_entrypoint,
 			const plat_psci_ops_t **psci_ops)
 {
+	unsigned int i;
+
 	*psci_ops = &plat_plat_pm_ops;
 	secure_entrypoint = sec_entrypoint;
 
+	/* Init cpu reset arch as AARCH64 of cluster 0 */
+	for (i = 0; i < PLATFORM_MAX_CPUS_PER_CLUSTER; i++) {
+		mcucfg_init_archstate(0, i, 1);
+		mcucfg_set_bootaddr(0, i, secure_entrypoint);
+	}
+
 	if (!check_mcdi_ctl_stat()) {
 		HP_SSPM_CTRL = false;
 		MCDI_SSPM = false;
diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c
index f89e77a..25fd84c 100644
--- a/plat/nvidia/tegra/common/tegra_bl31_setup.c
+++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c
@@ -54,8 +54,9 @@
 static plat_params_from_bl2_t plat_bl31_params_from_bl2 = {
 	.tzdram_size = TZDRAM_SIZE
 };
-static unsigned long bl32_mem_size;
-static unsigned long bl32_boot_params;
+#ifdef SPD_trusty
+static aapcs64_params_t bl32_args;
+#endif
 
 /*******************************************************************************
  * This variable holds the non-secure image entry address
@@ -129,10 +130,8 @@
 	struct tegra_bl31_params *arg_from_bl2 = (struct tegra_bl31_params *) arg0;
 	plat_params_from_bl2_t *plat_params = (plat_params_from_bl2_t *)arg1;
 	image_info_t bl32_img_info = { {0} };
-	uint64_t tzdram_start, tzdram_end, bl32_start, bl32_end, console_base;
-	uint32_t console_clock;
+	uint64_t tzdram_start, tzdram_end, bl32_start, bl32_end;
 	int32_t ret;
-	static console_16550_t console;
 
 	/*
 	 * For RESET_TO_BL31 systems, BL31 is the first bootloader to run so
@@ -157,8 +156,10 @@
 
 	if (arg_from_bl2->bl32_ep_info != NULL) {
 		bl32_image_ep_info = *arg_from_bl2->bl32_ep_info;
-		bl32_mem_size = arg_from_bl2->bl32_ep_info->args.arg0;
-		bl32_boot_params = arg_from_bl2->bl32_ep_info->args.arg2;
+#ifdef SPD_trusty
+		/* save BL32 boot parameters */
+		memcpy(&bl32_args, &arg_from_bl2->bl32_ep_info->args, sizeof(bl32_args));
+#endif
 	}
 
 	/*
@@ -182,31 +183,9 @@
 	}
 
 	/*
-	 * Reference clock used by the FPGAs is a lot slower.
-	 */
-	if (tegra_platform_is_fpga()) {
-		console_clock = TEGRA_BOOT_UART_CLK_13_MHZ;
-	} else {
-		console_clock = TEGRA_BOOT_UART_CLK_408_MHZ;
-	}
-
-	/*
-	 * Get the base address of the UART controller to be used for the
-	 * console
+	 * Enable console for the platform
 	 */
-	console_base = plat_get_console_from_id(plat_params->uart_id);
-
-	if (console_base != 0U) {
-		/*
-		 * Configure the UART port to be used as the console
-		 */
-		(void)console_16550_register(console_base,
-					     console_clock,
-					     TEGRA_CONSOLE_BAUDRATE,
-					     &console);
-		console_set_scope(&console.console, CONSOLE_FLAG_BOOT |
-			CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
-	}
+	plat_enable_console(plat_params->uart_id);
 
 	/*
 	 * The previous bootloader passes the base address of the shared memory
@@ -297,17 +276,20 @@
 #ifdef SPD_trusty
 void plat_trusty_set_boot_args(aapcs64_params_t *args)
 {
-	args->arg0 = bl32_mem_size;
-	args->arg1 = bl32_boot_params;
-	args->arg2 = TRUSTY_PARAMS_LEN_BYTES;
+	/*
+	* arg0 = TZDRAM aperture available for BL32
+	* arg1 = BL32 boot params
+	* arg2 = EKS Blob Length
+	* arg3 = Boot Profiler Carveout Base
+	*/
+	args->arg0 = bl32_args.arg0;
+	args->arg1 = bl32_args.arg2;
 
 	/* update EKS size */
-	if (args->arg4 != 0U) {
-		args->arg2 = args->arg4;
-	}
+	args->arg2 = bl32_args.arg4;
 
 	/* Profiler Carveout Base */
-	args->arg3 = args->arg5;
+	args->arg3 = bl32_args.arg5;
 }
 #endif
 
diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c
index 8ba02d6..39dc42c 100644
--- a/plat/nvidia/tegra/common/tegra_pm.c
+++ b/plat/nvidia/tegra/common/tegra_pm.c
@@ -28,14 +28,6 @@
 extern uint64_t tegra_sec_entry_point;
 
 /*
- * tegra_fake_system_suspend acts as a boolean var controlling whether
- * we are going to take fake system suspend code or normal system suspend code
- * path. This variable is set inside the sip call handlers,when the kernel
- * requests a SIP call to set the suspend debug flags.
- */
-uint8_t tegra_fake_system_suspend;
-
-/*
  * The following platform setup functions are weakly defined. They
  * provide typical implementations that will be overridden by a SoC.
  */
@@ -233,31 +225,10 @@
 __dead2 void tegra_pwr_domain_power_down_wfi(const psci_power_state_t
 					     *target_state)
 {
-	uint8_t pwr_state = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL];
-	uint64_t rmr_el3 = 0;
-
 	/* call the chip's power down handler */
 	(void)tegra_soc_pwr_domain_power_down_wfi(target_state);
 
-	/*
-	 * If we are in fake system suspend mode, ensure we start doing
-	 * procedures that help in looping back towards system suspend exit
-	 * instead of calling WFI by requesting a warm reset.
-	 * Else, just call WFI to enter low power state.
-	 */
-	if ((tegra_fake_system_suspend != 0U) &&
-	    (pwr_state == (uint8_t)PSTATE_ID_SOC_POWERDN)) {
-
-		/* warm reboot */
-		rmr_el3 = read_rmr_el3();
-		write_rmr_el3(rmr_el3 | RMR_WARM_RESET_CPU);
-
-	} else {
-		/* enter power down state */
-		wfi();
-	}
-
-	/* we can never reach here */
+	wfi();
 	panic();
 }
 
@@ -273,7 +244,7 @@
 	/*
 	 * Initialize the GIC cpu and distributor interfaces
 	 */
-	tegra_gic_init();
+	tegra_gic_pcpu_init();
 
 	/*
 	 * Check if we are exiting from deep sleep.
diff --git a/plat/nvidia/tegra/common/tegra_sip_calls.c b/plat/nvidia/tegra/common/tegra_sip_calls.c
index 957300e..b8ba095 100644
--- a/plat/nvidia/tegra/common/tegra_sip_calls.c
+++ b/plat/nvidia/tegra/common/tegra_sip_calls.c
@@ -24,14 +24,8 @@
 #define TEGRA_SIP_NEW_VIDEOMEM_REGION		0x82000003
 #define TEGRA_SIP_FIQ_NS_ENTRYPOINT		0x82000005
 #define TEGRA_SIP_FIQ_NS_GET_CONTEXT		0x82000006
-#define TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND	0xC2000007
 
 /*******************************************************************************
- * Fake system suspend mode control var
- ******************************************************************************/
-extern uint8_t tegra_fake_system_suspend;
-
-/*******************************************************************************
  * SoC specific SiP handler
  ******************************************************************************/
 #pragma weak plat_sip_handler
@@ -162,26 +156,6 @@
 
 			SMC_RET0(handle);
 
-		case TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND:
-			/*
-			 * System suspend fake mode is set if we are on VDK and we make
-			 * a debug SIP call. This mode ensures that we excercise debug
-			 * path instead of the regular code path to suit the pre-silicon
-			 * platform needs. These include replacing the call to WFI by
-			 * a warm reset request.
-			 */
-			if (tegra_platform_is_virt_dev_kit() != false) {
-
-				tegra_fake_system_suspend = 1;
-				SMC_RET1(handle, 0);
-			}
-
-			/*
-			 * We return to the external world as if this SIP is not
-			 * implemented in case, we are not running on VDK.
-			 */
-			break;
-
 		default:
 			ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
 			break;
diff --git a/plat/nvidia/tegra/include/drivers/bpmp_ipc.h b/plat/nvidia/tegra/include/drivers/bpmp_ipc.h
index 0d1e405..a0d02c9 100644
--- a/plat/nvidia/tegra/include/drivers/bpmp_ipc.h
+++ b/plat/nvidia/tegra/include/drivers/bpmp_ipc.h
@@ -1,11 +1,12 @@
 /*
  * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __BPMP_IPC_H__
-#define __BPMP_IPC_H__
+#ifndef BPMP_IPC_H
+#define BPMP_IPC_H
 
 #include <lib/utils_def.h>
 #include <stdbool.h>
@@ -44,4 +45,4 @@
  */
 int tegra_bpmp_ipc_disable_clock(uint32_t clk_id);
 
-#endif /* __BPMP_IPC_H__ */
+#endif /* BPMP_IPC_H */
diff --git a/plat/nvidia/tegra/include/drivers/gpcdma.h b/plat/nvidia/tegra/include/drivers/gpcdma.h
index fb5486a..a59df37 100644
--- a/plat/nvidia/tegra/include/drivers/gpcdma.h
+++ b/plat/nvidia/tegra/include/drivers/gpcdma.h
@@ -1,11 +1,12 @@
 /*
  * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __GPCDMA_H__
-#define __GPCDMA_H__
+#ifndef GPCDMA_H
+#define GPCDMA_H
 
 #include <stdint.h>
 
@@ -13,4 +14,4 @@
 			    uint32_t num_bytes);
 void tegra_gpcdma_zeromem(uint64_t dst_addr, uint32_t num_bytes);
 
-#endif /* __GPCDMA_H__ */
+#endif /* GPCDMA_H */
diff --git a/plat/nvidia/tegra/include/drivers/security_engine.h b/plat/nvidia/tegra/include/drivers/security_engine.h
index 4ab2f9a..8a24924 100644
--- a/plat/nvidia/tegra/include/drivers/security_engine.h
+++ b/plat/nvidia/tegra/include/drivers/security_engine.h
@@ -1,5 +1,5 @@
-/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+/*
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2017, NVIDIA CORPORATION.  All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
diff --git a/plat/nvidia/tegra/include/drivers/spe.h b/plat/nvidia/tegra/include/drivers/spe.h
new file mode 100644
index 0000000..0d6d69d
--- /dev/null
+++ b/plat/nvidia/tegra/include/drivers/spe.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2019, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPE_H
+#define SPE_H
+
+#include <stdint.h>
+
+#include <drivers/console.h>
+
+typedef struct {
+	console_t console;
+	uintptr_t base;
+} console_spe_t;
+
+/*
+ * Initialize a new spe console instance and register it with the console
+ * framework. The |console| pointer must point to storage that will be valid
+ * for the lifetime of the console, such as a global or static local variable.
+ * Its contents will be reinitialized from scratch.
+ */
+int console_spe_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
+			   console_spe_t *console);
+
+#endif /* SPE_H */
diff --git a/plat/nvidia/tegra/include/drivers/tegra_gic.h b/plat/nvidia/tegra/include/drivers/tegra_gic.h
index 6106b40..6661dff 100644
--- a/plat/nvidia/tegra/include/drivers/tegra_gic.h
+++ b/plat/nvidia/tegra/include/drivers/tegra_gic.h
@@ -1,11 +1,12 @@
 /*
  * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __TEGRA_GIC_H__
-#define __TEGRA_GIC_H__
+#ifndef TEGRA_GIC_H
+#define TEGRA_GIC_H
 
 #include <common/interrupt_props.h>
 
@@ -26,4 +27,4 @@
 void tegra_gic_setup(const interrupt_prop_t *interrupt_props,
 		     unsigned int interrupt_props_num);
 
-#endif /* __TEGRA_GIC_H__ */
+#endif /* TEGRA_GIC_H */
diff --git a/plat/nvidia/tegra/include/lib/profiler.h b/plat/nvidia/tegra/include/lib/profiler.h
index 60f8d80..684c872 100644
--- a/plat/nvidia/tegra/include/lib/profiler.h
+++ b/plat/nvidia/tegra/include/lib/profiler.h
@@ -1,11 +1,12 @@
 /*
  * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __PROFILER_H__
-#define __PROFILER_H__
+#ifndef PROFILER_H
+#define PROFILER_H
 
 /*******************************************************************************
  * Number of bytes of memory used by the profiler on Tegra
@@ -16,4 +17,4 @@
 void boot_profiler_add_record(const char *str);
 void boot_profiler_deinit(void);
 
-#endif /* __PROFILER_H__ */
+#endif /* PROFILER_H */
diff --git a/plat/nvidia/tegra/include/t194/tegra194_private.h b/plat/nvidia/tegra/include/t194/tegra194_private.h
new file mode 100644
index 0000000..8f1deb2
--- /dev/null
+++ b/plat/nvidia/tegra/include/t194/tegra194_private.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TEGRA194_PRIVATE_H
+#define TEGRA194_PRIVATE_H
+
+void tegra194_cpu_reset_handler(void);
+uint64_t tegra194_get_cpu_reset_handler_base(void);
+uint64_t tegra194_get_cpu_reset_handler_size(void);
+uint64_t tegra194_get_smmu_ctx_offset(void);
+void tegra194_set_system_suspend_entry(void);
+
+#endif /* TEGRA194_PRIVATE_H */
diff --git a/plat/nvidia/tegra/include/t194/tegra_def.h b/plat/nvidia/tegra/include/t194/tegra_def.h
new file mode 100644
index 0000000..a98aa2d
--- /dev/null
+++ b/plat/nvidia/tegra/include/t194/tegra_def.h
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TEGRA_DEF_H
+#define TEGRA_DEF_H
+
+#include <lib/utils_def.h>
+
+/*******************************************************************************
+ * Chip specific page table and MMU setup constants
+ ******************************************************************************/
+#define PLAT_PHY_ADDR_SPACE_SIZE	(ULL(1) << 40)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(ULL(1) << 40)
+
+/*******************************************************************************
+ * These values are used by the PSCI implementation during the `CPU_SUSPEND`
+ * and `SYSTEM_SUSPEND` calls as the `state-id` field in the 'power state'
+ * parameter.
+ ******************************************************************************/
+#define PSTATE_ID_CORE_IDLE		U(6)
+#define PSTATE_ID_CORE_POWERDN		U(7)
+#define PSTATE_ID_SOC_POWERDN		U(2)
+
+/*******************************************************************************
+ * Platform power states (used by PSCI framework)
+ *
+ * - PLAT_MAX_RET_STATE should be less than lowest PSTATE_ID
+ * - PLAT_MAX_OFF_STATE should be greater than the highest PSTATE_ID
+ ******************************************************************************/
+#define PLAT_MAX_RET_STATE		U(1)
+#define PLAT_MAX_OFF_STATE		U(8)
+
+/*******************************************************************************
+ * Secure IRQ definitions
+ ******************************************************************************/
+#define TEGRA194_MAX_SEC_IRQS		U(2)
+#define TEGRA194_TOP_WDT_IRQ		U(49)
+#define TEGRA194_AON_WDT_IRQ		U(50)
+
+#define TEGRA194_SEC_IRQ_TARGET_MASK	U(0xFF) /* 8 Carmel */
+
+/*******************************************************************************
+ * Tegra Miscellanous register constants
+ ******************************************************************************/
+#define TEGRA_MISC_BASE			U(0x00100000)
+
+#define HARDWARE_REVISION_OFFSET	U(0x4)
+#define MISCREG_EMU_REVID		U(0x3160)
+#define  BOARD_MASK_BITS		U(0xFF)
+#define  BOARD_SHIFT_BITS		U(24)
+#define MISCREG_PFCFG			U(0x200C)
+
+/*******************************************************************************
+ * Tegra Memory Controller constants
+ ******************************************************************************/
+#define TEGRA_MC_STREAMID_BASE		U(0x02C00000)
+#define TEGRA_MC_BASE			U(0x02C10000)
+
+/* General Security Carveout register macros */
+#define MC_GSC_CONFIG_REGS_SIZE		U(0x40)
+#define MC_GSC_LOCK_CFG_SETTINGS_BIT	(U(1) << 1)
+#define MC_GSC_ENABLE_TZ_LOCK_BIT	(U(1) << 0)
+#define MC_GSC_SIZE_RANGE_4KB_SHIFT	U(27)
+#define MC_GSC_BASE_LO_SHIFT		U(12)
+#define MC_GSC_BASE_LO_MASK		U(0xFFFFF)
+#define MC_GSC_BASE_HI_SHIFT		U(0)
+#define MC_GSC_BASE_HI_MASK		U(3)
+#define MC_GSC_ENABLE_CPU_SECURE_BIT    (U(1) << 31)
+
+/* TZDRAM carveout configuration registers */
+#define MC_SECURITY_CFG0_0		U(0x70)
+#define MC_SECURITY_CFG1_0		U(0x74)
+#define MC_SECURITY_CFG3_0		U(0x9BC)
+
+#define MC_SECURITY_BOM_MASK		(U(0xFFF) << 20)
+#define MC_SECURITY_SIZE_MB_MASK	(U(0x1FFF) << 0)
+#define MC_SECURITY_BOM_HI_MASK		(U(0x3) << 0)
+
+#define MC_SECURITY_CFG_REG_CTRL_0	U(0x154)
+#define  SECURITY_CFG_WRITE_ACCESS_BIT	(U(0x1) << 0)
+#define  SECURITY_CFG_WRITE_ACCESS_ENABLE	U(0x0)
+#define  SECURITY_CFG_WRITE_ACCESS_DISABLE	U(0x1)
+
+/* Video Memory carveout configuration registers */
+#define MC_VIDEO_PROTECT_BASE_HI	U(0x978)
+#define MC_VIDEO_PROTECT_BASE_LO	U(0x648)
+#define MC_VIDEO_PROTECT_SIZE_MB	U(0x64c)
+
+/*
+ * Carveout (MC_SECURITY_CARVEOUT24) registers used to clear the
+ * non-overlapping Video memory region
+ */
+#define MC_VIDEO_PROTECT_CLEAR_CFG	U(0x25A0)
+#define MC_VIDEO_PROTECT_CLEAR_BASE_LO	U(0x25A4)
+#define MC_VIDEO_PROTECT_CLEAR_BASE_HI	U(0x25A8)
+#define MC_VIDEO_PROTECT_CLEAR_SIZE	U(0x25AC)
+#define MC_VIDEO_PROTECT_CLEAR_ACCESS_CFG0	U(0x25B0)
+
+/* TZRAM carveout (MC_SECURITY_CARVEOUT11) configuration registers */
+#define MC_TZRAM_CARVEOUT_CFG		U(0x2190)
+#define MC_TZRAM_BASE_LO		U(0x2194)
+#define MC_TZRAM_BASE_HI		U(0x2198)
+#define MC_TZRAM_SIZE			U(0x219C)
+#define MC_TZRAM_CLIENT_ACCESS0_CFG0	U(0x21A0)
+#define MC_TZRAM_CLIENT_ACCESS1_CFG0	U(0x21A4)
+#define  TZRAM_ALLOW_MPCORER		(U(1) << 7)
+#define  TZRAM_ALLOW_MPCOREW		(U(1) << 25)
+
+/* Memory Controller Reset Control registers */
+#define  MC_CLIENT_HOTRESET_CTRL1_DLAA_FLUSH_ENB	(U(1) << 28)
+#define  MC_CLIENT_HOTRESET_CTRL1_DLA1A_FLUSH_ENB	(U(1) << 29)
+#define  MC_CLIENT_HOTRESET_CTRL1_PVA0A_FLUSH_ENB	(U(1) << 30)
+#define  MC_CLIENT_HOTRESET_CTRL1_PVA1A_FLUSH_ENB	(U(1) << 31)
+
+/*******************************************************************************
+ * Tegra UART Controller constants
+ ******************************************************************************/
+#define TEGRA_UARTA_BASE		U(0x03100000)
+#define TEGRA_UARTB_BASE		U(0x03110000)
+#define TEGRA_UARTC_BASE		U(0x0C280000)
+#define TEGRA_UARTD_BASE		U(0x03130000)
+#define TEGRA_UARTE_BASE		U(0x03140000)
+#define TEGRA_UARTF_BASE		U(0x03150000)
+#define TEGRA_UARTG_BASE		U(0x0C290000)
+
+/*******************************************************************************
+ * Tegra Fuse Controller related constants
+ ******************************************************************************/
+#define TEGRA_FUSE_BASE			U(0x03820000)
+#define  OPT_SUBREVISION		U(0x248)
+#define  SUBREVISION_MASK		U(0xF)
+
+/*******************************************************************************
+ * GICv2 & interrupt handling related constants
+ ******************************************************************************/
+#define TEGRA_GICD_BASE			U(0x03881000)
+#define TEGRA_GICC_BASE			U(0x03882000)
+
+/*******************************************************************************
+ * Security Engine related constants
+ ******************************************************************************/
+#define TEGRA_SE0_BASE			U(0x03AC0000)
+#define  SE0_MUTEX_WATCHDOG_NS_LIMIT	U(0x6C)
+#define  SE0_AES0_ENTROPY_SRC_AGE_CTRL	U(0x2FC)
+#define TEGRA_PKA1_BASE			U(0x03AD0000)
+#define  SE_PKA1_CTRL_SE_MUTEX_TMOUT_DFTVAL U(0x144)
+#define  PKA1_MUTEX_WATCHDOG_NS_LIMIT	SE_PKA1_CTRL_SE_MUTEX_TMOUT_DFTVAL
+#define TEGRA_RNG1_BASE			U(0x03AE0000)
+#define  RNG1_MUTEX_WATCHDOG_NS_LIMIT	U(0xFE0)
+
+/*******************************************************************************
+ * Tegra hardware synchronization primitives for the SPE engine
+ ******************************************************************************/
+#define TEGRA_AON_HSP_SM_6_7_BASE	U(0x0c190000)
+#define TEGRA_CONSOLE_SPE_BASE		(TEGRA_AON_HSP_SM_6_7_BASE + U(0x8000))
+
+/*******************************************************************************
+ * Tegra micro-seconds timer constants
+ ******************************************************************************/
+#define TEGRA_TMRUS_BASE		U(0x0C2E0000)
+#define TEGRA_TMRUS_SIZE		U(0x10000)
+
+/*******************************************************************************
+ * Tegra Power Mgmt Controller constants
+ ******************************************************************************/
+#define TEGRA_PMC_BASE			U(0x0C360000)
+
+/*******************************************************************************
+ * Tegra scratch registers constants
+ ******************************************************************************/
+#define TEGRA_SCRATCH_BASE		U(0x0C390000)
+#define  SECURE_SCRATCH_RSV81_LO	U(0x2EC)
+#define  SECURE_SCRATCH_RSV81_HI	U(0x2F0)
+#define  SECURE_SCRATCH_RSV97		U(0x36C)
+#define  SECURE_SCRATCH_RSV99_LO	U(0x37C)
+#define  SECURE_SCRATCH_RSV99_HI	U(0x380)
+#define  SECURE_SCRATCH_RSV109_LO	U(0x3CC)
+#define  SECURE_SCRATCH_RSV109_HI	U(0x3D0)
+
+#define SCRATCH_BL31_PARAMS_ADDR	SECURE_SCRATCH_RSV81_LO
+#define SCRATCH_BL31_PLAT_PARAMS_ADDR	SECURE_SCRATCH_RSV81_HI
+#define SCRATCH_SECURE_BOOTP_FCFG	SECURE_SCRATCH_RSV97
+#define SCRATCH_SMMU_TABLE_ADDR_LO	SECURE_SCRATCH_RSV99_LO
+#define SCRATCH_SMMU_TABLE_ADDR_HI	SECURE_SCRATCH_RSV99_HI
+#define SCRATCH_RESET_VECTOR_LO		SECURE_SCRATCH_RSV109_LO
+#define SCRATCH_RESET_VECTOR_HI		SECURE_SCRATCH_RSV109_HI
+
+/*******************************************************************************
+ * Tegra Memory Mapped Control Register Access Bus constants
+ ******************************************************************************/
+#define TEGRA_MMCRAB_BASE		U(0x0E000000)
+
+/*******************************************************************************
+ * Tegra SMMU Controller constants
+ ******************************************************************************/
+#define TEGRA_SMMU0_BASE		U(0x12000000)
+#define TEGRA_SMMU1_BASE		U(0x11000000)
+#define TEGRA_SMMU2_BASE		U(0x10000000)
+
+/*******************************************************************************
+ * Tegra TZRAM constants
+ ******************************************************************************/
+#define TEGRA_TZRAM_BASE		U(0x40000000)
+#define TEGRA_TZRAM_SIZE		U(0x40000)
+
+/*******************************************************************************
+ * Tegra Clock and Reset Controller constants
+ ******************************************************************************/
+#define TEGRA_CAR_RESET_BASE		U(0x20000000)
+#define TEGRA_GPU_RESET_REG_OFFSET	U(0x18)
+#define TEGRA_GPU_RESET_GPU_SET_OFFSET  U(0x1C)
+#define  GPU_RESET_BIT			(U(1) << 0)
+#define  GPU_SET_BIT			(U(1) << 0)
+
+/*******************************************************************************
+ * XUSB PADCTL
+ ******************************************************************************/
+#define TEGRA_XUSB_PADCTL_BASE			U(0x3520000)
+#define TEGRA_XUSB_PADCTL_SIZE			U(0x10000)
+#define XUSB_PADCTL_HOST_AXI_STREAMID_PF_0	U(0x136c)
+#define XUSB_PADCTL_HOST_AXI_STREAMID_VF_0	U(0x1370)
+#define XUSB_PADCTL_HOST_AXI_STREAMID_VF_1	U(0x1374)
+#define XUSB_PADCTL_HOST_AXI_STREAMID_VF_2	U(0x1378)
+#define XUSB_PADCTL_HOST_AXI_STREAMID_VF_3	U(0x137c)
+#define XUSB_PADCTL_DEV_AXI_STREAMID_PF_0	U(0x139c)
+
+/*******************************************************************************
+ * XUSB STREAMIDs
+ ******************************************************************************/
+#define TEGRA_SID_XUSB_HOST			U(0x1b)
+#define TEGRA_SID_XUSB_DEV			U(0x1c)
+#define TEGRA_SID_XUSB_VF0			U(0x5d)
+#define TEGRA_SID_XUSB_VF1			U(0x5e)
+#define TEGRA_SID_XUSB_VF2			U(0x5f)
+#define TEGRA_SID_XUSB_VF3			U(0x60)
+
+#endif /* TEGRA_DEF_H */
diff --git a/plat/nvidia/tegra/include/t194/tegra_mc_def.h b/plat/nvidia/tegra/include/t194/tegra_mc_def.h
new file mode 100644
index 0000000..09dcce3
--- /dev/null
+++ b/plat/nvidia/tegra/include/t194/tegra_mc_def.h
@@ -0,0 +1,653 @@
+/*
+ * Copyright (c) 2019-2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TEGRA_MC_DEF_H
+#define TEGRA_MC_DEF_H
+
+/*******************************************************************************
+ * Memory Controller Order_id registers
+ ******************************************************************************/
+#define MC_CLIENT_ORDER_ID_9				U(0x2a24)
+#define  MC_CLIENT_ORDER_ID_9_RESET_VAL			0x00000000U
+#define  MC_CLIENT_ORDER_ID_9_XUSB_HOSTW_MASK		(0x3U << 12)
+#define  MC_CLIENT_ORDER_ID_9_XUSB_HOSTW_ORDER_ID	(3U << 12)
+
+#define MC_CLIENT_ORDER_ID_27				U(0x2a6c)
+#define  MC_CLIENT_ORDER_ID_27_RESET_VAL		0x00000000U
+#define  MC_CLIENT_ORDER_ID_27_PCIE0W_MASK		(0x3U << 4)
+#define  MC_CLIENT_ORDER_ID_27_PCIE0W_ORDER_ID		(1U << 4)
+
+#define MC_CLIENT_ORDER_ID_28				U(0x2a70)
+#define  MC_CLIENT_ORDER_ID_28_RESET_VAL		0x00000000U
+#define  MC_CLIENT_ORDER_ID_28_PCIE4W_MASK		(0x3U << 4)
+#define  MC_CLIENT_ORDER_ID_28_PCIE4W_ORDER_ID		(3U << 4)
+#define  MC_CLIENT_ORDER_ID_28_PCIE5W_MASK		(0x3U << 12)
+#define  MC_CLIENT_ORDER_ID_28_PCIE5W_ORDER_ID		(2U << 12)
+
+#define mc_client_order_id(val, id, client) \
+	((val & ~MC_CLIENT_ORDER_ID_##id##_##client##_MASK) | \
+	MC_CLIENT_ORDER_ID_##id##_##client##_ORDER_ID)
+
+/*******************************************************************************
+ * Memory Controller's VC ID configuration registers
+ ******************************************************************************/
+#define VC_NISO						0U
+#define VC_SISO						1U
+#define VC_ISO						2U
+
+#define MC_HUB_PC_VC_ID_0				U(0x2a78)
+#define  MC_HUB_PC_VC_ID_0_RESET_VAL 			0x00020100U
+#define  MC_HUB_PC_VC_ID_0_APB_VC_ID_MASK		(0x3U << 8)
+#define  MC_HUB_PC_VC_ID_0_APB_VC_ID			(VC_NISO << 8)
+
+#define MC_HUB_PC_VC_ID_2				U(0x2a80)
+#define  MC_HUB_PC_VC_ID_2_RESET_VAL 			0x10001000U
+#define  MC_HUB_PC_VC_ID_2_SD_VC_ID_MASK		(0x3U << 28)
+#define  MC_HUB_PC_VC_ID_2_SD_VC_ID			(VC_NISO << 28)
+
+#define MC_HUB_PC_VC_ID_4				U(0x2a88)
+#define  MC_HUB_PC_VC_ID_4_RESET_VAL 			0x10020011U
+#define  MC_HUB_PC_VC_ID_4_NIC_VC_ID_MASK		(0x3U << 28)
+#define  MC_HUB_PC_VC_ID_4_NIC_VC_ID			(VC_NISO << 28)
+
+#define mc_hub_vc_id(val, id, client) \
+	((val & ~MC_HUB_PC_VC_ID_##id##_##client##_VC_ID_MASK) | \
+	MC_HUB_PC_VC_ID_##id##_##client##_VC_ID)
+
+/*******************************************************************************
+ * Memory Controller's PCFIFO client configuration registers
+ ******************************************************************************/
+#define MC_PCFIFO_CLIENT_CONFIG0				0xdd0U
+
+#define MC_PCFIFO_CLIENT_CONFIG1				0xdd4U
+#define  MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL			0x20200000U
+#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_UNORDERED		(0U << 17)
+#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_MASK		(1U << 17)
+#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_UNORDERED		(0U << 21)
+#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_MASK		(1U << 21)
+#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_UNORDERED	(0U << 29)
+#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_ORDERED		(1U << 29)
+#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_MASK		(1U << 29)
+
+#define MC_PCFIFO_CLIENT_CONFIG2				0xdd8U
+#define  MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL			0x00002800U
+#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_UNORDERED	(0U << 11)
+#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_MASK	(1U << 11)
+#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_UNORDERED	(0U << 13)
+#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_ORDERED	(1U << 13)
+#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_MASK		(1U << 13)
+#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_TSECSWR_UNORDERED	(0U << 21)
+#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_TSECSWR_MASK		(1U << 21)
+
+#define MC_PCFIFO_CLIENT_CONFIG3				0xddcU
+#define  MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL			0x08000080U
+#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWA_UNORDERED	(0U << 4)
+#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWA_MASK		(1U << 4)
+#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCW_UNORDERED	(0U << 6)
+#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCW_MASK		(1U << 6)
+#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_UNORDERED	(0U << 7)
+#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_MASK		(1U << 7)
+#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_VICSWR_UNORDERED	(0U << 13)
+#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_VICSWR_MASK		(1U << 13)
+#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_APEW_UNORDERED		(0U << 27)
+#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_APEW_MASK		(1U << 27)
+
+#define MC_PCFIFO_CLIENT_CONFIG4				0xde0U
+#define  MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL			0x5552a022U
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_UNORDERED 	(0U << 1)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_MASK		(1U << 1)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_UNORDERED		(0U << 5)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_MASK		(1U << 5)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_TSECSWRB_UNORDERED	(0U << 7)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_TSECSWRB_MASK		(1U << 7)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_UNORDERED 	(0U << 13)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_MASK		(1U << 13)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_ORDERED 		(1U << 15)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_MASK		(1U << 15)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_UNORDERED	(0U << 17)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_MASK		(1U << 17)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPW_UNORDERED	(0U << 20)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPW_MASK		(1U << 20)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_UNORDERED	(0U << 22)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_MASK		(1U << 22)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONW_UNORDERED		(0U << 24)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONW_MASK		(1U << 24)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_UNORDERED	(0U << 26)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_MASK		(1U << 26)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEW_UNORDERED		(0U << 28)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEW_MASK		(1U << 28)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_UNORDERED	(0U << 30)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_MASK		(1U << 30)
+
+#define MC_PCFIFO_CLIENT_CONFIG5				0xbf4U
+#define  MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL			0x20000001U
+#define  MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_UNORDERED	(0U << 0)
+#define  MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_MASK		(1U << 0)
+#define  MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_VIFALW_UNORDERED	(0U << 30)
+#define  MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_VIFALW_MASK		(1U << 30)
+
+#define MC_PCFIFO_CLIENT_CONFIG6				0xb90U
+#define  MC_PCFIFO_CLIENT_CONFIG6_RESET_VAL			0xaa280000U
+#define  MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_RCEW_UNORDERED		(0U << 19)
+#define  MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_RCEW_MASK		(1U << 19)
+#define  MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_RCEDMAW_UNORDERED	(0U << 21)
+#define  MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_RCEDMAW_MASK		(1U << 21)
+#define  MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE0W_UNORDERED	(0U << 25)
+#define  MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE0W_MASK		(1U << 25)
+#define  MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE1W_ORDERED		(1U << 27)
+#define  MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE1W_MASK		(1U << 27)
+#define  MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE2W_ORDERED		(1U << 29)
+#define  MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE2W_MASK		(1U << 29)
+#define  MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE3W_ORDERED		(1U << 31)
+#define  MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE3W_MASK		(1U << 31)
+
+#define MC_PCFIFO_CLIENT_CONFIG7				0xaccU
+#define  MC_PCFIFO_CLIENT_CONFIG7_RESET_VAL			0x0000000aU
+#define  MC_PCFIFO_CLIENT_CONFIG7_PCFIFO_PCIE4W_UNORDERED	(0U << 1)
+#define  MC_PCFIFO_CLIENT_CONFIG7_PCFIFO_PCIE4W_MASK		(1U << 1)
+#define  MC_PCFIFO_CLIENT_CONFIG7_PCFIFO_PCIE5W_UNORDERED	(0U << 3)
+#define  MC_PCFIFO_CLIENT_CONFIG7_PCFIFO_PCIE5W_MASK		(1U << 3)
+
+/*******************************************************************************
+ * StreamID to indicate no SMMU translations (requests to be steered on the
+ * SMMU bypass path)
+ ******************************************************************************/
+#define MC_STREAM_ID_MAX					0x7FU
+
+/*******************************************************************************
+ * Stream ID Override Config registers
+ ******************************************************************************/
+#define MC_STREAMID_OVERRIDE_CFG_PVA1RDA			0x660U
+#define MC_STREAMID_OVERRIDE_CFG_NVENCSRD			0xe0U
+#define MC_STREAMID_OVERRIDE_CFG_NVJPGSWR			0x3f8U
+#define MC_STREAMID_OVERRIDE_CFG_PVA0RDA1			0x758U
+#define MC_STREAMID_OVERRIDE_CFG_PVA0RDC			0x640U
+#define MC_STREAMID_OVERRIDE_CFG_DLA0RDA			0x5f0U
+#define MC_STREAMID_OVERRIDE_CFG_BPMPR				0x498U
+#define MC_STREAMID_OVERRIDE_CFG_APEDMAR			0x4f8U
+#define MC_STREAMID_OVERRIDE_CFG_AXISR				0x460U
+#define MC_STREAMID_OVERRIDE_CFG_TSECSRD			0x2a0U
+#define MC_STREAMID_OVERRIDE_CFG_DLA0FALRDB			0x5f8U
+#define MC_STREAMID_OVERRIDE_CFG_NVENC1SRD1			0x788U
+#define MC_STREAMID_OVERRIDE_CFG_MPCOREW			0x1c8U
+#define MC_STREAMID_OVERRIDE_CFG_NVENCSRD1			0x780U
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR			0x250U
+#define MC_STREAMID_OVERRIDE_CFG_MIU1R				0x540U
+#define MC_STREAMID_OVERRIDE_CFG_MIU0R				0x530U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE1W				0x6d8U
+#define MC_STREAMID_OVERRIDE_CFG_PVA1WRA			0x678U
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW			0x258U
+#define MC_STREAMID_OVERRIDE_CFG_AXIAPW				0x418U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAB			0x338U
+#define MC_STREAMID_OVERRIDE_CFG_SATAW				0x1e8U
+#define MC_STREAMID_OVERRIDE_CFG_DLA0WRA			0x600U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE3R				0x6f0U
+#define MC_STREAMID_OVERRIDE_CFG_MIU3W				0x588U
+#define MC_STREAMID_OVERRIDE_CFG_SCEDMAR			0x4e8U
+#define MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR			0xb0U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCWA			0x320U
+#define MC_STREAMID_OVERRIDE_CFG_MIU2R				0x570U
+#define MC_STREAMID_OVERRIDE_CFG_APEDMAW			0x500U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE2AW			0x6e8U
+#define MC_STREAMID_OVERRIDE_CFG_SESWR				0x408U
+#define MC_STREAMID_OVERRIDE_CFG_PVA1RDB1			0x770U
+#define MC_STREAMID_OVERRIDE_CFG_AXISW				0x468U
+#define MC_STREAMID_OVERRIDE_CFG_DLA1FALRDB			0x618U
+#define MC_STREAMID_OVERRIDE_CFG_AONDMAW			0x4d0U
+#define MC_STREAMID_OVERRIDE_CFG_TSECSWRB			0x438U
+#define MC_STREAMID_OVERRIDE_CFG_ISPWB				0x238U
+#define MC_STREAMID_OVERRIDE_CFG_HDAR				0xa8U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCRA			0x300U
+#define MC_STREAMID_OVERRIDE_CFG_ETRW				0x428U
+#define MC_STREAMID_OVERRIDE_CFG_RCEDMAW			0x6a8U
+#define MC_STREAMID_OVERRIDE_CFG_TSECSWR			0x2a8U
+#define MC_STREAMID_OVERRIDE_CFG_ETRR				0x420U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCR				0x310U
+#define MC_STREAMID_OVERRIDE_CFG_NVJPGSRD			0x3f0U
+#define MC_STREAMID_OVERRIDE_CFG_AONDMAR			0x4c8U
+#define MC_STREAMID_OVERRIDE_CFG_SCER				0x4d8U
+#define MC_STREAMID_OVERRIDE_CFG_MIU5W				0x7e8U
+#define MC_STREAMID_OVERRIDE_CFG_NVENC1SRD			0x6b0U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE4R				0x700U
+#define MC_STREAMID_OVERRIDE_CFG_ISPWA				0x230U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE0W				0x6c8U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE5R1			0x778U
+#define MC_STREAMID_OVERRIDE_CFG_DLA1RDA			0x610U
+#define MC_STREAMID_OVERRIDE_CFG_VICSWR				0x368U
+#define MC_STREAMID_OVERRIDE_CFG_SESRD				0x400U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCW				0x330U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAB			0x318U
+#define MC_STREAMID_OVERRIDE_CFG_ISPFALW			0x720U
+#define MC_STREAMID_OVERRIDE_CFG_EQOSW				0x478U
+#define MC_STREAMID_OVERRIDE_CFG_RCEDMAR			0x6a0U
+#define MC_STREAMID_OVERRIDE_CFG_RCER				0x690U
+#define MC_STREAMID_OVERRIDE_CFG_NVDECSWR			0x3c8U
+#define MC_STREAMID_OVERRIDE_CFG_UFSHCR				0x480U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE4W				0x708U
+#define MC_STREAMID_OVERRIDE_CFG_VICSRD				0x360U
+#define MC_STREAMID_OVERRIDE_CFG_APER				0x3d0U
+#define MC_STREAMID_OVERRIDE_CFG_MIU7R				0x8U
+#define MC_STREAMID_OVERRIDE_CFG_NVDEC1SRD			0x7c8U
+#define MC_STREAMID_OVERRIDE_CFG_MIU7W				0x10U
+#define MC_STREAMID_OVERRIDE_CFG_PVA1RDA1			0x768U
+#define MC_STREAMID_OVERRIDE_CFG_PVA1WRC			0x688U
+#define MC_STREAMID_OVERRIDE_CFG_AONW				0x4c0U
+#define MC_STREAMID_OVERRIDE_CFG_MIU4W				0x598U
+#define MC_STREAMID_OVERRIDE_CFG_HDAW				0x1a8U
+#define MC_STREAMID_OVERRIDE_CFG_BPMPW				0x4a0U
+#define MC_STREAMID_OVERRIDE_CFG_DLA1WRA			0x620U
+#define MC_STREAMID_OVERRIDE_CFG_DLA0RDA1			0x748U
+#define MC_STREAMID_OVERRIDE_CFG_MIU1W				0x548U
+#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1			0x508U
+#define MC_STREAMID_OVERRIDE_CFG_VICSRD1			0x510U
+#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAW			0x4b0U
+#define MC_STREAMID_OVERRIDE_CFG_NVDEC1SWR			0x7d8U
+#define MC_STREAMID_OVERRIDE_CFG_PVA0WRC			0x658U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE5R				0x710U
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR			0x260U
+#define MC_STREAMID_OVERRIDE_CFG_UFSHCW				0x488U
+#define MC_STREAMID_OVERRIDE_CFG_PVA1WRB			0x680U
+#define MC_STREAMID_OVERRIDE_CFG_PVA0WRB			0x650U
+#define MC_STREAMID_OVERRIDE_CFG_DLA1FALWRB			0x628U
+#define MC_STREAMID_OVERRIDE_CFG_NVENC1SWR			0x6b8U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE0R				0x6c0U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE3W				0x6f8U
+#define MC_STREAMID_OVERRIDE_CFG_PVA0RDA			0x630U
+#define MC_STREAMID_OVERRIDE_CFG_MIU6W				0x7f8U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE1R				0x6d0U
+#define MC_STREAMID_OVERRIDE_CFG_NVDEC1SRD1			0x7d0U
+#define MC_STREAMID_OVERRIDE_CFG_DLA0FALWRB			0x608U
+#define MC_STREAMID_OVERRIDE_CFG_PVA1RDC			0x670U
+#define MC_STREAMID_OVERRIDE_CFG_MIU0W				0x538U
+#define MC_STREAMID_OVERRIDE_CFG_MIU2W				0x578U
+#define MC_STREAMID_OVERRIDE_CFG_MPCORER			0x138U
+#define MC_STREAMID_OVERRIDE_CFG_AXIAPR				0x410U
+#define MC_STREAMID_OVERRIDE_CFG_AONR				0x4b8U
+#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAR			0x4a8U
+#define MC_STREAMID_OVERRIDE_CFG_PVA0RDB			0x638U
+#define MC_STREAMID_OVERRIDE_CFG_VIFALW				0x5e8U
+#define MC_STREAMID_OVERRIDE_CFG_MIU6R				0x7f0U
+#define MC_STREAMID_OVERRIDE_CFG_EQOSR				0x470U
+#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD			0x3c0U
+#define MC_STREAMID_OVERRIDE_CFG_TSECSRDB			0x430U
+#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD1			0x518U
+#define MC_STREAMID_OVERRIDE_CFG_PVA0RDB1			0x760U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE0R1			0x798U
+#define MC_STREAMID_OVERRIDE_CFG_SCEDMAW			0x4f0U
+#define MC_STREAMID_OVERRIDE_CFG_APEW				0x3d8U
+#define MC_STREAMID_OVERRIDE_CFG_MIU5R				0x7e0U
+#define MC_STREAMID_OVERRIDE_CFG_DLA1RDA1			0x750U
+#define MC_STREAMID_OVERRIDE_CFG_PVA0WRA			0x648U
+#define MC_STREAMID_OVERRIDE_CFG_ISPFALR			0x228U
+#define MC_STREAMID_OVERRIDE_CFG_PTCR				0x0U
+#define MC_STREAMID_OVERRIDE_CFG_MIU4R				0x590U
+#define MC_STREAMID_OVERRIDE_CFG_ISPRA				0x220U
+#define MC_STREAMID_OVERRIDE_CFG_VIFALR				0x5e0U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE2AR			0x6e0U
+#define MC_STREAMID_OVERRIDE_CFG_RCEW				0x698U
+#define MC_STREAMID_OVERRIDE_CFG_ISPRA1				0x790U
+#define MC_STREAMID_OVERRIDE_CFG_SCEW				0x4e0U
+#define MC_STREAMID_OVERRIDE_CFG_MIU3R				0x580U
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW			0x268U
+#define MC_STREAMID_OVERRIDE_CFG_SATAR				0xf8U
+#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR			0x490U
+#define MC_STREAMID_OVERRIDE_CFG_PVA1RDB			0x668U
+#define MC_STREAMID_OVERRIDE_CFG_VIW				0x390U
+#define MC_STREAMID_OVERRIDE_CFG_NVENCSWR			0x158U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE5W				0x718U
+
+/*******************************************************************************
+ * Macro to calculate Security cfg register addr from StreamID Override register
+ ******************************************************************************/
+#define MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(addr) ((addr) + (uint32_t)sizeof(uint32_t))
+
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_SO_DEV		(0U << 4)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_SO_DEV	(1U << 4)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SO_DEV		(2U << 4)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_SO_DEV	(3U << 4)
+
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_NORMAL		(0U << 8)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_NORMAL	(1U << 8)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_NORMAL		(2U << 8)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_NORMAL	(3U << 8)
+
+#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_ZERO				(0U << 12)
+#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_CLIENT_AXI_ID		(1U << 12)
+
+/*******************************************************************************
+ * Memory Controller transaction override config registers
+ ******************************************************************************/
+#define MC_TXN_OVERRIDE_CONFIG_HDAR				0x10a8U
+#define MC_TXN_OVERRIDE_CONFIG_DLA1WRA				0x1624U
+#define MC_TXN_OVERRIDE_CONFIG_PCIE1W				0x16dcU
+#define MC_TXN_OVERRIDE_CONFIG_PVA0RDC				0x1644U
+#define MC_TXN_OVERRIDE_CONFIG_PTCR				0x1000U
+#define MC_TXN_OVERRIDE_CONFIG_EQOSW				0x1478U
+#define MC_TXN_OVERRIDE_CONFIG_MPCOREW				0x11c8U
+#define MC_TXN_OVERRIDE_CONFIG_DLA1FALWRB			0x162cU
+#define MC_TXN_OVERRIDE_CONFIG_AXISR				0x1460U
+#define MC_TXN_OVERRIDE_CONFIG_PVA0WRB				0x1654U
+#define MC_TXN_OVERRIDE_CONFIG_MIU6R				0x17f4U
+#define MC_TXN_OVERRIDE_CONFIG_MIU5R				0x17e4U
+#define MC_TXN_OVERRIDE_CONFIG_NVENCSRD1			0x1784U
+#define MC_TXN_OVERRIDE_CONFIG_PCIE0R				0x16c4U
+#define MC_TXN_OVERRIDE_CONFIG_EQOSR				0x1470U
+#define MC_TXN_OVERRIDE_CONFIG_NVENCSRD				0x10e0U
+#define MC_TXN_OVERRIDE_CONFIG_NVENC1SRD1			0x178cU
+#define MC_TXN_OVERRIDE_CONFIG_PVA1RDB1				0x1774U
+#define MC_TXN_OVERRIDE_CONFIG_NVENC1SWR			0x16bcU
+#define MC_TXN_OVERRIDE_CONFIG_VICSRD1				0x1510U
+#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAR				0x14a8U
+#define MC_TXN_OVERRIDE_CONFIG_VIW				0x1390U
+#define MC_TXN_OVERRIDE_CONFIG_PCIE5R				0x1714U
+#define MC_TXN_OVERRIDE_CONFIG_AXISW				0x1468U
+#define MC_TXN_OVERRIDE_CONFIG_MIU6W				0x17fcU
+#define MC_TXN_OVERRIDE_CONFIG_UFSHCR				0x1480U
+#define MC_TXN_OVERRIDE_CONFIG_PCIE0R1				0x179cU
+#define MC_TXN_OVERRIDE_CONFIG_PVA0RDB1				0x1764U
+#define MC_TXN_OVERRIDE_CONFIG_TSECSWR				0x12a8U
+#define MC_TXN_OVERRIDE_CONFIG_MIU7R				0x1008U
+#define MC_TXN_OVERRIDE_CONFIG_SATAR				0x10f8U
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTW			0x1258U
+#define MC_TXN_OVERRIDE_CONFIG_DLA0RDA				0x15f4U
+#define MC_TXN_OVERRIDE_CONFIG_TSECSWRB				0x1438U
+#define MC_TXN_OVERRIDE_CONFIG_NVDEC1SWR			0x17dcU
+#define MC_TXN_OVERRIDE_CONFIG_PVA1RDA1				0x176cU
+#define MC_TXN_OVERRIDE_CONFIG_PVA1RDB				0x166cU
+#define MC_TXN_OVERRIDE_CONFIG_AONDMAW				0x14d0U
+#define MC_TXN_OVERRIDE_CONFIG_AONW				0x14c0U
+#define MC_TXN_OVERRIDE_CONFIG_ETRR				0x1420U
+#define MC_TXN_OVERRIDE_CONFIG_PCIE2AW				0x16ecU
+#define MC_TXN_OVERRIDE_CONFIG_PCIE1R				0x16d4U
+#define MC_TXN_OVERRIDE_CONFIG_PVA1RDC				0x1674U
+#define MC_TXN_OVERRIDE_CONFIG_PVA0WRA				0x164cU
+#define MC_TXN_OVERRIDE_CONFIG_TSECSRDB				0x1430U
+#define MC_TXN_OVERRIDE_CONFIG_MIU1W				0x1548U
+#define MC_TXN_OVERRIDE_CONFIG_PCIE0W				0x16ccU
+#define MC_TXN_OVERRIDE_CONFIG_NVDEC1SRD			0x17ccU
+#define MC_TXN_OVERRIDE_CONFIG_MIU7W				0x1010U
+#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD1			0x1518U
+#define MC_TXN_OVERRIDE_CONFIG_MIU3R				0x1580U
+#define MC_TXN_OVERRIDE_CONFIG_MIU3W				0x158cU
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTR			0x1250U
+#define MC_TXN_OVERRIDE_CONFIG_SESRD				0x1400U
+#define MC_TXN_OVERRIDE_CONFIG_SCER				0x14d8U
+#define MC_TXN_OVERRIDE_CONFIG_MPCORER				0x1138U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCWA				0x1320U
+#define MC_TXN_OVERRIDE_CONFIG_HDAW				0x11a8U
+#define MC_TXN_OVERRIDE_CONFIG_NVDECSWR				0x13c8U
+#define MC_TXN_OVERRIDE_CONFIG_PVA0RDA				0x1634U
+#define MC_TXN_OVERRIDE_CONFIG_AONDMAR				0x14c8U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAB				0x1338U
+#define MC_TXN_OVERRIDE_CONFIG_ISPFALR				0x1228U
+#define MC_TXN_OVERRIDE_CONFIG_PVA0RDA1				0x175cU
+#define MC_TXN_OVERRIDE_CONFIG_NVENC1SRD			0x16b4U
+#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR1			0x1508U
+#define MC_TXN_OVERRIDE_CONFIG_PVA1RDA				0x1664U
+#define MC_TXN_OVERRIDE_CONFIG_DLA0RDA1				0x174cU
+#define MC_TXN_OVERRIDE_CONFIG_ISPWB				0x1238U
+#define MC_TXN_OVERRIDE_CONFIG_APEW				0x13d8U
+#define MC_TXN_OVERRIDE_CONFIG_AXIAPR				0x1410U
+#define MC_TXN_OVERRIDE_CONFIG_PCIE2AR				0x16e4U
+#define MC_TXN_OVERRIDE_CONFIG_ISPFALW				0x1724U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCR				0x1310U
+#define MC_TXN_OVERRIDE_CONFIG_MIU2W				0x1578U
+#define MC_TXN_OVERRIDE_CONFIG_RCER				0x1694U
+#define MC_TXN_OVERRIDE_CONFIG_PCIE4W				0x170cU
+#define MC_TXN_OVERRIDE_CONFIG_BPMPW				0x14a0U
+#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR			0x1490U
+#define MC_TXN_OVERRIDE_CONFIG_ISPRA				0x1220U
+#define MC_TXN_OVERRIDE_CONFIG_NVJPGSWR				0x13f8U
+#define MC_TXN_OVERRIDE_CONFIG_VICSRD				0x1360U
+#define MC_TXN_OVERRIDE_CONFIG_NVDEC1SRD1			0x17d4U
+#define MC_TXN_OVERRIDE_CONFIG_DLA1RDA				0x1614U
+#define MC_TXN_OVERRIDE_CONFIG_SCEDMAW				0x14f0U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCW				0x1330U
+#define MC_TXN_OVERRIDE_CONFIG_DLA1FALRDB			0x161cU
+#define MC_TXN_OVERRIDE_CONFIG_APEDMAR				0x14f8U
+#define MC_TXN_OVERRIDE_CONFIG_RCEW				0x169cU
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAB				0x1318U
+#define MC_TXN_OVERRIDE_CONFIG_DLA0WRA				0x1604U
+#define MC_TXN_OVERRIDE_CONFIG_VIFALR				0x15e4U
+#define MC_TXN_OVERRIDE_CONFIG_PCIE3R				0x16f4U
+#define MC_TXN_OVERRIDE_CONFIG_MIU1R				0x1540U
+#define MC_TXN_OVERRIDE_CONFIG_PCIE5W				0x171cU
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVR			0x1260U
+#define MC_TXN_OVERRIDE_CONFIG_MIU0W				0x1538U
+#define MC_TXN_OVERRIDE_CONFIG_DLA0FALWRB			0x160cU
+#define MC_TXN_OVERRIDE_CONFIG_VIFALW				0x15ecU
+#define MC_TXN_OVERRIDE_CONFIG_DLA0FALRDB			0x15fcU
+#define MC_TXN_OVERRIDE_CONFIG_PCIE3W				0x16fcU
+#define MC_TXN_OVERRIDE_CONFIG_MIU0R				0x1530U
+#define MC_TXN_OVERRIDE_CONFIG_PVA0WRC				0x165cU
+#define MC_TXN_OVERRIDE_CONFIG_SCEDMAR				0x14e8U
+#define MC_TXN_OVERRIDE_CONFIG_APEDMAW				0x1500U
+#define MC_TXN_OVERRIDE_CONFIG_HOST1XDMAR			0x10b0U
+#define MC_TXN_OVERRIDE_CONFIG_SESWR				0x1408U
+#define MC_TXN_OVERRIDE_CONFIG_AXIAPW				0x1418U
+#define MC_TXN_OVERRIDE_CONFIG_MIU4R				0x1594U
+#define MC_TXN_OVERRIDE_CONFIG_MIU4W				0x159cU
+#define MC_TXN_OVERRIDE_CONFIG_NVJPGSRD				0x13f0U
+#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD				0x13c0U
+#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAW				0x14b0U
+#define MC_TXN_OVERRIDE_CONFIG_APER				0x13d0U
+#define MC_TXN_OVERRIDE_CONFIG_DLA1RDA1				0x1754U
+#define MC_TXN_OVERRIDE_CONFIG_PVA1WRB				0x1684U
+#define MC_TXN_OVERRIDE_CONFIG_ISPWA				0x1230U
+#define MC_TXN_OVERRIDE_CONFIG_PVA1WRC				0x168cU
+#define MC_TXN_OVERRIDE_CONFIG_RCEDMAR				0x16a4U
+#define MC_TXN_OVERRIDE_CONFIG_ISPRA1				0x1794U
+#define MC_TXN_OVERRIDE_CONFIG_AONR				0x14b8U
+#define MC_TXN_OVERRIDE_CONFIG_RCEDMAW				0x16acU
+#define MC_TXN_OVERRIDE_CONFIG_UFSHCW				0x1488U
+#define MC_TXN_OVERRIDE_CONFIG_ETRW				0x1428U
+#define MC_TXN_OVERRIDE_CONFIG_SATAW				0x11e8U
+#define MC_TXN_OVERRIDE_CONFIG_VICSWR				0x1368U
+#define MC_TXN_OVERRIDE_CONFIG_NVENCSWR				0x1158U
+#define MC_TXN_OVERRIDE_CONFIG_PCIE5R1				0x177cU
+#define MC_TXN_OVERRIDE_CONFIG_PVA0RDB				0x163cU
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCRA				0x1300U
+#define MC_TXN_OVERRIDE_CONFIG_PVA1WRA				0x167cU
+#define MC_TXN_OVERRIDE_CONFIG_MIU5W				0x17ecU
+#define MC_TXN_OVERRIDE_CONFIG_BPMPR				0x1498U
+#define MC_TXN_OVERRIDE_CONFIG_MIU2R				0x1570U
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVW			0x1268U
+#define MC_TXN_OVERRIDE_CONFIG_TSECSRD				0x12a0U
+#define MC_TXN_OVERRIDE_CONFIG_PCIE4R				0x1704U
+#define MC_TXN_OVERRIDE_CONFIG_SCEW				0x14e0U
+
+#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_CGID			(1U << 0)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV			(2U << 4)
+#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_CLIENT	(1U << 12)
+
+/*******************************************************************************
+ * Non-SO_DEV transactions override values for CGID_TAG bitfield for the
+ * MC_TXN_OVERRIDE_CONFIG_{module} registers
+ ******************************************************************************/
+#define MC_TXN_OVERRIDE_CGID_TAG_DEFAULT			0U
+#define MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID			1U
+#define MC_TXN_OVERRIDE_CGID_TAG_ZERO				2U
+#define MC_TXN_OVERRIDE_CGID_TAG_ADR				3U
+#define MC_TXN_OVERRIDE_CGID_TAG_MASK				3ULL
+
+/*******************************************************************************
+ * Memory Controller Reset Control registers
+ ******************************************************************************/
+#define MC_CLIENT_HOTRESET_CTRL0				0x200U
+#define  MC_CLIENT_HOTRESET_CTRL0_RESET_VAL			0U
+#define  MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB			(1U << 0)
+#define  MC_CLIENT_HOTRESET_CTRL0_HC_FLUSH_ENB			(1U << 6)
+#define  MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB			(1U << 7)
+#define  MC_CLIENT_HOTRESET_CTRL0_ISP2_FLUSH_ENB		(1U << 8)
+#define  MC_CLIENT_HOTRESET_CTRL0_MPCORE_FLUSH_ENB		(1U << 9)
+#define  MC_CLIENT_HOTRESET_CTRL0_NVENC_FLUSH_ENB		(1U << 11)
+#define  MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB		(1U << 15)
+#define  MC_CLIENT_HOTRESET_CTRL0_VI_FLUSH_ENB			(1U << 17)
+#define  MC_CLIENT_HOTRESET_CTRL0_VIC_FLUSH_ENB			(1U << 18)
+#define  MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB		(1U << 19)
+#define  MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB		(1U << 20)
+#define  MC_CLIENT_HOTRESET_CTRL0_TSEC_FLUSH_ENB		(1U << 22)
+#define  MC_CLIENT_HOTRESET_CTRL0_SDMMC1A_FLUSH_ENB		(1U << 29)
+#define  MC_CLIENT_HOTRESET_CTRL0_SDMMC2A_FLUSH_ENB		(1U << 30)
+#define  MC_CLIENT_HOTRESET_CTRL0_SDMMC3A_FLUSH_ENB		(1U << 31)
+#define MC_CLIENT_HOTRESET_STATUS0				0x204U
+#define MC_CLIENT_HOTRESET_CTRL1				0x970U
+#define  MC_CLIENT_HOTRESET_CTRL1_RESET_VAL			0U
+#define  MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB		(1U << 0)
+#define  MC_CLIENT_HOTRESET_CTRL1_GPU_FLUSH_ENB			(1U << 2)
+#define  MC_CLIENT_HOTRESET_CTRL1_NVDEC_FLUSH_ENB		(1U << 5)
+#define  MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB			(1U << 6)
+#define  MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB			(1U << 7)
+#define  MC_CLIENT_HOTRESET_CTRL1_NVJPG_FLUSH_ENB		(1U << 8)
+#define  MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB			(1U << 12)
+#define  MC_CLIENT_HOTRESET_CTRL1_TSECB_FLUSH_ENB		(1U << 13)
+#define  MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB		(1U << 17)
+#define  MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB		(1U << 18)
+#define  MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB		(1U << 19)
+#define  MC_CLIENT_HOTRESET_CTRL1_NVDISPLAY_FLUSH_ENB		(1U << 20)
+#define  MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB		(1U << 21)
+#define  MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB			(1U << 22)
+#define  MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB			(1U << 23)
+#define  MC_CLIENT_HOTRESET_CTRL1_VIFAL_FLUSH_ENB		(1U << 26)
+#define  MC_CLIENT_HOTRESET_CTRL1_RCE_FLUSH_ENB			(1U << 31)
+#define MC_CLIENT_HOTRESET_STATUS1				0x974U
+#define MC_CLIENT_HOTRESET_CTRL2				0x97cU
+#define  MC_CLIENT_HOTRESET_CTRL2_RESET_VAL			0U
+#define  MC_CLIENT_HOTRESET_CTRL2_RCEDMA_FLUSH_ENB		(1U << 0)
+#define  MC_CLIENT_HOTRESET_CTRL2_PCIE_FLUSH_ENB		(1U << 2)
+#define  MC_CLIENT_HOTRESET_CTRL2_PCIE5A_FLUSH_ENB		(1U << 4)
+#define  MC_CLIENT_HOTRESET_CTRL2_AONDMA_FLUSH_ENB		(1U << 9)
+#define  MC_CLIENT_HOTRESET_CTRL2_BPMPDMA_FLUSH_ENB		(1U << 10)
+#define  MC_CLIENT_HOTRESET_CTRL2_SCEDMA_FLUSH_ENB		(1U << 11)
+#define  MC_CLIENT_HOTRESET_CTRL2_APEDMA_FLUSH_ENB		(1U << 14)
+#define  MC_CLIENT_HOTRESET_CTRL2_PCIE3A_FLUSH_ENB		(1U << 16)
+#define  MC_CLIENT_HOTRESET_CTRL2_PCIE3_FLUSH_ENB		(1U << 17)
+#define  MC_CLIENT_HOTRESET_CTRL2_PCIE0A_FLUSH_ENB		(1U << 22)
+#define  MC_CLIENT_HOTRESET_CTRL2_PCIE0A2_FLUSH_ENB		(1U << 23)
+#define  MC_CLIENT_HOTRESET_CTRL2_PCIE4A_FLUSH_ENB		(1U << 25)
+#define MC_CLIENT_HOTRESET_STATUS2				0x1898U
+
+#define MC_COALESCE_CTRL					0x2930U
+#define  MC_COALESCE_CTRL_COALESCER_ENABLE			(1U << 31)
+
+/*******************************************************************************
+ * Tegra TSA Controller constants
+ ******************************************************************************/
+#define TEGRA_TSA_BASE						U(0x02000000)
+
+#define TSA_CONFIG_STATIC0_CSR_RESET_R				0x20000000U
+#define TSA_CONFIG_STATIC0_CSW_RESET_W				0x20001000U
+#define TSA_CONFIG_STATIC0_CSW_RESET_SO_DEV			0x20001000U
+
+#define TSA_CONFIG_STATIC0_CSW_PCIE1W				0x1004U
+#define TSA_CONFIG_STATIC0_CSW_PCIE2AW				0x1008U
+#define TSA_CONFIG_STATIC0_CSW_PCIE3W				0x100cU
+#define TSA_CONFIG_STATIC0_CSW_PCIE4W				0x1028U
+#define TSA_CONFIG_STATIC0_CSW_XUSB_DEVW			0x2004U
+#define TSA_CONFIG_STATIC0_CSR_SATAR				0x2010U
+#define TSA_CONFIG_STATIC0_CSW_SATAW				0x2014U
+#define TSA_CONFIG_STATIC0_CSW_PCIE0W				0x2020U
+#define TSA_CONFIG_STATIC0_CSW_XUSB_HOSTW			0x202cU
+#define TSA_CONFIG_STATIC0_CSW_NVENC1SWR			0x3004U
+#define TSA_CONFIG_STATIC0_CSW_NVENCSWR				0x3010U
+#define TSA_CONFIG_STATIC0_CSW_NVDEC1SWR			0x4004U
+#define TSA_CONFIG_STATIC0_CSR_ISPFALR				0x4010U
+#define TSA_CONFIG_STATIC0_CSW_ISPWA				0x4014U
+#define TSA_CONFIG_STATIC0_CSW_ISPWB				0x4018U
+#define TSA_CONFIG_STATIC0_CSW_ISPFALW				0x401cU
+#define TSA_CONFIG_STATIC0_CSW_NVDECSWR				0x5004U
+#define TSA_CONFIG_STATIC0_CSR_EQOSR				0x5010U
+#define TSA_CONFIG_STATIC0_CSW_EQOSW				0x5014U
+#define TSA_CONFIG_STATIC0_CSR_SDMMCRAB				0x5020U
+#define TSA_CONFIG_STATIC0_CSW_SDMMCWAB				0x5024U
+#define TSA_CONFIG_STATIC0_CSW_UFSHCW				0x6004U
+#define TSA_CONFIG_STATIC0_CSR_SDMMCR				0x6010U
+#define TSA_CONFIG_STATIC0_CSR_SDMMCRA				0x6014U
+#define TSA_CONFIG_STATIC0_CSW_SDMMCW				0x6018U
+#define TSA_CONFIG_STATIC0_CSW_SDMMCWA				0x601cU
+#define TSA_CONFIG_STATIC0_CSR_RCER				0x6030U
+#define TSA_CONFIG_STATIC0_CSR_RCEDMAR				0x6034U
+#define TSA_CONFIG_STATIC0_CSW_RCEW				0x6038U
+#define TSA_CONFIG_STATIC0_CSW_RCEDMAW				0x603cU
+#define TSA_CONFIG_STATIC0_CSR_SCER				0x6050U
+#define TSA_CONFIG_STATIC0_CSR_SCEDMAR				0x6054U
+#define TSA_CONFIG_STATIC0_CSW_SCEW				0x6058U
+#define TSA_CONFIG_STATIC0_CSW_SCEDMAW				0x605cU
+#define TSA_CONFIG_STATIC0_CSR_AXIAPR				0x7004U
+#define TSA_CONFIG_STATIC0_CSR_ETRR				0x7008U
+#define TSA_CONFIG_STATIC0_CSR_HOST1XDMAR			0x700cU
+#define TSA_CONFIG_STATIC0_CSW_AXIAPW				0x7010U
+#define TSA_CONFIG_STATIC0_CSW_ETRW				0x7014U
+#define TSA_CONFIG_STATIC0_CSR_NVJPGSRD				0x8004U
+#define TSA_CONFIG_STATIC0_CSW_NVJPGSWR				0x8008U
+#define TSA_CONFIG_STATIC0_CSR_AXISR				0x8014U
+#define TSA_CONFIG_STATIC0_CSW_AXISW				0x8018U
+#define TSA_CONFIG_STATIC0_CSR_BPMPR				0x9004U
+#define TSA_CONFIG_STATIC0_CSR_BPMPDMAR				0x9008U
+#define TSA_CONFIG_STATIC0_CSW_BPMPW				0x900cU
+#define TSA_CONFIG_STATIC0_CSW_BPMPDMAW				0x9010U
+#define TSA_CONFIG_STATIC0_CSR_SESRD				0x9024U
+#define TSA_CONFIG_STATIC0_CSR_TSECSRD				0x9028U
+#define TSA_CONFIG_STATIC0_CSR_TSECSRDB				0x902cU
+#define TSA_CONFIG_STATIC0_CSW_SESWR				0x9030U
+#define TSA_CONFIG_STATIC0_CSW_TSECSWR				0x9034U
+#define TSA_CONFIG_STATIC0_CSW_TSECSWRB				0x9038U
+#define TSA_CONFIG_STATIC0_CSW_PCIE5W				0xb004U
+#define TSA_CONFIG_STATIC0_CSW_VICSWR				0xc004U
+#define TSA_CONFIG_STATIC0_CSR_APER				0xd004U
+#define TSA_CONFIG_STATIC0_CSR_APEDMAR				0xd008U
+#define TSA_CONFIG_STATIC0_CSW_APEW				0xd00cU
+#define TSA_CONFIG_STATIC0_CSW_APEDMAW				0xd010U
+#define TSA_CONFIG_STATIC0_CSR_HDAR				0xf004U
+#define TSA_CONFIG_STATIC0_CSW_HDAW				0xf008U
+#define TSA_CONFIG_STATIC0_CSR_NVDISPLAYR			0xf014U
+#define TSA_CONFIG_STATIC0_CSR_VIFALR				0x10004U
+#define TSA_CONFIG_STATIC0_CSW_VIW				0x10008U
+#define TSA_CONFIG_STATIC0_CSW_VIFALW				0x1000cU
+#define TSA_CONFIG_STATIC0_CSR_AONR				0x12004U
+#define TSA_CONFIG_STATIC0_CSR_AONDMAR				0x12008U
+#define TSA_CONFIG_STATIC0_CSW_AONW				0x1200cU
+#define TSA_CONFIG_STATIC0_CSW_AONDMAW				0x12010U
+#define TSA_CONFIG_STATIC0_CSR_PCIE1R				0x14004U
+#define TSA_CONFIG_STATIC0_CSR_PCIE2AR				0x14008U
+#define TSA_CONFIG_STATIC0_CSR_PCIE3R				0x1400cU
+#define TSA_CONFIG_STATIC0_CSR_PCIE4R				0x14028U
+#define TSA_CONFIG_STATIC0_CSR_XUSB_DEVR			0x15004U
+#define TSA_CONFIG_STATIC0_CSR_XUSB_HOSTR			0x15010U
+#define TSA_CONFIG_STATIC0_CSR_UFSHCR				0x16004U
+#define TSA_CONFIG_STATIC0_CSW_DLA1WRA				0x18004U
+#define TSA_CONFIG_STATIC0_CSR_DLA1FALRDB			0x18010U
+#define TSA_CONFIG_STATIC0_CSW_DLA1FALWRB			0x18014U
+#define TSA_CONFIG_STATIC0_CSW_DLA0WRA				0x19004U
+#define TSA_CONFIG_STATIC0_CSR_DLA0FALRDB			0x19010U
+#define TSA_CONFIG_STATIC0_CSW_DLA0FALWRB			0x19014U
+#define TSA_CONFIG_STATIC0_CSR_PVA1RDC				0x1a004U
+#define TSA_CONFIG_STATIC0_CSW_PVA1WRC				0x1a008U
+#define TSA_CONFIG_STATIC0_CSW_PVA1WRA				0x1a014U
+#define TSA_CONFIG_STATIC0_CSW_PVA1WRB				0x1a020U
+#define TSA_CONFIG_STATIC0_CSW_PVA0WRB				0x1b004U
+#define TSA_CONFIG_STATIC0_CSR_PVA0RDC				0x1b010U
+#define TSA_CONFIG_STATIC0_CSW_PVA0WRC				0x1b014U
+#define TSA_CONFIG_STATIC0_CSW_PVA0WRA				0x1b020U
+#define TSA_CONFIG_STATIC0_CSR_NVENC1SRD			0x1d004U
+#define TSA_CONFIG_STATIC0_CSR_NVENCSRD				0x1d010U
+#define TSA_CONFIG_STATIC0_CSR_NVDEC1SRD			0x1e004U
+#define TSA_CONFIG_STATIC0_CSR_ISPRA				0x1e010U
+#define TSA_CONFIG_STATIC0_CSR_NVDECSRD				0x1f004U
+#define TSA_CONFIG_STATIC0_CSR_PCIE0R				0x21004U
+#define TSA_CONFIG_STATIC0_CSR_PCIE5R				0x23004U
+#define TSA_CONFIG_STATIC0_CSR_VICSRD				0x24004U
+#define TSA_CONFIG_STATIC0_CSR_DLA1RDA				0x26004U
+#define TSA_CONFIG_STATIC0_CSR_DLA0RDA				0x27004U
+#define TSA_CONFIG_STATIC0_CSR_PVA1RDA				0x28004U
+#define TSA_CONFIG_STATIC0_CSR_PVA1RDB				0x28010U
+#define TSA_CONFIG_STATIC0_CSR_PVA0RDB				0x29004U
+#define TSA_CONFIG_STATIC0_CSR_PVA0RDA				0x29010U
+
+#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK			(ULL(0x3) << 11)
+#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU			(ULL(0) << 11)
+
+#endif /* TEGRA_MC_DEF_H */
diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h
index 34a096c..761acde 100644
--- a/plat/nvidia/tegra/include/tegra_private.h
+++ b/plat/nvidia/tegra/include/tegra_private.h
@@ -76,7 +76,7 @@
 
 /* Declarations for plat_setup.c */
 const mmap_region_t *plat_get_mmio_map(void);
-uint32_t plat_get_console_from_id(int32_t id);
+void plat_enable_console(int32_t id);
 void plat_gic_setup(void);
 struct tegra_bl31_params *plat_get_bl31_params(void);
 plat_params_from_bl2_t *plat_get_bl31_plat_params(void);
@@ -97,8 +97,6 @@
 void tegra_security_setup_videomem(uintptr_t base, uint64_t size);
 
 /* Declarations for tegra_pm.c */
-extern uint8_t tegra_fake_system_suspend;
-
 void tegra_pm_system_suspend_entry(void);
 void tegra_pm_system_suspend_exit(void);
 int32_t tegra_system_suspended(void);
@@ -139,7 +137,6 @@
 void tegra_delay_timer_init(void);
 
 void tegra_secure_entrypoint(void);
-void tegra186_cpu_reset_handler(void);
 
 /* Declarations for tegra_sip_calls.c */
 uintptr_t tegra_sip_handler(uint32_t smc_fid,
diff --git a/plat/nvidia/tegra/scat/bl31.scat b/plat/nvidia/tegra/scat/bl31.scat
index 2f5fd9e..2d6d2b3 100644
--- a/plat/nvidia/tegra/scat/bl31.scat
+++ b/plat/nvidia/tegra/scat/bl31.scat
@@ -95,7 +95,7 @@
 	/* cpu_ops must always be defined */
 	ScatterAssert(ImageLength(__CPU_OPS__) > 0)
 
-#if ENABLE_SPM
+#if SPM_MM
 LR_SPM +0
 {
 	/*
diff --git a/plat/nvidia/tegra/soc/t132/plat_setup.c b/plat/nvidia/tegra/soc/t132/plat_setup.c
index 570acd9..df62678 100644
--- a/plat/nvidia/tegra/soc/t132/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t132/plat_setup.c
@@ -6,9 +6,11 @@
 
 #include <arch_helpers.h>
 #include <common/bl_common.h>
+#include <drivers/console.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
 #include <tegra_def.h>
+#include <tegra_platform.h>
 #include <tegra_private.h>
 
 /* sets of MMIO ranges setup */
@@ -85,14 +87,30 @@
 };
 
 /*******************************************************************************
- * Retrieve the UART controller base to be used as the console
+ * Enable console corresponding to the console ID
  ******************************************************************************/
-uint32_t plat_get_console_from_id(int id)
+void plat_enable_console(int32_t id)
 {
-	if (id > TEGRA132_MAX_UART_PORTS)
-		return 0;
+	static console_16550_t uart_console;
+	uint32_t console_clock;
+
+	if ((id > 0) && (id < TEGRA132_MAX_UART_PORTS)) {
+		/*
+		 * Reference clock used by the FPGAs is a lot slower.
+		 */
+		if (tegra_platform_is_fpga()) {
+			console_clock = TEGRA_BOOT_UART_CLK_13_MHZ;
+		} else {
+			console_clock = TEGRA_BOOT_UART_CLK_408_MHZ;
+		}
 
-	return tegra132_uart_addresses[id];
+		(void)console_16550_register(tegra132_uart_addresses[id],
+					     console_clock,
+					     TEGRA_CONSOLE_BAUDRATE,
+					     &uart_console);
+		console_set_scope(&uart_console.console, CONSOLE_FLAG_BOOT |
+			CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
+	}
 }
 
 /*******************************************************************************
diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c
index ef0ba4e..1018caa 100644
--- a/plat/nvidia/tegra/soc/t186/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t186/plat_setup.c
@@ -141,19 +141,30 @@
 };
 
 /*******************************************************************************
- * Retrieve the UART controller base to be used as the console
+ * Enable console corresponding to the console ID
  ******************************************************************************/
-uint32_t plat_get_console_from_id(int32_t id)
+void plat_enable_console(int32_t id)
 {
-	uint32_t ret;
+	static console_16550_t uart_console;
+	uint32_t console_clock;
 
-	if (id > TEGRA186_MAX_UART_PORTS) {
-		ret = 0;
-	} else {
-		ret = tegra186_uart_addresses[id];
-	}
+	if ((id > 0) && (id < TEGRA186_MAX_UART_PORTS)) {
+		/*
+		 * Reference clock used by the FPGAs is a lot slower.
+		 */
+		if (tegra_platform_is_fpga()) {
+			console_clock = TEGRA_BOOT_UART_CLK_13_MHZ;
+		} else {
+			console_clock = TEGRA_BOOT_UART_CLK_408_MHZ;
+		}
 
-	return ret;
+		(void)console_16550_register(tegra186_uart_addresses[id],
+					     console_clock,
+					     TEGRA_CONSOLE_BAUDRATE,
+					     &uart_console);
+		console_set_scope(&uart_console.console, CONSOLE_FLAG_BOOT |
+			CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
+	}
 }
 
 /*******************************************************************************
diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h b/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h
new file mode 100644
index 0000000..9741d08
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MCE_PRIVATE_H
+#define MCE_PRIVATE_H
+
+#include <stdbool.h>
+#include <tegra_def.h>
+
+/*******************************************************************************
+ * Macros to prepare CSTATE info request
+ ******************************************************************************/
+/* Description of the parameters for UPDATE_CSTATE_INFO request */
+#define CLUSTER_CSTATE_MASK			0x7U
+#define CLUSTER_CSTATE_SHIFT			0X0U
+#define CLUSTER_CSTATE_UPDATE_BIT		(1U << 7)
+#define CCPLEX_CSTATE_MASK			0x7U
+#define CCPLEX_CSTATE_SHIFT			8U
+#define CCPLEX_CSTATE_UPDATE_BIT		(1U << 15)
+#define SYSTEM_CSTATE_MASK			0xFU
+#define SYSTEM_CSTATE_SHIFT			16U
+#define SYSTEM_CSTATE_UPDATE_BIT		(1U << 23)
+#define CSTATE_WAKE_MASK_UPDATE_BIT		(1U << 31)
+#define CSTATE_WAKE_MASK_SHIFT			32U
+#define CSTATE_WAKE_MASK_CLEAR			0xFFFFFFFFU
+
+/*******************************************************************************
+ * Core ID mask (bits 3:0 in the online request)
+ ******************************************************************************/
+#define MCE_CORE_ID_MASK			0xFU
+
+/*******************************************************************************
+ * C-state statistics macros
+ ******************************************************************************/
+#define MCE_STAT_ID_SHIFT			16U
+
+/*******************************************************************************
+ * Security config macros
+ ******************************************************************************/
+#define STRICT_CHECKING_ENABLED_SET		(1UL << 0)
+#define STRICT_CHECKING_LOCKED_SET		(1UL << 1)
+
+/* declarations for NVG handler functions */
+uint64_t nvg_get_version(void);
+int32_t nvg_enable_power_perf_mode(void);
+int32_t nvg_disable_power_perf_mode(void);
+int32_t nvg_enable_power_saver_modes(void);
+int32_t nvg_disable_power_saver_modes(void);
+void nvg_set_wake_time(uint32_t wake_time);
+void nvg_update_cstate_info(uint32_t cluster, uint32_t ccplex,
+		uint32_t system, uint32_t wake_mask, uint8_t update_wake_mask);
+int32_t nvg_set_cstate_stat_query_value(uint64_t data);
+uint64_t nvg_get_cstate_stat_query_value(void);
+int32_t nvg_is_sc7_allowed(void);
+int32_t nvg_online_core(uint32_t core);
+int32_t nvg_update_ccplex_gsc(uint32_t gsc_idx);
+int32_t nvg_roc_clean_cache(void);
+int32_t nvg_roc_flush_cache(void);
+int32_t nvg_roc_clean_cache_trbits(void);
+int32_t nvg_enter_cstate(uint32_t state, uint32_t wake_time);
+void nvg_set_request_data(uint64_t req, uint64_t data);
+void nvg_set_request(uint64_t req);
+uint64_t nvg_get_result(void);
+uint64_t nvg_cache_clean(void);
+uint64_t nvg_cache_clean_inval(void);
+uint64_t nvg_cache_inval_all(void);
+void nvg_enable_strict_checking_mode(void);
+void nvg_system_shutdown(void);
+void nvg_system_reboot(void);
+
+/* MCE helper functions */
+void mce_enable_strict_checking(void);
+void mce_system_shutdown(void);
+void mce_system_reboot(void);
+
+#endif /* MCE_PRIVATE_H */
diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/se.h b/plat/nvidia/tegra/soc/t194/drivers/include/se.h
new file mode 100644
index 0000000..e7cf88d
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/drivers/include/se.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SE_H
+#define SE_H
+
+int32_t tegra_se_suspend(void);
+void tegra_se_resume(void);
+
+#endif /* SE_H */
diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h b/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h
new file mode 100644
index 0000000..06cbb4a
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef T194_NVG_H
+#define T194_NVG_H
+
+/**
+ * t194_nvg.h - Header for the NVIDIA Generic interface (NVG).
+ * Official documentation for this interface is included as part
+ * of the T194 TRM.
+ */
+
+/**
+ * Current version - Major version increments may break backwards
+ * compatiblity and binary compatibility. Minor version increments
+ * occur when there is only new functionality.
+ */
+enum {
+	TEGRA_NVG_VERSION_MAJOR = 6,
+	TEGRA_NVG_VERSION_MINOR = 4
+};
+
+typedef enum {
+	TEGRA_NVG_CHANNEL_VERSION			=  0,
+	TEGRA_NVG_CHANNEL_POWER_PERF			=  1,
+	TEGRA_NVG_CHANNEL_POWER_MODES			=  2,
+	TEGRA_NVG_CHANNEL_WAKE_TIME			=  3,
+	TEGRA_NVG_CHANNEL_CSTATE_INFO			=  4,
+	TEGRA_NVG_CHANNEL_CROSSOVER_C6_LOWER_BOUND	=  5,
+	TEGRA_NVG_CHANNEL_CROSSOVER_CC6_LOWER_BOUND	=  6,
+	TEGRA_NVG_CHANNEL_CROSSOVER_CG7_LOWER_BOUND	=  8,
+	TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_REQUEST	= 10,
+	TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_VALUE	= 11,
+	TEGRA_NVG_CHANNEL_SHUTDOWN			= 42,
+	TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED		= 43,
+	TEGRA_NVG_CHANNEL_ONLINE_CORE			= 44,
+	TEGRA_NVG_CHANNEL_CC3_CTRL			= 45,
+	TEGRA_NVG_CHANNEL_CCPLEX_CACHE_CONTROL		= 49,
+	TEGRA_NVG_CHANNEL_UPDATE_CCPLEX_GSC		= 50,
+	TEGRA_NVG_CHANNEL_HSM_ERROR_CTRL		= 53,
+	TEGRA_NVG_CHANNEL_SECURITY_CONFIG		= 54,
+	TEGRA_NVG_CHANNEL_DEBUG_CONFIG			= 55,
+	TEGRA_NVG_CHANNEL_DDA_SNOC_MCF			= 56,
+	TEGRA_NVG_CHANNEL_DDA_MCF_ORD1			= 57,
+	TEGRA_NVG_CHANNEL_DDA_MCF_ORD2			= 58,
+	TEGRA_NVG_CHANNEL_DDA_MCF_ORD3			= 59,
+	TEGRA_NVG_CHANNEL_DDA_MCF_ISO			= 60,
+	TEGRA_NVG_CHANNEL_DDA_MCF_SISO			= 61,
+	TEGRA_NVG_CHANNEL_DDA_MCF_NISO			= 62,
+	TEGRA_NVG_CHANNEL_DDA_MCF_NISO_REMOTE		= 63,
+	TEGRA_NVG_CHANNEL_DDA_L3CTRL_ISO		= 64,
+	TEGRA_NVG_CHANNEL_DDA_L3CTRL_SISO		= 65,
+	TEGRA_NVG_CHANNEL_DDA_L3CTRL_NISO		= 66,
+	TEGRA_NVG_CHANNEL_DDA_L3CTRL_NISO_REMOTE	= 67,
+	TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3FILL		= 68,
+	TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3WR		= 69,
+	TEGRA_NVG_CHANNEL_DDA_L3CTRL_RSP_L3RD_DMA	= 70,
+	TEGRA_NVG_CHANNEL_DDA_L3CTRL_RSP_MCFRD_DMA	= 71,
+	TEGRA_NVG_CHANNEL_DDA_L3CTRL_GLOBAL		= 72,
+	TEGRA_NVG_CHANNEL_DDA_L3CTRL_LL			= 73,
+	TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3D		= 74,
+	TEGRA_NVG_CHANNEL_DDA_L3CTRL_FCM_RD		= 75,
+	TEGRA_NVG_CHANNEL_DDA_L3CTRL_FCM_WR		= 76,
+	TEGRA_NVG_CHANNEL_DDA_SNOC_GLOBAL_CTRL		= 77,
+	TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REQ_CTRL	= 78,
+	TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REPLENTISH_CTRL = 79,
+
+	TEGRA_NVG_CHANNEL_LAST_INDEX
+} tegra_nvg_channel_id_t;
+
+typedef enum {
+	NVG_STAT_QUERY_SC7_ENTRIES		=  1,
+	NVG_STAT_QUERY_CC6_ENTRIES		=  6,
+	NVG_STAT_QUERY_CG7_ENTRIES		=  7,
+	NVG_STAT_QUERY_C6_ENTRIES		= 10,
+	NVG_STAT_QUERY_C7_ENTRIES		= 14,
+	NVG_STAT_QUERY_SC7_RESIDENCY_SUM	= 32,
+	NVG_STAT_QUERY_CC6_RESIDENCY_SUM	= 41,
+	NVG_STAT_QUERY_CG7_RESIDENCY_SUM	= 46,
+	NVG_STAT_QUERY_C6_RESIDENCY_SUM		= 51,
+	NVG_STAT_QUERY_C7_RESIDENCY_SUM		= 56,
+	NVG_STAT_QUERY_SC7_ENTRY_TIME_SUM	= 60,
+	NVG_STAT_QUERY_CC6_ENTRY_TIME_SUM	= 61,
+	NVG_STAT_QUERY_CG7_ENTRY_TIME_SUM	= 62,
+	NVG_STAT_QUERY_C6_ENTRY_TIME_SUM	= 63,
+	NVG_STAT_QUERY_C7_ENTRY_TIME_SUM	= 64,
+	NVG_STAT_QUERY_SC7_EXIT_TIME_SUM	= 70,
+	NVG_STAT_QUERY_CC6_EXIT_TIME_SUM	= 71,
+	NVG_STAT_QUERY_CG7_EXIT_TIME_SUM	= 72,
+	NVG_STAT_QUERY_C6_EXIT_TIME_SUM		= 73,
+	NVG_STAT_QUERY_C7_EXIT_TIME_SUM		= 74,
+	NVG_STAT_QUERY_SC7_ENTRY_LAST		= 80,
+	NVG_STAT_QUERY_CC6_ENTRY_LAST		= 81,
+	NVG_STAT_QUERY_CG7_ENTRY_LAST		= 82,
+	NVG_STAT_QUERY_C6_ENTRY_LAST		= 83,
+	NVG_STAT_QUERY_C7_ENTRY_LAST		= 84,
+	NVG_STAT_QUERY_SC7_EXIT_LAST		= 90,
+	NVG_STAT_QUERY_CC6_EXIT_LAST		= 91,
+	NVG_STAT_QUERY_CG7_EXIT_LAST		= 92,
+	NVG_STAT_QUERY_C6_EXIT_LAST		= 93,
+	NVG_STAT_QUERY_C7_EXIT_LAST		= 94
+} tegra_nvg_stat_query_t;
+
+typedef enum {
+	TEGRA_NVG_CORE_C0 = 0,
+	TEGRA_NVG_CORE_C1 = 1,
+	TEGRA_NVG_CORE_C6 = 6,
+	TEGRA_NVG_CORE_C7 = 7,
+	TEGRA_NVG_CORE_WARMRSTREQ = 8
+} tegra_nvg_core_sleep_state_t;
+
+typedef enum {
+	TEGRA_NVG_CLUSTER_CC0 = 0,
+	TEGRA_NVG_CLUSTER_CC6 = 6
+} tegra_nvg_cluster_sleep_state_t;
+
+typedef enum {
+	TEGRA_NVG_CG_CG0 = 0,
+	TEGRA_NVG_CG_CG7 = 7
+} tegra_nvg_cluster_group_sleep_state_t;
+
+typedef enum {
+	TEGRA_NVG_SYSTEM_SC0 = 0,
+	TEGRA_NVG_SYSTEM_SC7 = 7,
+	TEGRA_NVG_SYSTEM_SC8 = 8
+} tegra_nvg_system_sleep_state_t;
+
+typedef enum {
+    TEGRA_NVG_SHUTDOWN = 0U,
+    TEGRA_NVG_REBOOT = 1U,
+} tegra_nvg_shutdown_reboot_state_t;
+
+// ---------------------------------------------------------------------------
+// NVG Data subformats
+// ---------------------------------------------------------------------------
+
+typedef union {
+	uint64_t flat;
+	struct nvg_version_channel_t {
+		uint32_t minor_version	: 32;
+		uint32_t major_version	: 32;
+	} bits;
+} nvg_version_data_t;
+
+typedef union {
+	uint64_t flat;
+	struct nvg_power_perf_channel_t {
+		uint32_t perf_per_watt	: 1;
+		uint32_t reserved_31_1	: 31;
+		uint32_t reserved_63_32	: 32;
+	} bits;
+} nvg_power_perf_channel_t;
+
+typedef union {
+	uint64_t flat;
+	struct nvg_power_modes_channel_t {
+		uint32_t low_battery	: 1;
+		uint32_t reserved_1_1	: 1;
+		uint32_t battery_save	: 1;
+		uint32_t reserved_31_3	: 29;
+		uint32_t reserved_63_32	: 32;
+	} bits;
+} nvg_power_modes_channel_t;
+
+typedef union nvg_channel_1_data_u {
+	uint64_t flat;
+	struct nvg_channel_1_data_s {
+		uint32_t perf_per_watt_mode	: 1;
+		uint32_t reserved_31_1		: 31;
+		uint32_t reserved_63_32		: 32;
+	} bits;
+} nvg_channel_1_data_t;
+
+typedef union {
+	uint64_t flat;
+	struct nvg_ccplex_cache_control_channel_t {
+		uint32_t gpu_ways	: 5;
+		uint32_t reserved_7_5	: 3;
+		uint32_t gpu_only_ways	: 5;
+		uint32_t reserved_31_13	: 19;
+		uint32_t reserved_63_32	: 32;
+	} bits;
+} nvg_ccplex_cache_control_channel_t;
+
+typedef union nvg_channel_2_data_u {
+	uint64_t flat;
+	struct nvg_channel_2_data_s {
+		uint32_t reserved_1_0		: 2;
+		uint32_t battery_saver_mode	: 1;
+		uint32_t reserved_31_3		: 29;
+		uint32_t reserved_63_32		: 32;
+	} bits;
+} nvg_channel_2_data_t;
+
+typedef union {
+	uint64_t flat;
+	struct nvg_wake_time_channel_t {
+		uint32_t wake_time	: 32;
+		uint32_t reserved_63_32	: 32;
+	} bits;
+} nvg_wake_time_channel_t;
+
+typedef union {
+	uint64_t flat;
+	struct nvg_cstate_info_channel_t {
+		uint32_t cluster_state	: 3;
+		uint32_t reserved_6_3	: 4;
+		uint32_t update_cluster	: 1;
+		uint32_t cg_cstate	: 3;
+		uint32_t reserved_14_11	: 4;
+		uint32_t update_cg	: 1;
+		uint32_t system_cstate	: 4;
+		uint32_t reserved_22_20	: 3;
+		uint32_t update_system	: 1;
+		uint32_t reserved_30_24	: 7;
+		uint32_t update_wake_mask : 1;
+		uint32_t wake_mask	: 32;
+	} bits;
+} nvg_cstate_info_channel_t;
+
+typedef union {
+	uint64_t flat;
+	struct nvg_lower_bound_channel_t {
+		uint32_t crossover_value : 32;
+		uint32_t reserved_63_32	: 32;
+	} bits;
+} nvg_lower_bound_channel_t;
+
+typedef union {
+	uint64_t flat;
+	struct nvg_cstate_stat_query_channel_t {
+		uint32_t unit_id	: 4;
+		uint32_t reserved_15_4	: 12;
+		uint32_t stat_id	: 16;
+		uint32_t reserved_63_32	: 32;
+	} bits;
+} nvg_cstate_stat_query_channel_t;
+
+typedef union {
+	uint64_t flat;
+	struct nvg_is_sc7_allowed_channel_t {
+		uint32_t is_sc7_allowed	: 1;
+		uint32_t reserved_31_1	: 31;
+		uint32_t reserved_63_32	: 32;
+	} bits;
+} nvg_is_sc7_allowed_channel_t;
+
+typedef union {
+	uint64_t flat;
+	struct nvg_core_online_channel_t {
+		uint32_t core_id	: 4;
+		uint32_t reserved_31_4	: 28;
+		uint32_t reserved_63_32	: 32;
+	} bits;
+} nvg_core_online_channel_t;
+
+typedef union {
+	uint64_t flat;
+	struct nvg_cc3_control_channel_t {
+		uint32_t freq_req	: 8;
+		uint32_t reserved_30_8	: 23;
+		uint32_t enable		: 1;
+		uint32_t reserved_63_32	: 32;
+	} bits;
+} nvg_cc3_control_channel_t;
+
+typedef enum {
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_ALL		=  0,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_NVDEC		=  1,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_WPR1		=  2,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_WPR2		=  3,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_TSECA		=  4,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_TSECB		=  5,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP		=  6,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_APE		=  7,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_SPE		=  8,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_SCE		=  9,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_APR		=  10,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_TZRAM		=  11,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_IPC_SE_TSEC	=  12,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_RCE	=  13,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_MCE	=  14,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_SE_SC7		=  15,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_SPE	=  16,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_RCE		=  17,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_CPU_TZ_TO_BPMP	=  18,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_VM_ENCR1		=  19,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_CPU_NS_TO_BPMP	=  20,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_OEM_SC7		=  21,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_IPC_SE_SPE_SCE_BPMP = 22,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_SC7_RESUME_FW	=  23,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_CAMERA_TASKLIST	=  24,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_XUSB		=  25,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_CV			=  26,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_VM_ENCR2		=  27,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_HYPERVISOR_SW	=  28,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_SMMU_PAGETABLES	=  29,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_30			=  30,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_31			=  31,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_TZ_DRAM		=  32,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_NVLINK		=  33,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_SBS		=  34,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_VPR		=  35,
+	TEGRA_NVG_CHANNEL_UPDATE_GSC_LAST_INDEX
+} tegra_nvg_channel_update_gsc_gsc_enum_t;
+
+typedef union {
+	uint64_t flat;
+	struct nvg_update_ccplex_gsc_channel_t {
+		uint32_t gsc_enum	: 16;
+		uint32_t reserved_31_16	: 16;
+		uint32_t reserved_63_32	: 32;
+	} bits;
+} nvg_update_ccplex_gsc_channel_t;
+
+typedef union {
+	uint64_t flat;
+	struct nvg_security_config_channel_t {
+		uint32_t strict_checking_enabled : 1;
+		uint32_t strict_checking_locked	: 1;
+		uint32_t reserved_31_2		: 30;
+		uint32_t reserved_63_32		: 32;
+	} bits;
+} nvg_security_config_t;
+
+typedef union {
+	uint64_t flat;
+	struct nvg_shutdown_channel_t {
+		uint32_t reboot		: 1;
+		uint32_t reserved_31_1	: 31;
+		uint32_t reserved_63_32	: 32;
+	} bits;
+} nvg_shutdown_t;
+
+#endif
diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/aarch64/nvg_helpers.S b/plat/nvidia/tegra/soc/t194/drivers/mce/aarch64/nvg_helpers.S
new file mode 100644
index 0000000..3c47208
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/drivers/mce/aarch64/nvg_helpers.S
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+
+	.globl	nvg_set_request_data
+	.globl	nvg_set_request
+	.globl	nvg_get_result
+	.globl	nvg_cache_clean
+	.globl	nvg_cache_clean_inval
+	.globl	nvg_cache_inval_all
+
+/* void nvg_set_request_data(uint64_t req, uint64_t data) */
+func nvg_set_request_data
+	msr	s3_0_c15_c1_2, x0
+	msr	s3_0_c15_c1_3, x1
+	ret
+endfunc nvg_set_request_data
+
+/* void nvg_set_request(uint64_t req) */
+func nvg_set_request
+	msr	s3_0_c15_c1_2, x0
+	ret
+endfunc nvg_set_request
+
+/* uint64_t nvg_get_result(void) */
+func nvg_get_result
+	mrs	x0, s3_0_c15_c1_3
+	ret
+endfunc nvg_get_result
+
+/* uint64_t nvg_cache_clean(void) */
+func nvg_cache_clean
+	mrs	x0, s3_0_c15_c3_5
+	ret
+endfunc nvg_cache_clean
+
+/* uint64_t nvg_cache_clean_inval(void) */
+func nvg_cache_clean_inval
+	mrs	x0, s3_0_c15_c3_6
+	ret
+endfunc nvg_cache_clean_inval
+
+/* uint64_t nvg_cache_inval_all(void) */
+func nvg_cache_inval_all
+	mrs	x0, s3_0_c15_c3_7
+	ret
+endfunc nvg_cache_inval_all
\ No newline at end of file
diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c
new file mode 100644
index 0000000..00c671b
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <common/bl_common.h>
+#include <context.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <common/debug.h>
+#include <denver.h>
+#include <mce.h>
+#include <mce_private.h>
+#include <platform_def.h>
+#include <stdbool.h>
+#include <string.h>
+#include <errno.h>
+#include <t194_nvg.h>
+#include <tegra_def.h>
+#include <tegra_platform.h>
+#include <tegra_private.h>
+
+/* Handler to check if MCE firmware is supported */
+static bool mce_firmware_not_supported(void)
+{
+	bool status;
+
+	/* these platforms do not load MCE firmware */
+	status = tegra_platform_is_linsim() || tegra_platform_is_qt() ||
+		 tegra_platform_is_virt_dev_kit();
+
+	return status;
+}
+
+/*******************************************************************************
+ * Common handler for all MCE commands
+ ******************************************************************************/
+int32_t mce_command_handler(uint64_t cmd, uint64_t arg0, uint64_t arg1,
+			uint64_t arg2)
+{
+	int32_t ret = 0;
+
+	switch (cmd) {
+	case (uint64_t)MCE_CMD_ENTER_CSTATE:
+		ret = nvg_enter_cstate((uint32_t)arg0, (uint32_t)arg1);
+		if (ret < 0) {
+			ERROR("%s: enter_cstate failed(%d)\n", __func__, ret);
+		}
+
+		break;
+
+	case (uint64_t)MCE_CMD_IS_SC7_ALLOWED:
+		ret = nvg_is_sc7_allowed();
+		if (ret < 0) {
+			ERROR("%s: is_sc7_allowed failed(%d)\n", __func__, ret);
+		}
+
+		break;
+
+	case (uint64_t)MCE_CMD_ONLINE_CORE:
+		ret = nvg_online_core((uint32_t)arg0);
+		if (ret < 0) {
+			ERROR("%s: online_core failed(%d)\n", __func__, ret);
+		}
+
+		break;
+
+	default:
+		ERROR("unknown MCE command (%llu)\n", cmd);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/*******************************************************************************
+ * Handler to update carveout values for Video Memory Carveout region
+ ******************************************************************************/
+int32_t mce_update_gsc_videomem(void)
+{
+	int32_t ret;
+
+	/*
+	 * MCE firmware is not running on simulation platforms.
+	 */
+	if (mce_firmware_not_supported()) {
+		ret = -EINVAL;
+	} else {
+		ret = nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_CHANNEL_UPDATE_GSC_VPR);
+	}
+
+	return ret;
+}
+
+/*******************************************************************************
+ * Handler to update carveout values for TZDRAM aperture
+ ******************************************************************************/
+int32_t mce_update_gsc_tzdram(void)
+{
+	int32_t ret;
+
+	/*
+	 * MCE firmware is not running on simulation platforms.
+	 */
+	if (mce_firmware_not_supported()) {
+		ret = -EINVAL;
+	} else {
+		ret = nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_CHANNEL_UPDATE_GSC_TZ_DRAM);
+	}
+
+	return ret;
+}
+
+/*******************************************************************************
+ * Handler to update carveout values for TZ SysRAM aperture
+ ******************************************************************************/
+int32_t mce_update_gsc_tzram(void)
+{
+	int32_t ret;
+
+	/*
+	 * MCE firmware is not running on simulation platforms.
+	 */
+	if (mce_firmware_not_supported()) {
+		ret = -EINVAL;
+	} else {
+		ret = nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_CHANNEL_UPDATE_GSC_TZRAM);
+	}
+
+	return ret;
+}
+
+/*******************************************************************************
+ * Handler to issue the UPDATE_CSTATE_INFO request
+ ******************************************************************************/
+void mce_update_cstate_info(const mce_cstate_info_t *cstate)
+{
+	/* issue the UPDATE_CSTATE_INFO request */
+	nvg_update_cstate_info(cstate->cluster, cstate->ccplex, cstate->system,
+		cstate->wake_mask, cstate->update_wake_mask);
+}
+
+/*******************************************************************************
+ * Handler to read the MCE firmware version and check if it is compatible
+ * with interface header the BL3-1 was compiled against
+ ******************************************************************************/
+void mce_verify_firmware_version(void)
+{
+	uint64_t version;
+	uint32_t major, minor;
+
+	/*
+	 * MCE firmware is not running on simulation platforms.
+	 */
+	if (mce_firmware_not_supported()) {
+		return;
+	}
+
+	/*
+	 * Read the MCE firmware version and extract the major and minor
+	 * version fields
+	 */
+	version = nvg_get_version();
+	minor = (uint32_t)version;
+	major = (uint32_t)(version >> 32);
+
+	INFO("MCE Version - HW=%u:%u, SW=%u:%u\n", major, minor,
+		TEGRA_NVG_VERSION_MAJOR, TEGRA_NVG_VERSION_MINOR);
+
+	/*
+	 * Verify that the MCE firmware version and the interface header
+	 * match
+	 */
+	if (major != (uint32_t)TEGRA_NVG_VERSION_MAJOR) {
+		ERROR("MCE major version mismatch\n");
+		panic();
+	}
+
+	if (minor < (uint32_t)TEGRA_NVG_VERSION_MINOR) {
+		ERROR("MCE minor version mismatch\n");
+		panic();
+	}
+}
+
+#if ENABLE_STRICT_CHECKING_MODE
+/*******************************************************************************
+ * Handler to enable the strict checking mode
+ ******************************************************************************/
+void mce_enable_strict_checking(void)
+{
+	uint64_t sctlr = read_sctlr_el3();
+	int32_t ret = 0;
+
+	if (tegra_platform_is_silicon() || tegra_platform_is_fpga()) {
+		/*
+		 * Step1: TZ-DRAM and TZRAM should be setup before the MMU is
+		 * enabled.
+		 *
+		 * The common code makes sure that TZDRAM/TZRAM are already
+		 * enabled before calling into this handler. If this is not the
+		 * case, the following sequence must be executed before moving
+		 * on to step 2.
+		 *
+		 * tlbialle1is();
+		 * tlbialle3is();
+		 * dsbsy();
+		 * isb();
+		 *
+		 */
+		if ((sctlr & (uint64_t)SCTLR_M_BIT) == (uint64_t)SCTLR_M_BIT) {
+			tlbialle1is();
+			tlbialle3is();
+			dsbsy();
+			isb();
+		}
+
+		/*
+		 * Step2: SCF flush - Clean and invalidate caches and clear the
+		 * TR-bits
+		 */
+		ret = nvg_roc_clean_cache_trbits();
+		if (ret < 0) {
+			ERROR("%s: flush cache_trbits failed(%d)\n", __func__,
+				ret);
+			return;
+		}
+
+		/*
+		 * Step3: Issue the SECURITY_CONFIG request to MCE to enable
+		 * strict checking mode.
+		 */
+		nvg_enable_strict_checking_mode();
+	}
+}
+#endif
+
+/*******************************************************************************
+ * Handler to power down the entire system
+ ******************************************************************************/
+void mce_system_shutdown(void)
+{
+	nvg_system_shutdown();
+}
+
+/*******************************************************************************
+ * Handler to reboot the entire system
+ ******************************************************************************/
+void mce_system_reboot(void)
+{
+	nvg_system_reboot();
+}
diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c
new file mode 100644
index 0000000..a095fdd
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <denver.h>
+#include <errno.h>
+#include <lib/mmio.h>
+#include <mce_private.h>
+#include <platform_def.h>
+#include <t194_nvg.h>
+#include <tegra_private.h>
+
+#define	ID_AFR0_EL1_CACHE_OPS_SHIFT	12
+#define	ID_AFR0_EL1_CACHE_OPS_MASK	0xFU
+/*
+ * Reports the major and minor version of this interface.
+ *
+ * NVGDATA[0:31]: SW(R) Minor Version
+ * NVGDATA[32:63]: SW(R) Major Version
+ */
+uint64_t nvg_get_version(void)
+{
+	nvg_set_request((uint64_t)TEGRA_NVG_CHANNEL_VERSION);
+
+	return (uint64_t)nvg_get_result();
+}
+
+/*
+ * Enable the perf per watt mode.
+ *
+ * NVGDATA[0]: SW(RW), 1 = enable perf per watt mode
+ */
+int32_t nvg_enable_power_perf_mode(void)
+{
+	nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_POWER_PERF, 1U);
+
+	return 0;
+}
+
+/*
+ * Disable the perf per watt mode.
+ *
+ * NVGDATA[0]: SW(RW), 0 = disable perf per watt mode
+ */
+int32_t nvg_disable_power_perf_mode(void)
+{
+	nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_POWER_PERF, 0U);
+
+	return 0;
+}
+
+/*
+ * Enable the battery saver mode.
+ *
+ * NVGDATA[2]: SW(RW), 1 = enable battery saver mode
+ */
+int32_t nvg_enable_power_saver_modes(void)
+{
+	nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_POWER_MODES, 1U);
+
+	return 0;
+}
+
+/*
+ * Disable the battery saver mode.
+ *
+ * NVGDATA[2]: SW(RW), 0 = disable battery saver mode
+ */
+int32_t nvg_disable_power_saver_modes(void)
+{
+	nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_POWER_MODES, 0U);
+
+	return 0;
+}
+
+/*
+ * Set the expected wake time in TSC ticks for the next low-power state the
+ * core enters.
+ *
+ * NVGDATA[0:31]: SW(RW), WAKE_TIME
+ */
+void nvg_set_wake_time(uint32_t wake_time)
+{
+	/* time (TSC ticks) until the core is expected to get a wake event */
+	nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_WAKE_TIME, (uint64_t)wake_time);
+}
+
+/*
+ * This request allows updating of CLUSTER_CSTATE, CCPLEX_CSTATE and
+ * SYSTEM_CSTATE values.
+ *
+ * NVGDATA[0:2]: SW(RW), CLUSTER_CSTATE
+ * NVGDATA[7]: SW(W), update cluster flag
+ * NVGDATA[8:10]: SW(RW), CG_CSTATE
+ * NVGDATA[15]: SW(W), update ccplex flag
+ * NVGDATA[16:19]: SW(RW), SYSTEM_CSTATE
+ * NVGDATA[23]: SW(W), update system flag
+ * NVGDATA[31]: SW(W), update wake mask flag
+ * NVGDATA[32:63]: SW(RW), WAKE_MASK
+ */
+void nvg_update_cstate_info(uint32_t cluster, uint32_t ccplex,
+		uint32_t system, uint32_t wake_mask, uint8_t update_wake_mask)
+{
+	uint64_t val = 0;
+
+	/* update CLUSTER_CSTATE? */
+	if (cluster != 0U) {
+		val |= ((uint64_t)cluster & CLUSTER_CSTATE_MASK) |
+				CLUSTER_CSTATE_UPDATE_BIT;
+	}
+
+	/* update CCPLEX_CSTATE? */
+	if (ccplex != 0U) {
+		val |= (((uint64_t)ccplex & CCPLEX_CSTATE_MASK) << CCPLEX_CSTATE_SHIFT) |
+				CCPLEX_CSTATE_UPDATE_BIT;
+	}
+
+	/* update SYSTEM_CSTATE? */
+	if (system != 0U) {
+		val |= (((uint64_t)system & SYSTEM_CSTATE_MASK) << SYSTEM_CSTATE_SHIFT) |
+				SYSTEM_CSTATE_UPDATE_BIT;
+	}
+
+	/* update wake mask value? */
+	if (update_wake_mask != 0U) {
+		val |= CSTATE_WAKE_MASK_UPDATE_BIT;
+	}
+
+	/* set the wake mask */
+	val |= ((uint64_t)wake_mask & CSTATE_WAKE_MASK_CLEAR) << CSTATE_WAKE_MASK_SHIFT;
+
+	/* set the updated cstate info */
+	nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_CSTATE_INFO, val);
+}
+
+/*
+ * Return a non-zero value if the CCPLEX is able to enter SC7
+ *
+ * NVGDATA[0]: SW(R), Is allowed result
+ */
+int32_t nvg_is_sc7_allowed(void)
+{
+	/* issue command to check if SC7 is allowed */
+	nvg_set_request((uint64_t)TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED);
+
+	/* 1 = SC7 allowed, 0 = SC7 not allowed */
+	return (int32_t)nvg_get_result();
+}
+
+/*
+ * Wake an offlined logical core. Note that a core is offlined by entering
+ * a C-state where the WAKE_MASK is all 0.
+ *
+ * NVGDATA[0:3]: SW(W) logical core to online
+ */
+int32_t nvg_online_core(uint32_t core)
+{
+	int32_t ret = 0;
+
+	/* sanity check the core ID value */
+	if (core > (uint32_t)PLATFORM_CORE_COUNT) {
+		ERROR("%s: unknown core id (%d)\n", __func__, core);
+		ret = -EINVAL;
+	} else {
+		/* get a core online */
+		nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_ONLINE_CORE,
+					(uint64_t)core & MCE_CORE_ID_MASK);
+	}
+
+	return ret;
+}
+
+/*
+ * MC GSC (General Security Carveout) register values are expected to be
+ * changed by TrustZone ARM code after boot.
+ *
+ * NVGDATA[0:15] SW(R) GSC enun
+ */
+int32_t nvg_update_ccplex_gsc(uint32_t gsc_idx)
+{
+	int32_t ret = 0;
+
+	/* sanity check GSC ID */
+	if (gsc_idx > (uint32_t)TEGRA_NVG_CHANNEL_UPDATE_GSC_VPR) {
+		ERROR("%s: unknown gsc_idx (%u)\n", __func__, gsc_idx);
+		ret = -EINVAL;
+	} else {
+		nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_UPDATE_CCPLEX_GSC,
+				     (uint64_t)gsc_idx);
+	}
+
+	return ret;
+}
+
+/*
+ * Cache clean operation for all CCPLEX caches.
+ */
+int32_t nvg_roc_clean_cache(void)
+{
+	int32_t ret = 0;
+
+	/* check if cache flush through mts is supported */
+	if (((read_id_afr0_el1() >> ID_AFR0_EL1_CACHE_OPS_SHIFT) &
+			ID_AFR0_EL1_CACHE_OPS_MASK) == 1U) {
+		if (nvg_cache_clean() == 0U) {
+			ERROR("%s: failed\n", __func__);
+			ret = -ENODEV;
+		}
+	} else {
+		ret = -ENOTSUP;
+	}
+
+	return ret;
+}
+
+/*
+ * Cache clean and invalidate operation for all CCPLEX caches.
+ */
+int32_t nvg_roc_flush_cache(void)
+{
+	int32_t ret = 0;
+
+	/* check if cache flush through mts is supported */
+	if (((read_id_afr0_el1() >> ID_AFR0_EL1_CACHE_OPS_SHIFT) &
+			ID_AFR0_EL1_CACHE_OPS_MASK) == 1U) {
+		if (nvg_cache_clean_inval() == 0U) {
+			ERROR("%s: failed\n", __func__);
+			ret = -ENODEV;
+		}
+	} else {
+		ret = -ENOTSUP;
+	}
+
+	return ret;
+}
+
+/*
+ * Cache clean and invalidate, clear TR-bit operation for all CCPLEX caches.
+ */
+int32_t nvg_roc_clean_cache_trbits(void)
+{
+	int32_t ret = 0;
+
+	/* check if cache flush through mts is supported */
+	if (((read_id_afr0_el1() >> ID_AFR0_EL1_CACHE_OPS_SHIFT) &
+			ID_AFR0_EL1_CACHE_OPS_MASK) == 1U) {
+		if (nvg_cache_inval_all() == 0U) {
+			ERROR("%s: failed\n", __func__);
+			ret = -ENODEV;
+		}
+	} else {
+		ret = -ENOTSUP;
+	}
+
+	return ret;
+}
+
+/*
+ * Set the power state for a core
+ */
+int32_t nvg_enter_cstate(uint32_t state, uint32_t wake_time)
+{
+	int32_t ret = 0;
+	uint64_t val = 0ULL;
+
+	/* check for allowed power state */
+	if ((state != (uint32_t)TEGRA_NVG_CORE_C0) &&
+		(state != (uint32_t)TEGRA_NVG_CORE_C1) &&
+	    (state != (uint32_t)TEGRA_NVG_CORE_C6) &&
+		(state != (uint32_t)TEGRA_NVG_CORE_C7))
+	{
+		ERROR("%s: unknown cstate (%u)\n", __func__, state);
+		ret = -EINVAL;
+	} else {
+		/* time (TSC ticks) until the core is expected to get a wake event */
+		nvg_set_wake_time(wake_time);
+
+		/* set the core cstate */
+		val = read_actlr_el1() & ~ACTLR_EL1_PMSTATE_MASK;
+		write_actlr_el1(val | (uint64_t)state);
+	}
+
+	return ret;
+}
+
+#if ENABLE_STRICT_CHECKING_MODE
+/*
+ * Enable strict checking mode
+ *
+ * NVGDATA[3] strict_check ON + lock
+ */
+void nvg_enable_strict_checking_mode(void)
+{
+	uint64_t params = (uint64_t)(STRICT_CHECKING_ENABLED_SET |
+				     STRICT_CHECKING_LOCKED_SET);
+
+	nvg_set_request_data(TEGRA_NVG_CHANNEL_SECURITY_CONFIG, params);
+}
+#endif
+
+/*
+ * Request a reboot
+ *
+ * NVGDATA[0]: reboot command
+ */
+void nvg_system_reboot(void)
+{
+	/* issue command for reboot */
+	nvg_set_request_data(TEGRA_NVG_CHANNEL_SHUTDOWN, TEGRA_NVG_REBOOT);
+}
+
+/*
+ * Request a shutdown
+ *
+ * NVGDATA[0]: shutdown command
+ */
+void nvg_system_shutdown(void)
+{
+	/* issue command for shutdown */
+	nvg_set_request_data(TEGRA_NVG_CHANNEL_SHUTDOWN, TEGRA_NVG_SHUTDOWN);
+}
diff --git a/plat/nvidia/tegra/soc/t194/drivers/se/se.c b/plat/nvidia/tegra/soc/t194/drivers/se/se.c
new file mode 100644
index 0000000..a9f4610
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/drivers/se/se.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <lib/psci/psci.h>
+#include <tegra_platform.h>
+
+#include "se_private.h"
+
+/*******************************************************************************
+ * Constants and Macros
+ ******************************************************************************/
+#define ERR_STATUS_SW_CLEAR	U(0xFFFFFFFF)
+#define INT_STATUS_SW_CLEAR	U(0xFFFFFFFF)
+#define MAX_TIMEOUT_MS		U(100)	/* Timeout in 100ms */
+#define NUM_SE_REGS_TO_SAVE	U(4)
+
+/*******************************************************************************
+ * Data structure and global variables
+ ******************************************************************************/
+static uint32_t se_regs[NUM_SE_REGS_TO_SAVE];
+
+/*
+ * Check that SE operation has completed after kickoff.
+ *
+ * This function is invoked after an SE operation has been started,
+ * and it checks the following conditions:
+ *
+ * 1. SE_STATUS = IDLE
+ * 2. AHB bus data transfer is complete.
+ * 3. SE_ERR_STATUS is clean.
+ */
+static bool tegra_se_is_operation_complete(void)
+{
+	uint32_t val = 0, timeout = 0, sha_status, aes_status;
+	int32_t ret = 0;
+	bool se_is_busy, txn_has_errors, txn_successful;
+
+	/*
+	 * Poll the status register to check if the operation
+	 * completed.
+	 */
+	do {
+		val = tegra_se_read_32(CTX_SAVE_AUTO_STATUS);
+		se_is_busy = !!(val & CTX_SAVE_AUTO_SE_BUSY);
+
+		/* sleep until SE finishes */
+		if (se_is_busy) {
+			mdelay(1);
+			timeout++;
+		}
+
+	} while (se_is_busy && (timeout < MAX_TIMEOUT_MS));
+
+	/* any transaction errors? */
+	txn_has_errors = (tegra_se_read_32(SHA_ERR_STATUS) != 0U) ||
+			 (tegra_se_read_32(AES0_ERR_STATUS) != 0U);
+
+	/* transaction successful? */
+	sha_status = tegra_se_read_32(SHA_INT_STATUS) & SHA_SE_OP_DONE;
+	aes_status = tegra_se_read_32(AES0_INT_STATUS) & AES0_SE_OP_DONE;
+	txn_successful = (sha_status == SHA_SE_OP_DONE) &&
+			 (aes_status == AES0_SE_OP_DONE);
+
+	if ((timeout == MAX_TIMEOUT_MS) || txn_has_errors || !txn_successful) {
+		ERROR("%s: Atomic context save operation failed!\n",
+				__func__);
+		ret = -ECANCELED;
+	}
+
+	return (ret == 0);
+}
+
+/*
+ * Wait for SE engine to be idle and clear any pending interrupts, before
+ * starting the next SE operation.
+ */
+static bool tegra_se_is_ready(void)
+{
+	int32_t ret = 0;
+	uint32_t val = 0, timeout = 0;
+	bool se_is_ready;
+
+	/* Wait for previous operation to finish */
+	do {
+		val = tegra_se_read_32(CTX_SAVE_AUTO_STATUS);
+		se_is_ready = (val == CTX_SAVE_AUTO_SE_READY);
+
+		/* sleep until SE is ready */
+		if (!se_is_ready) {
+			mdelay(1);
+			timeout++;
+		}
+
+	} while (!se_is_ready && (timeout < MAX_TIMEOUT_MS));
+
+	if (timeout == MAX_TIMEOUT_MS) {
+		ERROR("%s: SE is not ready!\n", __func__);
+		ret = -ETIMEDOUT;
+	}
+
+	/* Clear any pending interrupts from previous operation */
+	tegra_se_write_32(AES0_INT_STATUS, INT_STATUS_SW_CLEAR);
+	tegra_se_write_32(AES1_INT_STATUS, INT_STATUS_SW_CLEAR);
+	tegra_se_write_32(RSA_INT_STATUS, INT_STATUS_SW_CLEAR);
+	tegra_se_write_32(SHA_INT_STATUS, INT_STATUS_SW_CLEAR);
+
+	/* Clear error status for each engine seen from current port */
+	tegra_se_write_32(AES0_ERR_STATUS, ERR_STATUS_SW_CLEAR);
+	tegra_se_write_32(AES1_ERR_STATUS, ERR_STATUS_SW_CLEAR);
+	tegra_se_write_32(RSA_ERR_STATUS, ERR_STATUS_SW_CLEAR);
+	tegra_se_write_32(SHA_ERR_STATUS, ERR_STATUS_SW_CLEAR);
+
+	return (ret == 0);
+}
+
+/*
+ * During System Suspend, this handler triggers the hardware context
+ * save operation.
+ */
+static int32_t tegra_se_save_context(void)
+{
+	int32_t ret = -ECANCELED;
+
+	/*
+	 * 1. Ensure all SE Driver including RNG1/PKA1 are shut down.
+	 *    TSEC/R5s are powergated/idle. All tasks on SE1~SE4, RNG1,
+	 *    PKA1 are wrapped up. SE0 is ready for use.
+	 * 2. Clear interrupt/error in SE0 status register.
+	 * 3. Scrub SE0 register to avoid false failure for illegal
+	 *    configuration. Probably not needed, dependent on HW
+	 *    implementation.
+	 * 4. Check SE is ready for HW CTX_SAVE by polling
+	 *    SE_CTX_SAVE_AUTO_STATUS.SE_READY.
+	 *
+	 *    Steps 1-4 are executed by tegra_se_is_ready().
+	 *
+	 * 5. Issue context save command.
+	 * 6. Check SE is busy with CTX_SAVE, the command in step5 was not
+	 *    dropped for ongoing traffic in any of SE port/engine.
+	 * 7. Poll SE register or wait for SE APB interrupt for task completion
+	 *    a. Polling: Read SE_CTX_SAVE_AUTO_STATUS.BUSY till it reports IDLE
+	 *    b. Interrupt: After receiving interrupt from SE APB, read
+	 *       SE_CTX_SAVE_AUTO_STATUS.BUSY till it reports IDLE.
+	 * 8. Check AES0 and SHA ERR_STATUS to ensure no error case.
+	 * 9. Check AES0 and SHA INT_STATUS to ensure operation has successfully
+	 *    completed.
+	 *
+	 *    Steps 6-9 are executed by tegra_se_is_operation_complete().
+	 */
+	if (tegra_se_is_ready()) {
+
+		/* Issue context save command */
+		tegra_se_write_32(AES0_OPERATION, SE_OP_CTX_SAVE);
+
+		/* Wait for operation to finish */
+		if (tegra_se_is_operation_complete()) {
+			ret = 0;
+		}
+	}
+
+	return ret;
+}
+
+/*
+ * Handler to power down the SE hardware blocks - SE, RNG1 and PKA1. This
+ * needs to be called only during System Suspend.
+ */
+int32_t tegra_se_suspend(void)
+{
+	int32_t ret = 0;
+
+	/* save SE registers */
+	se_regs[0] = mmio_read_32(TEGRA_SE0_BASE + SE0_MUTEX_WATCHDOG_NS_LIMIT);
+	se_regs[1] = mmio_read_32(TEGRA_SE0_BASE + SE0_AES0_ENTROPY_SRC_AGE_CTRL);
+	se_regs[2] = mmio_read_32(TEGRA_RNG1_BASE + RNG1_MUTEX_WATCHDOG_NS_LIMIT);
+	se_regs[3] = mmio_read_32(TEGRA_PKA1_BASE + PKA1_MUTEX_WATCHDOG_NS_LIMIT);
+
+	/* Save SE context. The BootROM restores it during System Resume */
+	ret = tegra_se_save_context();
+	if (ret != 0) {
+		ERROR("%s: context save failed (%d)\n", __func__, ret);
+	}
+
+	return ret;
+}
+
+/*
+ * Handler to power up the SE hardware block(s) during System Resume.
+ */
+void tegra_se_resume(void)
+{
+	/*
+	 * When TZ takes over after System Resume, TZ should first reconfigure
+	 * SE_MUTEX_WATCHDOG_NS_LIMIT, PKA1_MUTEX_WATCHDOG_NS_LIMIT,
+	 * RNG1_MUTEX_WATCHDOG_NS_LIMIT and SE_ENTROPY_SRC_AGE_CTRL before
+	 * other operations.
+	 */
+	mmio_write_32(TEGRA_SE0_BASE + SE0_MUTEX_WATCHDOG_NS_LIMIT, se_regs[0]);
+	mmio_write_32(TEGRA_SE0_BASE + SE0_AES0_ENTROPY_SRC_AGE_CTRL, se_regs[1]);
+	mmio_write_32(TEGRA_RNG1_BASE + RNG1_MUTEX_WATCHDOG_NS_LIMIT, se_regs[2]);
+	mmio_write_32(TEGRA_PKA1_BASE + PKA1_MUTEX_WATCHDOG_NS_LIMIT, se_regs[3]);
+}
diff --git a/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h b/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h
new file mode 100644
index 0000000..a2c5d1c
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SE_PRIVATE_H
+#define SE_PRIVATE_H
+
+#include <lib/utils_def.h>
+
+/* SE0_INT_ENABLE_0 */
+#define SE0_INT_ENABLE				U(0x88)
+#define  SE0_DISABLE_ALL_INT			U(0x0)
+
+/* SE0_INT_STATUS_0 */
+#define SE0_INT_STATUS				U(0x8C)
+#define  SE0_CLEAR_ALL_INT_STATUS		U(0x3F)
+
+/* SE0_SHA_INT_STATUS_0 */
+#define SHA_INT_STATUS				U(0x184)
+#define  SHA_SE_OP_DONE				(U(1) << 4)
+
+/* SE0_SHA_ERR_STATUS_0 */
+#define SHA_ERR_STATUS				U(0x18C)
+
+/* SE0_AES0_INT_STATUS_0 */
+#define AES0_INT_STATUS				U(0x2F0)
+#define  AES0_SE_OP_DONE			(U(1) << 4)
+
+/* SE0_AES0_ERR_STATUS_0 */
+#define AES0_ERR_STATUS				U(0x2F8)
+
+/* SE0_AES1_INT_STATUS_0 */
+#define AES1_INT_STATUS				U(0x4F0)
+
+/* SE0_AES1_ERR_STATUS_0 */
+#define AES1_ERR_STATUS				U(0x4F8)
+
+/* SE0_RSA_INT_STATUS_0 */
+#define RSA_INT_STATUS				U(0x758)
+
+/* SE0_RSA_ERR_STATUS_0 */
+#define RSA_ERR_STATUS				U(0x760)
+
+/* SE0_AES0_OPERATION_0 */
+#define AES0_OPERATION				U(0x238)
+#define  OP_MASK_BITS				U(0x7)
+#define  SE_OP_CTX_SAVE				U(0x3)
+
+/* SE0_AES0_CTX_SAVE_CONFIG_0 */
+#define	CTX_SAVE_CONFIG				U(0x2D4)
+
+/* SE0_AES0_CTX_SAVE_AUTO_STATUS_0 */
+#define CTX_SAVE_AUTO_STATUS			U(0x300)
+#define  CTX_SAVE_AUTO_SE_READY			U(0xFF)
+#define	 CTX_SAVE_AUTO_SE_BUSY			(U(0x1) << 31)
+
+/* SE0_AES0_CTX_SAVE_AUTO_CTRL_0 */
+#define CTX_SAVE_AUTO_CTRL			U(0x304)
+#define	 SE_CTX_SAVE_AUTO_EN			(U(0x1) << 0)
+#define	 SE_CTX_SAVE_AUTO_LOCK_EN		(U(0x1) << 1)
+
+/* SE0_AES0_CTX_SAVE_AUTO_START_ADDR_0 */
+#define CTX_SAVE_AUTO_START_ADDR		U(0x308)
+
+/* SE0_AES0_CTX_SAVE_AUTO_START_ADDR_HI_0 */
+#define CTX_SAVE_AUTO_START_ADDR_HI		U(0x30C)
+
+/*******************************************************************************
+ * Inline functions definition
+ ******************************************************************************/
+
+static inline uint32_t tegra_se_read_32(uint32_t offset)
+{
+	return mmio_read_32(TEGRA_SE0_BASE + offset);
+}
+
+static inline void tegra_se_write_32(uint32_t offset, uint32_t val)
+{
+	mmio_write_32(TEGRA_SE0_BASE + offset, val);
+}
+
+#endif /* SE_PRIVATE_H */
diff --git a/plat/nvidia/tegra/soc/t194/plat_memctrl.c b/plat/nvidia/tegra/soc/t194/plat_memctrl.c
new file mode 100644
index 0000000..5718650
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/plat_memctrl.c
@@ -0,0 +1,671 @@
+/*
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <common/bl_common.h>
+#include <mce.h>
+#include <memctrl_v2.h>
+#include <tegra_mc_def.h>
+#include <tegra_platform.h>
+
+/*******************************************************************************
+ * Array to hold stream_id override config register offsets
+ ******************************************************************************/
+const static uint32_t tegra194_streamid_override_regs[] = {
+	MC_STREAMID_OVERRIDE_CFG_HDAR,
+	MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR,
+	MC_STREAMID_OVERRIDE_CFG_NVENCSRD,
+	MC_STREAMID_OVERRIDE_CFG_SATAR,
+	MC_STREAMID_OVERRIDE_CFG_NVENCSWR,
+	MC_STREAMID_OVERRIDE_CFG_HDAW,
+	MC_STREAMID_OVERRIDE_CFG_SATAW,
+	MC_STREAMID_OVERRIDE_CFG_ISPRA,
+	MC_STREAMID_OVERRIDE_CFG_ISPFALR,
+	MC_STREAMID_OVERRIDE_CFG_ISPWA,
+	MC_STREAMID_OVERRIDE_CFG_ISPWB,
+	MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR,
+	MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW,
+	MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR,
+	MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW,
+	MC_STREAMID_OVERRIDE_CFG_TSECSRD,
+	MC_STREAMID_OVERRIDE_CFG_TSECSWR,
+	MC_STREAMID_OVERRIDE_CFG_SDMMCRA,
+	MC_STREAMID_OVERRIDE_CFG_SDMMCR,
+	MC_STREAMID_OVERRIDE_CFG_SDMMCRAB,
+	MC_STREAMID_OVERRIDE_CFG_SDMMCWA,
+	MC_STREAMID_OVERRIDE_CFG_SDMMCW,
+	MC_STREAMID_OVERRIDE_CFG_SDMMCWAB,
+	MC_STREAMID_OVERRIDE_CFG_VICSRD,
+	MC_STREAMID_OVERRIDE_CFG_VICSWR,
+	MC_STREAMID_OVERRIDE_CFG_VIW,
+	MC_STREAMID_OVERRIDE_CFG_NVDECSRD,
+	MC_STREAMID_OVERRIDE_CFG_NVDECSWR,
+	MC_STREAMID_OVERRIDE_CFG_APER,
+	MC_STREAMID_OVERRIDE_CFG_APEW,
+	MC_STREAMID_OVERRIDE_CFG_NVJPGSRD,
+	MC_STREAMID_OVERRIDE_CFG_NVJPGSWR,
+	MC_STREAMID_OVERRIDE_CFG_SESRD,
+	MC_STREAMID_OVERRIDE_CFG_SESWR,
+	MC_STREAMID_OVERRIDE_CFG_AXIAPR,
+	MC_STREAMID_OVERRIDE_CFG_AXIAPW,
+	MC_STREAMID_OVERRIDE_CFG_ETRR,
+	MC_STREAMID_OVERRIDE_CFG_ETRW,
+	MC_STREAMID_OVERRIDE_CFG_TSECSRDB,
+	MC_STREAMID_OVERRIDE_CFG_TSECSWRB,
+	MC_STREAMID_OVERRIDE_CFG_AXISR,
+	MC_STREAMID_OVERRIDE_CFG_AXISW,
+	MC_STREAMID_OVERRIDE_CFG_EQOSR,
+	MC_STREAMID_OVERRIDE_CFG_EQOSW,
+	MC_STREAMID_OVERRIDE_CFG_UFSHCR,
+	MC_STREAMID_OVERRIDE_CFG_UFSHCW,
+	MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR,
+	MC_STREAMID_OVERRIDE_CFG_BPMPR,
+	MC_STREAMID_OVERRIDE_CFG_BPMPW,
+	MC_STREAMID_OVERRIDE_CFG_BPMPDMAR,
+	MC_STREAMID_OVERRIDE_CFG_BPMPDMAW,
+	MC_STREAMID_OVERRIDE_CFG_AONR,
+	MC_STREAMID_OVERRIDE_CFG_AONW,
+	MC_STREAMID_OVERRIDE_CFG_AONDMAR,
+	MC_STREAMID_OVERRIDE_CFG_AONDMAW,
+	MC_STREAMID_OVERRIDE_CFG_SCER,
+	MC_STREAMID_OVERRIDE_CFG_SCEW,
+	MC_STREAMID_OVERRIDE_CFG_SCEDMAR,
+	MC_STREAMID_OVERRIDE_CFG_SCEDMAW,
+	MC_STREAMID_OVERRIDE_CFG_APEDMAR,
+	MC_STREAMID_OVERRIDE_CFG_APEDMAW,
+	MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1,
+	MC_STREAMID_OVERRIDE_CFG_VICSRD1,
+	MC_STREAMID_OVERRIDE_CFG_NVDECSRD1,
+	MC_STREAMID_OVERRIDE_CFG_VIFALR,
+	MC_STREAMID_OVERRIDE_CFG_VIFALW,
+	MC_STREAMID_OVERRIDE_CFG_DLA0RDA,
+	MC_STREAMID_OVERRIDE_CFG_DLA0FALRDB,
+	MC_STREAMID_OVERRIDE_CFG_DLA0WRA,
+	MC_STREAMID_OVERRIDE_CFG_DLA0FALWRB,
+	MC_STREAMID_OVERRIDE_CFG_DLA1RDA,
+	MC_STREAMID_OVERRIDE_CFG_DLA1FALRDB,
+	MC_STREAMID_OVERRIDE_CFG_DLA1WRA,
+	MC_STREAMID_OVERRIDE_CFG_DLA1FALWRB,
+	MC_STREAMID_OVERRIDE_CFG_PVA0RDA,
+	MC_STREAMID_OVERRIDE_CFG_PVA0RDB,
+	MC_STREAMID_OVERRIDE_CFG_PVA0RDC,
+	MC_STREAMID_OVERRIDE_CFG_PVA0WRA,
+	MC_STREAMID_OVERRIDE_CFG_PVA0WRB,
+	MC_STREAMID_OVERRIDE_CFG_PVA0WRC,
+	MC_STREAMID_OVERRIDE_CFG_PVA1RDA,
+	MC_STREAMID_OVERRIDE_CFG_PVA1RDB,
+	MC_STREAMID_OVERRIDE_CFG_PVA1RDC,
+	MC_STREAMID_OVERRIDE_CFG_PVA1WRA,
+	MC_STREAMID_OVERRIDE_CFG_PVA1WRB,
+	MC_STREAMID_OVERRIDE_CFG_PVA1WRC,
+	MC_STREAMID_OVERRIDE_CFG_RCER,
+	MC_STREAMID_OVERRIDE_CFG_RCEW,
+	MC_STREAMID_OVERRIDE_CFG_RCEDMAR,
+	MC_STREAMID_OVERRIDE_CFG_RCEDMAW,
+	MC_STREAMID_OVERRIDE_CFG_NVENC1SRD,
+	MC_STREAMID_OVERRIDE_CFG_NVENC1SWR,
+	MC_STREAMID_OVERRIDE_CFG_PCIE0R,
+	MC_STREAMID_OVERRIDE_CFG_PCIE0W,
+	MC_STREAMID_OVERRIDE_CFG_PCIE1R,
+	MC_STREAMID_OVERRIDE_CFG_PCIE1W,
+	MC_STREAMID_OVERRIDE_CFG_PCIE2AR,
+	MC_STREAMID_OVERRIDE_CFG_PCIE2AW,
+	MC_STREAMID_OVERRIDE_CFG_PCIE3R,
+	MC_STREAMID_OVERRIDE_CFG_PCIE3W,
+	MC_STREAMID_OVERRIDE_CFG_PCIE4R,
+	MC_STREAMID_OVERRIDE_CFG_PCIE4W,
+	MC_STREAMID_OVERRIDE_CFG_PCIE5R,
+	MC_STREAMID_OVERRIDE_CFG_PCIE5W,
+	MC_STREAMID_OVERRIDE_CFG_ISPFALW,
+	MC_STREAMID_OVERRIDE_CFG_DLA0RDA1,
+	MC_STREAMID_OVERRIDE_CFG_DLA1RDA1,
+	MC_STREAMID_OVERRIDE_CFG_PVA0RDA1,
+	MC_STREAMID_OVERRIDE_CFG_PVA0RDB1,
+	MC_STREAMID_OVERRIDE_CFG_PVA1RDA1,
+	MC_STREAMID_OVERRIDE_CFG_PVA1RDB1,
+	MC_STREAMID_OVERRIDE_CFG_PCIE5R1,
+	MC_STREAMID_OVERRIDE_CFG_NVENCSRD1,
+	MC_STREAMID_OVERRIDE_CFG_NVENC1SRD1,
+	MC_STREAMID_OVERRIDE_CFG_ISPRA1,
+	MC_STREAMID_OVERRIDE_CFG_MIU0R,
+	MC_STREAMID_OVERRIDE_CFG_MIU0W,
+	MC_STREAMID_OVERRIDE_CFG_MIU1R,
+	MC_STREAMID_OVERRIDE_CFG_MIU1W,
+	MC_STREAMID_OVERRIDE_CFG_MIU2R,
+	MC_STREAMID_OVERRIDE_CFG_MIU2W,
+	MC_STREAMID_OVERRIDE_CFG_MIU3R,
+	MC_STREAMID_OVERRIDE_CFG_MIU3W
+};
+
+/*******************************************************************************
+ * Array to hold the security configs for stream IDs
+ ******************************************************************************/
+const static mc_streamid_security_cfg_t tegra194_streamid_sec_cfgs[] = {
+	mc_make_sec_cfg(HDAR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(HOST1XDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVENCSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SATAR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVENCSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(HDAW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SATAW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(ISPRA, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(ISPFALR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(ISPWA, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(ISPWB, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(XUSB_HOSTR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(XUSB_HOSTW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(XUSB_DEVR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(XUSB_DEVW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(TSECSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(TSECSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SDMMCRA, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SDMMCR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SDMMCRAB, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SDMMCWA, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SDMMCW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SDMMCWAB, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(VICSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(VICSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(VIW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVDECSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVDECSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(APER, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(APEW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVJPGSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVJPGSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SESRD, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SESWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AXIAPR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AXIAPW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(ETRR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(ETRW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(TSECSRDB, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(TSECSWRB, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AXISR, SECURE, NO_OVERRIDE, DISABLE),
+	mc_make_sec_cfg(AXISW, SECURE, NO_OVERRIDE, DISABLE),
+	mc_make_sec_cfg(EQOSR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(EQOSW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(UFSHCR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(UFSHCW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVDISPLAYR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(BPMPR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(BPMPW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(BPMPDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(BPMPDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AONR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AONW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AONDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AONDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SCER, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SCEW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SCEDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SCEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(APEDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(APEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVDISPLAYR1, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(VICSRD1, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVDECSRD1, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(VIFALR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(VIFALW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(DLA0RDA, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(DLA0FALRDB, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(DLA0WRA, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(DLA0FALWRB, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(DLA1RDA, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(DLA1FALRDB, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(DLA1WRA, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(DLA1FALWRB, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA0RDA, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA0RDB, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA0RDC, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA0WRA, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA0WRB, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA0WRC, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA1RDA, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA1RDB, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA1RDC, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA1WRA, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA1WRB, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA1WRC, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(RCER, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(RCEW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(RCEDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(RCEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVENC1SRD, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVENC1SWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PCIE0R, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PCIE0W, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PCIE1R, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PCIE1W, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PCIE2AR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PCIE2AW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PCIE3R, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PCIE3W, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PCIE4R, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PCIE4W, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PCIE5R, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PCIE5W, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(ISPFALW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(DLA0RDA1, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(DLA1RDA1, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA0RDA1, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA0RDB1, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA1RDA1, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA1RDB1, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PCIE5R1, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVENCSRD1, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVENC1SRD1, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(ISPRA1, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(MIU0R, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(MIU0W, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(MIU1R, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(MIU1W, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(MIU2R, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(MIU2W, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(MIU3R, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(MIU3W, NON_SECURE, OVERRIDE, ENABLE),
+};
+
+/*******************************************************************************
+ * Array to hold the transaction override configs
+ ******************************************************************************/
+const static mc_txn_override_cfg_t tegra194_txn_override_cfgs[] = {
+	mc_make_txn_override_cfg(NVENCSWR, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(HDAW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(SATAW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(ISPWB, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(XUSB_HOSTW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(XUSB_DEVW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(TSECSWR, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(SDMMCWA, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(SDMMCW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(SDMMCWAB, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(VICSWR, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(NVDECSWR, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(APEW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(NVJPGSWR, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(SESWR, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(ETRW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(TSECSWRB, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(AXISW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(EQOSW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(UFSHCW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(BPMPW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(BPMPDMAW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(AONW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(AONDMAW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(SCEW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(SCEDMAW, CGID_TAG_ADR),
+};
+
+/* To be called by common memctrl_v2.c */
+static void tegra194_memctrl_reconfig_mss_clients(void)
+{
+	uint32_t reg_val, wdata_0, wdata_1, wdata_2;
+
+	wdata_0 = MC_CLIENT_HOTRESET_CTRL0_HC_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL0_VIC_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL0_TSEC_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL0_SDMMC3A_FLUSH_ENB;
+	if (tegra_platform_is_silicon()) {
+		wdata_0 |= MC_CLIENT_HOTRESET_CTRL0_SDMMC1A_FLUSH_ENB;
+	}
+
+	tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0);
+
+	/* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
+	do {
+		reg_val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0);
+	} while ((reg_val & wdata_0) != wdata_0);
+
+	wdata_1 = MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_TSECB_FLUSH_ENB|
+		  MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_NVDISPLAY_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_VIFAL_FLUSH_ENB;
+	if (tegra_platform_is_silicon()) {
+		wdata_1 |= MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB |
+			MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB |
+			MC_CLIENT_HOTRESET_CTRL1_RCE_FLUSH_ENB;
+	}
+	tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1);
+	/* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
+	do {
+		reg_val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1);
+	} while ((reg_val & wdata_1) != wdata_1);
+
+	wdata_2 = MC_CLIENT_HOTRESET_CTRL2_PCIE_FLUSH_ENB |
+		MC_CLIENT_HOTRESET_CTRL2_AONDMA_FLUSH_ENB |
+		MC_CLIENT_HOTRESET_CTRL2_BPMPDMA_FLUSH_ENB |
+		MC_CLIENT_HOTRESET_CTRL2_SCEDMA_FLUSH_ENB;
+	if (tegra_platform_is_silicon()) {
+		wdata_2 |= MC_CLIENT_HOTRESET_CTRL2_RCEDMA_FLUSH_ENB |
+			MC_CLIENT_HOTRESET_CTRL2_PCIE_FLUSH_ENB |
+			MC_CLIENT_HOTRESET_CTRL2_PCIE5A_FLUSH_ENB |
+			MC_CLIENT_HOTRESET_CTRL2_PCIE3A_FLUSH_ENB |
+			MC_CLIENT_HOTRESET_CTRL2_PCIE3_FLUSH_ENB |
+			MC_CLIENT_HOTRESET_CTRL2_PCIE0A_FLUSH_ENB |
+			MC_CLIENT_HOTRESET_CTRL2_PCIE0A2_FLUSH_ENB |
+			MC_CLIENT_HOTRESET_CTRL2_PCIE4A_FLUSH_ENB;
+	}
+	tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL2, wdata_2);
+	/* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
+	do {
+		reg_val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS2);
+	} while ((reg_val & wdata_2) != wdata_2);
+
+	/*
+	 * Change MEMTYPE_OVERRIDE from SO_DEV -> PASSTHRU for boot and
+	 * strongly ordered MSS clients.
+	 *
+	 * MC clients with default SO_DEV override still enabled at TSA:
+	 * EQOSW, SATAW, XUSB_DEVW, XUSB_HOSTW, PCIe0w, PCIe1w, PCIe2w,
+	 * PCIe3w, PCIe4w and PCIe5w.
+	 */
+	mc_set_tsa_w_passthrough(AONDMAW);
+	mc_set_tsa_w_passthrough(AONW);
+	mc_set_tsa_w_passthrough(APEDMAW);
+	mc_set_tsa_w_passthrough(APEW);
+	mc_set_tsa_w_passthrough(AXISW);
+	mc_set_tsa_w_passthrough(BPMPDMAW);
+	mc_set_tsa_w_passthrough(BPMPW);
+	mc_set_tsa_w_passthrough(ETRW);
+	mc_set_tsa_w_passthrough(SCEDMAW);
+	mc_set_tsa_w_passthrough(RCEDMAW);
+	mc_set_tsa_w_passthrough(RCEW);
+	mc_set_tsa_w_passthrough(SDMMCW);
+	mc_set_tsa_w_passthrough(SDMMCWA);
+	mc_set_tsa_w_passthrough(SDMMCWAB);
+	mc_set_tsa_w_passthrough(TSECSWR);
+	mc_set_tsa_w_passthrough(TSECSWRB);
+	mc_set_tsa_w_passthrough(UFSHCW);
+	mc_set_tsa_w_passthrough(VICSWR);
+	mc_set_tsa_w_passthrough(VIFALW);
+
+	/* Ordered MC Clients on Xavier are EQOS, SATA, XUSB, PCIe1 and PCIe3
+	 * ISO clients(DISP, VI, EQOS) should never snoop caches and
+	 *     don't need ROC/PCFIFO ordering.
+	 * ISO clients(EQOS) that need ordering should use PCFIFO ordering
+	 *     and bypass ROC ordering by using FORCE_NON_COHERENT path.
+	 * FORCE_NON_COHERENT/FORCE_COHERENT config take precedence
+	 *     over SMMU attributes.
+	 * Force all Normal memory transactions from ISO and non-ISO to be
+	 *     non-coherent(bypass ROC, avoid cache snoop to avoid perf hit).
+	 * Force the SO_DEV transactions from ordered ISO clients(EQOS) to
+	 *     non-coherent path and enable MC PCFIFO interlock for ordering.
+	 * Force the SO_DEV transactions from ordered non-ISO clients (PCIe,
+	 *     XUSB, SATA) to coherent so that the transactions are
+	 *     ordered by ROC.
+	 * PCFIFO ensure write ordering.
+	 * Read after Write ordering is maintained/enforced by MC clients.
+	 * Clients that need PCIe type write ordering must
+	 *     go through ROC ordering.
+	 * Ordering enable for Read clients is not necessary.
+	 * R5's and A9 would get necessary ordering from AXI and
+	 *     don't need ROC ordering enable:
+	 *     - MMIO ordering is through dev mapping and MMIO
+	 *       accesses bypass SMMU.
+	 *     - Normal memory is accessed through SMMU and ordering is
+	 *       ensured by client and AXI.
+	 *     - Ack point for Normal memory is WCAM in MC.
+	 *     - MMIO's can be early acked and AXI ensures dev memory ordering,
+	 *       Client ensures read/write direction change ordering.
+	 *     - See Bug 200312466 for more details.
+	 *
+	 * CGID_TAG_ADR is only present from T186 A02. As this code is common
+	 *    between A01 and A02, tegra_memctrl_set_overrides() programs
+	 *    CGID_TAG_ADR for the necessary clients on A02.
+	 */
+	mc_set_txn_override(AONDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(AONDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(AONR, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(AONW, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(APEDMAR, CGID_TAG_CLIENT_AXI_ID, SO_DEV_CLIENT_AXI_ID, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(APEDMAW, CGID_TAG_CLIENT_AXI_ID, SO_DEV_CLIENT_AXI_ID, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(APER, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(APEW, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(AXISR, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(AXISW, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(BPMPDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(BPMPDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(BPMPR, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(BPMPW, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(EQOSR, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(EQOSW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(ETRR, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(ETRW, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(HOST1XDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(MPCORER, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(MPCOREW, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(NVDISPLAYR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(PTCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(SATAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(SATAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT_SNOOP);
+	mc_set_txn_override(SCEDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(SCEDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(SCER, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(SCEW, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(RCEDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(RCEDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(RCER, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(RCEW, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(SDMMCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(SDMMCRAB, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(SDMMCRA, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(SDMMCW, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(SDMMCWA, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(SDMMCWAB, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(SESRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, NO_OVERRIDE);
+	mc_set_txn_override(SESWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, NO_OVERRIDE);
+	mc_set_txn_override(TSECSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(TSECSRDB, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(TSECSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(TSECSWRB, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(UFSHCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(UFSHCW, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(VICSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(VICSRD1, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(VICSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(VIW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(VIFALR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(VIFALW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(XUSB_DEVR, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(XUSB_DEVW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT,
+			     FORCE_COHERENT_SNOOP);
+	mc_set_txn_override(XUSB_HOSTR, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(XUSB_HOSTW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT,
+			    FORCE_COHERENT_SNOOP);
+	mc_set_txn_override(PCIE0R, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(PCIE0R1, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(PCIE0W, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT,
+			    FORCE_COHERENT_SNOOP);
+	mc_set_txn_override(PCIE1R, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(PCIE1W, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT,
+			    FORCE_COHERENT_SNOOP);
+	if (tegra_platform_is_silicon()) {
+		mc_set_txn_override(PCIE2AR, CGID_TAG_DEFAULT, SO_DEV_ZERO,
+				    NO_OVERRIDE, NO_OVERRIDE);
+		mc_set_txn_override(PCIE2AW, CGID_TAG_DEFAULT, SO_DEV_ZERO,
+				    FORCE_NON_COHERENT, FORCE_COHERENT_SNOOP);
+		mc_set_txn_override(PCIE3R, CGID_TAG_DEFAULT, SO_DEV_ZERO,
+				    NO_OVERRIDE, NO_OVERRIDE);
+		mc_set_txn_override(PCIE3W, CGID_TAG_DEFAULT, SO_DEV_ZERO,
+				    FORCE_NON_COHERENT, FORCE_COHERENT_SNOOP);
+		mc_set_txn_override(PCIE4R, CGID_TAG_DEFAULT, SO_DEV_ZERO,
+				    NO_OVERRIDE, NO_OVERRIDE);
+		mc_set_txn_override(PCIE4W, CGID_TAG_DEFAULT, SO_DEV_ZERO,
+				    FORCE_NON_COHERENT, FORCE_COHERENT_SNOOP);
+		mc_set_txn_override(PCIE5R, CGID_TAG_DEFAULT, SO_DEV_ZERO,
+				    NO_OVERRIDE, NO_OVERRIDE);
+		mc_set_txn_override(PCIE5W, CGID_TAG_DEFAULT, SO_DEV_ZERO,
+				    FORCE_NON_COHERENT, FORCE_COHERENT_SNOOP);
+		mc_set_txn_override(PCIE5R1, CGID_TAG_DEFAULT, SO_DEV_ZERO,
+				    NO_OVERRIDE, NO_OVERRIDE);
+	}
+	/*
+	 * At this point, ordering can occur at ROC. So, remove PCFIFO's
+	 * control over ordering requests.
+	 *
+	 * Change PCFIFO_*_ORDERED_CLIENT from ORDERED -> UNORDERED for
+	 * boot and strongly ordered MSS clients
+	 */
+	/* SATAW is ordered client */
+	reg_val = MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL |
+		mc_set_pcfifo_ordered_boot_so_mss(1, SATAW);
+	tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG1, reg_val);
+
+	reg_val = MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL &
+		mc_set_pcfifo_unordered_boot_so_mss(2, XUSB_HOSTW) &
+		mc_set_pcfifo_unordered_boot_so_mss(2, TSECSWR);
+	/* XUSB_DEVW has PCFIFO enabled. */
+	reg_val |= mc_set_pcfifo_ordered_boot_so_mss(2, XUSB_DEVW);
+	tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG2, reg_val);
+
+	reg_val = MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL &
+		mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCWA) &
+		mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCW) &
+		mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCWAB) &
+		mc_set_pcfifo_unordered_boot_so_mss(3, VICSWR) &
+		mc_set_pcfifo_unordered_boot_so_mss(3, APEW);
+	tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG3, reg_val);
+
+	reg_val = MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL &
+		mc_set_pcfifo_unordered_boot_so_mss(4, SESWR) &
+		mc_set_pcfifo_unordered_boot_so_mss(4, ETRW) &
+		mc_set_pcfifo_unordered_boot_so_mss(4, TSECSWRB) &
+		mc_set_pcfifo_unordered_boot_so_mss(4, AXISW) &
+		mc_set_pcfifo_unordered_boot_so_mss(4, UFSHCW) &
+		mc_set_pcfifo_unordered_boot_so_mss(4, BPMPW) &
+		mc_set_pcfifo_unordered_boot_so_mss(4, BPMPDMAW) &
+		mc_set_pcfifo_unordered_boot_so_mss(4, AONW) &
+		mc_set_pcfifo_unordered_boot_so_mss(4, AONDMAW) &
+		mc_set_pcfifo_unordered_boot_so_mss(4, SCEW) &
+		mc_set_pcfifo_unordered_boot_so_mss(4, SCEDMAW);
+	/* EQOSW has PCFIFO order enabled. */
+	reg_val |= mc_set_pcfifo_ordered_boot_so_mss(4, EQOSW);
+	tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG4, reg_val);
+
+	reg_val = MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL &
+		mc_set_pcfifo_unordered_boot_so_mss(5, APEDMAW) &
+		mc_set_pcfifo_unordered_boot_so_mss(5, VIFALW);
+	tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG5, reg_val);
+
+	reg_val = MC_PCFIFO_CLIENT_CONFIG6_RESET_VAL &
+		mc_set_pcfifo_unordered_boot_so_mss(6, RCEW) &
+		mc_set_pcfifo_unordered_boot_so_mss(6, RCEDMAW) &
+		mc_set_pcfifo_unordered_boot_so_mss(6, PCIE0W);
+	/* PCIE1, PCIE2 and PCI3 has PCFIFO enabled. */
+	reg_val |= mc_set_pcfifo_ordered_boot_so_mss(6, PCIE1W) |
+		mc_set_pcfifo_ordered_boot_so_mss(6, PCIE2W) |
+		mc_set_pcfifo_ordered_boot_so_mss(6, PCIE3W);
+	tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG6, reg_val);
+
+	reg_val = MC_PCFIFO_CLIENT_CONFIG7_RESET_VAL &
+		mc_set_pcfifo_unordered_boot_so_mss(7, PCIE4W) &
+		mc_set_pcfifo_unordered_boot_so_mss(7, PCIE5W);
+	tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG7, reg_val);
+
+	/* Set Order Id only for the clients having non zero order id */
+	reg_val = mc_client_order_id(MC_CLIENT_ORDER_ID_9_RESET_VAL, 9, XUSB_HOSTW);
+	tegra_mc_write_32(MC_CLIENT_ORDER_ID_9, reg_val);
+
+	reg_val = mc_client_order_id(MC_CLIENT_ORDER_ID_27_RESET_VAL, 27, PCIE0W);
+	tegra_mc_write_32(MC_CLIENT_ORDER_ID_27, reg_val);
+
+	reg_val = mc_client_order_id(MC_CLIENT_ORDER_ID_28_RESET_VAL, 28, PCIE4W);
+	reg_val = mc_client_order_id(reg_val, 28, PCIE5W);
+	tegra_mc_write_32(MC_CLIENT_ORDER_ID_28, reg_val);
+
+	/*
+	 * Set VC Id only for the clients having different reset values like
+	 * SDMMCRAB, SDMMCWAB, SESRD, SESWR, TSECSRD,TSECSRDB, TSECSWR and
+	 * TSECSWRB clients
+	 */
+	reg_val = mc_hub_vc_id(MC_HUB_PC_VC_ID_0_RESET_VAL, 0, APB);
+	tegra_mc_write_32(MC_HUB_PC_VC_ID_0, reg_val);
+
+	/* SDMMCRAB and SDMMCWAB clients */
+	reg_val = mc_hub_vc_id(MC_HUB_PC_VC_ID_2_RESET_VAL, 2, SD);
+	tegra_mc_write_32(MC_HUB_PC_VC_ID_2, reg_val);
+
+	reg_val = mc_hub_vc_id(MC_HUB_PC_VC_ID_4_RESET_VAL, 4, NIC);
+	tegra_mc_write_32(MC_HUB_PC_VC_ID_4, reg_val);
+
+	wdata_0 = MC_CLIENT_HOTRESET_CTRL0_RESET_VAL;
+	tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0);
+
+	wdata_1 = MC_CLIENT_HOTRESET_CTRL1_RESET_VAL;
+	tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1);
+
+	wdata_2 = MC_CLIENT_HOTRESET_CTRL2_RESET_VAL;
+	tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL2, wdata_2);
+
+	reg_val = MC_COALESCE_CTRL_COALESCER_ENABLE;
+	tegra_mc_write_32(MC_COALESCE_CTRL, reg_val);
+}
+
+/*******************************************************************************
+ * Struct to hold the memory controller settings
+ ******************************************************************************/
+static tegra_mc_settings_t tegra194_mc_settings = {
+	.streamid_override_cfg = tegra194_streamid_override_regs,
+	.num_streamid_override_cfgs = (uint32_t)ARRAY_SIZE(tegra194_streamid_override_regs),
+	.streamid_security_cfg = tegra194_streamid_sec_cfgs,
+	.num_streamid_security_cfgs = (uint32_t)ARRAY_SIZE(tegra194_streamid_sec_cfgs),
+	.txn_override_cfg = tegra194_txn_override_cfgs,
+	.num_txn_override_cfgs = (uint32_t)ARRAY_SIZE(tegra194_txn_override_cfgs),
+	.reconfig_mss_clients = tegra194_memctrl_reconfig_mss_clients
+};
+
+/*******************************************************************************
+ * Handler to return the pointer to the memory controller's settings struct
+ ******************************************************************************/
+tegra_mc_settings_t *tegra_get_mc_settings(void)
+{
+	return &tegra194_mc_settings;
+}
+
+/*******************************************************************************
+ * Handler to program the scratch registers with TZDRAM settings for the
+ * resume firmware
+ ******************************************************************************/
+void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes)
+{
+	uint32_t sec_reg_ctrl = tegra_mc_read_32(MC_SECURITY_CFG_REG_CTRL_0);
+
+	/*
+	 * Check TZDRAM carveout register access status. Setup TZDRAM fence
+	 * only if access is enabled.
+	 */
+	if ((sec_reg_ctrl & SECURITY_CFG_WRITE_ACCESS_BIT) ==
+	     SECURITY_CFG_WRITE_ACCESS_ENABLE) {
+
+		/*
+		 * Setup the Memory controller to allow only secure accesses to
+		 * the TZDRAM carveout
+		 */
+		INFO("Configuring TrustZone DRAM Memory Carveout\n");
+
+		tegra_mc_write_32(MC_SECURITY_CFG0_0, (uint32_t)phys_base);
+		tegra_mc_write_32(MC_SECURITY_CFG3_0, (uint32_t)(phys_base >> 32));
+		tegra_mc_write_32(MC_SECURITY_CFG1_0, (uint32_t)(size_in_bytes >> 20));
+
+		/*
+		 * MCE propagates the security configuration values across the
+		 * CCPLEX.
+		 */
+		(void)mce_update_gsc_tzdram();
+	}
+}
diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
new file mode 100644
index 0000000..b7e3703
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
@@ -0,0 +1,494 @@
+/*
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <assert.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <context.h>
+#include <denver.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/psci/psci.h>
+#include <mce.h>
+#include <mce_private.h>
+#include <plat/common/platform.h>
+#include <se.h>
+#include <smmu.h>
+#include <t194_nvg.h>
+#include <tegra194_private.h>
+#include <tegra_platform.h>
+#include <tegra_private.h>
+
+extern uint32_t __tegra194_cpu_reset_handler_data,
+		__tegra194_cpu_reset_handler_end;
+
+/* TZDRAM offset for saving SMMU context */
+#define TEGRA194_SMMU_CTX_OFFSET	16U
+
+/* state id mask */
+#define TEGRA194_STATE_ID_MASK		0xFU
+/* constants to get power state's wake time */
+#define TEGRA194_WAKE_TIME_MASK		0x0FFFFFF0U
+#define TEGRA194_WAKE_TIME_SHIFT	4U
+/* default core wake mask for CPU_SUSPEND */
+#define TEGRA194_CORE_WAKE_MASK		0x180cU
+
+static struct t19x_psci_percpu_data {
+	uint32_t wake_time;
+} __aligned(CACHE_WRITEBACK_GRANULE) t19x_percpu_data[PLATFORM_CORE_COUNT];
+
+/*
+ * tegra_fake_system_suspend acts as a boolean var controlling whether
+ * we are going to take fake system suspend code or normal system suspend code
+ * path. This variable is set inside the sip call handlers, when the kernel
+ * requests an SIP call to set the suspend debug flags.
+ */
+bool tegra_fake_system_suspend;
+
+int32_t tegra_soc_validate_power_state(uint32_t power_state,
+					psci_power_state_t *req_state)
+{
+	uint8_t state_id = (uint8_t)psci_get_pstate_id(power_state) &
+			   TEGRA194_STATE_ID_MASK;
+	uint32_t cpu = plat_my_core_pos();
+	int32_t ret = PSCI_E_SUCCESS;
+
+	/* save the core wake time (in TSC ticks)*/
+	t19x_percpu_data[cpu].wake_time = (power_state & TEGRA194_WAKE_TIME_MASK)
+			<< TEGRA194_WAKE_TIME_SHIFT;
+
+	/*
+	 * Clean t19x_percpu_data[cpu] to DRAM. This needs to be done to ensure
+	 * that the correct value is read in tegra_soc_pwr_domain_suspend(),
+	 * which is called with caches disabled. It is possible to read a stale
+	 * value from DRAM in that function, because the L2 cache is not flushed
+	 * unless the cluster is entering CC6/CC7.
+	 */
+	clean_dcache_range((uint64_t)&t19x_percpu_data[cpu],
+			sizeof(t19x_percpu_data[cpu]));
+
+	/* Sanity check the requested state id */
+	switch (state_id) {
+	case PSTATE_ID_CORE_IDLE:
+
+		/* Core idle request */
+		req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_RET_STATE;
+		req_state->pwr_domain_state[MPIDR_AFFLVL1] = PSCI_LOCAL_STATE_RUN;
+		break;
+
+	case PSTATE_ID_CORE_POWERDN:
+
+		/* Core powerdown request */
+		req_state->pwr_domain_state[MPIDR_AFFLVL0] = state_id;
+		req_state->pwr_domain_state[MPIDR_AFFLVL1] = state_id;
+
+		break;
+
+	default:
+		ERROR("%s: unsupported state id (%d)\n", __func__, state_id);
+		ret = PSCI_E_INVALID_PARAMS;
+		break;
+	}
+
+	return ret;
+}
+
+int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state)
+{
+	uint32_t cpu = plat_my_core_pos();
+	mce_cstate_info_t cstate_info = { 0 };
+
+	/* Program default wake mask */
+	cstate_info.wake_mask = TEGRA194_CORE_WAKE_MASK;
+	cstate_info.update_wake_mask = 1;
+	mce_update_cstate_info(&cstate_info);
+
+	/* Enter CPU idle */
+	(void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE,
+				  (uint64_t)TEGRA_NVG_CORE_C6,
+				  t19x_percpu_data[cpu].wake_time,
+				  0U);
+
+	return PSCI_E_SUCCESS;
+}
+
+int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
+{
+	const plat_local_state_t *pwr_domain_state;
+	uint8_t stateid_afflvl0, stateid_afflvl2;
+	plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+	uint64_t smmu_ctx_base;
+	uint32_t val;
+	mce_cstate_info_t sc7_cstate_info = {
+		.cluster = (uint32_t)TEGRA_NVG_CLUSTER_CC6,
+		.ccplex = (uint32_t)TEGRA_NVG_CG_CG7,
+		.system = (uint32_t)TEGRA_NVG_SYSTEM_SC7,
+		.system_state_force = 1U,
+		.update_wake_mask = 1U,
+	};
+	uint32_t cpu = plat_my_core_pos();
+	int32_t ret = 0;
+
+	/* get the state ID */
+	pwr_domain_state = target_state->pwr_domain_state;
+	stateid_afflvl0 = pwr_domain_state[MPIDR_AFFLVL0] &
+		TEGRA194_STATE_ID_MASK;
+	stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] &
+		TEGRA194_STATE_ID_MASK;
+
+	if ((stateid_afflvl0 == PSTATE_ID_CORE_POWERDN)) {
+
+		/* Enter CPU powerdown */
+		(void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE,
+					  (uint64_t)TEGRA_NVG_CORE_C7,
+					  t19x_percpu_data[cpu].wake_time,
+					  0U);
+
+	} else if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
+
+		/* save 'Secure Boot' Processor Feature Config Register */
+		val = mmio_read_32(TEGRA_MISC_BASE + MISCREG_PFCFG);
+		mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_BOOTP_FCFG, val);
+
+		/* save SMMU context */
+		smmu_ctx_base = params_from_bl2->tzdram_base +
+				tegra194_get_smmu_ctx_offset();
+		tegra_smmu_save_context((uintptr_t)smmu_ctx_base);
+
+		/*
+		 * Suspend SE, RNG1 and PKA1 only on silcon and fpga,
+		 * since VDK does not support atomic se ctx save
+		 */
+		if (tegra_platform_is_silicon() || tegra_platform_is_fpga()) {
+			ret = tegra_se_suspend();
+			assert(ret == 0);
+		}
+
+		if (!tegra_fake_system_suspend) {
+
+			/* Prepare for system suspend */
+			mce_update_cstate_info(&sc7_cstate_info);
+
+			do {
+				val = (uint32_t)mce_command_handler(
+						(uint32_t)MCE_CMD_IS_SC7_ALLOWED,
+						(uint32_t)TEGRA_NVG_CORE_C7,
+						MCE_CORE_SLEEP_TIME_INFINITE,
+						0U);
+			} while (val == 0U);
+
+			/* Instruct the MCE to enter system suspend state */
+			ret = mce_command_handler(
+					(uint64_t)MCE_CMD_ENTER_CSTATE,
+					(uint64_t)TEGRA_NVG_CORE_C7,
+					MCE_CORE_SLEEP_TIME_INFINITE,
+					0U);
+			assert(ret == 0);
+
+			/* set system suspend state for house-keeping */
+			tegra194_set_system_suspend_entry();
+		}
+	} else {
+		; /* do nothing */
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
+/*******************************************************************************
+ * Helper function to check if this is the last ON CPU in the cluster
+ ******************************************************************************/
+static bool tegra_last_on_cpu_in_cluster(const plat_local_state_t *states,
+			uint32_t ncpu)
+{
+	plat_local_state_t target;
+	bool last_on_cpu = true;
+	uint32_t num_cpus = ncpu, pos = 0;
+
+	do {
+		target = states[pos];
+		if (target != PLAT_MAX_OFF_STATE) {
+			last_on_cpu = false;
+		}
+		--num_cpus;
+		pos++;
+	} while (num_cpus != 0U);
+
+	return last_on_cpu;
+}
+
+/*******************************************************************************
+ * Helper function to get target power state for the cluster
+ ******************************************************************************/
+static plat_local_state_t tegra_get_afflvl1_pwr_state(const plat_local_state_t *states,
+			uint32_t ncpu)
+{
+	uint32_t core_pos = (uint32_t)read_mpidr() & (uint32_t)MPIDR_CPU_MASK;
+	plat_local_state_t target = states[core_pos];
+	mce_cstate_info_t cstate_info = { 0 };
+
+	/* CPU suspend */
+	if (target == PSTATE_ID_CORE_POWERDN) {
+
+		/* Program default wake mask */
+		cstate_info.wake_mask = TEGRA194_CORE_WAKE_MASK;
+		cstate_info.update_wake_mask = 1;
+		mce_update_cstate_info(&cstate_info);
+	}
+
+	/* CPU off */
+	if (target == PLAT_MAX_OFF_STATE) {
+
+		/* Enable cluster powerdn from last CPU in the cluster */
+		if (tegra_last_on_cpu_in_cluster(states, ncpu)) {
+
+			/* Enable CC6 state and turn off wake mask */
+			cstate_info.cluster = (uint32_t)TEGRA_NVG_CLUSTER_CC6;
+			cstate_info.update_wake_mask = 1U;
+			mce_update_cstate_info(&cstate_info);
+
+		} else {
+
+			/* Turn off wake_mask */
+			cstate_info.update_wake_mask = 1U;
+			mce_update_cstate_info(&cstate_info);
+			target = PSCI_LOCAL_STATE_RUN;
+		}
+	}
+
+	return target;
+}
+
+/*******************************************************************************
+ * Platform handler to calculate the proper target power level at the
+ * specified affinity level
+ ******************************************************************************/
+plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl,
+					     const plat_local_state_t *states,
+					     uint32_t ncpu)
+{
+	plat_local_state_t target = PSCI_LOCAL_STATE_RUN;
+	uint32_t cpu = plat_my_core_pos();
+
+	/* System Suspend */
+	if ((lvl == (uint32_t)MPIDR_AFFLVL2) && (states[cpu] == PSTATE_ID_SOC_POWERDN)) {
+		target = PSTATE_ID_SOC_POWERDN;
+	}
+
+	/* CPU off, CPU suspend */
+	if (lvl == (uint32_t)MPIDR_AFFLVL1) {
+		target = tegra_get_afflvl1_pwr_state(states, ncpu);
+	}
+
+	/* target cluster/system state */
+	return target;
+}
+
+int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
+{
+	const plat_local_state_t *pwr_domain_state =
+		target_state->pwr_domain_state;
+	plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+	uint8_t stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] &
+		TEGRA194_STATE_ID_MASK;
+	uint64_t val;
+	u_register_t ns_sctlr_el1;
+
+	if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
+		/*
+		 * The TZRAM loses power when we enter system suspend. To
+		 * allow graceful exit from system suspend, we need to copy
+		 * BL3-1 over to TZDRAM.
+		 */
+		val = params_from_bl2->tzdram_base +
+		      tegra194_get_cpu_reset_handler_size();
+		memcpy((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE,
+		       (uintptr_t)&__BL31_END__ - (uintptr_t)BL31_BASE);
+
+		/*
+		 * In fake suspend mode, ensure that the loopback procedure
+		 * towards system suspend exit is started, instead of calling
+		 * WFI. This is done by disabling both MMU's of EL1 & El3
+		 * and calling tegra_secure_entrypoint().
+		 */
+		if (tegra_fake_system_suspend) {
+
+			/*
+			 * Disable EL1's MMU.
+			 */
+			ns_sctlr_el1 = read_sctlr_el1();
+			ns_sctlr_el1 &= (~((u_register_t)SCTLR_M_BIT));
+			write_sctlr_el1(ns_sctlr_el1);
+
+			/*
+			 * Disable MMU to power up the CPU in a "clean"
+			 * state
+			 */
+			disable_mmu_el3();
+			tegra_secure_entrypoint();
+			panic();
+		}
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
+int32_t tegra_soc_pwr_domain_on(u_register_t mpidr)
+{
+	uint64_t target_cpu = mpidr & MPIDR_CPU_MASK;
+	uint64_t target_cluster = (mpidr & MPIDR_CLUSTER_MASK) >>
+			MPIDR_AFFINITY_BITS;
+	int32_t ret = 0;
+
+	if (target_cluster > ((uint32_t)PLATFORM_CLUSTER_COUNT - 1U)) {
+		ERROR("%s: unsupported CPU (0x%lx)\n", __func__ , mpidr);
+		return PSCI_E_NOT_PRESENT;
+	}
+
+	/* construct the target CPU # */
+	target_cpu += (target_cluster << 1U);
+
+	ret = mce_command_handler((uint64_t)MCE_CMD_ONLINE_CORE, target_cpu, 0U, 0U);
+	if (ret < 0) {
+		return PSCI_E_DENIED;
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
+int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+	uint8_t stateid_afflvl2 = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL];
+
+	/*
+	 * Reset power state info for CPUs when onlining, we set
+	 * deepest power when offlining a core but that may not be
+	 * requested by non-secure sw which controls idle states. It
+	 * will re-init this info from non-secure software when the
+	 * core come online.
+	 */
+
+	/*
+	 * Check if we are exiting from deep sleep and restore SE
+	 * context if we are.
+	 */
+	if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
+
+#if ENABLE_STRICT_CHECKING_MODE
+		/*
+		 * Enable strict checking after programming the GSC for
+		 * enabling TZSRAM and TZDRAM
+		 */
+		mce_enable_strict_checking();
+#endif
+
+		/* Init SMMU */
+		tegra_smmu_init();
+
+		/* Resume SE, RNG1 and PKA1 */
+		tegra_se_resume();
+
+		/*
+		 * Program XUSB STREAMIDs
+		 * ======================
+		 * T19x XUSB has support for XUSB virtualization. It will
+		 * have one physical function (PF) and four Virtual functions
+		 * (VF)
+		 *
+		 * There were below two SIDs for XUSB until T186.
+		 * 1) #define TEGRA_SID_XUSB_HOST    0x1bU
+		 * 2) #define TEGRA_SID_XUSB_DEV    0x1cU
+		 *
+		 * We have below four new SIDs added for VF(s)
+		 * 3) #define TEGRA_SID_XUSB_VF0    0x5dU
+		 * 4) #define TEGRA_SID_XUSB_VF1    0x5eU
+		 * 5) #define TEGRA_SID_XUSB_VF2    0x5fU
+		 * 6) #define TEGRA_SID_XUSB_VF3    0x60U
+		 *
+		 * When virtualization is enabled then we have to disable SID
+		 * override and program above SIDs in below newly added SID
+		 * registers in XUSB PADCTL MMIO space. These registers are
+		 * TZ protected and so need to be done in ATF.
+		 *
+		 * a) #define XUSB_PADCTL_HOST_AXI_STREAMID_PF_0 (0x136cU)
+		 * b) #define XUSB_PADCTL_DEV_AXI_STREAMID_PF_0  (0x139cU)
+		 * c) #define XUSB_PADCTL_HOST_AXI_STREAMID_VF_0 (0x1370U)
+		 * d) #define XUSB_PADCTL_HOST_AXI_STREAMID_VF_1 (0x1374U)
+		 * e) #define XUSB_PADCTL_HOST_AXI_STREAMID_VF_2 (0x1378U)
+		 * f) #define XUSB_PADCTL_HOST_AXI_STREAMID_VF_3 (0x137cU)
+		 *
+		 * This change disables SID override and programs XUSB SIDs
+		 * in above registers to support both virtualization and
+		 * non-virtualization platforms
+		 */
+		mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
+			XUSB_PADCTL_HOST_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_HOST);
+		mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
+			XUSB_PADCTL_HOST_AXI_STREAMID_VF_0, TEGRA_SID_XUSB_VF0);
+		mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
+			XUSB_PADCTL_HOST_AXI_STREAMID_VF_1, TEGRA_SID_XUSB_VF1);
+		mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
+			XUSB_PADCTL_HOST_AXI_STREAMID_VF_2, TEGRA_SID_XUSB_VF2);
+		mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
+			XUSB_PADCTL_HOST_AXI_STREAMID_VF_3, TEGRA_SID_XUSB_VF3);
+		mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
+			XUSB_PADCTL_DEV_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_DEV);
+
+		/*
+		 * Reset power state info for the last core doing SC7
+		 * entry and exit, we set deepest power state as CC7
+		 * and SC7 for SC7 entry which may not be requested by
+		 * non-secure SW which controls idle states.
+		 */
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
+int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
+{
+	uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
+	int32_t ret = 0;
+
+	(void)target_state;
+
+	/* Disable Denver's DCO operations */
+	if (impl == DENVER_IMPL) {
+		denver_disable_dco();
+	}
+
+	/* Turn off CPU */
+	ret = mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE,
+			(uint64_t)TEGRA_NVG_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0U);
+	assert(ret == 0);
+
+	return PSCI_E_SUCCESS;
+}
+
+__dead2 void tegra_soc_prepare_system_off(void)
+{
+	/* System power off */
+	mce_system_shutdown();
+
+	wfi();
+
+	/* wait for the system to power down */
+	for (;;) {
+		;
+	}
+}
+
+int32_t tegra_soc_prepare_system_reset(void)
+{
+	/* System reboot */
+	mce_system_reboot();
+
+	return PSCI_E_SUCCESS;
+}
diff --git a/plat/nvidia/tegra/soc/t194/plat_secondary.c b/plat/nvidia/tegra/soc/t194/plat_secondary.c
new file mode 100644
index 0000000..c397c91
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/plat_secondary.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <mce.h>
+#include <string.h>
+#include <tegra194_private.h>
+#include <tegra_def.h>
+#include <tegra_private.h>
+
+#define MISCREG_AA64_RST_LOW		0x2004U
+#define MISCREG_AA64_RST_HIGH		0x2008U
+
+#define CPU_RESET_MODE_AA64		1U
+
+/*******************************************************************************
+ * Setup secondary CPU vectors
+ ******************************************************************************/
+void plat_secondary_setup(void)
+{
+	uint32_t addr_low, addr_high;
+	plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+	uint64_t cpu_reset_handler_base, cpu_reset_handler_size;
+
+	INFO("Setting up secondary CPU boot\n");
+
+	/*
+	 * The BL31 code resides in the TZSRAM which loses state
+	 * when we enter System Suspend. Copy the wakeup trampoline
+	 * code to TZDRAM to help us exit from System Suspend.
+	 */
+	cpu_reset_handler_base = tegra194_get_cpu_reset_handler_base();
+	cpu_reset_handler_size = tegra194_get_cpu_reset_handler_size();
+	memcpy((void *)((uintptr_t)params_from_bl2->tzdram_base),
+		(void *)((uintptr_t)cpu_reset_handler_base),
+		cpu_reset_handler_size);
+
+	/* TZDRAM base will be used as the "resume" address */
+	addr_low = (uint32_t)params_from_bl2->tzdram_base | CPU_RESET_MODE_AA64;
+	addr_high = (uint32_t)((params_from_bl2->tzdram_base >> 32U) & 0x7ffU);
+
+	/* write lower 32 bits first, then the upper 11 bits */
+	mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_LOW, addr_low);
+	mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_HIGH, addr_high);
+
+	/* save reset vector to be used during SYSTEM_SUSPEND exit */
+	mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_LO,
+			addr_low);
+	mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_HI,
+			addr_high);
+}
diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c
new file mode 100644
index 0000000..3b58244
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/plat_setup.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl31/bl31.h>
+#include <common/bl_common.h>
+#include <common/interrupt_props.h>
+#include <drivers/console.h>
+#include <context.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <cortex_a57.h>
+#include <common/debug.h>
+#include <denver.h>
+#include <drivers/arm/gic_common.h>
+#include <drivers/arm/gicv2.h>
+#include <bl31/interrupt_mgmt.h>
+#include <mce.h>
+#include <mce_private.h>
+#include <plat/common/platform.h>
+#include <spe.h>
+#include <tegra_def.h>
+#include <tegra_mc_def.h>
+#include <tegra_platform.h>
+#include <tegra_private.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+/* ID for spe-console */
+#define TEGRA_CONSOLE_SPE_ID		0xFE
+
+/*******************************************************************************
+ * The Tegra power domain tree has a single system level power domain i.e. a
+ * single root node. The first entry in the power domain descriptor specifies
+ * the number of power domains at the highest power level.
+ *******************************************************************************
+ */
+static const uint8_t tegra_power_domain_tree_desc[] = {
+	/* No of root nodes */
+	1,
+	/* No of clusters */
+	PLATFORM_CLUSTER_COUNT,
+	/* No of CPU cores - cluster0 */
+	PLATFORM_MAX_CPUS_PER_CLUSTER,
+	/* No of CPU cores - cluster1 */
+	PLATFORM_MAX_CPUS_PER_CLUSTER,
+	/* No of CPU cores - cluster2 */
+	PLATFORM_MAX_CPUS_PER_CLUSTER,
+	/* No of CPU cores - cluster3 */
+	PLATFORM_MAX_CPUS_PER_CLUSTER
+};
+
+/*******************************************************************************
+ * This function returns the Tegra default topology tree information.
+ ******************************************************************************/
+const uint8_t *plat_get_power_domain_tree_desc(void)
+{
+	return tegra_power_domain_tree_desc;
+}
+
+/*
+ * Table of regions to map using the MMU.
+ */
+static const mmap_region_t tegra_mmap[] = {
+	MAP_REGION_FLAT(TEGRA_MISC_BASE, 0x10000U, /* 64KB */
+			(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_TSA_BASE, 0x20000U, /* 128KB */
+			(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_MC_STREAMID_BASE, 0x10000U, /* 64KB */
+			(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_MC_BASE, 0x10000U, /* 64KB */
+			(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
+#if !ENABLE_CONSOLE_SPE
+	MAP_REGION_FLAT(TEGRA_UARTA_BASE, 0x20000U, /* 128KB - UART A, B*/
+			(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_UARTC_BASE, 0x20000U, /* 128KB - UART C, G */
+			(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_UARTD_BASE, 0x30000U, /* 192KB - UART D, E, F */
+			(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
+#endif
+	MAP_REGION_FLAT(TEGRA_FUSE_BASE, 0x10000U, /* 64KB */
+			(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_GICD_BASE, 0x20000U, /* 128KB */
+			(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_SE0_BASE, 0x10000U, /* 64KB */
+			(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_PKA1_BASE, 0x10000U, /* 64KB */
+			(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_RNG1_BASE, 0x10000U, /* 64KB */
+			(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
+#if ENABLE_CONSOLE_SPE
+	MAP_REGION_FLAT(TEGRA_AON_HSP_SM_6_7_BASE, 0x10000U, /* 64KB */
+			(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
+#endif
+	MAP_REGION_FLAT(TEGRA_CAR_RESET_BASE, 0x10000U, /* 64KB */
+			(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_PMC_BASE, 0x40000U, /* 256KB */
+			(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_SCRATCH_BASE, 0x10000U, /* 64KB */
+			(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_MMCRAB_BASE, 0x60000U, /* 384KB */
+			(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_SMMU0_BASE, 0x1000000U, /* 64KB */
+			(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_SMMU1_BASE, 0x1000000U, /* 64KB */
+			(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_SMMU2_BASE, 0x1000000U, /* 64KB */
+			(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_XUSB_PADCTL_BASE, 0x10000U, /* 64KB */
+			(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE),
+	{0}
+};
+
+/*******************************************************************************
+ * Set up the pagetables as per the platform memory map & initialize the MMU
+ ******************************************************************************/
+const mmap_region_t *plat_get_mmio_map(void)
+{
+	/* MMIO space */
+	return tegra_mmap;
+}
+
+/*******************************************************************************
+ * Handler to get the System Counter Frequency
+ ******************************************************************************/
+uint32_t plat_get_syscnt_freq2(void)
+{
+	return 31250000;
+}
+
+#if !ENABLE_CONSOLE_SPE
+/*******************************************************************************
+ * Maximum supported UART controllers
+ ******************************************************************************/
+#define TEGRA194_MAX_UART_PORTS		7
+
+/*******************************************************************************
+ * This variable holds the UART port base addresses
+ ******************************************************************************/
+static uint32_t tegra194_uart_addresses[TEGRA194_MAX_UART_PORTS + 1] = {
+	0,	/* undefined - treated as an error case */
+	TEGRA_UARTA_BASE,
+	TEGRA_UARTB_BASE,
+	TEGRA_UARTC_BASE,
+	TEGRA_UARTD_BASE,
+	TEGRA_UARTE_BASE,
+	TEGRA_UARTF_BASE,
+	TEGRA_UARTG_BASE
+};
+#endif
+
+/*******************************************************************************
+ * Enable console corresponding to the console ID
+ ******************************************************************************/
+void plat_enable_console(int32_t id)
+{
+	uint32_t console_clock = 0U;
+
+#if ENABLE_CONSOLE_SPE
+	static console_spe_t spe_console;
+
+	if (id == TEGRA_CONSOLE_SPE_ID) {
+		(void)console_spe_register(TEGRA_CONSOLE_SPE_BASE,
+					   console_clock,
+					   TEGRA_CONSOLE_BAUDRATE,
+					   &spe_console);
+		console_set_scope(&spe_console.console, CONSOLE_FLAG_BOOT |
+			CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
+	}
+#else
+	static console_16550_t uart_console;
+
+	if ((id > 0) && (id < TEGRA194_MAX_UART_PORTS)) {
+		/*
+		 * Reference clock used by the FPGAs is a lot slower.
+		 */
+		if (tegra_platform_is_fpga()) {
+			console_clock = TEGRA_BOOT_UART_CLK_13_MHZ;
+		} else {
+			console_clock = TEGRA_BOOT_UART_CLK_408_MHZ;
+		}
+
+		(void)console_16550_register(tegra194_uart_addresses[id],
+					     console_clock,
+					     TEGRA_CONSOLE_BAUDRATE,
+					     &uart_console);
+		console_set_scope(&uart_console.console, CONSOLE_FLAG_BOOT |
+			CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
+	}
+#endif
+}
+
+/*******************************************************************************
+ * Handler for early platform setup
+ ******************************************************************************/
+void plat_early_platform_setup(void)
+{
+	/* sanity check MCE firmware compatibility */
+	mce_verify_firmware_version();
+
+	/*
+	 * Program XUSB STREAMIDs
+	 * ======================
+	 * T19x XUSB has support for XUSB virtualization. It will have one
+	 * physical function (PF) and four Virtual function (VF)
+	 *
+	 * There were below two SIDs for XUSB until T186.
+	 * 1) #define TEGRA_SID_XUSB_HOST    0x1bU
+	 * 2) #define TEGRA_SID_XUSB_DEV    0x1cU
+	 *
+	 * We have below four new SIDs added for VF(s)
+	 * 3) #define TEGRA_SID_XUSB_VF0    0x5dU
+	 * 4) #define TEGRA_SID_XUSB_VF1    0x5eU
+	 * 5) #define TEGRA_SID_XUSB_VF2    0x5fU
+	 * 6) #define TEGRA_SID_XUSB_VF3    0x60U
+	 *
+	 * When virtualization is enabled then we have to disable SID override
+	 * and program above SIDs in below newly added SID registers in XUSB
+	 * PADCTL MMIO space. These registers are TZ protected and so need to
+	 * be done in ATF.
+	 * a) #define XUSB_PADCTL_HOST_AXI_STREAMID_PF_0 (0x136cU)
+	 * b) #define XUSB_PADCTL_DEV_AXI_STREAMID_PF_0  (0x139cU)
+	 * c) #define XUSB_PADCTL_HOST_AXI_STREAMID_VF_0 (0x1370U)
+	 * d) #define XUSB_PADCTL_HOST_AXI_STREAMID_VF_1 (0x1374U)
+	 * e) #define XUSB_PADCTL_HOST_AXI_STREAMID_VF_2 (0x1378U)
+	 * f) #define XUSB_PADCTL_HOST_AXI_STREAMID_VF_3 (0x137cU)
+	 *
+	 * This change disables SID override and programs XUSB SIDs in
+	 * above registers to support both virtualization and
+	 * non-virtualization platforms
+	 */
+	mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
+		XUSB_PADCTL_HOST_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_HOST);
+	mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
+		XUSB_PADCTL_HOST_AXI_STREAMID_VF_0, TEGRA_SID_XUSB_VF0);
+	mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
+		XUSB_PADCTL_HOST_AXI_STREAMID_VF_1, TEGRA_SID_XUSB_VF1);
+	mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
+		XUSB_PADCTL_HOST_AXI_STREAMID_VF_2, TEGRA_SID_XUSB_VF2);
+	mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
+		XUSB_PADCTL_HOST_AXI_STREAMID_VF_3, TEGRA_SID_XUSB_VF3);
+	mmio_write_32(TEGRA_XUSB_PADCTL_BASE +
+		XUSB_PADCTL_DEV_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_DEV);
+}
+
+/* Secure IRQs for Tegra194 */
+static const interrupt_prop_t tegra194_interrupt_props[] = {
+	INTR_PROP_DESC(TEGRA194_TOP_WDT_IRQ, GIC_HIGHEST_SEC_PRIORITY,
+			GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE),
+	INTR_PROP_DESC(TEGRA194_AON_WDT_IRQ, GIC_HIGHEST_SEC_PRIORITY,
+			GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE)
+};
+
+/*******************************************************************************
+ * Initialize the GIC and SGIs
+ ******************************************************************************/
+void plat_gic_setup(void)
+{
+	tegra_gic_setup(tegra194_interrupt_props, ARRAY_SIZE(tegra194_interrupt_props));
+	tegra_gic_init();
+
+	/*
+	 * Initialize the FIQ handler
+	 */
+	tegra_fiq_handler_setup();
+}
+
+/*******************************************************************************
+ * Return pointer to the BL31 params from previous bootloader
+ ******************************************************************************/
+struct tegra_bl31_params *plat_get_bl31_params(void)
+{
+	uint32_t val;
+
+	val = mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_BL31_PARAMS_ADDR);
+
+	return (struct tegra_bl31_params *)(uintptr_t)val;
+}
+
+/*******************************************************************************
+ * Return pointer to the BL31 platform params from previous bootloader
+ ******************************************************************************/
+plat_params_from_bl2_t *plat_get_bl31_plat_params(void)
+{
+	uint32_t val;
+
+	val = mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_BL31_PLAT_PARAMS_ADDR);
+
+	return (plat_params_from_bl2_t *)(uintptr_t)val;
+}
+
+void plat_late_platform_setup(void)
+{
+#if ENABLE_STRICT_CHECKING_MODE
+	/*
+	 * Enable strict checking after programming the GSC for
+	 * enabling TZSRAM and TZDRAM
+	 */
+	mce_enable_strict_checking();
+#endif
+}
diff --git a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
new file mode 100644
index 0000000..8873358
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <common/bl_common.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <common/debug.h>
+#include <errno.h>
+#include <mce.h>
+#include <memctrl.h>
+#include <common/runtime_svc.h>
+#include <tegra_private.h>
+#include <tegra_platform.h>
+#include <stdbool.h>
+
+extern bool tegra_fake_system_suspend;
+
+/*******************************************************************************
+ * Tegra194 SiP SMCs
+ ******************************************************************************/
+#define TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND		0xC2FFFE03U
+
+/*******************************************************************************
+ * This function is responsible for handling all T194 SiP calls
+ ******************************************************************************/
+int32_t plat_sip_handler(uint32_t smc_fid,
+		     uint64_t x1,
+		     uint64_t x2,
+		     uint64_t x3,
+		     uint64_t x4,
+		     const void *cookie,
+		     void *handle,
+		     uint64_t flags)
+{
+	int32_t ret = -ENOTSUP;
+
+	(void)x1;
+	(void)x4;
+	(void)cookie;
+	(void)flags;
+
+	if (smc_fid == TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND) {
+		/*
+		 * System suspend mode is set if the platform ATF is
+		 * running on VDK and there is a debug SIP call. This mode
+		 * ensures that the debug path is exercised, instead of
+		 * regular code path to suit the pre-silicon platform needs.
+		 * This includes replacing the call to WFI, with calls to
+		 * system suspend exit procedures.
+		 */
+		if (tegra_platform_is_virt_dev_kit()) {
+			tegra_fake_system_suspend = true;
+			ret = 0;
+		}
+	}
+
+	return ret;
+}
diff --git a/plat/nvidia/tegra/soc/t194/plat_smmu.c b/plat/nvidia/tegra/soc/t194/plat_smmu.c
new file mode 100644
index 0000000..640ef4d
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/plat_smmu.c
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/bl_common.h>
+#include <common/debug.h>
+#include <smmu.h>
+#include <tegra_def.h>
+#include <tegra_mc_def.h>
+
+#define BOARD_SYSTEM_FPGA_BASE		U(1)
+#define BASE_CONFIG_SMMU_DEVICES	U(2)
+#define MAX_NUM_SMMU_DEVICES		U(3)
+
+static uint32_t tegra_misc_read_32(uint32_t off)
+{
+	return mmio_read_32((uintptr_t)TEGRA_MISC_BASE + off);
+}
+
+/*******************************************************************************
+ * Array to hold SMMU context for Tegra194
+ ******************************************************************************/
+static __attribute__((aligned(16))) smmu_regs_t tegra194_smmu_context[] = {
+	_START_OF_TABLE_,
+	mc_make_sid_security_cfg(HDAR),
+	mc_make_sid_security_cfg(HOST1XDMAR),
+	mc_make_sid_security_cfg(NVENCSRD),
+	mc_make_sid_security_cfg(SATAR),
+	mc_make_sid_security_cfg(NVENCSWR),
+	mc_make_sid_security_cfg(HDAW),
+	mc_make_sid_security_cfg(SATAW),
+	mc_make_sid_security_cfg(ISPRA),
+	mc_make_sid_security_cfg(ISPFALR),
+	mc_make_sid_security_cfg(ISPWA),
+	mc_make_sid_security_cfg(ISPWB),
+	mc_make_sid_security_cfg(XUSB_HOSTR),
+	mc_make_sid_security_cfg(XUSB_HOSTW),
+	mc_make_sid_security_cfg(XUSB_DEVR),
+	mc_make_sid_security_cfg(XUSB_DEVW),
+	mc_make_sid_security_cfg(TSECSRD),
+	mc_make_sid_security_cfg(TSECSWR),
+	mc_make_sid_security_cfg(SDMMCRA),
+	mc_make_sid_security_cfg(SDMMCR),
+	mc_make_sid_security_cfg(SDMMCRAB),
+	mc_make_sid_security_cfg(SDMMCWA),
+	mc_make_sid_security_cfg(SDMMCW),
+	mc_make_sid_security_cfg(SDMMCWAB),
+	mc_make_sid_security_cfg(VICSRD),
+	mc_make_sid_security_cfg(VICSWR),
+	mc_make_sid_security_cfg(VIW),
+	mc_make_sid_security_cfg(NVDECSRD),
+	mc_make_sid_security_cfg(NVDECSWR),
+	mc_make_sid_security_cfg(APER),
+	mc_make_sid_security_cfg(APEW),
+	mc_make_sid_security_cfg(NVJPGSRD),
+	mc_make_sid_security_cfg(NVJPGSWR),
+	mc_make_sid_security_cfg(SESRD),
+	mc_make_sid_security_cfg(SESWR),
+	mc_make_sid_security_cfg(AXIAPR),
+	mc_make_sid_security_cfg(AXIAPW),
+	mc_make_sid_security_cfg(ETRR),
+	mc_make_sid_security_cfg(ETRW),
+	mc_make_sid_security_cfg(TSECSRDB),
+	mc_make_sid_security_cfg(TSECSWRB),
+	mc_make_sid_security_cfg(AXISR),
+	mc_make_sid_security_cfg(AXISW),
+	mc_make_sid_security_cfg(EQOSR),
+	mc_make_sid_security_cfg(EQOSW),
+	mc_make_sid_security_cfg(UFSHCR),
+	mc_make_sid_security_cfg(UFSHCW),
+	mc_make_sid_security_cfg(NVDISPLAYR),
+	mc_make_sid_security_cfg(BPMPR),
+	mc_make_sid_security_cfg(BPMPW),
+	mc_make_sid_security_cfg(BPMPDMAR),
+	mc_make_sid_security_cfg(BPMPDMAW),
+	mc_make_sid_security_cfg(AONR),
+	mc_make_sid_security_cfg(AONW),
+	mc_make_sid_security_cfg(AONDMAR),
+	mc_make_sid_security_cfg(AONDMAW),
+	mc_make_sid_security_cfg(SCER),
+	mc_make_sid_security_cfg(SCEW),
+	mc_make_sid_security_cfg(SCEDMAR),
+	mc_make_sid_security_cfg(SCEDMAW),
+	mc_make_sid_security_cfg(APEDMAR),
+	mc_make_sid_security_cfg(APEDMAW),
+	mc_make_sid_security_cfg(NVDISPLAYR1),
+	mc_make_sid_security_cfg(VICSRD1),
+	mc_make_sid_security_cfg(NVDECSRD1),
+	mc_make_sid_security_cfg(VIFALR),
+	mc_make_sid_security_cfg(VIFALW),
+	mc_make_sid_security_cfg(DLA0RDA),
+	mc_make_sid_security_cfg(DLA0FALRDB),
+	mc_make_sid_security_cfg(DLA0WRA),
+	mc_make_sid_security_cfg(DLA0FALWRB),
+	mc_make_sid_security_cfg(DLA1RDA),
+	mc_make_sid_security_cfg(DLA1FALRDB),
+	mc_make_sid_security_cfg(DLA1WRA),
+	mc_make_sid_security_cfg(DLA1FALWRB),
+	mc_make_sid_security_cfg(PVA0RDA),
+	mc_make_sid_security_cfg(PVA0RDB),
+	mc_make_sid_security_cfg(PVA0RDC),
+	mc_make_sid_security_cfg(PVA0WRA),
+	mc_make_sid_security_cfg(PVA0WRB),
+	mc_make_sid_security_cfg(PVA0WRC),
+	mc_make_sid_security_cfg(PVA1RDA),
+	mc_make_sid_security_cfg(PVA1RDB),
+	mc_make_sid_security_cfg(PVA1RDC),
+	mc_make_sid_security_cfg(PVA1WRA),
+	mc_make_sid_security_cfg(PVA1WRB),
+	mc_make_sid_security_cfg(PVA1WRC),
+	mc_make_sid_security_cfg(RCER),
+	mc_make_sid_security_cfg(RCEW),
+	mc_make_sid_security_cfg(RCEDMAR),
+	mc_make_sid_security_cfg(RCEDMAW),
+	mc_make_sid_security_cfg(NVENC1SRD),
+	mc_make_sid_security_cfg(NVENC1SWR),
+	mc_make_sid_security_cfg(PCIE0R),
+	mc_make_sid_security_cfg(PCIE0W),
+	mc_make_sid_security_cfg(PCIE1R),
+	mc_make_sid_security_cfg(PCIE1W),
+	mc_make_sid_security_cfg(PCIE2AR),
+	mc_make_sid_security_cfg(PCIE2AW),
+	mc_make_sid_security_cfg(PCIE3R),
+	mc_make_sid_security_cfg(PCIE3W),
+	mc_make_sid_security_cfg(PCIE4R),
+	mc_make_sid_security_cfg(PCIE4W),
+	mc_make_sid_security_cfg(PCIE5R),
+	mc_make_sid_security_cfg(PCIE5W),
+	mc_make_sid_security_cfg(ISPFALW),
+	mc_make_sid_security_cfg(DLA0RDA1),
+	mc_make_sid_security_cfg(DLA1RDA1),
+	mc_make_sid_security_cfg(PVA0RDA1),
+	mc_make_sid_security_cfg(PVA0RDB1),
+	mc_make_sid_security_cfg(PVA1RDA1),
+	mc_make_sid_security_cfg(PVA1RDB1),
+	mc_make_sid_security_cfg(PCIE5R1),
+	mc_make_sid_security_cfg(NVENCSRD1),
+	mc_make_sid_security_cfg(NVENC1SRD1),
+	mc_make_sid_security_cfg(ISPRA1),
+	mc_make_sid_security_cfg(MIU0R),
+	mc_make_sid_security_cfg(MIU0W),
+	mc_make_sid_security_cfg(MIU1R),
+	mc_make_sid_security_cfg(MIU1W),
+	mc_make_sid_security_cfg(MIU2R),
+	mc_make_sid_security_cfg(MIU2W),
+	mc_make_sid_security_cfg(MIU3R),
+	mc_make_sid_security_cfg(MIU3W),
+	mc_make_sid_override_cfg(HDAR),
+	mc_make_sid_override_cfg(HOST1XDMAR),
+	mc_make_sid_override_cfg(NVENCSRD),
+	mc_make_sid_override_cfg(SATAR),
+	mc_make_sid_override_cfg(NVENCSWR),
+	mc_make_sid_override_cfg(HDAW),
+	mc_make_sid_override_cfg(SATAW),
+	mc_make_sid_override_cfg(ISPRA),
+	mc_make_sid_override_cfg(ISPFALR),
+	mc_make_sid_override_cfg(ISPWA),
+	mc_make_sid_override_cfg(ISPWB),
+	mc_make_sid_override_cfg(XUSB_HOSTR),
+	mc_make_sid_override_cfg(XUSB_HOSTW),
+	mc_make_sid_override_cfg(XUSB_DEVR),
+	mc_make_sid_override_cfg(XUSB_DEVW),
+	mc_make_sid_override_cfg(TSECSRD),
+	mc_make_sid_override_cfg(TSECSWR),
+	mc_make_sid_override_cfg(SDMMCRA),
+	mc_make_sid_override_cfg(SDMMCR),
+	mc_make_sid_override_cfg(SDMMCRAB),
+	mc_make_sid_override_cfg(SDMMCWA),
+	mc_make_sid_override_cfg(SDMMCW),
+	mc_make_sid_override_cfg(SDMMCWAB),
+	mc_make_sid_override_cfg(VICSRD),
+	mc_make_sid_override_cfg(VICSWR),
+	mc_make_sid_override_cfg(VIW),
+	mc_make_sid_override_cfg(NVDECSRD),
+	mc_make_sid_override_cfg(NVDECSWR),
+	mc_make_sid_override_cfg(APER),
+	mc_make_sid_override_cfg(APEW),
+	mc_make_sid_override_cfg(NVJPGSRD),
+	mc_make_sid_override_cfg(NVJPGSWR),
+	mc_make_sid_override_cfg(SESRD),
+	mc_make_sid_override_cfg(SESWR),
+	mc_make_sid_override_cfg(AXIAPR),
+	mc_make_sid_override_cfg(AXIAPW),
+	mc_make_sid_override_cfg(ETRR),
+	mc_make_sid_override_cfg(ETRW),
+	mc_make_sid_override_cfg(TSECSRDB),
+	mc_make_sid_override_cfg(TSECSWRB),
+	mc_make_sid_override_cfg(AXISR),
+	mc_make_sid_override_cfg(AXISW),
+	mc_make_sid_override_cfg(EQOSR),
+	mc_make_sid_override_cfg(EQOSW),
+	mc_make_sid_override_cfg(UFSHCR),
+	mc_make_sid_override_cfg(UFSHCW),
+	mc_make_sid_override_cfg(NVDISPLAYR),
+	mc_make_sid_override_cfg(BPMPR),
+	mc_make_sid_override_cfg(BPMPW),
+	mc_make_sid_override_cfg(BPMPDMAR),
+	mc_make_sid_override_cfg(BPMPDMAW),
+	mc_make_sid_override_cfg(AONR),
+	mc_make_sid_override_cfg(AONW),
+	mc_make_sid_override_cfg(AONDMAR),
+	mc_make_sid_override_cfg(AONDMAW),
+	mc_make_sid_override_cfg(SCER),
+	mc_make_sid_override_cfg(SCEW),
+	mc_make_sid_override_cfg(SCEDMAR),
+	mc_make_sid_override_cfg(SCEDMAW),
+	mc_make_sid_override_cfg(APEDMAR),
+	mc_make_sid_override_cfg(APEDMAW),
+	mc_make_sid_override_cfg(NVDISPLAYR1),
+	mc_make_sid_override_cfg(VICSRD1),
+	mc_make_sid_override_cfg(NVDECSRD1),
+	mc_make_sid_override_cfg(VIFALR),
+	mc_make_sid_override_cfg(VIFALW),
+	mc_make_sid_override_cfg(DLA0RDA),
+	mc_make_sid_override_cfg(DLA0FALRDB),
+	mc_make_sid_override_cfg(DLA0WRA),
+	mc_make_sid_override_cfg(DLA0FALWRB),
+	mc_make_sid_override_cfg(DLA1RDA),
+	mc_make_sid_override_cfg(DLA1FALRDB),
+	mc_make_sid_override_cfg(DLA1WRA),
+	mc_make_sid_override_cfg(DLA1FALWRB),
+	mc_make_sid_override_cfg(PVA0RDA),
+	mc_make_sid_override_cfg(PVA0RDB),
+	mc_make_sid_override_cfg(PVA0RDC),
+	mc_make_sid_override_cfg(PVA0WRA),
+	mc_make_sid_override_cfg(PVA0WRB),
+	mc_make_sid_override_cfg(PVA0WRC),
+	mc_make_sid_override_cfg(PVA1RDA),
+	mc_make_sid_override_cfg(PVA1RDB),
+	mc_make_sid_override_cfg(PVA1RDC),
+	mc_make_sid_override_cfg(PVA1WRA),
+	mc_make_sid_override_cfg(PVA1WRB),
+	mc_make_sid_override_cfg(PVA1WRC),
+	mc_make_sid_override_cfg(RCER),
+	mc_make_sid_override_cfg(RCEW),
+	mc_make_sid_override_cfg(RCEDMAR),
+	mc_make_sid_override_cfg(RCEDMAW),
+	mc_make_sid_override_cfg(NVENC1SRD),
+	mc_make_sid_override_cfg(NVENC1SWR),
+	mc_make_sid_override_cfg(PCIE0R),
+	mc_make_sid_override_cfg(PCIE0W),
+	mc_make_sid_override_cfg(PCIE1R),
+	mc_make_sid_override_cfg(PCIE1W),
+	mc_make_sid_override_cfg(PCIE2AR),
+	mc_make_sid_override_cfg(PCIE2AW),
+	mc_make_sid_override_cfg(PCIE3R),
+	mc_make_sid_override_cfg(PCIE3W),
+	mc_make_sid_override_cfg(PCIE4R),
+	mc_make_sid_override_cfg(PCIE4W),
+	mc_make_sid_override_cfg(PCIE5R),
+	mc_make_sid_override_cfg(PCIE5W),
+	mc_make_sid_override_cfg(ISPFALW),
+	mc_make_sid_override_cfg(DLA0RDA1),
+	mc_make_sid_override_cfg(DLA1RDA1),
+	mc_make_sid_override_cfg(PVA0RDA1),
+	mc_make_sid_override_cfg(PVA0RDB1),
+	mc_make_sid_override_cfg(PVA1RDA1),
+	mc_make_sid_override_cfg(PVA1RDB1),
+	mc_make_sid_override_cfg(PCIE5R1),
+	mc_make_sid_override_cfg(NVENCSRD1),
+	mc_make_sid_override_cfg(NVENC1SRD1),
+	mc_make_sid_override_cfg(ISPRA1),
+	mc_make_sid_override_cfg(MIU0R),
+	mc_make_sid_override_cfg(MIU0W),
+	mc_make_sid_override_cfg(MIU1R),
+	mc_make_sid_override_cfg(MIU1W),
+	mc_make_sid_override_cfg(MIU2R),
+	mc_make_sid_override_cfg(MIU2W),
+	mc_make_sid_override_cfg(MIU3R),
+	mc_make_sid_override_cfg(MIU3W),
+	smmu_make_cfg(TEGRA_SMMU0_BASE),
+	smmu_make_cfg(TEGRA_SMMU2_BASE),
+	smmu_bypass_cfg,	/* TBU settings */
+	_END_OF_TABLE_,
+};
+
+/*******************************************************************************
+ * Handler to return the pointer to the SMMU's context struct
+ ******************************************************************************/
+smmu_regs_t *plat_get_smmu_ctx(void)
+{
+	/* index of _END_OF_TABLE_ */
+	tegra194_smmu_context[0].val = (uint32_t)ARRAY_SIZE(tegra194_smmu_context) - 1U;
+
+	return tegra194_smmu_context;
+}
+
+/*******************************************************************************
+ * Handler to return the support SMMU devices number
+ ******************************************************************************/
+uint32_t plat_get_num_smmu_devices(void)
+{
+	uint32_t ret_num = MAX_NUM_SMMU_DEVICES;
+	uint32_t board_revid = ((tegra_misc_read_32(MISCREG_EMU_REVID) >> \
+							BOARD_SHIFT_BITS) & BOARD_MASK_BITS);
+
+	if (board_revid == BOARD_SYSTEM_FPGA_BASE) {
+		ret_num = BASE_CONFIG_SMMU_DEVICES;
+	}
+
+	return ret_num;
+}
diff --git a/plat/nvidia/tegra/soc/t194/plat_trampoline.S b/plat/nvidia/tegra/soc/t194/plat_trampoline.S
new file mode 100644
index 0000000..696a577
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/plat_trampoline.S
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <plat/common/common_def.h>
+#include <memctrl_v2.h>
+#include <tegra_def.h>
+
+#define TEGRA194_STATE_SYSTEM_SUSPEND	0x5C7
+#define TEGRA194_STATE_SYSTEM_RESUME	0x600D
+#define TEGRA194_SMMU_CTX_SIZE		0x80B
+
+	.align 4
+	.globl	tegra194_cpu_reset_handler
+
+/* CPU reset handler routine */
+func tegra194_cpu_reset_handler
+	/* check if we are exiting system suspend state */
+	adr	x0, __tegra194_system_suspend_state
+	ldr	x1, [x0]
+	mov	x2, #TEGRA194_STATE_SYSTEM_SUSPEND
+	lsl	x2, x2, #16
+	add	x2, x2, #TEGRA194_STATE_SYSTEM_SUSPEND
+	cmp	x1, x2
+	bne	boot_cpu
+
+	/* set system resume state */
+	mov	x1, #TEGRA194_STATE_SYSTEM_RESUME
+	lsl	x1, x1, #16
+	mov	x2, #TEGRA194_STATE_SYSTEM_RESUME
+	add	x1, x1, x2
+	str	x1, [x0]
+	dsb	sy
+
+	/* prepare to relocate to TZSRAM */
+	mov	x0, #BL31_BASE
+	adr	x1, __tegra194_cpu_reset_handler_end
+	adr	x2, __tegra194_cpu_reset_handler_data
+	ldr	x2, [x2, #8]
+
+	/* memcpy16 */
+m_loop16:
+	cmp	x2, #16
+	b.lt	m_loop1
+	ldp	x3, x4, [x1], #16
+	stp	x3, x4, [x0], #16
+	sub	x2, x2, #16
+	b	m_loop16
+	/* copy byte per byte */
+m_loop1:
+	cbz	x2, boot_cpu
+	ldrb	w3, [x1], #1
+	strb	w3, [x0], #1
+	subs	x2, x2, #1
+	b.ne	m_loop1
+
+boot_cpu:
+	adr	x0, __tegra194_cpu_reset_handler_data
+	ldr	x0, [x0]
+	br	x0
+endfunc tegra194_cpu_reset_handler
+
+	/*
+	 * Tegra194 reset data (offset 0x0 - 0x2490)
+	 *
+	 * 0x0000: secure world's entrypoint
+	 * 0x0008: BL31 size (RO + RW)
+	 * 0x0010: SMMU context start
+	 * 0x2490: SMMU context end
+	 */
+
+	.align 4
+	.type	__tegra194_cpu_reset_handler_data, %object
+	.globl	__tegra194_cpu_reset_handler_data
+__tegra194_cpu_reset_handler_data:
+	.quad	tegra_secure_entrypoint
+	.quad	__BL31_END__ - BL31_BASE
+
+	.globl	__tegra194_system_suspend_state
+__tegra194_system_suspend_state:
+	.quad	0
+
+	.align 4
+__tegra194_smmu_context:
+	.rept	TEGRA194_SMMU_CTX_SIZE
+	.quad	0
+	.endr
+	.size	__tegra194_cpu_reset_handler_data, \
+		. - __tegra194_cpu_reset_handler_data
+
+	.align 4
+	.globl	__tegra194_cpu_reset_handler_end
+__tegra194_cpu_reset_handler_end:
+
+	.globl tegra194_get_cpu_reset_handler_size
+	.globl tegra194_get_cpu_reset_handler_base
+	.globl tegra194_get_smmu_ctx_offset
+	.globl tegra194_set_system_suspend_entry
+
+/* return size of the CPU reset handler */
+func tegra194_get_cpu_reset_handler_size
+	adr	x0, __tegra194_cpu_reset_handler_end
+	adr	x1, tegra194_cpu_reset_handler
+	sub	x0, x0, x1
+	ret
+endfunc tegra194_get_cpu_reset_handler_size
+
+/* return the start address of the CPU reset handler */
+func tegra194_get_cpu_reset_handler_base
+	adr	x0, tegra194_cpu_reset_handler
+	ret
+endfunc tegra194_get_cpu_reset_handler_base
+
+/* return the size of the SMMU context */
+func tegra194_get_smmu_ctx_offset
+	adr	x0, __tegra194_smmu_context
+	adr	x1, tegra194_cpu_reset_handler
+	sub	x0, x0, x1
+	ret
+endfunc tegra194_get_smmu_ctx_offset
+
+/* set system suspend state before SC7 entry */
+func tegra194_set_system_suspend_entry
+	mov	x0, #TEGRA_MC_BASE
+	mov	x3, #MC_SECURITY_CFG3_0
+	ldr	w1, [x0, x3]
+	lsl	x1, x1, #32
+	mov	x3, #MC_SECURITY_CFG0_0
+	ldr	w2, [x0, x3]
+	orr	x3, x1, x2			/* TZDRAM base */
+	adr	x0, __tegra194_system_suspend_state
+	adr	x1, tegra194_cpu_reset_handler
+	sub	x2, x0, x1			/* offset in TZDRAM */
+	mov	x0, #TEGRA194_STATE_SYSTEM_SUSPEND
+	lsl	x0, x0, #16
+	add	x0, x0, #TEGRA194_STATE_SYSTEM_SUSPEND
+	str	x0, [x3, x2]			/* set value in TZDRAM */
+	dsb	sy
+	ret
+endfunc tegra194_set_system_suspend_entry
diff --git a/plat/nvidia/tegra/soc/t194/platform_t194.mk b/plat/nvidia/tegra/soc/t194/platform_t194.mk
new file mode 100644
index 0000000..f114b7e
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/platform_t194.mk
@@ -0,0 +1,57 @@
+#
+# Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# platform configs
+ENABLE_CONSOLE_SPE			:= 0
+$(eval $(call add_define,ENABLE_CONSOLE_SPE))
+
+ENABLE_STRICT_CHECKING_MODE	:= 1
+$(eval $(call add_define,ENABLE_STRICT_CHECKING_MODE))
+
+RESET_TO_BL31				:= 1
+
+PROGRAMMABLE_RESET_ADDRESS		:= 1
+
+COLD_BOOT_SINGLE_CPU			:= 1
+
+# platform settings
+TZDRAM_BASE				:= 0x40000000
+$(eval $(call add_define,TZDRAM_BASE))
+
+PLATFORM_CLUSTER_COUNT			:= 4
+$(eval $(call add_define,PLATFORM_CLUSTER_COUNT))
+
+PLATFORM_MAX_CPUS_PER_CLUSTER		:= 2
+$(eval $(call add_define,PLATFORM_MAX_CPUS_PER_CLUSTER))
+
+MAX_XLAT_TABLES				:= 25
+$(eval $(call add_define,MAX_XLAT_TABLES))
+
+MAX_MMAP_REGIONS			:= 30
+$(eval $(call add_define,MAX_MMAP_REGIONS))
+
+# platform files
+PLAT_INCLUDES		+=	-I${SOC_DIR}/drivers/include
+
+BL31_SOURCES		+=	drivers/ti/uart/aarch64/16550_console.S \
+				lib/cpus/aarch64/denver.S		\
+				${COMMON_DIR}/drivers/memctrl/memctrl_v2.c	\
+				${COMMON_DIR}/drivers/smmu/smmu.c	\
+				${SOC_DIR}/drivers/mce/mce.c		\
+				${SOC_DIR}/drivers/mce/nvg.c		\
+				${SOC_DIR}/drivers/mce/aarch64/nvg_helpers.S \
+				${SOC_DIR}/drivers/se/se.c		\
+				${SOC_DIR}/plat_memctrl.c		\
+				${SOC_DIR}/plat_psci_handlers.c		\
+				${SOC_DIR}/plat_setup.c			\
+				${SOC_DIR}/plat_secondary.c		\
+				${SOC_DIR}/plat_sip_calls.c		\
+				${SOC_DIR}/plat_smmu.c			\
+				${SOC_DIR}/plat_trampoline.S
+
+ifeq (${ENABLE_CONSOLE_SPE},1)
+BL31_SOURCES		+=	${COMMON_DIR}/drivers/spe/shared_console.S
+endif
diff --git a/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h b/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h
index be1f9cc..352107d 100644
--- a/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h
+++ b/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h
@@ -1,5 +1,5 @@
-/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+/*
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2017, NVIDIA CORPORATION.  All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
diff --git a/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c b/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c
index 8d7dbf9..d5e0491 100644
--- a/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c
+++ b/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c
@@ -1,5 +1,5 @@
-/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+/*
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2017, NVIDIA CORPORATION.  All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c
index 2a2d102..bfa8184 100644
--- a/plat/nvidia/tegra/soc/t210/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t210/plat_setup.c
@@ -114,14 +114,30 @@
 };
 
 /*******************************************************************************
- * Retrieve the UART controller base to be used as the console
+ * Enable console corresponding to the console ID
  ******************************************************************************/
-uint32_t plat_get_console_from_id(int id)
+void plat_enable_console(int32_t id)
 {
-	if (id > TEGRA210_MAX_UART_PORTS)
-		return 0;
+	static console_16550_t uart_console;
+	uint32_t console_clock;
+
+	if ((id > 0) && (id < TEGRA210_MAX_UART_PORTS)) {
+		/*
+		 * Reference clock used by the FPGAs is a lot slower.
+		 */
+		if (tegra_platform_is_fpga()) {
+			console_clock = TEGRA_BOOT_UART_CLK_13_MHZ;
+		} else {
+			console_clock = TEGRA_BOOT_UART_CLK_408_MHZ;
+		}
 
-	return tegra210_uart_addresses[id];
+		(void)console_16550_register(tegra210_uart_addresses[id],
+					     console_clock,
+					     TEGRA_CONSOLE_BAUDRATE,
+					     &uart_console);
+		console_set_scope(&uart_console.console, CONSOLE_FLAG_BOOT |
+			CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH);
+	}
 }
 
 /*******************************************************************************
diff --git a/plat/renesas/rcar/bl2_plat_mem_params_desc.c b/plat/renesas/rcar/bl2_plat_mem_params_desc.c
index 3b124c7..bf2706d 100644
--- a/plat/renesas/rcar/bl2_plat_mem_params_desc.c
+++ b/plat/renesas/rcar/bl2_plat_mem_params_desc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -53,6 +53,7 @@
 			entry_point_info_t, SECURE | EXECUTABLE),
 		.ep_info.pc = BL32_BASE,
 		.ep_info.spsr = 0,
+		.ep_info.args.arg3 = (uintptr_t)fdt_blob,
 
 		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2,
 			image_info_t, 0),
diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c
index ebe6ddd..193d80e 100644
--- a/plat/renesas/rcar/bl2_plat_setup.c
+++ b/plat/renesas/rcar/bl2_plat_setup.c
@@ -408,43 +408,46 @@
 	return &bl2_tzram_layout;
 }
 
-static void bl2_populate_compatible_string(void *fdt)
+static void bl2_populate_compatible_string(void *dt)
 {
 	uint32_t board_type;
 	uint32_t board_rev;
 	uint32_t reg;
 	int ret;
 
+	fdt_setprop_u32(dt, 0, "#address-cells", 2);
+	fdt_setprop_u32(dt, 0, "#size-cells", 2);
+
 	/* Populate compatible string */
 	rcar_get_board_type(&board_type, &board_rev);
 	switch (board_type) {
 	case BOARD_SALVATOR_X:
-		ret = fdt_setprop_string(fdt, 0, "compatible",
+		ret = fdt_setprop_string(dt, 0, "compatible",
 					 "renesas,salvator-x");
 		break;
 	case BOARD_SALVATOR_XS:
-		ret = fdt_setprop_string(fdt, 0, "compatible",
+		ret = fdt_setprop_string(dt, 0, "compatible",
 					 "renesas,salvator-xs");
 		break;
 	case BOARD_STARTER_KIT:
-		ret = fdt_setprop_string(fdt, 0, "compatible",
+		ret = fdt_setprop_string(dt, 0, "compatible",
 					 "renesas,m3ulcb");
 		break;
 	case BOARD_STARTER_KIT_PRE:
-		ret = fdt_setprop_string(fdt, 0, "compatible",
+		ret = fdt_setprop_string(dt, 0, "compatible",
 					 "renesas,h3ulcb");
 		break;
 	case BOARD_EAGLE:
-		ret = fdt_setprop_string(fdt, 0, "compatible",
+		ret = fdt_setprop_string(dt, 0, "compatible",
 					 "renesas,eagle");
 		break;
 	case BOARD_EBISU:
 	case BOARD_EBISU_4D:
-		ret = fdt_setprop_string(fdt, 0, "compatible",
+		ret = fdt_setprop_string(dt, 0, "compatible",
 					 "renesas,ebisu");
 		break;
 	case BOARD_DRAAK:
-		ret = fdt_setprop_string(fdt, 0, "compatible",
+		ret = fdt_setprop_string(dt, 0, "compatible",
 					 "renesas,draak");
 		break;
 	default:
@@ -460,27 +463,27 @@
 	reg = mmio_read_32(RCAR_PRR);
 	switch (reg & PRR_PRODUCT_MASK) {
 	case PRR_PRODUCT_H3:
-		ret = fdt_appendprop_string(fdt, 0, "compatible",
+		ret = fdt_appendprop_string(dt, 0, "compatible",
 					    "renesas,r8a7795");
 		break;
 	case PRR_PRODUCT_M3:
-		ret = fdt_appendprop_string(fdt, 0, "compatible",
+		ret = fdt_appendprop_string(dt, 0, "compatible",
 					    "renesas,r8a7796");
 		break;
 	case PRR_PRODUCT_M3N:
-		ret = fdt_appendprop_string(fdt, 0, "compatible",
+		ret = fdt_appendprop_string(dt, 0, "compatible",
 					    "renesas,r8a77965");
 		break;
 	case PRR_PRODUCT_V3M:
-		ret = fdt_appendprop_string(fdt, 0, "compatible",
+		ret = fdt_appendprop_string(dt, 0, "compatible",
 					    "renesas,r8a77970");
 		break;
 	case PRR_PRODUCT_E3:
-		ret = fdt_appendprop_string(fdt, 0, "compatible",
+		ret = fdt_appendprop_string(dt, 0, "compatible",
 					    "renesas,r8a77990");
 		break;
 	case PRR_PRODUCT_D3:
-		ret = fdt_appendprop_string(fdt, 0, "compatible",
+		ret = fdt_appendprop_string(dt, 0, "compatible",
 					    "renesas,r8a77995");
 		break;
 	default:
diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk
index dc58e19..4c41dd3 100644
--- a/plat/renesas/rcar/platform.mk
+++ b/plat/renesas/rcar/platform.mk
@@ -348,12 +348,12 @@
 ERRATA_A57_859972  := 1
 ERRATA_A57_813419  := 1
 
-include drivers/staging/renesas/rcar/ddr/ddr.mk
+include drivers/renesas/rcar/ddr/ddr.mk
 include drivers/renesas/rcar/qos/qos.mk
 include drivers/renesas/rcar/pfc/pfc.mk
 include lib/libfdt/libfdt.mk
 
-PLAT_INCLUDES	:=	-Idrivers/staging/renesas/rcar/ddr	\
+PLAT_INCLUDES	:=	-Idrivers/renesas/rcar/ddr		\
 			-Idrivers/renesas/rcar/qos		\
 			-Idrivers/renesas/rcar/iic_dvfs		\
 			-Idrivers/renesas/rcar/board		\
diff --git a/plat/rockchip/common/params_setup.c b/plat/rockchip/common/params_setup.c
index 8c2e5e9..b2fd201 100644
--- a/plat/rockchip/common/params_setup.c
+++ b/plat/rockchip/common/params_setup.c
@@ -6,6 +6,7 @@
 
 #include <assert.h>
 #include <errno.h>
+#include <limits.h>
 #include <string.h>
 
 #include <lib/bl_aux_params/bl_aux_params.h>
@@ -21,8 +22,8 @@
 #include <plat_params.h>
 #include <plat_private.h>
 
-static struct bl_aux_gpio_info rst_gpio;
-static struct bl_aux_gpio_info poweroff_gpio;
+static struct bl_aux_gpio_info rst_gpio = { .index = UINT_MAX } ;
+static struct bl_aux_gpio_info poweroff_gpio = { .index = UINT_MAX };
 static struct bl_aux_gpio_info suspend_gpio[10];
 uint32_t suspend_gpio_cnt;
 static struct bl_aux_rk_apio_info suspend_apio;
@@ -174,11 +175,17 @@
 
 struct bl_aux_gpio_info *plat_get_rockchip_gpio_reset(void)
 {
+	if (rst_gpio.index == UINT_MAX)
+		return NULL;
+
 	return &rst_gpio;
 }
 
 struct bl_aux_gpio_info *plat_get_rockchip_gpio_poweroff(void)
 {
+	if (poweroff_gpio.index == UINT_MAX)
+		return NULL;
+
 	return &poweroff_gpio;
 }
 
diff --git a/plat/rockchip/px30/drivers/pmu/pmu.c b/plat/rockchip/px30/drivers/pmu/pmu.c
index 0a2515d..5f4e64f 100644
--- a/plat/rockchip/px30/drivers/pmu/pmu.c
+++ b/plat/rockchip/px30/drivers/pmu/pmu.c
@@ -22,6 +22,7 @@
 #include <plat_private.h>
 #include <pmu.h>
 #include <px30_def.h>
+#include <secure.h>
 #include <soc.h>
 
 DEFINE_BAKERY_LOCK(rockchip_pd_lock);
diff --git a/plat/rockchip/px30/drivers/secure/secure.c b/plat/rockchip/px30/drivers/secure/secure.c
new file mode 100644
index 0000000..144f945
--- /dev/null
+++ b/plat/rockchip/px30/drivers/secure/secure.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <ddr_parameter.h>
+#include <plat_private.h>
+#include <secure.h>
+#include <px30_def.h>
+
+/**
+ * There are 8 regions for DDR security control
+ * @rgn - the DDR regions 0 ~ 7 which are can be configured.
+ * @st - start address to set as secure
+ * @sz - length of area to set as secure
+ * The internal unit is megabytes, so memory areas need to be aligned
+ * to megabyte borders.
+ */
+static void secure_ddr_region(uint32_t rgn,
+			      uintptr_t st, size_t sz)
+{
+	uintptr_t ed = st + sz;
+	uintptr_t st_mb, ed_mb;
+	uint32_t val;
+
+	assert(rgn <= 7);
+	assert(st < ed);
+
+	/* check aligned 1MB */
+	assert(st % SIZE_M(1) == 0);
+	assert(ed % SIZE_M(1) == 0);
+
+	st_mb = st / SIZE_M(1);
+	ed_mb = ed / SIZE_M(1);
+
+	/* map top and base */
+	mmio_write_32(FIREWALL_DDR_BASE +
+		      FIREWALL_DDR_FW_DDR_RGN(rgn),
+		      RG_MAP_SECURE(ed_mb, st_mb));
+
+	/* enable secure */
+	val = mmio_read_32(FIREWALL_DDR_BASE + FIREWALL_DDR_FW_DDR_CON_REG);
+	val |= BIT(rgn);
+	mmio_write_32(FIREWALL_DDR_BASE +
+		      FIREWALL_DDR_FW_DDR_CON_REG, val);
+}
+
+void secure_timer_init(void)
+{
+	mmio_write_32(STIMER_CHN_BASE(1) + TIMER_CONTROL_REG,
+		      TIMER_DIS);
+
+	mmio_write_32(STIMER_CHN_BASE(1) + TIMER_LOAD_COUNT0, 0xffffffff);
+	mmio_write_32(STIMER_CHN_BASE(1) + TIMER_LOAD_COUNT1, 0xffffffff);
+
+	/* auto reload & enable the timer */
+	mmio_write_32(STIMER_CHN_BASE(1) + TIMER_CONTROL_REG,
+		      TIMER_EN | TIMER_FMODE);
+}
+
+void sgrf_init(void)
+{
+#ifdef PLAT_RK_SECURE_DDR_MINILOADER
+	uint32_t i;
+	struct param_ddr_usage usg;
+
+	/* general secure regions */
+	usg = ddr_region_usage_parse(DDR_PARAM_BASE,
+				     PLAT_MAX_DDR_CAPACITY_MB);
+
+	/* region-0 for TF-A, region-1 for optional OP-TEE */
+	assert(usg.s_nr < 7);
+
+	for (i = 0; i < usg.s_nr; i++)
+		secure_ddr_region(7 - i, usg.s_top[i], usg.s_base[i]);
+#endif
+
+	/* secure the trustzone ram */
+	secure_ddr_region(0, TZRAM_BASE, TZRAM_SIZE);
+
+	/* set all slave ip into no-secure, except stimer */
+	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(4), SGRF_SLV_S_ALL_NS);
+	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(5), SGRF_SLV_S_ALL_NS);
+	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(6), SGRF_SLV_S_ALL_NS);
+	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(7), SGRF_SLV_S_ALL_NS);
+	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(8), 0x00030000);
+
+	/* set master crypto to no-secure, dcf to secure */
+	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(3), 0x000f0003);
+
+	/* set DMAC into no-secure */
+	mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(0), DMA_IRQ_BOOT_NS);
+	mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(1), DMA_PERI_CH_NS_15_0);
+	mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(2), DMA_PERI_CH_NS_19_16);
+	mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(3), DMA_MANAGER_BOOT_NS);
+
+	/* soft reset dma before use */
+	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1), DMA_SOFTRST_REQ);
+	udelay(5);
+	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1), DMA_SOFTRST_RLS);
+}
diff --git a/plat/rockchip/px30/drivers/secure/secure.h b/plat/rockchip/px30/drivers/secure/secure.h
new file mode 100644
index 0000000..498027d
--- /dev/null
+++ b/plat/rockchip/px30/drivers/secure/secure.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SECURE_H
+#define SECURE_H
+
+/***************************************************************************
+ * SGRF
+ ***************************************************************************/
+#define SGRF_SOC_CON(i)		((i) * 0x4)
+#define SGRF_DMAC_CON(i)	(0x30 + (i) * 0x4)
+
+#define SGRF_MST_S_ALL_NS	0xffffffff
+#define SGRF_SLV_S_ALL_NS	0xffff0000
+#define DMA_IRQ_BOOT_NS		0xffffffff
+#define DMA_PERI_CH_NS_15_0	0xffffffff
+#define DMA_PERI_CH_NS_19_16	0x000f000f
+#define DMA_MANAGER_BOOT_NS	0x00010001
+#define DMA_SOFTRST_REQ		BITS_WITH_WMASK(1, 0x1, 12)
+#define DMA_SOFTRST_RLS		BITS_WITH_WMASK(0, 0x1, 12)
+
+/***************************************************************************
+ * DDR FIREWALL
+ ***************************************************************************/
+#define FIREWALL_DDR_FW_DDR_RGN(i)	((i) * 0x4)
+#define FIREWALL_DDR_FW_DDR_MST(i)	(0x20 + (i) * 0x4)
+#define FIREWALL_DDR_FW_DDR_CON_REG	0x40
+#define FIREWALL_DDR_FW_DDR_RGN_NUM	8
+#define FIREWALL_DDR_FW_DDR_MST_NUM	6
+
+#define PLAT_MAX_DDR_CAPACITY_MB	4096
+#define RG_MAP_SECURE(top, base)	((((top) - 1) << 16) | (base))
+
+/**************************************************
+ * secure timer
+ **************************************************/
+
+/* chanal0~5 */
+#define STIMER_CHN_BASE(n)	(STIME_BASE + 0x20 * (n))
+
+#define TIMER_LOAD_COUNT0	0x0
+#define TIMER_LOAD_COUNT1	0x4
+
+#define TIMER_CUR_VALUE0	0x8
+#define TIMER_CUR_VALUE1	0xc
+
+#define TIMER_CONTROL_REG	0x10
+#define TIMER_INTSTATUS		0x18
+
+#define TIMER_DIS		0x0
+#define TIMER_EN		0x1
+
+#define TIMER_FMODE		(0x0 << 1)
+#define TIMER_RMODE		(0x1 << 1)
+
+#define TIMER_LOAD_COUNT0_MSK	(0xffffffff)
+#define TIMER_LOAD_COUNT1_MSK	(0xffffffff00000000)
+
+void secure_timer_init(void);
+void sgrf_init(void);
+
+#endif /* SECURE_H */
diff --git a/plat/rockchip/px30/drivers/soc/soc.c b/plat/rockchip/px30/drivers/soc/soc.c
index e00561d..200563d 100644
--- a/plat/rockchip/px30/drivers/soc/soc.c
+++ b/plat/rockchip/px30/drivers/soc/soc.c
@@ -12,10 +12,10 @@
 #include <drivers/delay_timer.h>
 #include <lib/mmio.h>
 
-#include <ddr_parameter.h>
 #include <platform_def.h>
 #include <pmu.h>
 #include <px30_def.h>
+#include <secure.h>
 #include <soc.h>
 #include <rockchip_sip_svc.h>
 
@@ -83,65 +83,6 @@
 			      0xffff0000);
 }
 
-void secure_timer_init(void)
-{
-	mmio_write_32(STIMER_CHN_BASE(1) + TIMER_CONTROL_REG,
-		      TIMER_DIS);
-
-	mmio_write_32(STIMER_CHN_BASE(1) + TIMER_LOAD_COUNT0, 0xffffffff);
-	mmio_write_32(STIMER_CHN_BASE(1) + TIMER_LOAD_COUNT1, 0xffffffff);
-
-	/* auto reload & enable the timer */
-	mmio_write_32(STIMER_CHN_BASE(1) + TIMER_CONTROL_REG,
-		      TIMER_EN | TIMER_FMODE);
-}
-
-static void sgrf_init(void)
-{
-	uint32_t i, val;
-	struct param_ddr_usage usg;
-
-	/* general secure regions */
-	usg = ddr_region_usage_parse(DDR_PARAM_BASE,
-				     PLAT_MAX_DDR_CAPACITY_MB);
-	for (i = 0; i < usg.s_nr; i++) {
-		/* enable secure */
-		val = mmio_read_32(FIREWALL_DDR_BASE +
-			      FIREWALL_DDR_FW_DDR_CON_REG);
-		val |= BIT(7 - i);
-		mmio_write_32(FIREWALL_DDR_BASE +
-			      FIREWALL_DDR_FW_DDR_CON_REG, val);
-		/* map top and base */
-		mmio_write_32(FIREWALL_DDR_BASE +
-			      FIREWALL_DDR_FW_DDR_RGN(7 - i),
-			      RG_MAP_SECURE(usg.s_top[i], usg.s_base[i]));
-	}
-
-	/* set ddr rgn0_top and rga0_top as 0 */
-	mmio_write_32(FIREWALL_DDR_BASE + FIREWALL_DDR_FW_DDR_RGN(0), 0x0);
-
-	/* set all slave ip into no-secure, except stimer */
-	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(4), SGRF_SLV_S_ALL_NS);
-	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(5), SGRF_SLV_S_ALL_NS);
-	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(6), SGRF_SLV_S_ALL_NS);
-	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(7), SGRF_SLV_S_ALL_NS);
-	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(8), 0x00030000);
-
-	/* set master crypto to no-secure, dcf to secure */
-	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(3), 0x000f0003);
-
-	/* set DMAC into no-secure */
-	mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(0), DMA_IRQ_BOOT_NS);
-	mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(1), DMA_PERI_CH_NS_15_0);
-	mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(2), DMA_PERI_CH_NS_19_16);
-	mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(3), DMA_MANAGER_BOOT_NS);
-
-	/* soft reset dma before use */
-	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1), DMA_SOFTRST_REQ);
-	udelay(5);
-	mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1), DMA_SOFTRST_RLS);
-}
-
 static void soc_reset_config_all(void)
 {
 	uint32_t tmp;
diff --git a/plat/rockchip/px30/drivers/soc/soc.h b/plat/rockchip/px30/drivers/soc/soc.h
index 69f2de4..648d18b 100644
--- a/plat/rockchip/px30/drivers/soc/soc.h
+++ b/plat/rockchip/px30/drivers/soc/soc.h
@@ -29,21 +29,6 @@
 };
 
 /***************************************************************************
- * SGRF
- ***************************************************************************/
-#define SGRF_SOC_CON(i)		((i) * 0x4)
-#define SGRF_DMAC_CON(i)	(0x30 + (i) * 0x4)
-
-#define SGRF_MST_S_ALL_NS	0xffffffff
-#define SGRF_SLV_S_ALL_NS	0xffff0000
-#define DMA_IRQ_BOOT_NS		0xffffffff
-#define DMA_PERI_CH_NS_15_0	0xffffffff
-#define DMA_PERI_CH_NS_19_16	0x000f000f
-#define DMA_MANAGER_BOOT_NS	0x00010001
-#define DMA_SOFTRST_REQ		BITS_WITH_WMASK(1, 0x1, 12)
-#define DMA_SOFTRST_RLS		BITS_WITH_WMASK(0, 0x1, 12)
-
-/***************************************************************************
  * GRF
  ***************************************************************************/
 #define GRF_SOC_CON(i)		(0x0400 + (i) * 4)
@@ -61,18 +46,6 @@
 #define GRF_SOC_CON2_NSWDT_RST_EN 12
 
 /***************************************************************************
- * DDR FIREWALL
- ***************************************************************************/
-#define FIREWALL_DDR_FW_DDR_RGN(i)	((i) * 0x4)
-#define FIREWALL_DDR_FW_DDR_MST(i)	(0x20 + (i) * 0x4)
-#define FIREWALL_DDR_FW_DDR_CON_REG	0x40
-#define FIREWALL_DDR_FW_DDR_RGN_NUM	8
-#define FIREWALL_DDR_FW_DDR_MST_NUM	6
-
-#define PLAT_MAX_DDR_CAPACITY_MB	4096
-#define RG_MAP_SECURE(top, base)	((((top) - 1) << 16) | (base))
-
-/***************************************************************************
  * cru
  ***************************************************************************/
 #define CRU_MODE		0xa0
@@ -136,37 +109,10 @@
 #define GPIO_INT_STATUS		0x40
 #define GPIO_NUMS		4
 
-/**************************************************
- * secure timer
- **************************************************/
-
-/* chanal0~5 */
-#define STIMER_CHN_BASE(n)	(STIME_BASE + 0x20 * (n))
-
-#define TIMER_LOAD_COUNT0	0x0
-#define TIMER_LOAD_COUNT1	0x4
-
-#define TIMER_CUR_VALUE0	0x8
-#define TIMER_CUR_VALUE1	0xc
-
-#define TIMER_CONTROL_REG	0x10
-#define TIMER_INTSTATUS		0x18
-
-#define TIMER_DIS		0x0
-#define TIMER_EN		0x1
-
-#define TIMER_FMODE		(0x0 << 1)
-#define TIMER_RMODE		(0x1 << 1)
-
-#define TIMER_LOAD_COUNT0_MSK	(0xffffffff)
-#define TIMER_LOAD_COUNT1_MSK	(0xffffffff00000000)
-
 void clk_gate_con_save(uint32_t *clkgt_save);
 void clk_gate_con_restore(uint32_t *clkgt_save);
 void clk_gate_con_disable(void);
 
-void secure_timer_init(void);
-void secure_timer_disable(void);
 void px30_soc_reset_config(void);
 
 #endif /* __SOC_H__ */
diff --git a/plat/rockchip/px30/include/platform_def.h b/plat/rockchip/px30/include/platform_def.h
index 9dccab8..2f4f672 100644
--- a/plat/rockchip/px30/include/platform_def.h
+++ b/plat/rockchip/px30/include/platform_def.h
@@ -69,9 +69,9 @@
 /*******************************************************************************
  * Platform memory map related constants
  ******************************************************************************/
-/* TF text, ro, rw, Size: 512KB */
+/* TF text, ro, rw, Size: 1MB */
 #define TZRAM_BASE		(0x0)
-#define TZRAM_SIZE		(0x80000)
+#define TZRAM_SIZE		(0x100000)
 
 /*******************************************************************************
  * BL31 specific defines.
diff --git a/plat/rockchip/px30/platform.mk b/plat/rockchip/px30/platform.mk
index ee85cd3..87cf187 100644
--- a/plat/rockchip/px30/platform.mk
+++ b/plat/rockchip/px30/platform.mk
@@ -20,6 +20,7 @@
 				-I${RK_PLAT_COMMON}/pmusram			\
 				-I${RK_PLAT_SOC}/				\
 				-I${RK_PLAT_SOC}/drivers/pmu/			\
+				-I${RK_PLAT_SOC}/drivers/secure/		\
 				-I${RK_PLAT_SOC}/drivers/soc/			\
 				-I${RK_PLAT_SOC}/include/
 
@@ -45,16 +46,20 @@
 				${RK_PLAT_COMMON}/aarch64/plat_helpers.S	\
 				${RK_PLAT_COMMON}/aarch64/platform_common.c	\
 				${RK_PLAT_COMMON}/bl31_plat_setup.c		\
-				${RK_PLAT_COMMON}/drivers/parameter/ddr_parameter.c	\
 				${RK_PLAT_COMMON}/params_setup.c		\
 				${RK_PLAT_COMMON}/pmusram/cpus_on_fixed_addr.S	\
 				${RK_PLAT_COMMON}/plat_pm.c			\
 				${RK_PLAT_COMMON}/plat_topology.c		\
 				${RK_PLAT_COMMON}/rockchip_sip_svc.c		\
 				${RK_PLAT_SOC}/drivers/pmu/pmu.c		\
+				${RK_PLAT_SOC}/drivers/secure/secure.c		\
 				${RK_PLAT_SOC}/drivers/soc/soc.c		\
 				${RK_PLAT_SOC}/plat_sip_calls.c
 
+ifdef PLAT_RK_SECURE_DDR_MINILOADER
+BL31_SOURCES		+=	${RK_PLAT_COMMON}/drivers/parameter/ddr_parameter.c
+endif
+
 ENABLE_PLAT_COMPAT	:=	0
 MULTI_CONSOLE_API	:=	1
 
diff --git a/plat/rockchip/px30/px30_def.h b/plat/rockchip/px30/px30_def.h
index 9b8ccfc..efe789e 100644
--- a/plat/rockchip/px30/px30_def.h
+++ b/plat/rockchip/px30/px30_def.h
@@ -11,6 +11,7 @@
 #define MINOR_VERSION		(0)
 
 #define SIZE_K(n)		((n) * 1024)
+#define SIZE_M(n)		((n) * 1024 * 1024)
 
 #define WITH_16BITS_WMSK(bits)	(0xffff0000 | (bits))
 
@@ -54,6 +55,9 @@
 #define UART2_BASE		0xff160000
 #define UART2_SIZE		SIZE_K(64)
 
+#define UART3_BASE		0xff168000
+#define UART3_SIZE		SIZE_K(64)
+
 #define UART5_BASE		0xff178000
 #define UART5_SIZE		SIZE_K(64)
 
diff --git a/plat/rockchip/rk3288/drivers/secure/secure.c b/plat/rockchip/rk3288/drivers/secure/secure.c
index 68994e4..25e1cca 100644
--- a/plat/rockchip/rk3288/drivers/secure/secure.c
+++ b/plat/rockchip/rk3288/drivers/secure/secure.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -38,15 +38,18 @@
  * SGRF_SOC_CON21 - end address of the RGN_7 + RGN_X control
  *
  * @rgn - the DDR regions 0 ~ 7 which are can be configured.
- * The @st and @ed indicate the start and end addresses for which to set
- * the security, and the unit is byte. When the st_mb == 0, ed_mb == 0, the
+ * @st - start address to set as secure
+ * @sz - length of area to set as secure
+ * The @st_mb and @ed_mb indicate the start and end addresses for which to set
+ * the security, and the unit is megabyte. When the st_mb == 0, ed_mb == 0, the
  * address range 0x0 ~ 0xfffff is secure.
  *
  * For example, if we would like to set the range [0, 32MB) is security via
  * DDR_RGN0, then rgn == 0, st_mb == 0, ed_mb == 31.
  */
-static void sgrf_ddr_rgn_config(uint32_t rgn, uintptr_t st, uintptr_t ed)
+static void sgrf_ddr_rgn_config(uint32_t rgn, uintptr_t st, size_t sz)
 {
+	uintptr_t ed = st + sz;
 	uintptr_t st_mb, ed_mb;
 
 	assert(rgn <= 7);
diff --git a/plat/rockchip/rk3328/drivers/soc/soc.c b/plat/rockchip/rk3328/drivers/soc/soc.c
index 59d8572..306308f 100644
--- a/plat/rockchip/rk3328/drivers/soc/soc.c
+++ b/plat/rockchip/rk3328/drivers/soc/soc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -97,6 +97,7 @@
 
 void sgrf_init(void)
 {
+#ifdef PLAT_RK_SECURE_DDR_MINILOADER
 	uint32_t i, val;
 	struct param_ddr_usage usg;
 
@@ -115,6 +116,7 @@
 			      FIREWALL_DDR_FW_DDR_RGN(7 - i),
 			      RG_MAP_SECURE(usg.s_top[i], usg.s_base[i]));
 	}
+#endif
 
 	/* set ddr rgn0_top and rga0_top as 0 */
 	mmio_write_32(FIREWALL_DDR_BASE + FIREWALL_DDR_FW_DDR_RGN(0), 0x0);
diff --git a/plat/rockchip/rk3328/drivers/soc/soc.h b/plat/rockchip/rk3328/drivers/soc/soc.h
index a1f35b2..e8cbc09 100644
--- a/plat/rockchip/rk3328/drivers/soc/soc.h
+++ b/plat/rockchip/rk3328/drivers/soc/soc.h
@@ -16,8 +16,6 @@
 #define TIMER_INTSTATUS		0x18
 #define TIMER_EN		0x1
 
-extern const unsigned char rockchip_power_domain_tree_desc[];
-
 /**************************** read/write **************************************/
 #ifndef BITS_WMSK
 #define BITS_WMSK(msk, shift)	((msk) << (shift + REG_MSK_SHIFT))
diff --git a/plat/rockchip/rk3328/include/platform_def.h b/plat/rockchip/rk3328/include/platform_def.h
index baac12d..e9eb3fa 100644
--- a/plat/rockchip/rk3328/include/platform_def.h
+++ b/plat/rockchip/rk3328/include/platform_def.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
  */
@@ -66,9 +66,9 @@
 /*******************************************************************************
  * Platform memory map related constants
  ******************************************************************************/
-/* TF text, ro, rw, Size: 512KB */
+/* TF text, ro, rw, Size: 1MB */
 #define TZRAM_BASE		(0x0)
-#define TZRAM_SIZE		(0x80000)
+#define TZRAM_SIZE		(0x100000)
 
 /*******************************************************************************
  * BL31 specific defines.
diff --git a/plat/rockchip/rk3328/platform.mk b/plat/rockchip/rk3328/platform.mk
index 0da4f2d..0219422 100644
--- a/plat/rockchip/rk3328/platform.mk
+++ b/plat/rockchip/rk3328/platform.mk
@@ -42,7 +42,6 @@
 				drivers/delay_timer/generic_delay_timer.c	\
 				lib/cpus/aarch64/aem_generic.S			\
 				lib/cpus/aarch64/cortex_a53.S			\
-				${RK_PLAT_COMMON}/drivers/parameter/ddr_parameter.c	\
 				${RK_PLAT_COMMON}/aarch64/plat_helpers.S	\
 				${RK_PLAT_COMMON}/params_setup.c		\
 				${RK_PLAT_COMMON}/bl31_plat_setup.c		\
@@ -53,9 +52,16 @@
 				${RK_PLAT_SOC}/drivers/pmu/pmu.c		\
 				${RK_PLAT_SOC}/drivers/soc/soc.c
 
+ifdef PLAT_RK_SECURE_DDR_MINILOADER
+BL31_SOURCES		+=	${RK_PLAT_COMMON}/drivers/parameter/ddr_parameter.c
+endif
+
 include lib/coreboot/coreboot.mk
 include lib/libfdt/libfdt.mk
 
+# Enable workarounds for selected Cortex-A53 errata
+ERRATA_A53_855873	:=	1
+
 $(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
 $(eval $(call add_define,PLAT_SKIP_OPTEE_S_EL1_INT_REGISTER))
 
diff --git a/plat/rockchip/rk3368/include/platform_def.h b/plat/rockchip/rk3368/include/platform_def.h
index 9334a83..2abd56b 100644
--- a/plat/rockchip/rk3368/include/platform_def.h
+++ b/plat/rockchip/rk3368/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -67,9 +67,9 @@
 /*******************************************************************************
  * Platform memory map related constants
  ******************************************************************************/
-/* TF text, ro, rw, Size: 512KB */
+/* TF text, ro, rw, Size: 1MB */
 #define TZRAM_BASE		(0x0)
-#define TZRAM_SIZE		(0x80000)
+#define TZRAM_SIZE		(0x100000)
 
 /*******************************************************************************
  * BL31 specific defines.
diff --git a/plat/rockchip/rk3399/drivers/dp/cdn_dp.c b/plat/rockchip/rk3399/drivers/dp/cdn_dp.c
index aa71fde..a8773f4 100644
--- a/plat/rockchip/rk3399/drivers/dp/cdn_dp.c
+++ b/plat/rockchip/rk3399/drivers/dp/cdn_dp.c
@@ -18,7 +18,7 @@
 	".global hdcp_handler\n"
 	".balign 4\n"
 	"hdcp_handler:\n"
-	".incbin \"" __XSTRING(HDCPFW) "\"\n"
+	".incbin \"" HDCPFW "\"\n"
 	".type hdcp_handler, %function\n"
 	".size hdcp_handler, .- hdcp_handler\n"
 	".popsection\n"
diff --git a/plat/rockchip/rk3399/drivers/dram/dfs.c b/plat/rockchip/rk3399/drivers/dram/dfs.c
index 3b627d2..816372b 100644
--- a/plat/rockchip/rk3399/drivers/dram/dfs.c
+++ b/plat/rockchip/rk3399/drivers/dram/dfs.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -78,10 +78,10 @@
 	.zqcsi = 0
 };
 
-static uint32_t get_cs_die_capability(struct rk3399_sdram_params *sdram_config,
+static uint32_t get_cs_die_capability(struct rk3399_sdram_params *ram_config,
 		uint8_t channel, uint8_t cs)
 {
-	struct rk3399_sdram_channel *ch = &sdram_config->ch[channel];
+	struct rk3399_sdram_channel *ch = &ram_config->ch[channel];
 	uint32_t bandwidth;
 	uint32_t die_bandwidth;
 	uint32_t die;
diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu.c b/plat/rockchip/rk3399/drivers/pmu/pmu.c
index 30941fd..faee678 100644
--- a/plat/rockchip/rk3399/drivers/pmu/pmu.c
+++ b/plat/rockchip/rk3399/drivers/pmu/pmu.c
@@ -400,6 +400,25 @@
 	clk_gate_con_restore();
 }
 
+void pmu_power_domains_on(void)
+{
+	clk_gate_con_disable();
+	pmu_set_power_domain(PD_VDU, pmu_pd_on);
+	pmu_set_power_domain(PD_VCODEC, pmu_pd_on);
+	pmu_set_power_domain(PD_RGA, pmu_pd_on);
+	pmu_set_power_domain(PD_IEP, pmu_pd_on);
+	pmu_set_power_domain(PD_EDP, pmu_pd_on);
+	pmu_set_power_domain(PD_GMAC, pmu_pd_on);
+	pmu_set_power_domain(PD_SDIOAUDIO, pmu_pd_on);
+	pmu_set_power_domain(PD_HDCP, pmu_pd_on);
+	pmu_set_power_domain(PD_ISP1, pmu_pd_on);
+	pmu_set_power_domain(PD_ISP0, pmu_pd_on);
+	pmu_set_power_domain(PD_VO, pmu_pd_on);
+	pmu_set_power_domain(PD_TCPD1, pmu_pd_on);
+	pmu_set_power_domain(PD_TCPD0, pmu_pd_on);
+	pmu_set_power_domain(PD_GPU, pmu_pd_on);
+}
+
 void rk3399_flush_l2_b(void)
 {
 	uint32_t wait_cnt = 0;
diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu.h b/plat/rockchip/rk3399/drivers/pmu/pmu.h
index 74db82f..bb7de50 100644
--- a/plat/rockchip/rk3399/drivers/pmu/pmu.h
+++ b/plat/rockchip/rk3399/drivers/pmu/pmu.h
@@ -136,5 +136,6 @@
 extern uint32_t clst_warmboot_data[PLATFORM_CLUSTER_COUNT];
 
 extern void sram_func_set_ddrctl_pll(uint32_t pll_src);
+void pmu_power_domains_on(void);
 
 #endif /* PMU_H */
diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c b/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c
index a09ad21..25596b1 100644
--- a/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c
+++ b/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c
@@ -5,20 +5,18 @@
  */
 
 /* convoluted way to make sure that the define is pasted just the right way */
-#define _INCBIN(file, sym, sec) \
+#define INCBIN(file, sym, sec) \
 	__asm__( \
-		".section " #sec "\n" \
-		".global " #sym "\n" \
-		".type " #sym ", %object\n" \
+		".section " sec "\n" \
+		".global " sym "\n" \
+		".type " sym ", %object\n" \
 		".align 4\n" \
-		#sym ":\n" \
-		".incbin \"" #file "\"\n" \
-		".size " #sym ", .-" #sym "\n" \
-		".global " #sym "_end\n" \
-		#sym "_end:\n" \
+		sym ":\n" \
+		".incbin \"" file "\"\n" \
+		".size " sym ", .-" sym "\n" \
+		".global " sym "_end\n" \
+		sym "_end:\n" \
 	)
 
-#define INCBIN(file, sym, sec) _INCBIN(file, sym, sec)
-
-INCBIN(RK3399M0FW, rk3399m0_bin, ".sram.incbin");
-INCBIN(RK3399M0PMUFW, rk3399m0pmu_bin, ".pmusram.incbin");
+INCBIN(RK3399M0FW, "rk3399m0_bin", ".sram.incbin");
+INCBIN(RK3399M0PMUFW, "rk3399m0pmu_bin", ".pmusram.incbin");
diff --git a/plat/rockchip/rk3399/drivers/secure/secure.c b/plat/rockchip/rk3399/drivers/secure/secure.c
index 8286f17..13c83ca 100644
--- a/plat/rockchip/rk3399/drivers/secure/secure.c
+++ b/plat/rockchip/rk3399/drivers/secure/secure.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -45,6 +45,8 @@
  *                bypass, 1: enable bypass
  *
  * @rgn - the DDR regions 0 ~ 7 which are can be configured.
+ * @st - start address to set as secure
+ * @sz - length of area to set as secure
  * The @st_mb and @ed_mb indicate the start and end addresses for which to set
  * the security, and the unit is megabyte. When the st_mb == 0, ed_mb == 0, the
  * address range 0x0 ~ 0xfffff is secure.
@@ -53,8 +55,9 @@
  * DDR_RGN0, then rgn == 0, st_mb == 0, ed_mb == 31.
  */
 static void sgrf_ddr_rgn_config(uint32_t rgn,
-				uintptr_t st, uintptr_t ed)
+				uintptr_t st, size_t sz)
 {
+	uintptr_t ed = st + sz;
 	uintptr_t st_mb, ed_mb;
 
 	assert(rgn <= 7);
diff --git a/plat/rockchip/rk3399/drivers/soc/soc.c b/plat/rockchip/rk3399/drivers/soc/soc.c
index c877dbd..98b5ad6 100644
--- a/plat/rockchip/rk3399/drivers/soc/soc.c
+++ b/plat/rockchip/rk3399/drivers/soc/soc.c
@@ -17,6 +17,7 @@
 #include <dram.h>
 #include <m0_ctl.h>
 #include <plat_private.h>
+#include <pmu.h>
 #include <rk3399_def.h>
 #include <secure.h>
 #include <soc.h>
@@ -327,6 +328,7 @@
 
 void __dead2 soc_global_soft_reset(void)
 {
+	pmu_power_domains_on();
 	set_pll_slow_mode(VPLL_ID);
 	set_pll_slow_mode(NPLL_ID);
 	set_pll_slow_mode(GPLL_ID);
diff --git a/plat/rockchip/rk3399/plat_sip_calls.c b/plat/rockchip/rk3399/plat_sip_calls.c
index c2cc5b1..ce8476c 100644
--- a/plat/rockchip/rk3399/plat_sip_calls.c
+++ b/plat/rockchip/rk3399/plat_sip_calls.c
@@ -56,17 +56,21 @@
 				    void *handle,
 				    u_register_t flags)
 {
+#ifdef PLAT_RK_DP_HDCP
 	uint64_t x5, x6;
+#endif
 
 	switch (smc_fid) {
 	case RK_SIP_DDR_CFG:
 		SMC_RET1(handle, ddr_smc_handler(x1, x2, x3, x4));
+#ifdef PLAT_RK_DP_HDCP
 	case RK_SIP_HDCP_CONTROL:
 		SMC_RET1(handle, dp_hdcp_ctrl(x1));
 	case RK_SIP_HDCP_KEY_DATA64:
 		x5 = read_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X5);
 		x6 = read_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X6);
 		SMC_RET1(handle, dp_hdcp_store_key(x1, x2, x3, x4, x5, x6));
+#endif
 	default:
 		ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
 		SMC_RET1(handle, SMC_UNK);
diff --git a/plat/rockchip/rk3399/platform.mk b/plat/rockchip/rk3399/platform.mk
index cfc48e8..5a23d3c 100644
--- a/plat/rockchip/rk3399/platform.mk
+++ b/plat/rockchip/rk3399/platform.mk
@@ -56,7 +56,6 @@
 			${RK_PLAT_COMMON}/aarch64/platform_common.c	\
 			${RK_PLAT_COMMON}/rockchip_sip_svc.c		\
 			${RK_PLAT_SOC}/plat_sip_calls.c			\
-			${RK_PLAT_SOC}/drivers/dp/cdn_dp.c		\
 			${RK_PLAT_SOC}/drivers/gpio/rk3399_gpio.c	\
 			${RK_PLAT_SOC}/drivers/pmu/pmu.c		\
 			${RK_PLAT_SOC}/drivers/pmu/pmu_fw.c		\
@@ -82,22 +81,26 @@
 BUILD_M0		:=	${BUILD_PLAT}/m0
 
 RK3399M0FW=${BUILD_M0}/${PLAT_M0}.bin
-$(eval $(call add_define,RK3399M0FW))
+$(eval $(call add_define_val,RK3399M0FW,\"$(RK3399M0FW)\"))
 
 RK3399M0PMUFW=${BUILD_M0}/${PLAT_M0}pmu.bin
-$(eval $(call add_define,RK3399M0PMUFW))
+$(eval $(call add_define_val,RK3399M0PMUFW,\"$(RK3399M0PMUFW)\"))
+
+ifdef PLAT_RK_DP_HDCP
+BL31_SOURCES	+= ${RK_PLAT_SOC}/drivers/dp/cdn_dp.c
 
 HDCPFW=${RK_PLAT_SOC}/drivers/dp/hdcp.bin
-$(eval $(call add_define,HDCPFW))
+$(eval $(call add_define_val,HDCPFW,\"$(HDCPFW)\"))
+
+${BUILD_PLAT}/bl31/cdn_dp.o: CCACHE_EXTRAFILES=$(HDCPFW)
+${RK_PLAT_SOC}/drivers/dp/cdn_dp.c: $(HDCPFW)
+endif
 
 # CCACHE_EXTRAFILES is needed because ccache doesn't handle .incbin
 export CCACHE_EXTRAFILES
 ${BUILD_PLAT}/bl31/pmu_fw.o: CCACHE_EXTRAFILES=$(RK3399M0FW):$(RK3399M0PMUFW)
 ${RK_PLAT_SOC}/drivers/pmu/pmu_fw.c: $(RK3399M0FW)
 
-${BUILD_PLAT}/bl31/cdn_dp.o: CCACHE_EXTRAFILES=$(HDCPFW)
-${RK_PLAT_SOC}/drivers/dp/cdn_dp.c: $(HDCPFW)
-
 $(eval $(call MAKE_PREREQ_DIR,${BUILD_M0},${BUILD_PLAT}))
 .PHONY: $(RK3399M0FW)
 $(RK3399M0FW): | ${BUILD_M0}
diff --git a/plat/rpi/common/rpi3_pm.c b/plat/rpi/common/rpi3_pm.c
index 8c2d070..2a6bf07 100644
--- a/plat/rpi/common/rpi3_pm.c
+++ b/plat/rpi/common/rpi3_pm.c
@@ -123,6 +123,15 @@
 #endif
 }
 
+void __dead2 plat_secondary_cold_boot_setup(void);
+
+static void __dead2
+rpi3_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state)
+{
+	disable_mmu_el3();
+	plat_secondary_cold_boot_setup();
+}
+
 /*******************************************************************************
  * Platform handler called when a power domain is about to be turned on. The
  * mpidr determines the CPU to be turned on.
@@ -224,6 +233,7 @@
 static const plat_psci_ops_t plat_rpi3_psci_pm_ops = {
 	.cpu_standby = rpi3_cpu_standby,
 	.pwr_domain_off = rpi3_pwr_domain_off,
+	.pwr_domain_pwr_down_wfi = rpi3_pwr_domain_pwr_down_wfi,
 	.pwr_domain_on = rpi3_pwr_domain_on,
 	.pwr_domain_on_finish = rpi3_pwr_domain_on_finish,
 	.system_off = rpi3_system_off,
diff --git a/plat/rpi/rpi4/aarch64/plat_helpers.S b/plat/rpi/rpi4/aarch64/plat_helpers.S
index 46073b7..083c30e 100644
--- a/plat/rpi/rpi4/aarch64/plat_helpers.S
+++ b/plat/rpi/rpi4/aarch64/plat_helpers.S
@@ -136,8 +136,8 @@
 	 */
 func plat_crash_console_init
 	mov_imm	x0, PLAT_RPI3_UART_BASE
-	mov_imm	x1, PLAT_RPI4_VPU_CLK_RATE
-	mov_imm	x2, PLAT_RPI3_UART_BAUDRATE
+	mov	x1, xzr
+	mov	x2, xzr
 	b	console_16550_core_init
 endfunc plat_crash_console_init
 
diff --git a/plat/rpi/rpi4/include/rpi_hw.h b/plat/rpi/rpi4/include/rpi_hw.h
index ed367ee..b1dd4e9 100644
--- a/plat/rpi/rpi4/include/rpi_hw.h
+++ b/plat/rpi/rpi4/include/rpi_hw.h
@@ -59,13 +59,6 @@
 #define RPI3_PM_RSTS_WRCFG_HALT		U(0x00000555)
 
 /*
- * Clock controller
- */
-#define RPI4_IO_CLOCK_OFFSET		ULL(0x00101000)
-#define RPI4_CLOCK_BASE			(RPI_IO_BASE + RPI4_IO_CLOCK_OFFSET)
-#define RPI4_VPU_CLOCK_DIVIDER		ULL(0x0000000c)
-
-/*
  * Hardware random number generator.
  */
 #define RPI3_IO_RNG_OFFSET		ULL(0x00104000)
@@ -88,7 +81,6 @@
  */
 #define RPI3_IO_MINI_UART_OFFSET	ULL(0x00215040)
 #define RPI3_MINI_UART_BASE		(RPI_IO_BASE + RPI3_IO_MINI_UART_OFFSET)
-#define PLAT_RPI4_VPU_CLK_RATE		ULL(1000000000)
 
 /*
  * GPIO controller
diff --git a/plat/rpi/rpi4/rpi4_bl31_setup.c b/plat/rpi/rpi4/rpi4_bl31_setup.c
index 53ab0c2..9e3b539 100644
--- a/plat/rpi/rpi4/rpi4_bl31_setup.c
+++ b/plat/rpi/rpi4/rpi4_bl31_setup.c
@@ -119,8 +119,6 @@
 				u_register_t arg2, u_register_t arg3)
 
 {
-	uint32_t div_reg;
-
 	/*
 	 * LOCAL_CONTROL:
 	 * Bit 9 clear: Increment by 1 (vs. 2).
@@ -136,16 +134,12 @@
 
 	/*
 	 * Initialize the console to provide early debug support.
-	 * Different GPU firmware revisions set up the VPU divider differently,
-	 * so read the actual divider register to learn the UART base clock
-	 * rate. The divider is encoded as a 12.12 fixed point number, but we
-	 * just care about the integer part of it.
+	 * We rely on the GPU firmware to have initialised the UART correctly,
+	 * as the baud base clock rate differs across GPU firmware revisions.
+	 * Providing a base clock of 0 lets the 16550 UART init routine skip
+	 * the initial enablement and baud rate setup.
 	 */
-	div_reg = mmio_read_32(RPI4_CLOCK_BASE + RPI4_VPU_CLOCK_DIVIDER);
-	div_reg = (div_reg >> 12) & 0xfff;
-	if (div_reg == 0)
-		div_reg = 1;
-	rpi3_console_init(PLAT_RPI4_VPU_CLK_RATE / div_reg);
+	rpi3_console_init(0);
 
 	bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
 	bl33_image_ep_info.spsr = rpi3_get_spsr_for_bl33_entry();
diff --git a/plat/socionext/synquacer/platform.mk b/plat/socionext/synquacer/platform.mk
index fe1448f..ab1f69e 100644
--- a/plat/socionext/synquacer/platform.mk
+++ b/plat/socionext/synquacer/platform.mk
@@ -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
 #
@@ -57,7 +57,7 @@
 				drivers/arm/css/mhu/css_mhu_doorbell.c
 endif
 
-ifeq (${ENABLE_SPM},1)
+ifeq (${SPM_MM},1)
 $(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
 
 BL31_SOURCES		+=	$(PLAT_PATH)/sq_spm.c
diff --git a/plat/socionext/synquacer/sq_bl31_setup.c b/plat/socionext/synquacer/sq_bl31_setup.c
index c78fe91..b864021 100644
--- a/plat/socionext/synquacer/sq_bl31_setup.c
+++ b/plat/socionext/synquacer/sq_bl31_setup.c
@@ -159,7 +159,7 @@
 void bl31_plat_arch_setup(void)
 {
 	static const mmap_region_t secure_partition_mmap[] = {
-#if ENABLE_SPM && SPM_MM
+#if SPM_MM
 		MAP_REGION_FLAT(PLAT_SPM_BUF_BASE,
 				PLAT_SPM_BUF_SIZE,
 				MT_RW_DATA | MT_SECURE),
@@ -173,7 +173,7 @@
 	sq_mmap_setup(BL31_BASE, BL31_SIZE, secure_partition_mmap);
 	enable_mmu_el3(XLAT_TABLE_NC);
 
-#if ENABLE_SPM && SPM_MM
+#if SPM_MM
 	memcpy((void *)SPM_SHIM_EXCEPTIONS_START,
 	       (void *)SPM_SHIM_EXCEPTIONS_LMA,
 	       (uintptr_t)SPM_SHIM_EXCEPTIONS_END -
diff --git a/plat/socionext/synquacer/sq_spm.c b/plat/socionext/synquacer/sq_spm.c
index 01cce17..7bea111 100644
--- a/plat/socionext/synquacer/sq_spm.c
+++ b/plat/socionext/synquacer/sq_spm.c
@@ -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
  */
@@ -10,7 +10,7 @@
 
 #include <bl31/ehf.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
-#include <services/secure_partition.h>
+#include <services/spm_mm_partition.h>
 
 static const mmap_region_t plat_arm_secure_partition_mmap[] = {
 	PLAT_SQ_FLASH_MMAP,
@@ -27,7 +27,7 @@
  * Boot information passed to a secure partition during initialisation. Linear
  * indices in MP information will be filled at runtime.
  */
-static secure_partition_mp_info_t sp_mp_info[] = {
+static spm_mm_mp_info_t sp_mp_info[] = {
 	{0x80000000, 0}, {0x80000001, 0}, {0x80000100, 0}, {0x80000101, 0},
 	{0x80000200, 0}, {0x80000201, 0}, {0x80000300, 0}, {0x80000301, 0},
 	{0x80000400, 0}, {0x80000401, 0}, {0x80000500, 0}, {0x80000501, 0},
@@ -36,10 +36,10 @@
 	{0x80000a00, 0}, {0x80000a01, 0}, {0x80000b00, 0}, {0x80000b01, 0},
 };
 
-const secure_partition_boot_info_t plat_arm_secure_partition_boot_info = {
+const spm_mm_boot_info_t plat_arm_secure_partition_boot_info = {
 	.h.type			= PARAM_SP_IMAGE_BOOT_INFO,
 	.h.version		= VERSION_1,
-	.h.size			= sizeof(secure_partition_boot_info_t),
+	.h.size			= sizeof(spm_mm_boot_info_t),
 	.h.attr			= 0,
 	.sp_mem_base		= BL32_BASE,
 	.sp_mem_limit		= BL32_LIMIT,
@@ -63,7 +63,7 @@
 	return plat_arm_secure_partition_mmap;
 }
 
-const struct secure_partition_boot_info *plat_get_secure_partition_boot_info(
+const struct spm_mm_boot_info *plat_get_secure_partition_boot_info(
 		void *cookie)
 {
 	return &plat_arm_secure_partition_boot_info;
diff --git a/plat/socionext/uniphier/platform.mk b/plat/socionext/uniphier/platform.mk
index d974584..d31fbe8 100644
--- a/plat/socionext/uniphier/platform.mk
+++ b/plat/socionext/uniphier/platform.mk
@@ -60,6 +60,7 @@
 				plat/common/plat_gicv3.c		\
 				plat/common/plat_psci_common.c		\
 				$(PLAT_PATH)/uniphier_bl31_setup.c	\
+				$(PLAT_PATH)/uniphier_boot_device.c	\
 				$(PLAT_PATH)/uniphier_cci.c		\
 				$(PLAT_PATH)/uniphier_gicv3.c		\
 				$(PLAT_PATH)/uniphier_psci.c		\
diff --git a/plat/socionext/uniphier/uniphier_image_desc.c b/plat/socionext/uniphier/uniphier_image_desc.c
index 9e171e0..817029a 100644
--- a/plat/socionext/uniphier/uniphier_image_desc.c
+++ b/plat/socionext/uniphier/uniphier_image_desc.c
@@ -80,7 +80,7 @@
 				      VERSION_2, entry_point_info_t,
 				      NON_SECURE | EXECUTABLE),
 		.ep_info.pc = UNIPHIER_BL33_BASE,
-		.ep_info.spsr = SPSR_64(MODE_EL1, MODE_SP_ELX,
+		.ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
 					DISABLE_ALL_EXCEPTIONS),
 
 		.next_handoff_image_id = INVALID_IMAGE_ID,
diff --git a/plat/socionext/uniphier/uniphier_psci.c b/plat/socionext/uniphier/uniphier_psci.c
index 464252d..2acc874 100644
--- a/plat/socionext/uniphier/uniphier_psci.c
+++ b/plat/socionext/uniphier/uniphier_psci.c
@@ -6,6 +6,7 @@
 
 #include <arch_helpers.h>
 #include <common/debug.h>
+#include <errno.h>
 #include <lib/mmio.h>
 #include <lib/psci/psci.h>
 
@@ -113,17 +114,27 @@
 int plat_setup_psci_ops(uintptr_t sec_entrypoint,
 			const struct plat_psci_ops **psci_ops)
 {
+	unsigned int soc;
+
+	soc = uniphier_get_soc_id();
+	if (soc == UNIPHIER_SOC_UNKNOWN) {
+		ERROR("unsupported SoC\n");
+		return -ENOTSUP;
+	}
+
+	if (uniphier_get_boot_master(soc) == UNIPHIER_BOOT_MASTER_SCP) {
+		uniphier_psci_scp_mode = uniphier_scp_is_running();
+		flush_dcache_range((uint64_t)&uniphier_psci_scp_mode,
+				   sizeof(uniphier_psci_scp_mode));
+
+		if (uniphier_psci_scp_mode)
+			uniphier_scp_open_com();
+	}
+
 	uniphier_sec_entrypoint = sec_entrypoint;
 	flush_dcache_range((uint64_t)&uniphier_sec_entrypoint,
 			   sizeof(uniphier_sec_entrypoint));
 
-	uniphier_psci_scp_mode = uniphier_scp_is_running();
-	flush_dcache_range((uint64_t)&uniphier_psci_scp_mode,
-			   sizeof(uniphier_psci_scp_mode));
-
-	if (uniphier_psci_scp_mode)
-		uniphier_scp_open_com();
-
 	*psci_ops = &uniphier_psci_ops;
 
 	return 0;
diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c
index 38b2a0b..3ec7d40 100644
--- a/plat/st/common/bl2_io_storage.c
+++ b/plat/st/common/bl2_io_storage.c
@@ -14,11 +14,17 @@
 #include <drivers/io/io_block.h>
 #include <drivers/io/io_driver.h>
 #include <drivers/io/io_dummy.h>
+#include <drivers/io/io_mtd.h>
 #include <drivers/io/io_storage.h>
 #include <drivers/mmc.h>
 #include <drivers/partition/partition.h>
+#include <drivers/raw_nand.h>
+#include <drivers/spi_nand.h>
+#include <drivers/spi_nor.h>
 #include <drivers/st/io_mmc.h>
 #include <drivers/st/io_stm32image.h>
+#include <drivers/st/stm32_fmc2_nand.h>
+#include <drivers/st/stm32_qspi.h>
 #include <drivers/st/stm32_sdmmc2.h>
 #include <lib/mmio.h>
 #include <lib/utils.h>
@@ -30,7 +36,9 @@
 static uintptr_t dummy_dev_spec;
 
 static uintptr_t image_dev_handle;
+static uintptr_t storage_dev_handle;
 
+#if STM32MP_SDMMC || STM32MP_EMMC
 static io_block_spec_t gpt_block_spec = {
 	.offset = 0,
 	.length = 34 * MMC_BLOCK_SIZE, /* Size of GPT table */
@@ -51,8 +59,41 @@
 	.block_size = MMC_BLOCK_SIZE,
 };
 
-static uintptr_t storage_dev_handle;
 static const io_dev_connector_t *mmc_dev_con;
+#endif /* STM32MP_SDMMC || STM32MP_EMMC */
+
+#if STM32MP_SPI_NOR
+static io_mtd_dev_spec_t spi_nor_dev_spec = {
+	.ops = {
+		.init = spi_nor_init,
+		.read = spi_nor_read,
+	},
+};
+#endif
+
+#if STM32MP_RAW_NAND
+static io_mtd_dev_spec_t nand_dev_spec = {
+	.ops = {
+		.init = nand_raw_init,
+		.read = nand_read,
+	},
+};
+
+static const io_dev_connector_t *nand_dev_con;
+#endif
+
+#if STM32MP_SPI_NAND
+static io_mtd_dev_spec_t spi_nand_dev_spec = {
+	.ops = {
+		.init = spi_nand_init,
+		.read = nand_read,
+	},
+};
+#endif
+
+#if STM32MP_SPI_NAND || STM32MP_SPI_NOR
+static const io_dev_connector_t *spi_dev_con;
+#endif
 
 #ifdef AARCH32_SP_OPTEE
 static const struct stm32image_part_info optee_header_partition_spec = {
@@ -96,7 +137,7 @@
 	IMG_IDX_NUM
 };
 
-static struct stm32image_device_info stm32image_dev_info_spec = {
+static struct stm32image_device_info stm32image_dev_info_spec __unused = {
 	.lba_size = MMC_BLOCK_SIZE,
 	.part_info[IMG_IDX_BL33] = {
 		.name = BL33_IMAGE_NAME,
@@ -123,7 +164,7 @@
 	.length = 0,
 };
 
-static const io_dev_connector_t *stm32image_dev_con;
+static const io_dev_connector_t *stm32image_dev_con __unused;
 
 static int open_dummy(const uintptr_t spec);
 static int open_image(const uintptr_t spec);
@@ -169,11 +210,13 @@
 		.image_spec = (uintptr_t)&bl33_partition_spec,
 		.check = open_image
 	},
+#if STM32MP_SDMMC || STM32MP_EMMC
 	[GPT_IMAGE_ID] = {
 		.dev_handle = &storage_dev_handle,
 		.image_spec = (uintptr_t)&gpt_block_spec,
 		.check = open_storage
 	},
+#endif
 	[STM32_IMAGE_ID] = {
 		.dev_handle = &storage_dev_handle,
 		.image_spec = (uintptr_t)&stm32image_block_spec,
@@ -205,6 +248,15 @@
 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
 		INFO("Using EMMC\n");
 		break;
+	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
+		INFO("Using QSPI NOR\n");
+		break;
+	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
+		INFO("Using FMC NAND\n");
+		break;
+	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI:
+		INFO("Using SPI NAND\n");
+		break;
 	default:
 		ERROR("Boot interface not found\n");
 		panic();
@@ -216,6 +268,7 @@
 	}
 }
 
+#if STM32MP_SDMMC || STM32MP_EMMC
 static void boot_mmc(enum mmc_device_type mmc_dev_type,
 		     uint16_t boot_interface_instance)
 {
@@ -296,6 +349,166 @@
 
 	io_result = io_dev_open(mmc_dev_con, 0, &storage_dev_handle);
 	assert(io_result == 0);
+
+	io_result = register_io_dev_stm32image(&stm32image_dev_con);
+	assert(io_result == 0);
+
+	io_result = io_dev_open(stm32image_dev_con,
+				(uintptr_t)&stm32image_dev_info_spec,
+				&image_dev_handle);
+	assert(io_result == 0);
+}
+#endif /* STM32MP_SDMMC || STM32MP_EMMC */
+
+#if STM32MP_SPI_NOR
+static void boot_spi_nor(boot_api_context_t *boot_context)
+{
+	int io_result __unused;
+	uint8_t idx;
+	struct stm32image_part_info *part;
+
+	io_result = stm32_qspi_init();
+	assert(io_result == 0);
+
+	io_result = register_io_dev_mtd(&spi_dev_con);
+	assert(io_result == 0);
+
+	/* Open connections to device */
+	io_result = io_dev_open(spi_dev_con,
+				(uintptr_t)&spi_nor_dev_spec,
+				&storage_dev_handle);
+	assert(io_result == 0);
+
+	stm32image_dev_info_spec.device_size = spi_nor_dev_spec.device_size;
+
+	idx = IMG_IDX_BL33;
+	part = &stm32image_dev_info_spec.part_info[idx];
+	part->part_offset = STM32MP_NOR_BL33_OFFSET;
+	part->bkp_offset = 0U;
+
+#ifdef AARCH32_SP_OPTEE
+	idx = IMG_IDX_OPTEE_HEADER;
+	part = &stm32image_dev_info_spec.part_info[idx];
+	part->part_offset = STM32MP_NOR_TEEH_OFFSET;
+	part->bkp_offset = 0U;
+
+	idx = IMG_IDX_OPTEE_PAGED;
+	part = &stm32image_dev_info_spec.part_info[idx];
+	part->part_offset = STM32MP_NOR_TEED_OFFSET;
+	part->bkp_offset = 0U;
+
+	idx = IMG_IDX_OPTEE_PAGER;
+	part = &stm32image_dev_info_spec.part_info[idx];
+	part->part_offset = STM32MP_NOR_TEEX_OFFSET;
+	part->bkp_offset = 0U;
+#endif
+
+	io_result = register_io_dev_stm32image(&stm32image_dev_con);
+	assert(io_result == 0);
+
+	io_result = io_dev_open(stm32image_dev_con,
+				(uintptr_t)&stm32image_dev_info_spec,
+				&image_dev_handle);
+	assert(io_result == 0);
+}
+#endif /* STM32MP_SPI_NOR */
+
+#if STM32MP_RAW_NAND
+static void boot_fmc2_nand(boot_api_context_t *boot_context)
+{
+	int io_result __unused;
+	uint8_t idx;
+	struct stm32image_part_info *part;
+
+	io_result = stm32_fmc2_init();
+	assert(io_result == 0);
+
+	/* Register the IO device on this platform */
+	io_result = register_io_dev_mtd(&nand_dev_con);
+	assert(io_result == 0);
+
+	/* Open connections to device */
+	io_result = io_dev_open(nand_dev_con, (uintptr_t)&nand_dev_spec,
+				&storage_dev_handle);
+	assert(io_result == 0);
+
+	stm32image_dev_info_spec.device_size = nand_dev_spec.device_size;
+
+	idx = IMG_IDX_BL33;
+	part = &stm32image_dev_info_spec.part_info[idx];
+	part->part_offset = STM32MP_NAND_BL33_OFFSET;
+	part->bkp_offset = nand_dev_spec.erase_size;
+
+#ifdef AARCH32_SP_OPTEE
+	idx = IMG_IDX_OPTEE_HEADER;
+	part = &stm32image_dev_info_spec.part_info[idx];
+	part->part_offset = STM32MP_NAND_TEEH_OFFSET;
+	part->bkp_offset = nand_dev_spec.erase_size;
+
+	idx = IMG_IDX_OPTEE_PAGED;
+	part = &stm32image_dev_info_spec.part_info[idx];
+	part->part_offset = STM32MP_NAND_TEED_OFFSET;
+	part->bkp_offset = nand_dev_spec.erase_size;
+
+	idx = IMG_IDX_OPTEE_PAGER;
+	part = &stm32image_dev_info_spec.part_info[idx];
+	part->part_offset = STM32MP_NAND_TEEX_OFFSET;
+	part->bkp_offset = nand_dev_spec.erase_size;
+#endif
+
+	io_result = register_io_dev_stm32image(&stm32image_dev_con);
+	assert(io_result == 0);
+
+	io_result = io_dev_open(stm32image_dev_con,
+				(uintptr_t)&stm32image_dev_info_spec,
+				&image_dev_handle);
+	assert(io_result == 0);
+}
+#endif /* STM32MP_RAW_NAND */
+
+#if STM32MP_SPI_NAND
+static void boot_spi_nand(boot_api_context_t *boot_context)
+{
+	int io_result __unused;
+	uint8_t idx;
+	struct stm32image_part_info *part;
+
+	io_result = stm32_qspi_init();
+	assert(io_result == 0);
+
+	io_result = register_io_dev_mtd(&spi_dev_con);
+	assert(io_result == 0);
+
+	/* Open connections to device */
+	io_result = io_dev_open(spi_dev_con,
+				(uintptr_t)&spi_nand_dev_spec,
+				&storage_dev_handle);
+	assert(io_result == 0);
+
+	stm32image_dev_info_spec.device_size =
+		spi_nand_dev_spec.device_size;
+
+	idx = IMG_IDX_BL33;
+	part = &stm32image_dev_info_spec.part_info[idx];
+	part->part_offset = STM32MP_NAND_BL33_OFFSET;
+	part->bkp_offset = spi_nand_dev_spec.erase_size;
+
+#ifdef AARCH32_SP_OPTEE
+	idx = IMG_IDX_OPTEE_HEADER;
+	part = &stm32image_dev_info_spec.part_info[idx];
+	part->part_offset = STM32MP_NAND_TEEH_OFFSET;
+	part->bkp_offset = spi_nand_dev_spec.erase_size;
+
+	idx = IMG_IDX_OPTEE_PAGED;
+	part = &stm32image_dev_info_spec.part_info[idx];
+	part->part_offset = STM32MP_NAND_TEED_OFFSET;
+	part->bkp_offset = spi_nand_dev_spec.erase_size;
+
+	idx = IMG_IDX_OPTEE_PAGER;
+	part = &stm32image_dev_info_spec.part_info[idx];
+	part->part_offset = STM32MP_NAND_TEEX_OFFSET;
+	part->bkp_offset = spi_nand_dev_spec.erase_size;
+#endif
 
 	io_result = register_io_dev_stm32image(&stm32image_dev_con);
 	assert(io_result == 0);
@@ -305,6 +518,7 @@
 				&image_dev_handle);
 	assert(io_result == 0);
 }
+#endif /* STM32MP_SPI_NAND */
 
 void stm32mp_io_setup(void)
 {
@@ -328,14 +542,36 @@
 	assert(io_result == 0);
 
 	switch (boot_context->boot_interface_selected) {
+#if STM32MP_SDMMC
 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
 		dmbsy();
 		boot_mmc(MMC_IS_SD, boot_context->boot_interface_instance);
 		break;
+#endif
+#if STM32MP_EMMC
 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
 		dmbsy();
 		boot_mmc(MMC_IS_EMMC, boot_context->boot_interface_instance);
 		break;
+#endif
+#if STM32MP_SPI_NOR
+	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
+		dmbsy();
+		boot_spi_nor(boot_context);
+		break;
+#endif
+#if STM32MP_RAW_NAND
+	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
+		dmbsy();
+		boot_fmc2_nand(boot_context);
+		break;
+#endif
+#if STM32MP_SPI_NAND
+	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI:
+		dmbsy();
+		boot_spi_nand(boot_context);
+		break;
+#endif
 
 	default:
 		ERROR("Boot interface %d not supported\n",
diff --git a/plat/st/common/include/stm32mp_dt.h b/plat/st/common/include/stm32mp_dt.h
index 74b01b3..a29d914 100644
--- a/plat/st/common/include/stm32mp_dt.h
+++ b/plat/st/common/include/stm32mp_dt.h
@@ -32,6 +32,8 @@
 				 uint32_t dflt_value);
 int fdt_read_uint32_array(int node, const char *prop_name,
 			  uint32_t *array, uint32_t count);
+int fdt_get_reg_props_by_name(int node, const char *name, uintptr_t *base,
+			      size_t *size);
 int dt_set_stdout_pinctrl(void);
 void dt_fill_device_info(struct dt_node_info *info, int node);
 int dt_get_node(struct dt_node_info *info, int offset, const char *compat);
diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c
index 17da490..4fa796f 100644
--- a/plat/st/common/stm32mp_dt.c
+++ b/plat/st/common/stm32mp_dt.c
@@ -93,6 +93,46 @@
 }
 
 /*******************************************************************************
+ * This function returns the address cells from the node parent.
+ * Returns:
+ * - #address-cells value if success.
+ * - invalid value if error.
+ * - a default value if undefined #address-cells property as per libfdt
+ *   implementation.
+ ******************************************************************************/
+int fdt_get_node_parent_address_cells(int node)
+{
+	int parent;
+
+	parent = fdt_parent_offset(fdt, node);
+	if (parent < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	return fdt_address_cells(fdt, parent);
+}
+
+/*******************************************************************************
+ * This function returns the size cells from the node parent.
+ * Returns:
+ * - #size-cells value if success.
+ * - invalid value if error.
+ * - a default value if undefined #size-cells property as per libfdt
+ *   implementation.
+ ******************************************************************************/
+int fdt_get_node_parent_size_cells(int node)
+{
+	int parent;
+
+	parent = fdt_parent_offset(fdt, node);
+	if (parent < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	return fdt_size_cells(fdt, parent);
+}
+
+/*******************************************************************************
  * This function reads a value of a node property (generic use of fdt
  * library).
  * Returns value if success, and a default value if property not found.
@@ -146,6 +186,46 @@
 }
 
 /*******************************************************************************
+ * This function fills reg node info (base & size) with an index found by
+ * checking the reg-names node.
+ * Returns 0 on success and a negative FDT error code on failure.
+ ******************************************************************************/
+int fdt_get_reg_props_by_name(int node, const char *name, uintptr_t *base,
+			      size_t *size)
+{
+	const fdt32_t *cuint;
+	int index, len;
+
+	assert((fdt_get_node_parent_address_cells(node) == 1) &&
+	       (fdt_get_node_parent_size_cells(node) == 1));
+
+	index = fdt_stringlist_search(fdt, node, "reg-names", name);
+	if (index < 0) {
+		return index;
+	}
+
+	cuint = fdt_getprop(fdt, node, "reg", &len);
+	if (cuint == NULL) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	if ((index * (int)sizeof(uint32_t)) > len) {
+		return -FDT_ERR_BADVALUE;
+	}
+
+	cuint += index << 1;
+	if (base != NULL) {
+		*base = fdt32_to_cpu(*cuint);
+	}
+	cuint++;
+	if (size != NULL) {
+		*size = fdt32_to_cpu(*cuint);
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
  * This function gets the stdout path node.
  * It reads the value indicated inside the device tree.
  * Returns node offset on success and a negative FDT error code on failure.
@@ -215,6 +295,8 @@
 {
 	const fdt32_t *cuint;
 
+	assert(fdt_get_node_parent_address_cells(node) == 1);
+
 	cuint = fdt_getprop(fdt, node, "reg", NULL);
 	if (cuint != NULL) {
 		info->base = fdt32_to_cpu(*cuint);
@@ -309,6 +391,9 @@
 		return 0;
 	}
 
+	assert((fdt_get_node_parent_address_cells(node) == 1) &&
+	       (fdt_get_node_parent_size_cells(node) == 1));
+
 	if (fdt_read_uint32_array(node, "reg", array, 4) < 0) {
 		return 0;
 	}
@@ -331,6 +416,9 @@
 		return 0;
 	}
 
+	assert((fdt_get_node_parent_address_cells(node) == 1) &&
+	       (fdt_get_node_parent_size_cells(node) == 1));
+
 	if (fdt_read_uint32_array(node, "reg", array, 4) < 0) {
 		return 0;
 	}
@@ -353,6 +441,8 @@
 		return 0;
 	}
 
+	assert(fdt_get_node_parent_address_cells(node) == 1);
+
 	cuint = fdt_getprop(fdt, node, "reg", NULL);
 	if (cuint == NULL) {
 		return 0;
@@ -415,6 +505,8 @@
 		return 0;
 	}
 
+	assert(fdt_get_node_parent_address_cells(node) == 1);
+
 	cuint = fdt_getprop(fdt, node, "reg", NULL);
 	if (cuint == NULL) {
 		return 0;
diff --git a/plat/st/stm32mp1/include/boot_api.h b/plat/st/stm32mp1/include/boot_api.h
index 2284970..c16639a 100644
--- a/plat/st/stm32mp1/include/boot_api.h
+++ b/plat/st/stm32mp1/include/boot_api.h
@@ -33,6 +33,15 @@
 /* Boot occurred on EMMC */
 #define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC		0x2U
 
+/* Boot occurred on FMC */
+#define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC		0x3U
+
+/* Boot occurred on QSPI NOR */
+#define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI		0x4U
+
+/* Boot occurred on QSPI NAND */
+#define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI		0x7U
+
 /**
  * @brief  Possible value of boot context field 'EmmcXferStatus'
  */
@@ -124,7 +133,7 @@
 /* Closed = OTP_CFG0[6] */
 #define BOOT_API_OTP_MODE_CLOSED_BIT_POS			6
 
-#define BOOT_API_RETURN_OK					0x66U
+#define BOOT_API_RETURN_OK					0x77U
 
 /*
  * Boot Context related definitions
diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h
index 263e6d6..450a9d4 100644
--- a/plat/st/stm32mp1/include/platform_def.h
+++ b/plat/st/stm32mp1/include/platform_def.h
@@ -51,6 +51,7 @@
 #define MAX_IO_DEVICES			U(4)
 #define MAX_IO_HANDLES			U(4)
 #define MAX_IO_BLOCK_DEVICES		U(1)
+#define MAX_IO_MTD_DEVICES		U(1)
 
 /*******************************************************************************
  * BL2 specific defines.
diff --git a/plat/st/stm32mp1/include/stm32mp1_boot_device.h b/plat/st/stm32mp1/include/stm32mp1_boot_device.h
new file mode 100644
index 0000000..a745983
--- /dev/null
+++ b/plat/st/stm32mp1/include/stm32mp1_boot_device.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP1_BOOT_DEVICE_H
+#define STM32MP1_BOOT_DEVICE_H
+
+#include <drivers/raw_nand.h>
+#include <drivers/spi_nand.h>
+#include <drivers/spi_nor.h>
+
+int plat_get_raw_nand_data(struct rawnand_device *device);
+int plat_get_spi_nand_data(struct spinand_device *device);
+int plat_get_nor_data(struct nor_device *device);
+
+#endif /* STM32MP1_BOOT_DEVICE_H */
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index 90b3e3c..b86287b 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -24,6 +24,29 @@
 endif
 $(eval $(call add_define,PLAT_PARTITION_MAX_ENTRIES))
 
+# Boot devices
+STM32MP_EMMC		?=	0
+STM32MP_SDMMC		?=	0
+STM32MP_RAW_NAND	?=	0
+STM32MP_SPI_NAND	?=	0
+STM32MP_SPI_NOR		?=	0
+
+ifeq ($(filter 1,${STM32MP_EMMC} ${STM32MP_SDMMC} ${STM32MP_RAW_NAND} \
+	${STM32MP_SPI_NAND} ${STM32MP_SPI_NOR}),)
+$(error "No boot device driver is enabled")
+endif
+
+$(eval $(call assert_boolean,STM32MP_EMMC))
+$(eval $(call assert_boolean,STM32MP_SDMMC))
+$(eval $(call assert_boolean,STM32MP_RAW_NAND))
+$(eval $(call assert_boolean,STM32MP_SPI_NAND))
+$(eval $(call assert_boolean,STM32MP_SPI_NOR))
+$(eval $(call add_define,STM32MP_EMMC))
+$(eval $(call add_define,STM32MP_SDMMC))
+$(eval $(call add_define,STM32MP_RAW_NAND))
+$(eval $(call add_define,STM32MP_SPI_NAND))
+$(eval $(call add_define,STM32MP_SPI_NOR))
+
 PLAT_INCLUDES		:=	-Iplat/st/common/include/
 PLAT_INCLUDES		+=	-Iplat/st/stm32mp1/include/
 
@@ -70,6 +93,7 @@
 
 BL2_SOURCES		+=	drivers/io/io_block.c					\
 				drivers/io/io_dummy.c					\
+				drivers/io/io_mtd.c					\
 				drivers/io/io_storage.c					\
 				drivers/st/crypto/stm32_hash.c				\
 				drivers/st/io/io_stm32image.c				\
@@ -77,11 +101,40 @@
 				plat/st/common/bl2_io_storage.c				\
 				plat/st/stm32mp1/bl2_plat_setup.c
 
+ifneq ($(filter 1,${STM32MP_EMMC} ${STM32MP_SDMMC}),)
 BL2_SOURCES		+=	drivers/mmc/mmc.c					\
 				drivers/partition/gpt.c					\
 				drivers/partition/partition.c				\
 				drivers/st/io/io_mmc.c					\
 				drivers/st/mmc/stm32_sdmmc2.c
+endif
+
+ifeq (${STM32MP_RAW_NAND},1)
+$(eval $(call add_define_val,NAND_ONFI_DETECT,1))
+BL2_SOURCES		+=	drivers/mtd/nand/raw_nand.c				\
+				drivers/st/fmc/stm32_fmc2_nand.c
+endif
+
+ifeq (${STM32MP_SPI_NAND},1)
+BL2_SOURCES		+=	drivers/mtd/nand/spi_nand.c
+endif
+
+ifeq (${STM32MP_SPI_NOR},1)
+BL2_SOURCES		+=	drivers/mtd/nor/spi_nor.c
+endif
+
+ifneq ($(filter 1,${STM32MP_SPI_NAND} ${STM32MP_SPI_NOR}),)
+BL2_SOURCES		+=	drivers/mtd/spi-mem/spi_mem.c				\
+				drivers/st/spi/stm32_qspi.c
+endif
+
+ifneq ($(filter 1,${STM32MP_RAW_NAND} ${STM32MP_SPI_NAND}),)
+BL2_SOURCES		+=	drivers/mtd/nand/core.c
+endif
+
+ifneq ($(filter 1,${STM32MP_RAW_NAND} ${STM32MP_SPI_NAND} ${STM32MP_SPI_NOR}),)
+BL2_SOURCES		+=	plat/st/stm32mp1/stm32mp1_boot_device.c
+endif
 
 BL2_SOURCES		+=	drivers/st/ddr/stm32mp1_ddr.c				\
 				drivers/st/ddr/stm32mp1_ram.c
diff --git a/plat/st/stm32mp1/stm32mp1_boot_device.c b/plat/st/stm32mp1/stm32mp1_boot_device.c
new file mode 100644
index 0000000..2d8eccf
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_boot_device.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <drivers/nand.h>
+#include <lib/utils.h>
+#include <plat/common/platform.h>
+
+#define SZ_512		0x200U
+#define SZ_64M		0x4000000U
+
+#if STM32MP_RAW_NAND || STM32MP_SPI_NAND
+static int get_data_from_otp(struct nand_device *nand_dev, bool is_slc)
+{
+	int result;
+	uint32_t nand_param;
+
+	/* Check if NAND parameters are stored in OTP */
+	result = bsec_shadow_read_otp(&nand_param, NAND_OTP);
+	if (result != BSEC_OK) {
+		ERROR("BSEC: NAND_OTP Error %i\n", result);
+		return -EACCES;
+	}
+
+	if (nand_param == 0U) {
+		return 0;
+	}
+
+	if ((nand_param & NAND_PARAM_STORED_IN_OTP) == 0U) {
+		goto ecc;
+	}
+
+	/* NAND parameter shall be read from OTP */
+	if ((nand_param & NAND_WIDTH_MASK) != 0U) {
+		nand_dev->buswidth = NAND_BUS_WIDTH_16;
+	} else {
+		nand_dev->buswidth = NAND_BUS_WIDTH_8;
+	}
+
+	switch ((nand_param & NAND_PAGE_SIZE_MASK) >> NAND_PAGE_SIZE_SHIFT) {
+	case NAND_PAGE_SIZE_2K:
+		nand_dev->page_size = 0x800U;
+		break;
+
+	case NAND_PAGE_SIZE_4K:
+		nand_dev->page_size = 0x1000U;
+		break;
+
+	case NAND_PAGE_SIZE_8K:
+		nand_dev->page_size = 0x2000U;
+		break;
+
+	default:
+		ERROR("Cannot read NAND page size\n");
+		return -EINVAL;
+	}
+
+	switch ((nand_param & NAND_BLOCK_SIZE_MASK) >> NAND_BLOCK_SIZE_SHIFT) {
+	case NAND_BLOCK_SIZE_64_PAGES:
+		nand_dev->block_size = 64U * nand_dev->page_size;
+		break;
+
+	case NAND_BLOCK_SIZE_128_PAGES:
+		nand_dev->block_size = 128U * nand_dev->page_size;
+		break;
+
+	case NAND_BLOCK_SIZE_256_PAGES:
+		nand_dev->block_size = 256U * nand_dev->page_size;
+		break;
+
+	default:
+		ERROR("Cannot read NAND block size\n");
+		return -EINVAL;
+	}
+
+	nand_dev->size = ((nand_param & NAND_BLOCK_NB_MASK) >>
+			  NAND_BLOCK_NB_SHIFT) *
+		NAND_BLOCK_NB_UNIT * nand_dev->block_size;
+
+ecc:
+	if (is_slc) {
+		switch ((nand_param & NAND_ECC_BIT_NB_MASK) >>
+			NAND_ECC_BIT_NB_SHIFT) {
+		case NAND_ECC_BIT_NB_1_BITS:
+			nand_dev->ecc.max_bit_corr = 1U;
+			break;
+
+		case NAND_ECC_BIT_NB_4_BITS:
+			nand_dev->ecc.max_bit_corr = 4U;
+			break;
+
+		case NAND_ECC_BIT_NB_8_BITS:
+			nand_dev->ecc.max_bit_corr = 8U;
+			break;
+
+		case NAND_ECC_ON_DIE:
+			nand_dev->ecc.mode = NAND_ECC_ONDIE;
+			break;
+
+		default:
+			if (nand_dev->ecc.max_bit_corr == 0U) {
+				ERROR("No valid eccbit number\n");
+				return -EINVAL;
+			}
+		}
+	} else {
+		/* Selected multiple plane NAND */
+		if ((nand_param & NAND_PLANE_BIT_NB_MASK) != 0U) {
+			nand_dev->nb_planes = 2U;
+		} else {
+			nand_dev->nb_planes = 1U;
+		}
+	}
+
+	VERBOSE("OTP: Block %i Page %i Size %lli\n", nand_dev->block_size,
+	     nand_dev->page_size, nand_dev->size);
+
+	return 0;
+}
+#endif /* STM32MP_RAW_NAND || STM32MP_SPI_NAND */
+
+#if STM32MP_RAW_NAND
+int plat_get_raw_nand_data(struct rawnand_device *device)
+{
+	device->nand_dev->ecc.mode = NAND_ECC_HW;
+	device->nand_dev->ecc.size = SZ_512;
+
+	return get_data_from_otp(device->nand_dev, true);
+}
+#endif
+
+#if STM32MP_SPI_NAND
+int plat_get_spi_nand_data(struct spinand_device *device)
+{
+	zeromem(&device->spi_read_cache_op, sizeof(struct spi_mem_op));
+	device->spi_read_cache_op.cmd.opcode = SPI_NAND_OP_READ_FROM_CACHE_4X;
+	device->spi_read_cache_op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+	device->spi_read_cache_op.addr.nbytes = 2U;
+	device->spi_read_cache_op.addr.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+	device->spi_read_cache_op.dummy.nbytes = 1U;
+	device->spi_read_cache_op.dummy.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+	device->spi_read_cache_op.data.buswidth = SPI_MEM_BUSWIDTH_4_LINE;
+	device->spi_read_cache_op.data.dir = SPI_MEM_DATA_IN;
+
+	return get_data_from_otp(device->nand_dev, false);
+}
+#endif
+
+#if STM32MP_SPI_NOR
+int plat_get_nor_data(struct nor_device *device)
+{
+	device->size = SZ_64M;
+
+	zeromem(&device->read_op, sizeof(struct spi_mem_op));
+	device->read_op.cmd.opcode = SPI_NOR_OP_READ_1_1_4;
+	device->read_op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+	device->read_op.addr.nbytes = 3U;
+	device->read_op.addr.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+	device->read_op.dummy.nbytes = 1U;
+	device->read_op.dummy.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+	device->read_op.data.buswidth = SPI_MEM_BUSWIDTH_4_LINE;
+	device->read_op.data.dir = SPI_MEM_DATA_IN;
+
+	return 0;
+}
+#endif
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index a40852b..11b01ab 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -23,6 +23,7 @@
 #include <stm32mp_common.h>
 #include <stm32mp_dt.h>
 #include <stm32mp_shres_helpers.h>
+#include <stm32mp1_boot_device.h>
 #include <stm32mp1_dbgmcu.h>
 #include <stm32mp1_private.h>
 #endif
@@ -74,7 +75,7 @@
 #endif
 
 /* Section used inside TF binaries */
-#define STM32MP_PARAM_LOAD_SIZE		U(0x00002400)	/* 9 Ko for param */
+#define STM32MP_PARAM_LOAD_SIZE		U(0x00002400)	/* 9 KB for param */
 /* 256 Octets reserved for header */
 #define STM32MP_HEADER_SIZE		U(0x00000100)
 
@@ -95,9 +96,9 @@
 					 STM32MP_OPTEE_BASE)
 #else
 #if STACK_PROTECTOR_ENABLED
-#define STM32MP_BL32_SIZE		U(0x00012000)	/* 72 Ko for BL32 */
+#define STM32MP_BL32_SIZE		U(0x00012000)	/* 72 KB for BL32 */
 #else
-#define STM32MP_BL32_SIZE		U(0x00011000)	/* 68 Ko for BL32 */
+#define STM32MP_BL32_SIZE		U(0x00011000)	/* 68 KB for BL32 */
 #endif
 #endif
 
@@ -107,23 +108,23 @@
 
 #ifdef AARCH32_SP_OPTEE
 #if STACK_PROTECTOR_ENABLED
-#define STM32MP_BL2_SIZE		U(0x00019000)	/* 100 Ko for BL2 */
+#define STM32MP_BL2_SIZE		U(0x0001A000)	/* 100 KB for BL2 */
 #else
-#define STM32MP_BL2_SIZE		U(0x00017000)	/* 92 Ko for BL2 */
+#define STM32MP_BL2_SIZE		U(0x00018000)	/* 92 KB for BL2 */
 #endif
 #else
 #if STACK_PROTECTOR_ENABLED
-#define STM32MP_BL2_SIZE		U(0x00018000)	/* 96 Ko for BL2 */
+#define STM32MP_BL2_SIZE		U(0x00019000)	/* 96 KB for BL2 */
 #else
-#define STM32MP_BL2_SIZE		U(0x00016000)	/* 88 Ko for BL2 */
+#define STM32MP_BL2_SIZE		U(0x00017000)	/* 88 KB for BL2 */
 #endif
 #endif
 
 #define STM32MP_BL2_BASE		(STM32MP_BL32_BASE - \
 					 STM32MP_BL2_SIZE)
 
-/* BL2 and BL32/sp_min require 5 tables */
-#define MAX_XLAT_TABLES			5
+/* BL2 and BL32/sp_min require 4 tables */
+#define MAX_XLAT_TABLES			U(4)		/* 16 KB for mapping */
 
 /*
  * MAX_MMAP_REGIONS is usually:
@@ -137,13 +138,33 @@
 #endif
 
 /* DTB initialization value */
-#define STM32MP_DTB_SIZE		U(0x00005000)	/* 20Ko for DTB */
+#define STM32MP_DTB_SIZE		U(0x00005000)	/* 20 KB for DTB */
 
 #define STM32MP_DTB_BASE		(STM32MP_BL2_BASE - \
 					 STM32MP_DTB_SIZE)
 
 #define STM32MP_BL33_BASE		(STM32MP_DDR_BASE + U(0x100000))
 
+/* Define maximum page size for NAND devices */
+#define PLATFORM_MTD_MAX_PAGE_SIZE	U(0x1000)
+
+/*******************************************************************************
+ * STM32MP1 RAW partition offset for MTD devices
+ ******************************************************************************/
+#define STM32MP_NOR_BL33_OFFSET		U(0x00080000)
+#ifdef AARCH32_SP_OPTEE
+#define STM32MP_NOR_TEEH_OFFSET		U(0x00280000)
+#define STM32MP_NOR_TEED_OFFSET		U(0x002C0000)
+#define STM32MP_NOR_TEEX_OFFSET		U(0x00300000)
+#endif
+
+#define STM32MP_NAND_BL33_OFFSET	U(0x00200000)
+#ifdef AARCH32_SP_OPTEE
+#define STM32MP_NAND_TEEH_OFFSET	U(0x00600000)
+#define STM32MP_NAND_TEED_OFFSET	U(0x00680000)
+#define STM32MP_NAND_TEEX_OFFSET	U(0x00700000)
+#endif
+
 /*******************************************************************************
  * STM32MP1 device/io map related constants (used for MMU)
  ******************************************************************************/
@@ -266,6 +287,7 @@
 /* OTP offsets */
 #define DATA0_OTP			U(0)
 #define PART_NUMBER_OTP			U(1)
+#define NAND_OTP			U(9)
 #define PACKAGE_OTP			U(16)
 #define HW2_OTP				U(18)
 
@@ -289,6 +311,45 @@
 /* HW2 OTP */
 #define HW2_OTP_PRODUCT_BELOW_2V5	BIT(13)
 
+/* NAND OTP */
+/* NAND parameter storage flag */
+#define NAND_PARAM_STORED_IN_OTP	BIT(31)
+
+/* NAND page size in bytes */
+#define NAND_PAGE_SIZE_MASK		GENMASK_32(30, 29)
+#define NAND_PAGE_SIZE_SHIFT		29
+#define NAND_PAGE_SIZE_2K		U(0)
+#define NAND_PAGE_SIZE_4K		U(1)
+#define NAND_PAGE_SIZE_8K		U(2)
+
+/* NAND block size in pages */
+#define NAND_BLOCK_SIZE_MASK		GENMASK_32(28, 27)
+#define NAND_BLOCK_SIZE_SHIFT		27
+#define NAND_BLOCK_SIZE_64_PAGES	U(0)
+#define NAND_BLOCK_SIZE_128_PAGES	U(1)
+#define NAND_BLOCK_SIZE_256_PAGES	U(2)
+
+/* NAND number of block (in unit of 256 blocs) */
+#define NAND_BLOCK_NB_MASK		GENMASK_32(26, 19)
+#define NAND_BLOCK_NB_SHIFT		19
+#define NAND_BLOCK_NB_UNIT		U(256)
+
+/* NAND bus width in bits */
+#define NAND_WIDTH_MASK			BIT(18)
+#define NAND_WIDTH_SHIFT		18
+
+/* NAND number of ECC bits per 512 bytes */
+#define NAND_ECC_BIT_NB_MASK		GENMASK_32(17, 15)
+#define NAND_ECC_BIT_NB_SHIFT		15
+#define NAND_ECC_BIT_NB_UNSET		U(0)
+#define NAND_ECC_BIT_NB_1_BITS		U(1)
+#define NAND_ECC_BIT_NB_4_BITS		U(2)
+#define NAND_ECC_BIT_NB_8_BITS		U(3)
+#define NAND_ECC_ON_DIE			U(4)
+
+/* NAND number of planes */
+#define NAND_PLANE_BIT_NB_MASK		BIT(14)
+
 /*******************************************************************************
  * STM32MP1 TAMP
  ******************************************************************************/
diff --git a/plat/xilinx/common/include/pm_ipi.h b/plat/xilinx/common/include/pm_ipi.h
index 16db5c5..7bcf596 100644
--- a/plat/xilinx/common/include/pm_ipi.h
+++ b/plat/xilinx/common/include/pm_ipi.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -26,5 +26,8 @@
 void pm_ipi_irq_enable(const struct pm_proc *proc);
 void pm_ipi_irq_clear(const struct pm_proc *proc);
 uint32_t pm_ipi_irq_status(const struct pm_proc *proc);
+#if ZYNQMP_IPI_CRC_CHECK
+uint32_t calculate_crc(uint32_t payload[PAYLOAD_ARG_CNT], uint32_t buffersize);
+#endif
 
 #endif /* PM_IPI_H */
diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c
index 034cd5b..c83d25b 100644
--- a/plat/xilinx/common/pm_service/pm_ipi.c
+++ b/plat/xilinx/common/pm_service/pm_ipi.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -57,6 +57,9 @@
 	uintptr_t buffer_base = proc->ipi->buffer_base +
 					IPI_BUFFER_TARGET_REMOTE_OFFSET +
 					IPI_BUFFER_REQ_OFFSET;
+#if ZYNQMP_IPI_CRC_CHECK
+	payload[PAYLOAD_CRC_POS] = calculate_crc(payload, IPI_W0_TO_W6_SIZE);
+#endif
 
 	/* Write payload into IPI buffer */
 	for (size_t i = 0; i < PAYLOAD_ARG_CNT; i++) {
@@ -132,6 +135,10 @@
 					   unsigned int *value, size_t count)
 {
 	size_t i;
+#if ZYNQMP_IPI_CRC_CHECK
+	size_t j;
+	unsigned int response_payload[PAYLOAD_ARG_CNT];
+#endif
 	uintptr_t buffer_base = proc->ipi->buffer_base +
 				IPI_BUFFER_TARGET_REMOTE_OFFSET +
 				IPI_BUFFER_RESP_OFFSET;
@@ -147,6 +154,16 @@
 		*value = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE));
 		value++;
 	}
+#if ZYNQMP_IPI_CRC_CHECK
+	for (j = 0; j < PAYLOAD_ARG_CNT; j++)
+		response_payload[j] = mmio_read_32(buffer_base +
+						(j * PAYLOAD_ARG_SIZE));
+
+	if (response_payload[PAYLOAD_CRC_POS] !=
+			calculate_crc(response_payload, IPI_W0_TO_W6_SIZE))
+		NOTICE("ERROR in CRC response payload value:0x%x\n",
+					response_payload[PAYLOAD_CRC_POS]);
+#endif
 
 	return mmio_read_32(buffer_base);
 }
@@ -162,6 +179,10 @@
 void pm_ipi_buff_read_callb(unsigned int *value, size_t count)
 {
 	size_t i;
+#if ZYNQMP_IPI_CRC_CHECK
+	size_t j;
+	unsigned int response_payload[PAYLOAD_ARG_CNT];
+#endif
 	uintptr_t buffer_base = IPI_BUFFER_REMOTE_BASE +
 				IPI_BUFFER_TARGET_LOCAL_OFFSET +
 				IPI_BUFFER_REQ_OFFSET;
@@ -173,6 +194,16 @@
 		*value = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE));
 		value++;
 	}
+#if ZYNQMP_IPI_CRC_CHECK
+	for (j = 0; j < PAYLOAD_ARG_CNT; j++)
+		response_payload[j] = mmio_read_32(buffer_base +
+						(j * PAYLOAD_ARG_SIZE));
+
+	if (response_payload[PAYLOAD_CRC_POS] !=
+			calculate_crc(response_payload, IPI_W0_TO_W6_SIZE))
+		NOTICE("ERROR in CRC response payload value:0x%x\n",
+					response_payload[PAYLOAD_CRC_POS]);
+#endif
 }
 
 /**
@@ -228,3 +259,34 @@
 	else
 		return 0;
 }
+
+#if ZYNQMP_IPI_CRC_CHECK
+uint32_t calculate_crc(uint32_t *payload, uint32_t bufsize)
+{
+	uint32_t crcinit = CRC_INIT_VALUE;
+	uint32_t order   = CRC_ORDER;
+	uint32_t polynom = CRC_POLYNOM;
+	uint32_t i, j, c, bit, datain, crcmask, crchighbit;
+	uint32_t crc = crcinit;
+
+	crcmask = ((uint32_t)((1U << (order - 1U)) - 1U) << 1U) | 1U;
+	crchighbit = (uint32_t)(1U << (order - 1U));
+
+	for (i = 0U; i < bufsize; i++) {
+		datain = mmio_read_8((unsigned long)payload + i);
+		c = datain;
+		j = 0x80U;
+		while (j != 0U) {
+			bit = crc & crchighbit;
+			crc <<= 1U;
+			if (0U != (c & j))
+				bit ^= crchighbit;
+			if (bit != 0U)
+				crc ^= polynom;
+			j >>= 1U;
+		}
+		crc &= crcmask;
+	}
+	return crc;
+}
+#endif
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
index ab5d95d..d6313a6 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
@@ -189,6 +189,18 @@
 		.id = 0x65,
 		.name = "25DR",
 	},
+	{
+		.id = 0x66,
+		.name = "39DR",
+	},
+	{
+		.id = 0x7b,
+		.name = "48DR",
+	},
+	{
+		.id = 0x7e,
+		.name = "49DR",
+	},
 };
 
 #define ZYNQMP_PL_STATUS_BIT	9
@@ -338,7 +350,7 @@
 	unsigned int ver = zynqmp_get_silicon_ver();
 
 	if (ver == ZYNQMP_CSU_VERSION_QEMU)
-		return 50000000;
+		return 65000000;
 	else
 		return mmio_read_32(IOU_SCNTRS_BASEFREQ);
 }
diff --git a/plat/xilinx/zynqmp/include/plat_pm_common.h b/plat/xilinx/zynqmp/include/plat_pm_common.h
index 1b371cc..56a747a 100644
--- a/plat/xilinx/zynqmp/include/plat_pm_common.h
+++ b/plat/xilinx/zynqmp/include/plat_pm_common.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,7 +16,16 @@
 #include <common/debug.h>
 #include "pm_defs.h"
 
-#define PAYLOAD_ARG_CNT		6U
+#if ZYNQMP_IPI_CRC_CHECK
+#define PAYLOAD_ARG_CNT         8U
+#define IPI_W0_TO_W6_SIZE       28U
+#define PAYLOAD_CRC_POS         7U
+#define CRC_INIT_VALUE          0x4F4EU
+#define CRC_ORDER               16U
+#define CRC_POLYNOM             0x8005U
+#else
+#define PAYLOAD_ARG_CNT         6U
+#endif
 #define PAYLOAD_ARG_SIZE	4U	/* size in bytes */
 
 #define ZYNQMP_TZ_VERSION_MAJOR		1
diff --git a/plat/xilinx/zynqmp/include/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h
index 8648b9a..5d335d9 100644
--- a/plat/xilinx/zynqmp/include/zynqmp_def.h
+++ b/plat/xilinx/zynqmp/include/zynqmp_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -330,6 +330,7 @@
 #define IOU_SLCR_GEM_CLK_CTRL		(IOU_SLCR_BASEADDR + 0x308)
 #define IOU_SLCR_CAN_MIO_CTRL		(IOU_SLCR_BASEADDR + 0x304)
 #define FPD_SLCR_WDT_CLK_SEL		(FPD_SLCR_BASEADDR + 0x100)
+#define IOU_SLCR_WDT_CLK_SEL		(IOU_SLCR_BASEADDR + 0x300)
 
 /* Global general storage register base address */
 #define GGS_BASEADDR		(0xFFD80030U)
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index c34a516..1039e27 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 
@@ -9,6 +9,7 @@
 A53_DISABLE_NON_TEMPORAL_HINT := 0
 SEPARATE_CODE_AND_RODATA := 1
 ZYNQMP_WDT_RESTART := 0
+ZYNQMP_IPI_CRC_CHECK := 0
 override RESET_TO_BL31 := 1
 
 # Do not enable SVE
@@ -45,7 +46,12 @@
 $(eval $(call add_define,ZYNQMP_WDT_RESTART))
 endif
 
-PLAT_INCLUDES		:=	-Iinclude/plat/arm/common/aarch64/		\
+ifdef ZYNQMP_IPI_CRC_CHECK
+    $(eval $(call add_define,ZYNQMP_IPI_CRC_CHECK))
+endif
+
+PLAT_INCLUDES		:=	-Iinclude/plat/arm/common/			\
+				-Iinclude/plat/arm/common/aarch64/		\
 				-Iplat/xilinx/common/include/			\
 				-Iplat/xilinx/zynqmp/include/			\
 				-Iplat/xilinx/zynqmp/pm_service/		\
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
index 85cffcb..852f927 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
@@ -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
  */
@@ -30,6 +30,10 @@
 #define CLK_TYPE_SHIFT			U(2)
 #define CLK_CLKFLAGS_SHIFT		U(8)
 #define CLK_TYPEFLAGS_SHIFT		U(24)
+#define CLK_TYPEFLAGS2_SHIFT		U(4)
+#define CLK_TYPEFLAGS_BITS_MASK		U(0xFF)
+#define CLK_TYPEFLAGS2_BITS_MASK	U(0x0F00)
+#define CLK_TYPEFLAGS_BITS		U(8)
 
 #define CLK_EXTERNAL_PARENT	(PARENT_CLK_EXTERNAL << CLK_PARENTS_ID_LEN)
 
@@ -364,9 +368,8 @@
 		.offset = PERIPH_MUX_SHIFT,
 		.width = PERIPH_MUX_WIDTH,
 		.clkflags = CLK_SET_RATE_NO_REPARENT |
-			    CLK_SET_RATE_PARENT |
-			    CLK_FRAC | CLK_IS_BASIC,
-		.typeflags = NA_TYPE_FLAGS,
+			    CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+		.typeflags = CLK_FRAC,
 		.mult = NA_MULT,
 		.div = NA_DIV,
 	},
@@ -375,8 +378,9 @@
 		.offset = PERIPH_DIV1_SHIFT,
 		.width = PERIPH_DIV1_WIDTH,
 		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT |
-			    CLK_FRAC | CLK_IS_BASIC,
-		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+			    CLK_IS_BASIC,
+		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO |
+			     CLK_FRAC,
 		.mult = NA_MULT,
 		.div = NA_DIV,
 	},
@@ -385,8 +389,9 @@
 		.offset = PERIPH_DIV2_SHIFT,
 		.width = PERIPH_DIV2_WIDTH,
 		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT |
-			    CLK_FRAC | CLK_IS_BASIC,
-		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+			    CLK_IS_BASIC,
+		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO |
+			     CLK_FRAC,
 		.mult = NA_MULT,
 		.div = NA_DIV,
 	},
@@ -562,13 +567,13 @@
 	},
 };
 
-static struct pm_clock_node gem_nodes[] = {
+static struct pm_clock_node gem_ref_ungated_nodes[] = {
 	GENERIC_MUX,
 	{
 		.type = TYPE_DIV1,
 		.offset = 8,
 		.width = 6,
-		.clkflags = CLK_IS_BASIC,
+		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
 		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -577,77 +582,74 @@
 		.type = TYPE_DIV2,
 		.offset = 16,
 		.width = 6,
-		.clkflags = CLK_IS_BASIC,
+		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC |
+			    CLK_SET_RATE_PARENT,
 		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
 		.mult = NA_MULT,
 		.div = NA_DIV,
 	},
-	{
-		.type = TYPE_GATE,
-		.offset = 25,
-		.width = PERIPH_GATE_WIDTH,
-		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
-		.typeflags = NA_TYPE_FLAGS,
-		.mult = NA_MULT,
-		.div = NA_DIV,
-	},
 };
 
-static struct pm_clock_node gem0_tx_nodes[] = {
+static struct pm_clock_node gem0_ref_nodes[] = {
 	{
 		.type = TYPE_MUX,
 		.offset = 1,
 		.width = 1,
-		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
-		.typeflags = NA_TYPE_FLAGS,
-		.mult = NA_MULT,
-		.div = NA_DIV,
-	},
-	{
-		.type = TYPE_GATE,
-		.offset = 26,
-		.width = PERIPH_GATE_WIDTH,
-		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+		.clkflags = CLK_SET_RATE_PARENT |
+			    CLK_SET_RATE_NO_REPARENT |
+			    CLK_IS_BASIC,
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
 	},
 };
 
-static struct pm_clock_node gem1_tx_nodes[] = {
+static struct pm_clock_node gem1_ref_nodes[] = {
 	{
 		.type = TYPE_MUX,
 		.offset = 6,
 		.width = 1,
-		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
+		.clkflags = CLK_SET_RATE_PARENT |
+			    CLK_SET_RATE_NO_REPARENT |
+			    CLK_IS_BASIC,
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
 	},
+};
+
+static struct pm_clock_node gem2_ref_nodes[] = {
 	{
-		.type = TYPE_GATE,
-		.offset = 26,
-		.width = PERIPH_GATE_WIDTH,
-		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+		.type = TYPE_MUX,
+		.offset = 11,
+		.width = 1,
+		.clkflags = CLK_SET_RATE_PARENT |
+			    CLK_SET_RATE_NO_REPARENT |
+			    CLK_IS_BASIC,
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
 	},
 };
 
-static struct pm_clock_node gem2_tx_nodes[] = {
+static struct pm_clock_node gem3_ref_nodes[] = {
 	{
 		.type = TYPE_MUX,
-		.offset = 11,
+		.offset = 16,
 		.width = 1,
-		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
+		.clkflags = CLK_SET_RATE_PARENT |
+			    CLK_SET_RATE_NO_REPARENT |
+			    CLK_IS_BASIC,
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
 	},
+};
+
+static struct pm_clock_node gem_tx_nodes[] = {
 	{
 		.type = TYPE_GATE,
-		.offset = 26,
+		.offset = 25,
 		.width = PERIPH_GATE_WIDTH,
 		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
 		.typeflags = NA_TYPE_FLAGS,
@@ -656,21 +658,12 @@
 	},
 };
 
-static struct pm_clock_node gem3_tx_nodes[] = {
-	{
-		.type = TYPE_MUX,
-		.offset = 16,
-		.width = 1,
-		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
-		.typeflags = NA_TYPE_FLAGS,
-		.mult = NA_MULT,
-		.div = NA_DIV,
-	},
+static struct pm_clock_node gem_rx_nodes[] = {
 	{
 		.type = TYPE_GATE,
 		.offset = 26,
 		.width = PERIPH_GATE_WIDTH,
-		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+		.clkflags = CLK_IS_BASIC,
 		.typeflags = NA_TYPE_FLAGS,
 		.mult = NA_MULT,
 		.div = NA_DIV,
@@ -1442,8 +1435,8 @@
 		.nodes = &generic_mux_div_unused_gate_nodes,
 		.num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
 	},
-	[CLK_GEM0_REF] = {
-		.name = "gem0_ref",
+	[CLK_GEM0_REF_UNGATED] = {
+		.name = "gem0_ref_ung",
 		.control_reg = CRL_APB_GEM0_REF_CTRL,
 		.status_reg = 0,
 		.parents = &((int32_t []) {
@@ -1453,11 +1446,11 @@
 			CLK_DPLL_TO_LPD,
 			CLK_NA_PARENT
 		}),
-		.nodes = &gem_nodes,
-		.num_nodes = ARRAY_SIZE(gem_nodes),
+		.nodes = &gem_ref_ungated_nodes,
+		.num_nodes = ARRAY_SIZE(gem_ref_ungated_nodes),
 	},
-	[CLK_GEM1_REF] = {
-		.name = "gem1_ref",
+	[CLK_GEM1_REF_UNGATED] = {
+		.name = "gem1_ref_ung",
 		.control_reg = CRL_APB_GEM1_REF_CTRL,
 		.status_reg = 0,
 		.parents = &((int32_t []) {
@@ -1467,11 +1460,11 @@
 			CLK_DPLL_TO_LPD,
 			CLK_NA_PARENT
 		}),
-		.nodes = &gem_nodes,
-		.num_nodes = ARRAY_SIZE(gem_nodes),
+		.nodes = &gem_ref_ungated_nodes,
+		.num_nodes = ARRAY_SIZE(gem_ref_ungated_nodes),
 	},
-	[CLK_GEM2_REF] = {
-		.name = "gem2_ref",
+	[CLK_GEM2_REF_UNGATED] = {
+		.name = "gem2_ref_ung",
 		.control_reg = CRL_APB_GEM2_REF_CTRL,
 		.status_reg = 0,
 		.parents = &((int32_t []) {
@@ -1481,11 +1474,11 @@
 			CLK_DPLL_TO_LPD,
 			CLK_NA_PARENT
 		}),
-		.nodes = &gem_nodes,
-		.num_nodes = ARRAY_SIZE(gem_nodes),
+		.nodes = &gem_ref_ungated_nodes,
+		.num_nodes = ARRAY_SIZE(gem_ref_ungated_nodes),
 	},
-	[CLK_GEM3_REF] = {
-		.name = "gem3_ref",
+	[CLK_GEM3_REF_UNGATED] = {
+		.name = "gem3_ref_ung",
 		.control_reg = CRL_APB_GEM3_REF_CTRL,
 		.status_reg = 0,
 		.parents = &((int32_t []) {
@@ -1495,8 +1488,60 @@
 			CLK_DPLL_TO_LPD,
 			CLK_NA_PARENT
 		}),
-		.nodes = &gem_nodes,
-		.num_nodes = ARRAY_SIZE(gem_nodes),
+		.nodes = &gem_ref_ungated_nodes,
+		.num_nodes = ARRAY_SIZE(gem_ref_ungated_nodes),
+	},
+	[CLK_GEM0_REF] = {
+		.name = "gem0_ref",
+		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_GEM0_REF_UNGATED |
+			(PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
+			EXT_CLK_GEM0_TX_EMIO | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &gem0_ref_nodes,
+		.num_nodes = ARRAY_SIZE(gem0_ref_nodes),
+	},
+	[CLK_GEM1_REF] = {
+		.name = "gem1_ref",
+		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_GEM1_REF_UNGATED |
+			(PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
+			EXT_CLK_GEM1_TX_EMIO | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &gem1_ref_nodes,
+		.num_nodes = ARRAY_SIZE(gem1_ref_nodes),
+	},
+	[CLK_GEM2_REF] = {
+		.name = "gem2_ref",
+		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_GEM2_REF_UNGATED |
+			(PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
+			EXT_CLK_GEM2_TX_EMIO | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &gem2_ref_nodes,
+		.num_nodes = ARRAY_SIZE(gem2_ref_nodes),
+	},
+	[CLK_GEM3_REF] = {
+		.name = "gem3_ref",
+		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_GEM3_REF_UNGATED |
+			(PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
+			EXT_CLK_GEM3_TX_EMIO | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &gem3_ref_nodes,
+		.num_nodes = ARRAY_SIZE(gem3_ref_nodes),
 	},
 	[CLK_USB0_BUS_REF] = {
 		.name = "usb0_bus_ref",
@@ -1960,69 +2005,93 @@
 		.nodes = &generic_domain_crossing_nodes,
 		.num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes),
 	},
-	/*
-	 * This clock control requires different registers for mux and gate.
-	 * Use control and status registers for the same.
-	 */
 	[CLK_GEM0_TX] = {
 		.name = "gem0_tx",
-		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
-		.status_reg = CRL_APB_GEM0_REF_CTRL,
+		.control_reg = CRL_APB_GEM0_REF_CTRL,
+		.status_reg = 0,
 		.parents = &((int32_t []) {
-			CLK_GEM0_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
-			EXT_CLK_GEM0_EMIO | CLK_EXTERNAL_PARENT,
+			CLK_GEM0_REF,
 			CLK_NA_PARENT
 		}),
-		.nodes = &gem0_tx_nodes,
-		.num_nodes = ARRAY_SIZE(gem0_tx_nodes),
+		.nodes = &gem_tx_nodes,
+		.num_nodes = ARRAY_SIZE(gem_tx_nodes),
 	},
-	/*
-	 * This clock control requires different registers for mux and gate.
-	 * Use control and status registers for the same.
-	 */
 	[CLK_GEM1_TX] = {
 		.name = "gem1_tx",
-		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
-		.status_reg = CRL_APB_GEM1_REF_CTRL,
+		.control_reg = CRL_APB_GEM1_REF_CTRL,
+		.status_reg = 0,
 		.parents = &((int32_t []) {
-			CLK_GEM1_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
-			EXT_CLK_GEM1_EMIO | CLK_EXTERNAL_PARENT,
+			CLK_GEM1_REF,
 			CLK_NA_PARENT
 		}),
-		.nodes = &gem1_tx_nodes,
-		.num_nodes = ARRAY_SIZE(gem1_tx_nodes),
+		.nodes = &gem_tx_nodes,
+		.num_nodes = ARRAY_SIZE(gem_tx_nodes),
 	},
-	/*
-	 * This clock control requires different registers for mux and gate.
-	 * Use control and status registers for the same.
-	 */
 	[CLK_GEM2_TX] = {
 		.name = "gem2_tx",
-		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
-		.status_reg = CRL_APB_GEM2_REF_CTRL,
+		.control_reg = CRL_APB_GEM2_REF_CTRL,
+		.status_reg = 0,
 		.parents = &((int32_t []) {
-			CLK_GEM2_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
-			EXT_CLK_GEM2_EMIO | CLK_EXTERNAL_PARENT,
+			CLK_GEM2_REF,
 			CLK_NA_PARENT
 		}),
-		.nodes = &gem2_tx_nodes,
-		.num_nodes = ARRAY_SIZE(gem2_tx_nodes),
+		.nodes = &gem_tx_nodes,
+		.num_nodes = ARRAY_SIZE(gem_tx_nodes),
 	},
-	/*
-	 * This clock control requires different registers for mux and gate.
-	 * Use control and status registers for the same.
-	 */
 	[CLK_GEM3_TX] = {
 		.name = "gem3_tx",
-		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
-		.status_reg = CRL_APB_GEM3_REF_CTRL,
+		.control_reg = CRL_APB_GEM3_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_GEM3_REF,
+			CLK_NA_PARENT
+		}),
+		.nodes = &gem_tx_nodes,
+		.num_nodes = ARRAY_SIZE(gem_tx_nodes),
+	},
+	[CLK_GEM0_RX] = {
+		.name = "gem0_rx",
+		.control_reg = CRL_APB_GEM0_REF_CTRL,
+		.status_reg = 0,
 		.parents = &((int32_t []) {
-			CLK_GEM3_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
-			EXT_CLK_GEM3_EMIO | CLK_EXTERNAL_PARENT,
+			EXT_CLK_GEM0_RX_EMIO | CLK_EXTERNAL_PARENT,
 			CLK_NA_PARENT
 		}),
-		.nodes = &gem3_tx_nodes,
-		.num_nodes = ARRAY_SIZE(gem3_tx_nodes),
+		.nodes = &gem_rx_nodes,
+		.num_nodes = ARRAY_SIZE(gem_rx_nodes),
+	},
+	[CLK_GEM1_RX] = {
+		.name = "gem1_rx",
+		.control_reg = CRL_APB_GEM1_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			EXT_CLK_GEM1_RX_EMIO | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &gem_rx_nodes,
+		.num_nodes = ARRAY_SIZE(gem_rx_nodes),
+	},
+	[CLK_GEM2_RX] = {
+		.name = "gem2_rx",
+		.control_reg = CRL_APB_GEM2_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			EXT_CLK_GEM2_RX_EMIO | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &gem_rx_nodes,
+		.num_nodes = ARRAY_SIZE(gem_rx_nodes),
+	},
+	[CLK_GEM3_RX] = {
+		.name = "gem3_rx",
+		.control_reg = CRL_APB_GEM3_REF_CTRL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			EXT_CLK_GEM3_RX_EMIO | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &gem_rx_nodes,
+		.num_nodes = ARRAY_SIZE(gem_rx_nodes),
 	},
 	[CLK_ACPU_HALF] = {
 		.name = "acpu_half",
@@ -2035,8 +2104,8 @@
 		.nodes = &acpu_half_nodes,
 		.num_nodes = ARRAY_SIZE(acpu_half_nodes),
 	},
-	[CLK_WDT] = {
-		.name = "wdt",
+	[CLK_FPD_WDT] = {
+		.name = "fpd_wdt",
 		.control_reg = FPD_SLCR_WDT_CLK_SEL,
 		.status_reg = 0,
 		.parents = &((int32_t []) {
@@ -2135,6 +2204,18 @@
 		.nodes = &can1_nodes,
 		.num_nodes = ARRAY_SIZE(can1_nodes),
 	},
+	[CLK_LPD_WDT] = {
+		.name = "lpd_wdt",
+		.control_reg = IOU_SLCR_WDT_CLK_SEL,
+		.status_reg = 0,
+		.parents = &((int32_t []) {
+			CLK_LPD_LSBUS,
+			EXT_CLK_SWDT1 | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.nodes = &wdt_nodes,
+		.num_nodes = ARRAY_SIZE(wdt_nodes),
+	},
 };
 
 static struct pm_ext_clock ext_clocks[] = {
@@ -2159,17 +2240,29 @@
 	[EXT_CLK_INDEX(EXT_CLK_SWDT1)] = {
 		.name = "swdt1_ext_clk",
 	},
+	[EXT_CLK_INDEX(EXT_CLK_GEM0_TX_EMIO)] = {
+		.name = "gem0_tx_ext",
+	},
+	[EXT_CLK_INDEX(EXT_CLK_GEM1_TX_EMIO)] = {
+		.name = "gem1_tx_ext",
+	},
-	[EXT_CLK_INDEX(EXT_CLK_GEM0_EMIO)] = {
-		.name = "gem0_emio_clk",
+	[EXT_CLK_INDEX(EXT_CLK_GEM2_TX_EMIO)] = {
+		.name = "gem2_tx_ext",
 	},
-	[EXT_CLK_INDEX(EXT_CLK_GEM1_EMIO)] = {
-		.name = "gem1_emio_clk",
+	[EXT_CLK_INDEX(EXT_CLK_GEM3_TX_EMIO)] = {
+		.name = "gem3_tx_ext",
 	},
-	[EXT_CLK_INDEX(EXT_CLK_GEM2_EMIO)] = {
-		.name = "gem2_emio_clk",
+	[EXT_CLK_INDEX(EXT_CLK_GEM0_RX_EMIO)] = {
+		.name = "gem0_rx_ext",
 	},
-	[EXT_CLK_INDEX(EXT_CLK_GEM3_EMIO)] = {
-		.name = "gem3_emio_clk",
+	[EXT_CLK_INDEX(EXT_CLK_GEM1_RX_EMIO)] = {
+		.name = "gem1_rx_ext",
+	},
+	[EXT_CLK_INDEX(EXT_CLK_GEM2_RX_EMIO)] = {
+		.name = "gem2_rx_ext",
+	},
+	[EXT_CLK_INDEX(EXT_CLK_GEM3_RX_EMIO)] = {
+		.name = "gem3_rx_ext",
 	},
 	[EXT_CLK_INDEX(EXT_CLK_MIO50_OR_MIO51)] = {
 		.name = "mio_clk_50_51",
@@ -2265,10 +2358,8 @@
 	CLK_DBG_TSTMP,
 	CLK_DDR_REF,
 	CLK_TOPSW_MAIN,
-	CLK_TOPSW_LSBUS,
 	CLK_GTGREF0_REF,
 	CLK_LPD_SWITCH,
-	CLK_LPD_LSBUS,
 	CLK_CPU_R5,
 	CLK_CPU_R5_CORE,
 	CLK_CSU_SPB,
@@ -2376,6 +2467,7 @@
 	struct pm_clock_node *clock_nodes;
 	uint8_t num_nodes;
 	unsigned int i;
+	uint16_t typeflags;
 
 	if (!pm_clock_valid(clock_id))
 		return PM_RET_ERROR_ARGS;
@@ -2395,11 +2487,14 @@
 	for (i = 0; i < 3U; i++) {
 		if ((index + i) == num_nodes)
 			break;
-		topology[i] =  clock_nodes[index + i].type;
+		topology[i] = clock_nodes[index + i].type;
 		topology[i] |= clock_nodes[index + i].clkflags <<
 					CLK_CLKFLAGS_SHIFT;
-		topology[i] |= clock_nodes[index + i].typeflags <<
+		typeflags = clock_nodes[index + i].typeflags;
+		topology[i] |= (typeflags & CLK_TYPEFLAGS_BITS_MASK) <<
 					CLK_TYPEFLAGS_SHIFT;
+		topology[i] |= (typeflags & CLK_TYPEFLAGS2_BITS_MASK) >>
+				(CLK_TYPEFLAGS_BITS - CLK_TYPEFLAGS2_SHIFT);
 	}
 
 	return PM_RET_SUCCESS;
@@ -2526,6 +2621,42 @@
 }
 
 /**
+ * pm_api_clock_get_max_divisor - PM call to get max divisor
+ * @clock_id	Clock ID
+ * @div_type	Divisor Type (TYPE_DIV1 or TYPE_DIV2)
+ * @max_div	Maximum supported divisor
+ *
+ * This function is used by master to get maximum supported value.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+enum pm_ret_status pm_api_clock_get_max_divisor(enum clock_id clock_id,
+						uint8_t div_type,
+						uint32_t *max_div)
+{
+	uint32_t i;
+	struct pm_clock_node *nodes;
+
+	if (clock_id >= CLK_MAX_OUTPUT_CLK)
+		return PM_RET_ERROR_ARGS;
+
+	nodes = *clocks[clock_id].nodes;
+	for (i = 0; i < clocks[clock_id].num_nodes; i++) {
+		if (nodes[i].type == div_type) {
+			if (CLK_DIVIDER_POWER_OF_TWO &
+					nodes[i].typeflags) {
+				*max_div = (1 << (BIT(nodes[i].width) - 1));
+			} else {
+				*max_div = BIT(nodes[i].width) - 1;
+			}
+			return PM_RET_SUCCESS;
+		}
+	}
+
+	return PM_RET_ERROR_ARGS;
+}
+
+/**
  * struct pm_pll - PLL related data required to map IOCTL-based PLL control
  * implemented by linux to system-level EEMI APIs
  * @nid:	PLL node ID
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
index 9717ca8..301ed24 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
@@ -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
  */
@@ -43,7 +43,6 @@
 #define CLK_IS_CRITICAL		BIT(11) /* do not gate, ever */
 /* parents need enable during gate/ungate, set rate and re-parent */
 #define CLK_OPS_PARENT_ENABLE	BIT(12)
-#define CLK_FRAC		BIT(13)
 
 #define CLK_DIVIDER_ONE_BASED		BIT(0)
 #define CLK_DIVIDER_POWER_OF_TWO	BIT(1)
@@ -52,6 +51,7 @@
 #define CLK_DIVIDER_ROUND_CLOSEST	BIT(4)
 #define CLK_DIVIDER_READ_ONLY		BIT(5)
 #define CLK_DIVIDER_MAX_AT_ZERO		BIT(6)
+#define CLK_FRAC		BIT(8)
 
 #define END_OF_CLK     "END_OF_CLK"
 
@@ -102,14 +102,14 @@
 	CLK_IOU_SWITCH,
 	CLK_GEM_TSU_REF,
 	CLK_GEM_TSU,
-	CLK_GEM0_REF,
-	CLK_GEM1_REF,
-	CLK_GEM2_REF,
-	CLK_GEM3_REF,
 	CLK_GEM0_TX,
 	CLK_GEM1_TX,
 	CLK_GEM2_TX,
 	CLK_GEM3_TX,
+	CLK_GEM0_RX,
+	CLK_GEM1_RX,
+	CLK_GEM2_RX,
+	CLK_GEM3_RX,
 	CLK_QSPI_REF,
 	CLK_SDIO0_REF,
 	CLK_SDIO1_REF,
@@ -132,7 +132,7 @@
 	CLK_PL1_REF,
 	CLK_PL2_REF,
 	CLK_PL3_REF,
-	CLK_WDT,
+	CLK_FPD_WDT,
 	CLK_IOPLL_INT,
 	CLK_IOPLL_PRE_SRC,
 	CLK_IOPLL_HALF,
@@ -161,6 +161,15 @@
 	CLK_CAN0_MIO,
 	CLK_CAN1_MIO,
 	CLK_ACPU_FULL,
+	CLK_GEM0_REF,
+	CLK_GEM1_REF,
+	CLK_GEM2_REF,
+	CLK_GEM3_REF,
+	CLK_GEM0_REF_UNGATED,
+	CLK_GEM1_REF_UNGATED,
+	CLK_GEM2_REF_UNGATED,
+	CLK_GEM3_REF_UNGATED,
+	CLK_LPD_WDT,
 	END_OF_OUTPUT_CLKS,
 };
 
@@ -175,10 +184,14 @@
 	EXT_CLK_GT_CRX_REF,
 	EXT_CLK_SWDT0,
 	EXT_CLK_SWDT1,
-	EXT_CLK_GEM0_EMIO,
-	EXT_CLK_GEM1_EMIO,
-	EXT_CLK_GEM2_EMIO,
-	EXT_CLK_GEM3_EMIO,
+	EXT_CLK_GEM0_TX_EMIO,
+	EXT_CLK_GEM1_TX_EMIO,
+	EXT_CLK_GEM2_TX_EMIO,
+	EXT_CLK_GEM3_TX_EMIO,
+	EXT_CLK_GEM0_RX_EMIO,
+	EXT_CLK_GEM1_RX_EMIO,
+	EXT_CLK_GEM2_RX_EMIO,
+	EXT_CLK_GEM3_RX_EMIO,
 	EXT_CLK_MIO50_OR_MIO51,
 	EXT_CLK_MIO0,
 	EXT_CLK_MIO1,
@@ -294,6 +307,9 @@
 					    uint32_t *parents);
 enum pm_ret_status pm_api_clock_get_attributes(unsigned int clock_id,
 					       uint32_t *attr);
+enum pm_ret_status pm_api_clock_get_max_divisor(enum clock_id clock_id,
+						uint8_t div_type,
+						uint32_t *max_div);
 
 enum pm_ret_status pm_clock_get_pll_node_id(enum clock_id clock_id,
 					    enum pm_node_id *node_id);
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
index 44acb4b..60e80d9 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
@@ -58,7 +58,7 @@
 {
 	unsigned int val;
 
-	if (mmio_read_32(CRL_APB_RST_LPD_TOP) && CRL_APB_RPU_AMBA_RESET)
+	if (mmio_read_32(CRL_APB_RST_LPD_TOP) & CRL_APB_RPU_AMBA_RESET)
 		return PM_RET_ERROR_ACCESS;
 
 	val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
index e0b9816..b1720d9 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -630,6 +630,22 @@
 }
 
 /**
+ * pm_get_callbackdata() - Read from IPI response buffer
+ * @data - array of PAYLOAD_ARG_CNT elements
+ *
+ * Read value from ipi buffer response buffer.
+ */
+void pm_get_callbackdata(uint32_t *data, size_t count)
+{
+	/* Return if interrupt is not from PMU */
+	if (!pm_ipi_irq_status(primary_proc))
+		return;
+
+	pm_ipi_buff_read_callb(data, count);
+	pm_ipi_irq_clear(primary_proc);
+}
+
+/**
  * pm_pinctrl_request() - Request Pin from firmware
  * @pin		Pin number to request
  *
@@ -741,6 +757,23 @@
 }
 
 /**
+ * pm_clock_get_max_divisor - PM call to get max divisor
+ * @clock_id	Clock ID
+ * @div_type	Divisor ID (TYPE_DIV1 or TYPE_DIV2)
+ * @max_div	Maximum supported divisor
+ *
+ * This function is used by master to get maximum supported value.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+static enum pm_ret_status pm_clock_get_max_divisor(unsigned int clock_id,
+						   uint8_t div_type,
+						   uint32_t *max_div)
+{
+	return pm_api_clock_get_max_divisor(clock_id, div_type, max_div);
+}
+
+/**
  * pm_clock_get_num_clocks - PM call to request number of clocks
  * @nclockss: Number of clocks
  *
@@ -1322,6 +1355,11 @@
 		ret = pm_clock_get_num_clocks(&data[1]);
 		data[0] = (unsigned int)ret;
 		break;
+
+	case PM_QID_CLOCK_GET_MAX_DIVISOR:
+		ret = pm_clock_get_max_divisor(arg1, arg2, &data[1]);
+		data[0] = (unsigned int)ret;
+		break;
 	default:
 		ret = PM_RET_ERROR_ARGS;
 		WARN("Unimplemented query service call: 0x%x\n", qid);
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
index 282ca3d..ff66d3f 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -25,6 +25,7 @@
 	PM_QID_PINCTRL_GET_FUNCTION_GROUPS,
 	PM_QID_PINCTRL_GET_PIN_GROUPS,
 	PM_QID_CLOCK_GET_NUM_CLOCKS,
+	PM_QID_CLOCK_GET_MAX_DIVISOR,
 };
 
 /**********************************************************
@@ -116,6 +117,7 @@
 				    uint32_t size,
 				    uint32_t flags);
 unsigned int pm_get_shutdown_scope(void);
+void pm_get_callbackdata(uint32_t *data, size_t count);
 enum pm_ret_status pm_pinctrl_request(unsigned int pin);
 enum pm_ret_status pm_pinctrl_release(unsigned int pin);
 enum pm_ret_status pm_pinctrl_get_function(unsigned int pin,
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
index faa2827..5a320f1 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -25,6 +25,7 @@
 #include "pm_client.h"
 #include "pm_ipi.h"
 
+#define PM_GET_CALLBACK_DATA	0xa01
 #define PM_SET_SUSPEND_MODE	0xa02
 #define PM_GET_TRUSTZONE_VERSION	0xa03
 
@@ -412,6 +413,16 @@
 				       pm_arg[3]);
 		SMC_RET1(handle, (uint64_t)ret);
 
+	case PM_GET_CALLBACK_DATA:
+	{
+		uint32_t result[4] = {0};
+
+		pm_get_callbackdata(result, (sizeof(result)/sizeof(uint32_t)));
+		SMC_RET2(handle,
+			 (uint64_t)result[0] | ((uint64_t)result[1] << 32),
+			 (uint64_t)result[2] | ((uint64_t)result[3] << 32));
+	}
+
 	case PM_PINCTRL_REQUEST:
 		ret = pm_pinctrl_request(pm_arg[0]);
 		SMC_RET1(handle, (uint64_t)ret);
diff --git a/services/std_svc/spm/README.rst b/services/std_svc/spm/README.rst
deleted file mode 100644
index 63406a3..0000000
--- a/services/std_svc/spm/README.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-This is a prototype loosely based on the SPCI Alpha and SPRT pre-alpha
-specifications. Any interface / platform API introduced for this is subject to
-change as it evolves.
diff --git a/services/std_svc/spm/aarch64/spm_helpers.S b/services/std_svc/spm/aarch64/spm_helpers.S
deleted file mode 100644
index aa35811..0000000
--- a/services/std_svc/spm/aarch64/spm_helpers.S
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <asm_macros.S>
-#include "../spm_private.h"
-
-	.global spm_secure_partition_enter
-	.global spm_secure_partition_exit
-
-	/* ---------------------------------------------------------------------
-	 * This function is called with SP_EL0 as stack. Here we stash our EL3
-	 * callee-saved registers on to the stack as a part of saving the C
-	 * runtime and enter the secure payload.
-	 * 'x0' contains a pointer to the memory where the address of the C
-	 *  runtime context is to be saved.
-	 * ---------------------------------------------------------------------
-	 */
-func spm_secure_partition_enter
-	/* Make space for the registers that we're going to save */
-	mov	x3, sp
-	str	x3, [x0, #0]
-	sub	sp, sp, #SP_C_RT_CTX_SIZE
-
-	/* Save callee-saved registers on to the stack */
-	stp	x19, x20, [sp, #SP_C_RT_CTX_X19]
-	stp	x21, x22, [sp, #SP_C_RT_CTX_X21]
-	stp	x23, x24, [sp, #SP_C_RT_CTX_X23]
-	stp	x25, x26, [sp, #SP_C_RT_CTX_X25]
-	stp	x27, x28, [sp, #SP_C_RT_CTX_X27]
-	stp	x29, x30, [sp, #SP_C_RT_CTX_X29]
-
-	/* ---------------------------------------------------------------------
-	 * Everything is setup now. el3_exit() will use the secure context to
-	 * restore to the general purpose and EL3 system registers to ERET
-	 * into the secure payload.
-	 * ---------------------------------------------------------------------
-	 */
-	b	el3_exit
-endfunc spm_secure_partition_enter
-
-	/* ---------------------------------------------------------------------
-	 * This function is called with 'x0' pointing to a C runtime context
-	 * saved in spm_secure_partition_enter().
-	 * It restores the saved registers and jumps to that runtime with 'x0'
-	 * as the new SP register. This destroys the C runtime context that had
-	 * been built on the stack below the saved context by the caller. Later
-	 * the second parameter 'x1' is passed as a return value to the caller.
-	 * ---------------------------------------------------------------------
-	 */
-func spm_secure_partition_exit
-	/* Restore the previous stack */
-	mov	sp, x0
-
-	/* Restore callee-saved registers on to the stack */
-	ldp	x19, x20, [x0, #(SP_C_RT_CTX_X19 - SP_C_RT_CTX_SIZE)]
-	ldp	x21, x22, [x0, #(SP_C_RT_CTX_X21 - SP_C_RT_CTX_SIZE)]
-	ldp	x23, x24, [x0, #(SP_C_RT_CTX_X23 - SP_C_RT_CTX_SIZE)]
-	ldp	x25, x26, [x0, #(SP_C_RT_CTX_X25 - SP_C_RT_CTX_SIZE)]
-	ldp	x27, x28, [x0, #(SP_C_RT_CTX_X27 - SP_C_RT_CTX_SIZE)]
-	ldp	x29, x30, [x0, #(SP_C_RT_CTX_X29 - SP_C_RT_CTX_SIZE)]
-
-	/* ---------------------------------------------------------------------
-	 * This should take us back to the instruction after the call to the
-	 * last spm_secure_partition_enter().* Place the second parameter to x0
-	 * so that the caller will see it as a return value from the original
-	 * entry call.
-	 * ---------------------------------------------------------------------
-	 */
-	mov	x0, x1
-	ret
-endfunc spm_secure_partition_exit
diff --git a/services/std_svc/spm/aarch64/spm_shim_exceptions.S b/services/std_svc/spm/aarch64/spm_shim_exceptions.S
deleted file mode 100644
index dab6150..0000000
--- a/services/std_svc/spm/aarch64/spm_shim_exceptions.S
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <asm_macros.S>
-#include <common/bl_common.h>
-#include <context.h>
-
-/* -----------------------------------------------------------------------------
- * Very simple stackless exception handlers used by the spm shim layer.
- * -----------------------------------------------------------------------------
- */
-	.globl	spm_shim_exceptions_ptr
-
-vector_base spm_shim_exceptions_ptr, .spm_shim_exceptions
-
-	/* -----------------------------------------------------
-	 * Current EL with SP0 : 0x0 - 0x200
-	 * -----------------------------------------------------
-	 */
-vector_entry SynchronousExceptionSP0, .spm_shim_exceptions
-	b	.
-end_vector_entry SynchronousExceptionSP0
-
-vector_entry IrqSP0, .spm_shim_exceptions
-	b	.
-end_vector_entry IrqSP0
-
-vector_entry FiqSP0, .spm_shim_exceptions
-	b	.
-end_vector_entry FiqSP0
-
-vector_entry SErrorSP0, .spm_shim_exceptions
-	b	.
-end_vector_entry SErrorSP0
-
-	/* -----------------------------------------------------
-	 * Current EL with SPx: 0x200 - 0x400
-	 * -----------------------------------------------------
-	 */
-vector_entry SynchronousExceptionSPx, .spm_shim_exceptions
-	b	.
-end_vector_entry SynchronousExceptionSPx
-
-vector_entry IrqSPx, .spm_shim_exceptions
-	b	.
-end_vector_entry IrqSPx
-
-vector_entry FiqSPx, .spm_shim_exceptions
-	b	.
-end_vector_entry FiqSPx
-
-vector_entry SErrorSPx, .spm_shim_exceptions
-	b	.
-end_vector_entry SErrorSPx
-
-	/* -----------------------------------------------------
-	 * Lower EL using AArch64 : 0x400 - 0x600. No exceptions
-	 * are handled since secure_partition does not implement
-	 * a lower EL
-	 * -----------------------------------------------------
-	 */
-vector_entry SynchronousExceptionA64, .spm_shim_exceptions
-	msr	tpidr_el1, x30
-	mrs	x30, esr_el1
-	ubfx	x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH
-
-	cmp	x30, #EC_AARCH64_SVC
-	b.eq 	do_smc
-
-	cmp	x30, #EC_AARCH32_SVC
-	b.eq	do_smc
-
-	cmp	x30, #EC_AARCH64_SYS
-	b.eq	handle_sys_trap
-
-	/* Fail in all the other cases */
-	b	panic
-
-	/* ---------------------------------------------
-	 * Tell SPM that we are done initialising
-	 * ---------------------------------------------
-	 */
-do_smc:
-	mrs	x30, tpidr_el1
-	smc	#0
-	eret
-
-	/* AArch64 system instructions trap are handled as a panic for now */
-handle_sys_trap:
-panic:
-	b	panic
-end_vector_entry SynchronousExceptionA64
-
-vector_entry IrqA64, .spm_shim_exceptions
-	b	.
-end_vector_entry IrqA64
-
-vector_entry FiqA64, .spm_shim_exceptions
-	b	.
-end_vector_entry FiqA64
-
-vector_entry SErrorA64, .spm_shim_exceptions
-	b	.
-end_vector_entry SErrorA64
-
-	/* -----------------------------------------------------
-	 * Lower EL using AArch32 : 0x600 - 0x800
-	 * -----------------------------------------------------
-	 */
-vector_entry SynchronousExceptionA32, .spm_shim_exceptions
-	b	.
-end_vector_entry SynchronousExceptionA32
-
-vector_entry IrqA32, .spm_shim_exceptions
-	b	.
-end_vector_entry IrqA32
-
-vector_entry FiqA32, .spm_shim_exceptions
-	b	.
-end_vector_entry FiqA32
-
-vector_entry SErrorA32, .spm_shim_exceptions
-	b	.
-end_vector_entry SErrorA32
diff --git a/services/std_svc/spm/spci.c b/services/std_svc/spm/spci.c
deleted file mode 100644
index 2e12a6c..0000000
--- a/services/std_svc/spm/spci.c
+++ /dev/null
@@ -1,769 +0,0 @@
-/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <string.h>
-
-#include <common/debug.h>
-#include <common/runtime_svc.h>
-#include <lib/el3_runtime/context_mgmt.h>
-#include <lib/smccc.h>
-#include <lib/spinlock.h>
-#include <lib/utils.h>
-#include <services/spci_svc.h>
-#include <services/sprt_svc.h>
-#include <smccc_helpers.h>
-#include <sprt_host.h>
-
-#include "spm_private.h"
-
-/*******************************************************************************
- * Macros to print UUIDs.
- ******************************************************************************/
-#define PRINT_UUID_FORMAT	"%08x-%08x-%08x-%08x"
-#define PRINT_UUID_ARGS(x)	x[0], x[1], x[2], x[3]
-
-/*******************************************************************************
- * Array of structs that contains information about all handles of Secure
- * Services that are currently open.
- ******************************************************************************/
-typedef enum spci_handle_status {
-	HANDLE_STATUS_CLOSED = 0,
-	HANDLE_STATUS_OPEN,
-} spci_handle_status_t;
-
-typedef struct spci_handle {
-	/* 16-bit value used as reference in all SPCI calls */
-	uint16_t handle;
-
-	/* Client ID of the client that requested the handle */
-	uint16_t client_id;
-
-	/* Current status of the handle */
-	spci_handle_status_t status;
-
-	/*
-	 * Context of the Secure Partition that provides the Secure Service
-	 * referenced by this handle.
-	 */
-	sp_context_t *sp_ctx;
-
-	/*
-	 * The same handle might be used for multiple requests, keep a reference
-	 * counter of them.
-	 */
-	unsigned int num_active_requests;
-} spci_handle_t;
-
-static spci_handle_t spci_handles[PLAT_SPCI_HANDLES_MAX_NUM];
-static spinlock_t spci_handles_lock;
-
-/*
- * Given a handle and a client ID, return the element of the spci_handles
- * array that contains the information of the handle. It can only return open
- * handles. It returns NULL if it couldn't find the element in the array.
- */
-static spci_handle_t *spci_handle_info_get(uint16_t handle, uint16_t client_id)
-{
-	size_t i;
-
-	for (i = 0; i < ARRAY_SIZE(spci_handles); i++) {
-		spci_handle_t *h = &(spci_handles[i]);
-
-		/* Only check for open handles */
-		if (h->status == HANDLE_STATUS_CLOSED) {
-			continue;
-		}
-
-		/* Check if either the handle or the client ID are different */
-		if ((h->handle != handle) || (h->client_id != client_id)) {
-			continue;
-		}
-
-		return h;
-	}
-
-	return NULL;
-}
-
-/*
- * Returns a unique value for a handle. This function must be called while
- * spci_handles_lock is locked. It returns 0 on success, -1 on error.
- */
-static int spci_create_handle_value(uint16_t *handle)
-{
-	/*
-	 * Trivial implementation that relies on the fact that any handle will
-	 * be closed before 2^16 more handles have been opened.
-	 */
-	static uint16_t handle_count;
-
-	*handle = handle_count;
-
-	handle_count++;
-
-	return 0;
-}
-
-/*******************************************************************************
- * Returns a unique token for a Secure Service request.
- ******************************************************************************/
-static uint32_t spci_create_token_value(void)
-{
-	/*
-	 * Trivial implementation that relies on the fact that any response will
-	 * be read before 2^32 more service requests have been done.
-	 */
-	static uint32_t token_count;
-
-	return token_count++;
-}
-
-/*******************************************************************************
- * This function looks for a Secure Partition that has a Secure Service
- * identified by the given UUID. It returns a handle that the client can use to
- * access the service, and an SPCI_*** error code.
- ******************************************************************************/
-static uint64_t spci_service_handle_open_poll(void *handle, u_register_t x1,
-			u_register_t x2, u_register_t x3, u_register_t x4,
-			u_register_t x5, u_register_t x6, u_register_t x7)
-{
-	unsigned int i;
-	sp_context_t *sp_ptr;
-	uint16_t service_handle;
-
-	/* Bits 31:16 of w7 are reserved (MBZ). */
-	assert((x7 & 0xFFFF0000U) == 0);
-
-	uint16_t client_id = x7 & 0x0000FFFFU;
-	uint32_t uuid[4] = { x1, x2, x3, x4 };
-
-	/* Get pointer to the Secure Partition that handles this service */
-	sp_ptr = spm_sp_get_by_uuid(&uuid);
-	if (sp_ptr == NULL) {
-		WARN("SPCI: Service requested by client 0x%04x not found\n",
-		     client_id);
-		WARN("SPCI:   UUID: " PRINT_UUID_FORMAT "\n",
-		     PRINT_UUID_ARGS(uuid));
-
-		SMC_RET2(handle, SPCI_NOT_PRESENT, 0);
-	}
-
-	/* Get lock of the array of handles */
-	spin_lock(&spci_handles_lock);
-
-	/*
-	 * We need to record the client ID and Secure Partition that correspond
-	 * to this handle. Look for the first free entry in the array.
-	 */
-	for (i = 0; i < PLAT_SPCI_HANDLES_MAX_NUM; i++) {
-		if (spci_handles[i].status == HANDLE_STATUS_CLOSED) {
-			break;
-		}
-	}
-
-	if (i == PLAT_SPCI_HANDLES_MAX_NUM) {
-		spin_unlock(&spci_handles_lock);
-
-		WARN("SPCI: Can't open more handles. Client 0x%04x\n",
-		     client_id);
-		WARN("SPCI:   UUID: " PRINT_UUID_FORMAT "\n",
-		     PRINT_UUID_ARGS(uuid));
-
-		SMC_RET2(handle, SPCI_NO_MEMORY, 0);
-	}
-
-	/* Create new handle value */
-	if (spci_create_handle_value(&service_handle) != 0) {
-		spin_unlock(&spci_handles_lock);
-
-		WARN("SPCI: Can't create a new handle value. Client 0x%04x\n",
-		     client_id);
-		WARN("SPCI:   UUID: " PRINT_UUID_FORMAT "\n",
-		     PRINT_UUID_ARGS(uuid));
-
-		SMC_RET2(handle, SPCI_NO_MEMORY, 0);
-	}
-
-	/* Save all information about this handle */
-	spci_handles[i].status = HANDLE_STATUS_OPEN;
-	spci_handles[i].client_id = client_id;
-	spci_handles[i].handle = service_handle;
-	spci_handles[i].num_active_requests = 0U;
-	spci_handles[i].sp_ctx = sp_ptr;
-
-	/* Release lock of the array of handles */
-	spin_unlock(&spci_handles_lock);
-
-	VERBOSE("SPCI: Service handle request by client 0x%04x: 0x%04x\n",
-		client_id, service_handle);
-	VERBOSE("SPCI:   UUID: " PRINT_UUID_FORMAT "\n", PRINT_UUID_ARGS(uuid));
-
-	/* The handle is returned in the top 16 bits of x1 */
-	SMC_RET2(handle, SPCI_SUCCESS, ((uint32_t)service_handle) << 16);
-}
-
-/*******************************************************************************
- * This function closes a handle that a specific client uses to access a Secure
- * Service. It returns a SPCI_*** error code.
- ******************************************************************************/
-static uint64_t spci_service_handle_close(void *handle, u_register_t x1)
-{
-	spci_handle_t *handle_info;
-	uint16_t client_id = x1 & 0x0000FFFFU;
-	uint16_t service_handle = (x1 >> 16) & 0x0000FFFFU;
-
-	spin_lock(&spci_handles_lock);
-
-	handle_info = spci_handle_info_get(service_handle, client_id);
-
-	if (handle_info == NULL) {
-		spin_unlock(&spci_handles_lock);
-
-		WARN("SPCI: Tried to close invalid handle 0x%04x by client 0x%04x\n",
-		     service_handle, client_id);
-
-		SMC_RET1(handle, SPCI_INVALID_PARAMETER);
-	}
-
-	if (handle_info->status != HANDLE_STATUS_OPEN) {
-		spin_unlock(&spci_handles_lock);
-
-		WARN("SPCI: Tried to close handle 0x%04x by client 0x%04x in status %d\n",
-			service_handle, client_id, handle_info->status);
-
-		SMC_RET1(handle, SPCI_INVALID_PARAMETER);
-	}
-
-	if (handle_info->num_active_requests != 0U) {
-		spin_unlock(&spci_handles_lock);
-
-		/* A handle can't be closed if there are requests left */
-		WARN("SPCI: Tried to close handle 0x%04x by client 0x%04x with %d requests left\n",
-			service_handle, client_id,
-			handle_info->num_active_requests);
-
-		SMC_RET1(handle, SPCI_BUSY);
-	}
-
-	memset(handle_info, 0, sizeof(spci_handle_t));
-
-	handle_info->status = HANDLE_STATUS_CLOSED;
-
-	spin_unlock(&spci_handles_lock);
-
-	VERBOSE("SPCI: Closed handle 0x%04x by client 0x%04x.\n",
-		service_handle, client_id);
-
-	SMC_RET1(handle, SPCI_SUCCESS);
-}
-
-/*******************************************************************************
- * This function requests a Secure Service from a given handle and client ID.
- ******************************************************************************/
-static uint64_t spci_service_request_blocking(void *handle,
-			uint32_t smc_fid, u_register_t x1, u_register_t x2,
-			u_register_t x3, u_register_t x4, u_register_t x5,
-			u_register_t x6, u_register_t x7)
-{
-	spci_handle_t *handle_info;
-	sp_context_t *sp_ctx;
-	cpu_context_t *cpu_ctx;
-	uint32_t rx0;
-	u_register_t rx1, rx2, rx3;
-	uint16_t request_handle, client_id;
-
-	/* Get handle array lock */
-	spin_lock(&spci_handles_lock);
-
-	/* Get pointer to struct of this open handle and client ID. */
-	request_handle = (x7 >> 16U) & 0x0000FFFFU;
-	client_id = x7 & 0x0000FFFFU;
-
-	handle_info = spci_handle_info_get(request_handle, client_id);
-	if (handle_info == NULL) {
-		spin_unlock(&spci_handles_lock);
-
-		WARN("SPCI_SERVICE_TUN_REQUEST_BLOCKING: Not found.\n");
-		WARN("  Handle 0x%04x. Client ID 0x%04x\n", request_handle,
-		     client_id);
-
-		SMC_RET1(handle, SPCI_BUSY);
-	}
-
-	/* Get pointer to the Secure Partition that handles the service */
-	sp_ctx = handle_info->sp_ctx;
-	assert(sp_ctx != NULL);
-	cpu_ctx = &(sp_ctx->cpu_ctx);
-
-	/* Blocking requests are only allowed if the queue is empty */
-	if (handle_info->num_active_requests > 0) {
-		spin_unlock(&spci_handles_lock);
-
-		SMC_RET1(handle, SPCI_BUSY);
-	}
-
-	if (spm_sp_request_increase_if_zero(sp_ctx) == -1) {
-		spin_unlock(&spci_handles_lock);
-
-		SMC_RET1(handle, SPCI_BUSY);
-	}
-
-	/* Prevent this handle from being closed */
-	handle_info->num_active_requests += 1;
-
-	/* Release handle lock */
-	spin_unlock(&spci_handles_lock);
-
-	/* Save the Normal world context */
-	cm_el1_sysregs_context_save(NON_SECURE);
-
-	/* Wait until the Secure Partition is idle and set it to busy. */
-	sp_state_wait_switch(sp_ctx, SP_STATE_IDLE, SP_STATE_BUSY);
-
-	/* Pass arguments to the Secure Partition */
-	struct sprt_queue_entry_message message = {
-		.type = SPRT_MSG_TYPE_SERVICE_TUN_REQUEST,
-		.client_id = client_id,
-		.service_handle = request_handle,
-		.session_id = x6,
-		.token = 0, /* No token needed for blocking requests */
-		.args = {smc_fid, x1, x2, x3, x4, x5}
-	};
-
-	spin_lock(&(sp_ctx->spm_sp_buffer_lock));
-	int rc = sprt_push_message((void *)sp_ctx->spm_sp_buffer_base, &message,
-				   SPRT_QUEUE_NUM_BLOCKING);
-	spin_unlock(&(sp_ctx->spm_sp_buffer_lock));
-	if (rc != 0) {
-		/*
-		 * This shouldn't happen, blocking requests can only be made if
-		 * the request queue is empty.
-		 */
-		assert(rc == -ENOMEM);
-		ERROR("SPCI_SERVICE_TUN_REQUEST_BLOCKING: Queue is full.\n");
-		panic();
-	}
-
-	/* Jump to the Secure Partition. */
-	rx0 = spm_sp_synchronous_entry(sp_ctx, 0);
-
-	/* Verify returned value */
-	if (rx0 != SPRT_PUT_RESPONSE_AARCH64) {
-		ERROR("SPM: %s: Unexpected x0 value 0x%x\n", __func__, rx0);
-		panic();
-	}
-
-	rx1 = read_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X3);
-	rx2 = read_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X4);
-	rx3 = read_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X5);
-
-	/* Flag Secure Partition as idle. */
-	assert(sp_ctx->state == SP_STATE_BUSY);
-	sp_state_set(sp_ctx, SP_STATE_IDLE);
-
-	/* Decrease count of requests. */
-	spin_lock(&spci_handles_lock);
-	handle_info->num_active_requests -= 1;
-	spin_unlock(&spci_handles_lock);
-	spm_sp_request_decrease(sp_ctx);
-
-	/* Restore non-secure state */
-	cm_el1_sysregs_context_restore(NON_SECURE);
-	cm_set_next_eret_context(NON_SECURE);
-
-	SMC_RET4(handle, SPCI_SUCCESS, rx1, rx2, rx3);
-}
-
-/*******************************************************************************
- * This function handles the returned values from the Secure Partition.
- ******************************************************************************/
-static void spci_handle_returned_values(const cpu_context_t *cpu_ctx,
-					uint64_t ret)
-{
-	if (ret == SPRT_PUT_RESPONSE_AARCH64) {
-		uint32_t token;
-		uint64_t x3, x4, x5, x6;
-
-		token = read_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X1);
-		x3 = read_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X3);
-		x4 = read_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X4);
-		x5 = read_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X5);
-		x6 = read_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X6);
-
-		uint16_t client_id = x6 & 0xFFFFU;
-		uint16_t service_handle = x6 >> 16;
-
-		int rc = spm_response_add(client_id, service_handle, token,
-					  x3, x4, x5);
-		if (rc != 0) {
-			/*
-			 * This is error fatal because we can't return to the SP
-			 * from this SMC. The SP has crashed.
-			 */
-			panic();
-		}
-	} else if ((ret != SPRT_YIELD_AARCH64) &&
-		   (ret != SPM_SECURE_PARTITION_PREEMPTED)) {
-		ERROR("SPM: %s: Unexpected x0 value 0x%llx\n", __func__, ret);
-		panic();
-	}
-}
-
-/*******************************************************************************
- * This function requests a Secure Service from a given handle and client ID.
- ******************************************************************************/
-static uint64_t spci_service_request_start(void *handle,
-			uint32_t smc_fid, u_register_t x1, u_register_t x2,
-			u_register_t x3, u_register_t x4, u_register_t x5,
-			u_register_t x6, u_register_t x7)
-{
-	spci_handle_t *handle_info;
-	sp_context_t *sp_ctx;
-	cpu_context_t *cpu_ctx;
-	uint16_t request_handle, client_id;
-	uint32_t token;
-
-	/* Get handle array lock */
-	spin_lock(&spci_handles_lock);
-
-	/* Get pointer to struct of this open handle and client ID. */
-	request_handle = (x7 >> 16U) & 0x0000FFFFU;
-	client_id = x7 & 0x0000FFFFU;
-
-	handle_info = spci_handle_info_get(request_handle, client_id);
-	if (handle_info == NULL) {
-		spin_unlock(&spci_handles_lock);
-
-		WARN("SPCI_SERVICE_TUN_REQUEST_START: Not found.\n"
-		     "  Handle 0x%04x. Client ID 0x%04x\n", request_handle,
-		     client_id);
-
-		SMC_RET1(handle, SPCI_INVALID_PARAMETER);
-	}
-
-	/* Get pointer to the Secure Partition that handles the service */
-	sp_ctx = handle_info->sp_ctx;
-	assert(sp_ctx != NULL);
-	cpu_ctx = &(sp_ctx->cpu_ctx);
-
-	/* Prevent this handle from being closed */
-	handle_info->num_active_requests += 1;
-
-	spm_sp_request_increase(sp_ctx);
-
-	/* Create new token for this request */
-	token = spci_create_token_value();
-
-	/* Release handle lock */
-	spin_unlock(&spci_handles_lock);
-
-	/* Pass arguments to the Secure Partition */
-	struct sprt_queue_entry_message message = {
-		.type = SPRT_MSG_TYPE_SERVICE_TUN_REQUEST,
-		.client_id = client_id,
-		.service_handle = request_handle,
-		.session_id = x6,
-		.token = token,
-		.args = {smc_fid, x1, x2, x3, x4, x5}
-	};
-
-	spin_lock(&(sp_ctx->spm_sp_buffer_lock));
-	int rc = sprt_push_message((void *)sp_ctx->spm_sp_buffer_base, &message,
-				   SPRT_QUEUE_NUM_NON_BLOCKING);
-	spin_unlock(&(sp_ctx->spm_sp_buffer_lock));
-	if (rc != 0) {
-		WARN("SPCI_SERVICE_TUN_REQUEST_START: SPRT queue full.\n"
-		     "  Handle 0x%04x. Client ID 0x%04x\n", request_handle,
-		     client_id);
-		SMC_RET1(handle, SPCI_NO_MEMORY);
-	}
-
-	/* Try to enter the partition. If it's not possible, simply return. */
-	if (sp_state_try_switch(sp_ctx, SP_STATE_IDLE, SP_STATE_BUSY) != 0) {
-		SMC_RET2(handle, SPCI_SUCCESS, token);
-	}
-
-	/* Save the Normal world context */
-	cm_el1_sysregs_context_save(NON_SECURE);
-
-	/*
-	 * This request is non-blocking and needs to be interruptible by
-	 * non-secure interrupts. Enable their routing to EL3 during the
-	 * processing of the Secure Partition's service on this core.
-	 */
-
-	/* Jump to the Secure Partition. */
-	uint64_t ret = spm_sp_synchronous_entry(sp_ctx, 1);
-
-	/* Handle returned values */
-	spci_handle_returned_values(cpu_ctx, ret);
-
-	/* Flag Secure Partition as idle. */
-	assert(sp_ctx->state == SP_STATE_BUSY);
-	sp_state_set(sp_ctx, SP_STATE_IDLE);
-
-	/* Restore non-secure state */
-	cm_el1_sysregs_context_restore(NON_SECURE);
-	cm_set_next_eret_context(NON_SECURE);
-
-	SMC_RET2(handle, SPCI_SUCCESS, token);
-}
-
-/*******************************************************************************
- * This function returns the response of a Secure Service given a handle, a
- * client ID and a token. If not available, it will schedule a Secure Partition
- * and give it CPU time.
- ******************************************************************************/
-static uint64_t spci_service_request_resume(void *handle, u_register_t x1,
-					    u_register_t x7)
-{
-	int rc;
-	u_register_t rx1 = 0, rx2 = 0, rx3 = 0;
-	spci_handle_t *handle_info;
-	sp_context_t *sp_ctx;
-	cpu_context_t *cpu_ctx;
-	uint32_t token = (uint32_t) x1;
-	uint16_t client_id = x7 & 0x0000FFFF;
-	uint16_t service_handle = (x7 >> 16) & 0x0000FFFF;
-
-	/* Get pointer to struct of this open handle and client ID. */
-	spin_lock(&spci_handles_lock);
-
-	handle_info = spci_handle_info_get(service_handle, client_id);
-	if (handle_info == NULL) {
-		spin_unlock(&spci_handles_lock);
-		WARN("SPCI_SERVICE_REQUEST_RESUME: Not found.\n"
-		     "Handle 0x%04x. Client ID 0x%04x, Token 0x%08x.\n",
-		     client_id, service_handle, token);
-
-		SMC_RET1(handle, SPCI_INVALID_PARAMETER);
-	}
-
-	/* Get pointer to the Secure Partition that handles the service */
-	sp_ctx = handle_info->sp_ctx;
-	assert(sp_ctx != NULL);
-	cpu_ctx = &(sp_ctx->cpu_ctx);
-
-	spin_unlock(&spci_handles_lock);
-
-	/* Look for a valid response in the global queue */
-	rc = spm_response_get(client_id, service_handle, token,
-			      &rx1, &rx2, &rx3);
-	if (rc == 0) {
-		/* Decrease request count */
-		spin_lock(&spci_handles_lock);
-		handle_info->num_active_requests -= 1;
-		spin_unlock(&spci_handles_lock);
-		spm_sp_request_decrease(sp_ctx);
-
-		SMC_RET4(handle, SPCI_SUCCESS, rx1, rx2, rx3);
-	}
-
-	/* Try to enter the partition. If it's not possible, simply return. */
-	if (sp_state_try_switch(sp_ctx, SP_STATE_IDLE, SP_STATE_BUSY) != 0) {
-		SMC_RET1(handle, SPCI_QUEUED);
-	}
-
-	/* Save the Normal world context */
-	cm_el1_sysregs_context_save(NON_SECURE);
-
-	/*
-	 * This request is non-blocking and needs to be interruptible by
-	 * non-secure interrupts. Enable their routing to EL3 during the
-	 * processing of the Secure Partition's service on this core.
-	 */
-
-	/* Jump to the Secure Partition. */
-	uint64_t ret = spm_sp_synchronous_entry(sp_ctx, 1);
-
-	/* Handle returned values */
-	spci_handle_returned_values(cpu_ctx, ret);
-
-	/* Flag Secure Partition as idle. */
-	assert(sp_ctx->state == SP_STATE_BUSY);
-	sp_state_set(sp_ctx, SP_STATE_IDLE);
-
-	/* Restore non-secure state */
-	cm_el1_sysregs_context_restore(NON_SECURE);
-	cm_set_next_eret_context(NON_SECURE);
-
-	/* Look for a valid response in the global queue */
-	rc = spm_response_get(client_id, service_handle, token,
-			      &rx1, &rx2, &rx3);
-	if (rc != 0) {
-		SMC_RET1(handle, SPCI_QUEUED);
-	}
-
-	/* Decrease request count */
-	spin_lock(&spci_handles_lock);
-	handle_info->num_active_requests -= 1;
-	spin_unlock(&spci_handles_lock);
-	spm_sp_request_decrease(sp_ctx);
-
-	/* Return response */
-	SMC_RET4(handle, SPCI_SUCCESS, rx1, rx2, rx3);
-}
-
-/*******************************************************************************
- * This function returns the response of a Secure Service given a handle, a
- * client ID and a token.
- ******************************************************************************/
-static uint64_t spci_service_get_response(void *handle, u_register_t x1,
-					    u_register_t x7)
-
-{
-	int rc;
-	u_register_t rx1 = 0, rx2 = 0, rx3 = 0;
-	spci_handle_t *handle_info;
-	uint32_t token = (uint32_t) x1;
-	uint16_t client_id = x7 & 0x0000FFFF;
-	uint16_t service_handle = (x7 >> 16) & 0x0000FFFF;
-
-	/* Get pointer to struct of this open handle and client ID. */
-
-	spin_lock(&spci_handles_lock);
-
-	handle_info = spci_handle_info_get(service_handle, client_id);
-	if (handle_info == NULL) {
-		spin_unlock(&spci_handles_lock);
-		WARN("SPCI_SERVICE_GET_RESPONSE: Not found.\n"
-		     "Handle 0x%04x. Client ID 0x%04x, Token 0x%08x.\n",
-		     client_id, service_handle, token);
-
-		SMC_RET1(handle, SPCI_INVALID_PARAMETER);
-	}
-
-	spin_unlock(&spci_handles_lock);
-
-	/* Look for a valid response in the global queue */
-	rc = spm_response_get(client_id, service_handle, token,
-			      &rx1, &rx2, &rx3);
-
-	if (rc != 0) {
-		SMC_RET1(handle, SPCI_QUEUED);
-	}
-
-	/* Decrease request count */
-	spin_lock(&spci_handles_lock);
-	handle_info->num_active_requests -= 1;
-	sp_context_t *sp_ctx;
-	sp_ctx = handle_info->sp_ctx;
-	spin_unlock(&spci_handles_lock);
-	spm_sp_request_decrease(sp_ctx);
-
-	/* Return response */
-	SMC_RET4(handle, SPCI_SUCCESS, rx1, rx2, rx3);
-}
-
-/*******************************************************************************
- * This function handles all SMCs in the range reserved for SPCI.
- ******************************************************************************/
-static uintptr_t spci_smc_handler(uint32_t smc_fid, u_register_t x1,
-				  u_register_t x2, u_register_t x3,
-				  u_register_t x4, void *cookie, void *handle,
-				  u_register_t flags)
-{
-	uint32_t spci_fid;
-
-	/* SPCI only supported from the Non-secure world for now */
-	if (is_caller_non_secure(flags) == SMC_FROM_SECURE) {
-		SMC_RET1(handle, SMC_UNK);
-	}
-
-	if ((smc_fid & SPCI_FID_TUN_FLAG) == 0) {
-
-		/* Miscellaneous calls */
-
-		spci_fid = (smc_fid >> SPCI_FID_MISC_SHIFT) & SPCI_FID_MISC_MASK;
-
-		switch (spci_fid) {
-
-		case SPCI_FID_VERSION:
-			SMC_RET1(handle, SPCI_VERSION_COMPILED);
-
-		case SPCI_FID_SERVICE_HANDLE_OPEN:
-		{
-			if ((smc_fid & SPCI_SERVICE_HANDLE_OPEN_NOTIFY_BIT) != 0) {
-				/* Not supported for now */
-				WARN("SPCI_SERVICE_HANDLE_OPEN_NOTIFY not supported.\n");
-				SMC_RET1(handle, SPCI_INVALID_PARAMETER);
-			}
-
-			uint64_t x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
-			uint64_t x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
-			uint64_t x7 = SMC_GET_GP(handle, CTX_GPREG_X7);
-
-			return spci_service_handle_open_poll(handle, x1, x2, x3,
-							     x4, x5, x6, x7);
-		}
-		case SPCI_FID_SERVICE_HANDLE_CLOSE:
-			return spci_service_handle_close(handle, x1);
-
-		case SPCI_FID_SERVICE_REQUEST_BLOCKING:
-		{
-			uint64_t x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
-			uint64_t x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
-			uint64_t x7 = SMC_GET_GP(handle, CTX_GPREG_X7);
-
-			return spci_service_request_blocking(handle,
-					smc_fid, x1, x2, x3, x4, x5, x6, x7);
-		}
-
-		case SPCI_FID_SERVICE_REQUEST_START:
-		{
-			uint64_t x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
-			uint64_t x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
-			uint64_t x7 = SMC_GET_GP(handle, CTX_GPREG_X7);
-
-			return spci_service_request_start(handle,
-					smc_fid, x1, x2, x3, x4, x5, x6, x7);
-		}
-
-		case SPCI_FID_SERVICE_GET_RESPONSE:
-		{
-			uint64_t x7 = SMC_GET_GP(handle, CTX_GPREG_X7);
-
-			return spci_service_get_response(handle, x1, x7);
-		}
-
-		default:
-			break;
-		}
-
-	} else {
-
-		/* Tunneled calls */
-
-		spci_fid = (smc_fid >> SPCI_FID_TUN_SHIFT) & SPCI_FID_TUN_MASK;
-
-		switch (spci_fid) {
-
-		case SPCI_FID_SERVICE_REQUEST_RESUME:
-		{
-			uint64_t x7 = SMC_GET_GP(handle, CTX_GPREG_X7);
-
-			return spci_service_request_resume(handle, x1, x7);
-		}
-
-		default:
-			break;
-		}
-	}
-
-	WARN("SPCI: Unsupported call 0x%08x\n", smc_fid);
-	SMC_RET1(handle, SPCI_NOT_SUPPORTED);
-}
-
-DECLARE_RT_SVC(
-	spci_handler,
-	OEN_SPCI_START,
-	OEN_SPCI_END,
-	SMC_TYPE_FAST,
-	NULL,
-	spci_smc_handler
-);
diff --git a/services/std_svc/spm/spm.mk b/services/std_svc/spm/spm.mk
deleted file mode 100644
index 448aba4..0000000
--- a/services/std_svc/spm/spm.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-ifneq (${SPD},none)
-        $(error "Error: SPD and SPM are incompatible build options.")
-endif
-ifneq (${ARCH},aarch64)
-        $(error "Error: SPM is only supported on aarch64.")
-endif
-
-include lib/sprt/sprt_host.mk
-
-SPM_SOURCES	:=	$(addprefix services/std_svc/spm/,	\
-			${ARCH}/spm_helpers.S			\
-			${ARCH}/spm_shim_exceptions.S		\
-			spci.c					\
-			spm_buffers.c				\
-			spm_main.c				\
-			spm_setup.c				\
-			spm_xlat.c				\
-			sprt.c)					\
-			${SPRT_LIB_SOURCES}
-
-INCLUDES	+=	${SPRT_LIB_INCLUDES}
-
-# Let the top-level Makefile know that we intend to include a BL32 image
-NEED_BL32		:=	yes
diff --git a/services/std_svc/spm/spm_buffers.c b/services/std_svc/spm/spm_buffers.c
deleted file mode 100644
index 79398ba..0000000
--- a/services/std_svc/spm/spm_buffers.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch_helpers.h>
-#include <lib/spinlock.h>
-#include <lib/utils_def.h>
-#include <platform_def.h>
-
-#include "./spm_private.h"
-
-/*******************************************************************************
- * Secure Service response global array. All the responses to the requests done
- * to the Secure Partition are stored here. They are removed from the array as
- * soon as their value is read.
- ******************************************************************************/
-struct sprt_response {
-	int is_valid;
-	uint32_t token;
-	uint16_t client_id, handle;
-	u_register_t x1, x2, x3;
-};
-
-static struct sprt_response responses[PLAT_SPM_RESPONSES_MAX];
-
-static spinlock_t responses_lock;
-
-/* Add response to the global response buffer. Returns 0 on success else -1. */
-int spm_response_add(uint16_t client_id, uint16_t handle, uint32_t token,
-		     u_register_t x1, u_register_t x2, u_register_t x3)
-{
-	spin_lock(&responses_lock);
-
-	/* Make sure that there isn't any other response with the same token. */
-	for (unsigned int i = 0U; i < ARRAY_SIZE(responses); i++) {
-		struct sprt_response *resp = &(responses[i]);
-
-		if ((resp->is_valid == 1) && (resp->token == token)) {
-			spin_unlock(&responses_lock);
-
-			return -1;
-		}
-	}
-
-	for (unsigned int i = 0U; i < ARRAY_SIZE(responses); i++) {
-		struct sprt_response *resp = &(responses[i]);
-
-		if (resp->is_valid == 0) {
-			resp->token = token;
-			resp->client_id = client_id;
-			resp->handle = handle;
-			resp->x1 = x1;
-			resp->x2 = x2;
-			resp->x3 = x3;
-
-			dmbish();
-
-			resp->is_valid = 1;
-
-			spin_unlock(&responses_lock);
-
-			return 0;
-		}
-	}
-
-	spin_unlock(&responses_lock);
-
-	return -1;
-}
-
-/*
- * Returns a response from the requests array and removes it from it. Returns 0
- * on success, -1 if it wasn't found.
- */
-int spm_response_get(uint16_t client_id, uint16_t handle, uint32_t token,
-		     u_register_t *x1, u_register_t *x2, u_register_t *x3)
-{
-	spin_lock(&responses_lock);
-
-	for (unsigned int i = 0U; i < ARRAY_SIZE(responses); i++) {
-		struct sprt_response *resp = &(responses[i]);
-
-		/* Ignore invalid entries */
-		if (resp->is_valid == 0) {
-			continue;
-		}
-
-		/* Make sure that all the information matches the stored one */
-		if ((resp->token != token) || (resp->client_id != client_id) ||
-		    (resp->handle != handle)) {
-			continue;
-		}
-
-		*x1 = resp->x1;
-		*x2 = resp->x2;
-		*x3 = resp->x3;
-
-		dmbish();
-
-		resp->is_valid = 0;
-
-		spin_unlock(&responses_lock);
-
-		return 0;
-	}
-
-	spin_unlock(&responses_lock);
-
-	return -1;
-}
diff --git a/services/std_svc/spm/spm_main.c b/services/std_svc/spm/spm_main.c
deleted file mode 100644
index 3a63f1c..0000000
--- a/services/std_svc/spm/spm_main.c
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <string.h>
-
-#include <arch_helpers.h>
-#include <bl31/bl31.h>
-#include <bl31/ehf.h>
-#include <bl31/interrupt_mgmt.h>
-#include <common/debug.h>
-#include <common/runtime_svc.h>
-#include <lib/el3_runtime/context_mgmt.h>
-#include <lib/smccc.h>
-#include <lib/spinlock.h>
-#include <lib/utils.h>
-#include <lib/xlat_tables/xlat_tables_v2.h>
-#include <plat/common/platform.h>
-#include <services/spm_svc.h>
-#include <services/sprt_svc.h>
-#include <smccc_helpers.h>
-
-#include "spm_private.h"
-
-/*******************************************************************************
- * Secure Partition context information.
- ******************************************************************************/
-sp_context_t sp_ctx_array[PLAT_SPM_MAX_PARTITIONS];
-
-/* Last Secure Partition last used by the CPU */
-sp_context_t *cpu_sp_ctx[PLATFORM_CORE_COUNT];
-
-void spm_cpu_set_sp_ctx(unsigned int linear_id, sp_context_t *sp_ctx)
-{
-	assert(linear_id < PLATFORM_CORE_COUNT);
-
-	cpu_sp_ctx[linear_id] = sp_ctx;
-}
-
-sp_context_t *spm_cpu_get_sp_ctx(unsigned int linear_id)
-{
-	assert(linear_id < PLATFORM_CORE_COUNT);
-
-	return cpu_sp_ctx[linear_id];
-}
-
-/*******************************************************************************
- * Functions to keep track of how many requests a Secure Partition has received
- * and hasn't finished.
- ******************************************************************************/
-void spm_sp_request_increase(sp_context_t *sp_ctx)
-{
-	spin_lock(&(sp_ctx->request_count_lock));
-	sp_ctx->request_count++;
-	spin_unlock(&(sp_ctx->request_count_lock));
-}
-
-void spm_sp_request_decrease(sp_context_t *sp_ctx)
-{
-	spin_lock(&(sp_ctx->request_count_lock));
-	sp_ctx->request_count--;
-	spin_unlock(&(sp_ctx->request_count_lock));
-}
-
-/* Returns 0 if it was originally 0, -1 otherwise. */
-int spm_sp_request_increase_if_zero(sp_context_t *sp_ctx)
-{
-	int ret = -1;
-
-	spin_lock(&(sp_ctx->request_count_lock));
-	if (sp_ctx->request_count == 0U) {
-		sp_ctx->request_count++;
-		ret = 0U;
-	}
-	spin_unlock(&(sp_ctx->request_count_lock));
-
-	return ret;
-}
-
-/*******************************************************************************
- * This function returns a pointer to the context of the Secure Partition that
- * handles the service specified by an UUID. It returns NULL if the UUID wasn't
- * found.
- ******************************************************************************/
-sp_context_t *spm_sp_get_by_uuid(const uint32_t (*svc_uuid)[4])
-{
-	unsigned int i;
-
-	for (i = 0U; i < PLAT_SPM_MAX_PARTITIONS; i++) {
-
-		sp_context_t *sp_ctx = &sp_ctx_array[i];
-
-		if (sp_ctx->is_present == 0) {
-			continue;
-		}
-
-		struct sp_rd_sect_service *rdsvc;
-
-		for (rdsvc = sp_ctx->rd.service; rdsvc != NULL;
-		     rdsvc = rdsvc->next) {
-			uint32_t *rd_uuid = (uint32_t *)(rdsvc->uuid);
-
-			if (memcmp(rd_uuid, svc_uuid, sizeof(*svc_uuid)) == 0) {
-				return sp_ctx;
-			}
-		}
-	}
-
-	return NULL;
-}
-
-/*******************************************************************************
- * Set state of a Secure Partition context.
- ******************************************************************************/
-void sp_state_set(sp_context_t *sp_ptr, sp_state_t state)
-{
-	spin_lock(&(sp_ptr->state_lock));
-	sp_ptr->state = state;
-	spin_unlock(&(sp_ptr->state_lock));
-}
-
-/*******************************************************************************
- * Wait until the state of a Secure Partition is the specified one and change it
- * to the desired state.
- ******************************************************************************/
-void sp_state_wait_switch(sp_context_t *sp_ptr, sp_state_t from, sp_state_t to)
-{
-	int success = 0;
-
-	while (success == 0) {
-		spin_lock(&(sp_ptr->state_lock));
-
-		if (sp_ptr->state == from) {
-			sp_ptr->state = to;
-
-			success = 1;
-		}
-
-		spin_unlock(&(sp_ptr->state_lock));
-	}
-}
-
-/*******************************************************************************
- * Check if the state of a Secure Partition is the specified one and, if so,
- * change it to the desired state. Returns 0 on success, -1 on error.
- ******************************************************************************/
-int sp_state_try_switch(sp_context_t *sp_ptr, sp_state_t from, sp_state_t to)
-{
-	int ret = -1;
-
-	spin_lock(&(sp_ptr->state_lock));
-
-	if (sp_ptr->state == from) {
-		sp_ptr->state = to;
-
-		ret = 0;
-	}
-
-	spin_unlock(&(sp_ptr->state_lock));
-
-	return ret;
-}
-
-/*******************************************************************************
- * This function takes an SP context pointer and performs a synchronous entry
- * into it.
- ******************************************************************************/
-uint64_t spm_sp_synchronous_entry(sp_context_t *sp_ctx, int can_preempt)
-{
-	uint64_t rc;
-	unsigned int linear_id = plat_my_core_pos();
-
-	assert(sp_ctx != NULL);
-
-	/* Assign the context of the SP to this CPU */
-	spm_cpu_set_sp_ctx(linear_id, sp_ctx);
-	cm_set_context(&(sp_ctx->cpu_ctx), SECURE);
-
-	/* Restore the context assigned above */
-	cm_el1_sysregs_context_restore(SECURE);
-	cm_set_next_eret_context(SECURE);
-
-	/* Invalidate TLBs at EL1. */
-	tlbivmalle1();
-	dsbish();
-
-	if (can_preempt == 1) {
-		enable_intr_rm_local(INTR_TYPE_NS, SECURE);
-	} else {
-		disable_intr_rm_local(INTR_TYPE_NS, SECURE);
-	}
-
-	/* Enter Secure Partition */
-	rc = spm_secure_partition_enter(&sp_ctx->c_rt_ctx);
-
-	/* Save secure state */
-	cm_el1_sysregs_context_save(SECURE);
-
-	return rc;
-}
-
-/*******************************************************************************
- * This function returns to the place where spm_sp_synchronous_entry() was
- * called originally.
- ******************************************************************************/
-__dead2 void spm_sp_synchronous_exit(uint64_t rc)
-{
-	/* Get context of the SP in use by this CPU. */
-	unsigned int linear_id = plat_my_core_pos();
-	sp_context_t *ctx = spm_cpu_get_sp_ctx(linear_id);
-
-	/*
-	 * The SPM must have initiated the original request through a
-	 * synchronous entry into the secure partition. Jump back to the
-	 * original C runtime context with the value of rc in x0;
-	 */
-	spm_secure_partition_exit(ctx->c_rt_ctx, rc);
-
-	panic();
-}
-
-/*******************************************************************************
- * This function is the handler registered for Non secure interrupts by the SPM.
- * It validates the interrupt and upon success arranges entry into the normal
- * world for handling the interrupt.
- ******************************************************************************/
-static uint64_t spm_ns_interrupt_handler(uint32_t id, uint32_t flags,
-					  void *handle, void *cookie)
-{
-	/* Check the security state when the exception was generated */
-	assert(get_interrupt_src_ss(flags) == SECURE);
-
-	spm_sp_synchronous_exit(SPM_SECURE_PARTITION_PREEMPTED);
-}
-
-/*******************************************************************************
- * Jump to each Secure Partition for the first time.
- ******************************************************************************/
-static int32_t spm_init(void)
-{
-	uint64_t rc = 0;
-	sp_context_t *ctx;
-
-	for (unsigned int i = 0U; i < PLAT_SPM_MAX_PARTITIONS; i++) {
-
-		ctx = &sp_ctx_array[i];
-
-		if (ctx->is_present == 0) {
-			continue;
-		}
-
-		INFO("Secure Partition %u init...\n", i);
-
-		ctx->state = SP_STATE_RESET;
-
-		rc = spm_sp_synchronous_entry(ctx, 0);
-		if (rc != SPRT_YIELD_AARCH64) {
-			ERROR("Unexpected return value 0x%llx\n", rc);
-			panic();
-		}
-
-		ctx->state = SP_STATE_IDLE;
-
-		INFO("Secure Partition %u initialized.\n", i);
-	}
-
-	return rc;
-}
-
-/*******************************************************************************
- * Initialize contexts of all Secure Partitions.
- ******************************************************************************/
-int32_t spm_setup(void)
-{
-	int rc;
-	sp_context_t *ctx;
-	void *sp_base, *rd_base;
-	size_t sp_size, rd_size;
-	uint64_t flags = 0U;
-
-	/* Disable MMU at EL1 (initialized by BL2) */
-	disable_mmu_icache_el1();
-
-	/*
-	 * Non-blocking services can be interrupted by Non-secure interrupts.
-	 * Register an interrupt handler for NS interrupts when generated while
-	 * the CPU is in secure state. They are routed to EL3.
-	 */
-	set_interrupt_rm_flag(flags, SECURE);
-
-	uint64_t rc_int = register_interrupt_type_handler(INTR_TYPE_NS,
-				spm_ns_interrupt_handler, flags);
-	if (rc_int) {
-		ERROR("SPM: Failed to register NS interrupt handler with rc = %llx\n",
-		      rc_int);
-		panic();
-	}
-
-	/* Setup shim layer */
-	spm_exceptions_xlat_init_context();
-
-	/*
-	 * Setup all Secure Partitions.
-	 */
-	unsigned int i = 0U;
-
-	while (1) {
-		rc = plat_spm_sp_get_next_address(&sp_base, &sp_size,
-						&rd_base, &rd_size);
-		if (rc < 0) {
-			/* Reached the end of the package. */
-			break;
-		}
-
-		if (i >= PLAT_SPM_MAX_PARTITIONS) {
-			ERROR("Too many partitions in the package.\n");
-			panic();
-		}
-
-		ctx = &sp_ctx_array[i];
-
-		assert(ctx->is_present == 0);
-
-		/* Initialize context of the SP */
-		INFO("Secure Partition %u context setup start...\n", i);
-
-		/* Save location of the image in physical memory */
-		ctx->image_base = (uintptr_t)sp_base;
-		ctx->image_size = sp_size;
-
-		rc = plat_spm_sp_rd_load(&ctx->rd, rd_base, rd_size);
-		if (rc < 0) {
-			ERROR("Error while loading RD blob.\n");
-			panic();
-		}
-
-		spm_sp_setup(ctx);
-
-		ctx->is_present = 1;
-
-		INFO("Secure Partition %u setup done.\n", i);
-
-		i++;
-	}
-
-	if (i == 0U) {
-		ERROR("No present partitions in the package.\n");
-		panic();
-	}
-
-	/* Register init function for deferred init.  */
-	bl31_register_bl32_init(&spm_init);
-
-	return 0;
-}
diff --git a/services/std_svc/spm/spm_private.h b/services/std_svc/spm/spm_private.h
deleted file mode 100644
index efc91cb..0000000
--- a/services/std_svc/spm/spm_private.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPM_PRIVATE_H
-#define SPM_PRIVATE_H
-
-#include <context.h>
-
-/*******************************************************************************
- * Constants that allow assembler code to preserve callee-saved registers of the
- * C runtime context while performing a security state switch.
- ******************************************************************************/
-#define SP_C_RT_CTX_X19		0x0
-#define SP_C_RT_CTX_X20		0x8
-#define SP_C_RT_CTX_X21		0x10
-#define SP_C_RT_CTX_X22		0x18
-#define SP_C_RT_CTX_X23		0x20
-#define SP_C_RT_CTX_X24		0x28
-#define SP_C_RT_CTX_X25		0x30
-#define SP_C_RT_CTX_X26		0x38
-#define SP_C_RT_CTX_X27		0x40
-#define SP_C_RT_CTX_X28		0x48
-#define SP_C_RT_CTX_X29		0x50
-#define SP_C_RT_CTX_X30		0x58
-
-#define SP_C_RT_CTX_SIZE	0x60
-#define SP_C_RT_CTX_ENTRIES	(SP_C_RT_CTX_SIZE >> DWORD_SHIFT)
-
-/* Value returned by spm_sp_synchronous_entry() when a partition is preempted */
-#define SPM_SECURE_PARTITION_PREEMPTED	U(0x1234)
-
-#ifndef __ASSEMBLER__
-
-#include <stdint.h>
-
-#include <lib/xlat_tables/xlat_tables_v2.h>
-#include <lib/spinlock.h>
-#include <services/sp_res_desc.h>
-
-typedef enum sp_state {
-	SP_STATE_RESET = 0,
-	SP_STATE_IDLE,
-	SP_STATE_BUSY
-} sp_state_t;
-
-typedef struct sp_context {
-	/* 1 if the partition is present, 0 otherwise */
-	int is_present;
-
-	/* Location of the image in physical memory */
-	unsigned long long image_base;
-	size_t image_size;
-
-	uint64_t c_rt_ctx;
-	cpu_context_t cpu_ctx;
-	struct sp_res_desc rd;
-
-	/* Translation tables context */
-	xlat_ctx_t *xlat_ctx_handle;
-	spinlock_t xlat_ctx_lock;
-
-	sp_state_t state;
-	spinlock_t state_lock;
-
-	unsigned int request_count;
-	spinlock_t request_count_lock;
-
-	/* Base and size of the shared SPM<->SP buffer */
-	uintptr_t spm_sp_buffer_base;
-	size_t spm_sp_buffer_size;
-	spinlock_t spm_sp_buffer_lock;
-} sp_context_t;
-
-/* Functions used to enter/exit a Secure Partition synchronously */
-uint64_t spm_sp_synchronous_entry(sp_context_t *sp_ctx, int can_preempt);
-__dead2 void spm_sp_synchronous_exit(uint64_t rc);
-
-/* Assembly helpers */
-uint64_t spm_secure_partition_enter(uint64_t *c_rt_ctx);
-void __dead2 spm_secure_partition_exit(uint64_t c_rt_ctx, uint64_t ret);
-
-/* Secure Partition setup */
-void spm_sp_setup(sp_context_t *sp_ctx);
-
-/* Secure Partition state management helpers */
-void sp_state_set(sp_context_t *sp_ptr, sp_state_t state);
-void sp_state_wait_switch(sp_context_t *sp_ptr, sp_state_t from, sp_state_t to);
-int sp_state_try_switch(sp_context_t *sp_ptr, sp_state_t from, sp_state_t to);
-
-/* Functions to keep track of the number of active requests per SP */
-void spm_sp_request_increase(sp_context_t *sp_ctx);
-void spm_sp_request_decrease(sp_context_t *sp_ctx);
-int spm_sp_request_increase_if_zero(sp_context_t *sp_ctx);
-
-/* Functions related to the shim layer translation tables */
-void spm_exceptions_xlat_init_context(void);
-uint64_t *spm_exceptions_xlat_get_base_table(void);
-
-/* Functions related to the translation tables management */
-void spm_sp_xlat_context_alloc(sp_context_t *sp_ctx);
-void sp_map_memory_regions(sp_context_t *sp_ctx);
-
-/* Functions to handle Secure Partition contexts */
-void spm_cpu_set_sp_ctx(unsigned int linear_id, sp_context_t *sp_ctx);
-sp_context_t *spm_cpu_get_sp_ctx(unsigned int linear_id);
-sp_context_t *spm_sp_get_by_uuid(const uint32_t (*svc_uuid)[4]);
-
-/* Functions to manipulate response and requests buffers */
-int spm_response_add(uint16_t client_id, uint16_t handle, uint32_t token,
-		     u_register_t x1, u_register_t x2, u_register_t x3);
-int spm_response_get(uint16_t client_id, uint16_t handle, uint32_t token,
-		     u_register_t *x1, u_register_t *x2, u_register_t *x3);
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* SPM_PRIVATE_H */
diff --git a/services/std_svc/spm/spm_setup.c b/services/std_svc/spm/spm_setup.c
deleted file mode 100644
index 2ed44d1..0000000
--- a/services/std_svc/spm/spm_setup.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include <platform_def.h>
-
-#include <arch.h>
-#include <arch_helpers.h>
-#include <context.h>
-#include <common/debug.h>
-#include <lib/el3_runtime/context_mgmt.h>
-#include <lib/xlat_tables/xlat_tables_v2.h>
-#include <plat/common/common_def.h>
-#include <plat/common/platform.h>
-#include <services/sp_res_desc.h>
-#include <sprt_host.h>
-
-#include "spm_private.h"
-#include "spm_shim_private.h"
-
-/* Setup context of the Secure Partition */
-void spm_sp_setup(sp_context_t *sp_ctx)
-{
-	cpu_context_t *ctx = &(sp_ctx->cpu_ctx);
-
-	/*
-	 * Initialize CPU context
-	 * ----------------------
-	 */
-
-	entry_point_info_t ep_info = {0};
-
-	SET_PARAM_HEAD(&ep_info, PARAM_EP, VERSION_1, SECURE | EP_ST_ENABLE);
-
-	/* Setup entrypoint and SPSR */
-	ep_info.pc = sp_ctx->rd.attribute.entrypoint;
-	ep_info.spsr = SPSR_64(MODE_EL0, MODE_SP_EL0, DISABLE_ALL_EXCEPTIONS);
-
-	/*
-	 * X0: Unused (MBZ).
-	 * X1: Unused (MBZ).
-	 * X2: cookie value (Implementation Defined)
-	 * X3: cookie value (Implementation Defined)
-	 * X4 to X7 = 0
-	 */
-	ep_info.args.arg0 = 0;
-	ep_info.args.arg1 = 0;
-	ep_info.args.arg2 = PLAT_SPM_COOKIE_0;
-	ep_info.args.arg3 = PLAT_SPM_COOKIE_1;
-
-	cm_setup_context(ctx, &ep_info);
-
-	/*
-	 * Setup translation tables
-	 * ------------------------
-	 */
-
-	/* Assign translation tables context. */
-	spm_sp_xlat_context_alloc(sp_ctx);
-
-	sp_map_memory_regions(sp_ctx);
-
-	/*
-	 * MMU-related registers
-	 * ---------------------
-	 */
-	xlat_ctx_t *xlat_ctx = sp_ctx->xlat_ctx_handle;
-
-	uint64_t mmu_cfg_params[MMU_CFG_PARAM_MAX];
-
-	setup_mmu_cfg((uint64_t *)&mmu_cfg_params, 0, xlat_ctx->base_table,
-		      xlat_ctx->pa_max_address, xlat_ctx->va_max_address,
-		      EL1_EL0_REGIME);
-
-	write_ctx_reg(get_sysregs_ctx(ctx), CTX_MAIR_EL1,
-		      mmu_cfg_params[MMU_CFG_MAIR]);
-
-	/* Enable translations using TTBR1_EL1 */
-	int t1sz = 64 - __builtin_ctzll(SPM_SHIM_XLAT_VIRT_ADDR_SPACE_SIZE);
-	mmu_cfg_params[MMU_CFG_TCR] &= ~TCR_EPD1_BIT;
-	mmu_cfg_params[MMU_CFG_TCR] |=
-		((uint64_t)t1sz << TCR_T1SZ_SHIFT) |
-		TCR_SH1_INNER_SHAREABLE |
-		TCR_RGN1_OUTER_WBA | TCR_RGN1_INNER_WBA |
-		TCR_TG1_4K;
-
-	write_ctx_reg(get_sysregs_ctx(ctx), CTX_TCR_EL1,
-		      mmu_cfg_params[MMU_CFG_TCR]);
-
-	write_ctx_reg(get_sysregs_ctx(ctx), CTX_TTBR0_EL1,
-		      mmu_cfg_params[MMU_CFG_TTBR0]);
-
-	write_ctx_reg(get_sysregs_ctx(ctx), CTX_TTBR1_EL1,
-		      (uint64_t)spm_exceptions_xlat_get_base_table());
-
-	/* Setup SCTLR_EL1 */
-	u_register_t sctlr_el1 = read_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1);
-
-	sctlr_el1 |=
-		/*SCTLR_EL1_RES1 |*/
-		/* Don't trap DC CVAU, DC CIVAC, DC CVAC, DC CVAP, or IC IVAU */
-		SCTLR_UCI_BIT							|
-		/* RW regions at xlat regime EL1&0 are forced to be XN. */
-		SCTLR_WXN_BIT							|
-		/* Don't trap to EL1 execution of WFI or WFE at EL0. */
-		SCTLR_NTWI_BIT | SCTLR_NTWE_BIT					|
-		/* Don't trap to EL1 accesses to CTR_EL0 from EL0. */
-		SCTLR_UCT_BIT							|
-		/* Don't trap to EL1 execution of DZ ZVA at EL0. */
-		SCTLR_DZE_BIT							|
-		/* Enable SP Alignment check for EL0 */
-		SCTLR_SA0_BIT							|
-		/* Allow cacheable data and instr. accesses to normal memory. */
-		SCTLR_C_BIT | SCTLR_I_BIT					|
-		/* Alignment fault checking enabled when at EL1 and EL0. */
-		SCTLR_A_BIT							|
-		/* Enable MMU. */
-		SCTLR_M_BIT
-	;
-
-	sctlr_el1 &= ~(
-		/* Explicit data accesses at EL0 are little-endian. */
-		SCTLR_E0E_BIT							|
-		/* Accesses to DAIF from EL0 are trapped to EL1. */
-		SCTLR_UMA_BIT
-	);
-
-	write_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_el1);
-
-	/*
-	 * Setup other system registers
-	 * ----------------------------
-	 */
-
-	/*
-	 * Shim exception vector base address. It is mapped at the start of the
-	 * address space accessed by TTBR1_EL1, which means that the base
-	 * address of the exception vectors depends on the size of the address
-	 * space specified in TCR_EL1.T1SZ.
-	 */
-	write_ctx_reg(get_sysregs_ctx(ctx), CTX_VBAR_EL1,
-		      UINT64_MAX - (SPM_SHIM_XLAT_VIRT_ADDR_SPACE_SIZE - 1ULL));
-
-	/*
-	 * FPEN: Allow the Secure Partition to access FP/SIMD registers.
-	 * Note that SPM will not do any saving/restoring of these registers on
-	 * behalf of the SP. This falls under the SP's responsibility.
-	 * TTA: Enable access to trace registers.
-	 * ZEN (v8.2): Trap SVE instructions and access to SVE registers.
-	 */
-	write_ctx_reg(get_sysregs_ctx(ctx), CTX_CPACR_EL1,
-			CPACR_EL1_FPEN(CPACR_EL1_FP_TRAP_NONE));
-
-	/*
-	 * Prepare shared buffers
-	 * ----------------------
-	 */
-
-	/* Initialize SPRT queues */
-	sprt_initialize_queues((void *)sp_ctx->spm_sp_buffer_base,
-			       sp_ctx->spm_sp_buffer_size);
-}
diff --git a/services/std_svc/spm/spm_shim_private.h b/services/std_svc/spm/spm_shim_private.h
deleted file mode 100644
index fc510b1..0000000
--- a/services/std_svc/spm/spm_shim_private.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPM_SHIM_PRIVATE_H
-#define SPM_SHIM_PRIVATE_H
-
-#include <stdint.h>
-
-#include <lib/utils_def.h>
-
-/* Assembly source */
-IMPORT_SYM(uintptr_t, spm_shim_exceptions_ptr,		SPM_SHIM_EXCEPTIONS_PTR);
-
-/* Linker symbols */
-IMPORT_SYM(uintptr_t, __SPM_SHIM_EXCEPTIONS_START__,	SPM_SHIM_EXCEPTIONS_START);
-IMPORT_SYM(uintptr_t, __SPM_SHIM_EXCEPTIONS_END__,	SPM_SHIM_EXCEPTIONS_END);
-
-/* Definitions */
-
-#define SPM_SHIM_EXCEPTIONS_SIZE	\
-	(SPM_SHIM_EXCEPTIONS_END - SPM_SHIM_EXCEPTIONS_START)
-
-/*
- * Use the smallest virtual address space size allowed in ARMv8.0 for
- * compatibility.
- */
-#define SPM_SHIM_XLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 25)
-#define SPM_SHIM_MMAP_REGIONS	1
-#define SPM_SHIM_XLAT_TABLES	1
-
-#endif /* SPM_SHIM_PRIVATE_H */
diff --git a/services/std_svc/spm/spm_xlat.c b/services/std_svc/spm/spm_xlat.c
deleted file mode 100644
index 5d5bc51..0000000
--- a/services/std_svc/spm/spm_xlat.c
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <arch_features.h>
-#include <arch_helpers.h>
-#include <assert.h>
-#include <errno.h>
-#include <string.h>
-
-#include <platform_def.h>
-
-#include <lib/object_pool.h>
-#include <lib/utils.h>
-#include <lib/utils_def.h>
-#include <lib/xlat_tables/xlat_tables_v2.h>
-#include <plat/common/platform.h>
-#include <services/sp_res_desc.h>
-
-#include "spm_private.h"
-#include "spm_shim_private.h"
-
-/*******************************************************************************
- * Instantiation of translation table context
- ******************************************************************************/
-
-/* Place translation tables by default along with the ones used by BL31. */
-#ifndef PLAT_SP_IMAGE_XLAT_SECTION_NAME
-#define PLAT_SP_IMAGE_XLAT_SECTION_NAME	"xlat_table"
-#endif
-
-/*
- * Allocate elements of the translation contexts for the Secure Partitions.
- */
-
-/* Allocate an array of mmap_region per partition. */
-static struct mmap_region sp_mmap_regions[PLAT_SP_IMAGE_MMAP_REGIONS + 1]
-	[PLAT_SPM_MAX_PARTITIONS];
-static OBJECT_POOL(sp_mmap_regions_pool, sp_mmap_regions,
-	sizeof(mmap_region_t) * (PLAT_SP_IMAGE_MMAP_REGIONS + 1),
-	PLAT_SPM_MAX_PARTITIONS);
-
-/* Allocate individual translation tables. */
-static uint64_t sp_xlat_tables[XLAT_TABLE_ENTRIES]
-	[(PLAT_SP_IMAGE_MAX_XLAT_TABLES + 1) * PLAT_SPM_MAX_PARTITIONS]
-	__aligned(XLAT_TABLE_SIZE) __section(PLAT_SP_IMAGE_XLAT_SECTION_NAME);
-static OBJECT_POOL(sp_xlat_tables_pool, sp_xlat_tables,
-	XLAT_TABLE_ENTRIES * sizeof(uint64_t),
-	(PLAT_SP_IMAGE_MAX_XLAT_TABLES + 1) * PLAT_SPM_MAX_PARTITIONS);
-
-/* Allocate arrays. */
-static int sp_xlat_mapped_regions[PLAT_SP_IMAGE_MAX_XLAT_TABLES]
-	[PLAT_SPM_MAX_PARTITIONS];
-static OBJECT_POOL(sp_xlat_mapped_regions_pool, sp_xlat_mapped_regions,
-	sizeof(int) * PLAT_SP_IMAGE_MAX_XLAT_TABLES, PLAT_SPM_MAX_PARTITIONS);
-
-/* Allocate individual contexts. */
-static xlat_ctx_t sp_xlat_ctx[PLAT_SPM_MAX_PARTITIONS];
-static OBJECT_POOL(sp_xlat_ctx_pool, sp_xlat_ctx, sizeof(xlat_ctx_t),
-	PLAT_SPM_MAX_PARTITIONS);
-
-/* Get handle of Secure Partition translation context */
-void spm_sp_xlat_context_alloc(sp_context_t *sp_ctx)
-{
-	/* Allocate xlat context elements */
-
-	xlat_ctx_t *ctx = pool_alloc(&sp_xlat_ctx_pool);
-
-	struct mmap_region *mmap = pool_alloc(&sp_mmap_regions_pool);
-
-	uint64_t *base_table = pool_alloc(&sp_xlat_tables_pool);
-	uint64_t **tables = pool_alloc_n(&sp_xlat_tables_pool,
-					PLAT_SP_IMAGE_MAX_XLAT_TABLES);
-
-	int *mapped_regions = pool_alloc(&sp_xlat_mapped_regions_pool);
-
-	/* Calculate the size of the virtual address space needed */
-
-	uintptr_t va_size = 0U;
-	struct sp_rd_sect_mem_region *rdmem;
-
-	for (rdmem = sp_ctx->rd.mem_region; rdmem != NULL; rdmem = rdmem->next) {
-		uintptr_t end_va = (uintptr_t)rdmem->base +
-				   (uintptr_t)rdmem->size;
-
-		if (end_va > va_size)
-			va_size = end_va;
-	}
-
-	if (va_size == 0U) {
-		ERROR("No regions in resource description.\n");
-		panic();
-	}
-
-	/*
-	 * Get the power of two that is greater or equal to the top VA. The
-	 * values of base and size in the resource description are 32-bit wide
-	 * so the values will never overflow when using a uintptr_t.
-	 */
-	if (!IS_POWER_OF_TWO(va_size)) {
-		va_size = 1ULL <<
-			((sizeof(va_size) * 8) - __builtin_clzll(va_size));
-	}
-
-	if (va_size > PLAT_VIRT_ADDR_SPACE_SIZE) {
-		ERROR("Resource description requested too much virtual memory.\n");
-		panic();
-	}
-
-	uintptr_t min_va_size;
-
-	/* The following sizes are only valid for 4KB pages */
-	assert(PAGE_SIZE == (4U * 1024U));
-
-	if (is_armv8_4_ttst_present()) {
-		VERBOSE("Using ARMv8.4-TTST\n");
-		min_va_size = 1ULL << (64 - TCR_TxSZ_MAX_TTST);
-	} else {
-		min_va_size = 1ULL << (64 - TCR_TxSZ_MAX);
-	}
-
-	if (va_size < min_va_size) {
-		va_size = min_va_size;
-	}
-
-	/* Initialize xlat context */
-
-	xlat_setup_dynamic_ctx(ctx, PLAT_PHY_ADDR_SPACE_SIZE - 1ULL,
-			       va_size - 1ULL, mmap,
-			       PLAT_SP_IMAGE_MMAP_REGIONS, tables,
-			       PLAT_SP_IMAGE_MAX_XLAT_TABLES, base_table,
-			       EL1_EL0_REGIME, mapped_regions);
-
-	sp_ctx->xlat_ctx_handle = ctx;
-};
-
-/*******************************************************************************
- * Translation table context used for S-EL1 exception vectors
- ******************************************************************************/
-
-REGISTER_XLAT_CONTEXT2(spm_sel1, SPM_SHIM_MMAP_REGIONS, SPM_SHIM_XLAT_TABLES,
-		SPM_SHIM_XLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE,
-		EL1_EL0_REGIME, PLAT_SP_IMAGE_XLAT_SECTION_NAME);
-
-void spm_exceptions_xlat_init_context(void)
-{
-	/* This region contains the exception vectors used at S-EL1. */
-	mmap_region_t sel1_exception_vectors =
-		MAP_REGION(SPM_SHIM_EXCEPTIONS_PTR,
-			   0x0UL,
-			   SPM_SHIM_EXCEPTIONS_SIZE,
-			   MT_CODE | MT_SECURE | MT_PRIVILEGED);
-
-	mmap_add_region_ctx(&spm_sel1_xlat_ctx,
-			    &sel1_exception_vectors);
-
-	init_xlat_tables_ctx(&spm_sel1_xlat_ctx);
-}
-
-uint64_t *spm_exceptions_xlat_get_base_table(void)
-{
-	return spm_sel1_xlat_ctx.base_table;
-}
-
-/*******************************************************************************
- * Functions to allocate memory for regions.
- ******************************************************************************/
-
-/*
- * The region with base PLAT_SPM_HEAP_BASE and size PLAT_SPM_HEAP_SIZE is
- * reserved for SPM to use as heap to allocate memory regions of Secure
- * Partitions. This is only done at boot.
- */
-static OBJECT_POOL(spm_heap_mem, (void *)PLAT_SPM_HEAP_BASE, 1U,
-		   PLAT_SPM_HEAP_SIZE);
-
-static uintptr_t spm_alloc_heap(size_t size)
-{
-	return (uintptr_t)pool_alloc_n(&spm_heap_mem, size);
-}
-
-/*******************************************************************************
- * Functions to map memory regions described in the resource description.
- ******************************************************************************/
-static unsigned int rdmem_attr_to_mmap_attr(uint32_t attr)
-{
-	unsigned int index = attr & RD_MEM_MASK;
-
-	const unsigned int mmap_attr_arr[8] = {
-		MT_DEVICE | MT_RW | MT_SECURE,	/* RD_MEM_DEVICE */
-		MT_CODE | MT_SECURE,		/* RD_MEM_NORMAL_CODE */
-		MT_MEMORY | MT_RW | MT_SECURE,	/* RD_MEM_NORMAL_DATA */
-		MT_MEMORY | MT_RW | MT_SECURE,	/* RD_MEM_NORMAL_BSS */
-		MT_RO_DATA | MT_SECURE,		/* RD_MEM_NORMAL_RODATA */
-		MT_MEMORY | MT_RW | MT_SECURE,	/* RD_MEM_NORMAL_SPM_SP_SHARED_MEM */
-		MT_MEMORY | MT_RW | MT_SECURE,	/* RD_MEM_NORMAL_CLIENT_SHARED_MEM */
-		MT_MEMORY | MT_RW | MT_SECURE	/* RD_MEM_NORMAL_MISCELLANEOUS */
-	};
-
-	if (index >= ARRAY_SIZE(mmap_attr_arr)) {
-		ERROR("Unsupported RD memory attributes 0x%x\n", attr);
-		panic();
-	}
-
-	return mmap_attr_arr[index];
-}
-
-/*
- * The data provided in the resource description structure is not directly
- * compatible with a mmap_region structure. This function handles the conversion
- * and maps it.
- */
-static void map_rdmem(sp_context_t *sp_ctx, struct sp_rd_sect_mem_region *rdmem)
-{
-	int rc;
-	mmap_region_t mmap;
-
-	/* Location of the SP image */
-	uintptr_t sp_size = sp_ctx->image_size;
-	uintptr_t sp_base_va = sp_ctx->rd.attribute.load_address;
-	unsigned long long sp_base_pa = sp_ctx->image_base;
-
-	/* Location of the memory region to map */
-	size_t rd_size = rdmem->size;
-	uintptr_t rd_base_va = rdmem->base;
-	unsigned long long rd_base_pa;
-
-	unsigned int memtype = rdmem->attr & RD_MEM_MASK;
-
-	if (rd_size == 0U) {
-		VERBOSE("Memory region '%s' is empty. Ignored.\n", rdmem->name);
-		return;
-	}
-
-	VERBOSE("Adding memory region '%s'\n", rdmem->name);
-
-	mmap.granularity = REGION_DEFAULT_GRANULARITY;
-
-	/* Check if the RD region is inside of the SP image or not */
-	int is_outside = (rd_base_va + rd_size <= sp_base_va) ||
-			 (sp_base_va + sp_size <= rd_base_va);
-
-	/* Set to 1 if it is needed to zero this region */
-	int zero_region = 0;
-
-	switch (memtype) {
-	case RD_MEM_DEVICE:
-		/* Device regions are mapped 1:1 */
-		rd_base_pa = rd_base_va;
-		break;
-
-	case RD_MEM_NORMAL_CODE:
-	case RD_MEM_NORMAL_RODATA:
-	{
-		if (is_outside == 1) {
-			ERROR("Code and rodata sections must be fully contained in the image.");
-			panic();
-		}
-
-		/* Get offset into the image */
-		rd_base_pa = sp_base_pa + rd_base_va - sp_base_va;
-		break;
-	}
-	case RD_MEM_NORMAL_DATA:
-	{
-		if (is_outside == 1) {
-			ERROR("Data sections must be fully contained in the image.");
-			panic();
-		}
-
-		rd_base_pa = spm_alloc_heap(rd_size);
-
-		/* Get offset into the image */
-		void *img_pa = (void *)(sp_base_pa + rd_base_va - sp_base_va);
-
-		VERBOSE("  Copying data from %p to 0x%llx\n", img_pa, rd_base_pa);
-
-		/* Map destination */
-		rc = mmap_add_dynamic_region(rd_base_pa, rd_base_pa,
-				rd_size, MT_MEMORY | MT_RW | MT_SECURE);
-		if (rc != 0) {
-			ERROR("Unable to map data region at EL3: %d\n", rc);
-			panic();
-		}
-
-		/* Copy original data to destination */
-		memcpy((void *)rd_base_pa, img_pa, rd_size);
-
-		/* Unmap destination region */
-		rc = mmap_remove_dynamic_region(rd_base_pa, rd_size);
-		if (rc != 0) {
-			ERROR("Unable to remove data region at EL3: %d\n", rc);
-			panic();
-		}
-
-		break;
-	}
-	case RD_MEM_NORMAL_MISCELLANEOUS:
-		/* Allow SPM to change the attributes of the region. */
-		mmap.granularity = PAGE_SIZE;
-		rd_base_pa = spm_alloc_heap(rd_size);
-		zero_region = 1;
-		break;
-
-	case RD_MEM_NORMAL_SPM_SP_SHARED_MEM:
-		if ((sp_ctx->spm_sp_buffer_base != 0) ||
-		    (sp_ctx->spm_sp_buffer_size != 0)) {
-			ERROR("A partition must have only one SPM<->SP buffer.\n");
-			panic();
-		}
-		rd_base_pa = spm_alloc_heap(rd_size);
-		zero_region = 1;
-		/* Save location of this buffer, it is needed by SPM */
-		sp_ctx->spm_sp_buffer_base = rd_base_pa;
-		sp_ctx->spm_sp_buffer_size = rd_size;
-		break;
-
-	case RD_MEM_NORMAL_CLIENT_SHARED_MEM:
-		/* Fallthrough */
-	case RD_MEM_NORMAL_BSS:
-		rd_base_pa = spm_alloc_heap(rd_size);
-		zero_region = 1;
-		break;
-
-	default:
-		panic();
-	}
-
-	mmap.base_pa = rd_base_pa;
-	mmap.base_va = rd_base_va;
-	mmap.size = rd_size;
-
-	/* Only S-EL0 mappings supported for now */
-	mmap.attr = rdmem_attr_to_mmap_attr(rdmem->attr) | MT_USER;
-
-	VERBOSE("  VA: 0x%lx PA: 0x%llx (0x%lx, attr: 0x%x)\n",
-		mmap.base_va, mmap.base_pa, mmap.size, mmap.attr);
-
-	/* Map region in the context of the Secure Partition */
-	mmap_add_region_ctx(sp_ctx->xlat_ctx_handle, &mmap);
-
-	if (zero_region == 1) {
-		VERBOSE("  Zeroing region...\n");
-
-		rc = mmap_add_dynamic_region(mmap.base_pa, mmap.base_pa,
-				mmap.size, MT_MEMORY | MT_RW | MT_SECURE);
-		if (rc != 0) {
-			ERROR("Unable to map memory at EL3 to zero: %d\n",
-			      rc);
-			panic();
-		}
-
-		zeromem((void *)mmap.base_pa, mmap.size);
-
-		/*
-		 * Unmap destination region unless it is the SPM<->SP buffer,
-		 * which must be used by SPM.
-		 */
-		if (memtype != RD_MEM_NORMAL_SPM_SP_SHARED_MEM) {
-			rc = mmap_remove_dynamic_region(rd_base_pa, rd_size);
-			if (rc != 0) {
-				ERROR("Unable to remove region at EL3: %d\n", rc);
-				panic();
-			}
-		}
-	}
-}
-
-void sp_map_memory_regions(sp_context_t *sp_ctx)
-{
-	struct sp_rd_sect_mem_region *rdmem;
-
-	for (rdmem = sp_ctx->rd.mem_region; rdmem != NULL; rdmem = rdmem->next) {
-		map_rdmem(sp_ctx, rdmem);
-	}
-
-	init_xlat_tables_ctx(sp_ctx->xlat_ctx_handle);
-}
diff --git a/services/std_svc/spm/sprt.c b/services/std_svc/spm/sprt.c
deleted file mode 100644
index 20ad2af..0000000
--- a/services/std_svc/spm/sprt.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <limits.h>
-
-#include <arch_helpers.h>
-#include <common/debug.h>
-#include <common/runtime_svc.h>
-#include <lib/el3_runtime/context_mgmt.h>
-#include <lib/smccc.h>
-#include <lib/utils.h>
-#include <plat/common/platform.h>
-#include <services/sprt_svc.h>
-#include <smccc_helpers.h>
-
-#include "spm_private.h"
-
-/*******************************************************************************
- * Functions to manipulate memory regions
- ******************************************************************************/
-
-/*
- * Attributes are encoded using a different format in the SMC interface than in
- * the Trusted Firmware, where the mmap_attr_t enum type is used. This function
- * converts an attributes value from the SMC format to the mmap_attr_t format by
- * setting MT_RW/MT_RO, MT_USER/MT_PRIVILEGED and MT_EXECUTE/MT_EXECUTE_NEVER.
- * The other fields are left as 0 because they are ignored by the function
- * xlat_change_mem_attributes_ctx().
- */
-static unsigned int smc_attr_to_mmap_attr(unsigned int attributes)
-{
-	unsigned int perm = attributes & SPRT_MEMORY_PERM_ATTR_MASK;
-
-	if (perm == SPRT_MEMORY_PERM_ATTR_RW) {
-		return MT_RW | MT_EXECUTE_NEVER | MT_USER;
-	} else if (perm ==  SPRT_MEMORY_PERM_ATTR_RO) {
-		return MT_RO | MT_EXECUTE_NEVER | MT_USER;
-	} else if (perm == SPRT_MEMORY_PERM_ATTR_RO_EXEC) {
-		return MT_RO | MT_USER;
-	} else {
-		return UINT_MAX;
-	}
-}
-
-/*
- * This function converts attributes from the Trusted Firmware format into the
- * SMC interface format.
- */
-static unsigned int mmap_attr_to_smc_attr(unsigned int attr)
-{
-	unsigned int perm;
-
-	/* No access from EL0. */
-	if ((attr & MT_USER) == 0U)
-		return UINT_MAX;
-
-	if ((attr & MT_RW) != 0) {
-		assert(MT_TYPE(attr) != MT_DEVICE);
-		perm = SPRT_MEMORY_PERM_ATTR_RW;
-	} else {
-		if ((attr & MT_EXECUTE_NEVER) != 0U) {
-			perm = SPRT_MEMORY_PERM_ATTR_RO;
-		} else {
-			perm = SPRT_MEMORY_PERM_ATTR_RO_EXEC;
-		}
-	}
-
-	return perm << SPRT_MEMORY_PERM_ATTR_SHIFT;
-}
-
-static int32_t sprt_memory_perm_attr_get(sp_context_t *sp_ctx, uintptr_t base_va)
-{
-	uint32_t attributes;
-
-	spin_lock(&(sp_ctx->xlat_ctx_lock));
-
-	int ret = xlat_get_mem_attributes_ctx(sp_ctx->xlat_ctx_handle,
-				     base_va, &attributes);
-
-	spin_unlock(&(sp_ctx->xlat_ctx_lock));
-
-	/* Convert error codes of xlat_get_mem_attributes_ctx() into SPM. */
-	assert((ret == 0) || (ret == -EINVAL));
-
-	if (ret != 0)
-		return SPRT_INVALID_PARAMETER;
-
-	unsigned int perm = mmap_attr_to_smc_attr(attributes);
-
-	if (perm == UINT_MAX)
-		return SPRT_INVALID_PARAMETER;
-
-	return SPRT_SUCCESS | perm;
-}
-
-static int32_t sprt_memory_perm_attr_set(sp_context_t *sp_ctx,
-		u_register_t page_address, u_register_t pages_count,
-		u_register_t smc_attributes)
-{
-	int ret;
-	uintptr_t base_va = (uintptr_t) page_address;
-	size_t size = pages_count * PAGE_SIZE;
-
-	VERBOSE("  Start address  : 0x%lx\n", base_va);
-	VERBOSE("  Number of pages: %i (%zi bytes)\n", (int) pages_count, size);
-	VERBOSE("  Attributes     : 0x%lx\n", smc_attributes);
-
-	uint32_t mmap_attr = smc_attr_to_mmap_attr(smc_attributes);
-
-	if (mmap_attr == UINT_MAX) {
-		WARN("%s: Invalid memory attributes: 0x%lx\n", __func__,
-		     smc_attributes);
-		return SPRT_INVALID_PARAMETER;
-	}
-
-	/*
-	 * Perform some checks before actually trying to change the memory
-	 * attributes.
-	 */
-
-	spin_lock(&(sp_ctx->xlat_ctx_lock));
-
-	uint32_t attributes;
-
-	ret = xlat_get_mem_attributes_ctx(sp_ctx->xlat_ctx_handle,
-				     base_va, &attributes);
-
-	if (ret != 0) {
-		spin_unlock(&(sp_ctx->xlat_ctx_lock));
-		return SPRT_INVALID_PARAMETER;
-	}
-
-	if ((attributes & MT_USER) == 0U) {
-		/* Prohibit changing attributes of S-EL1 regions */
-		spin_unlock(&(sp_ctx->xlat_ctx_lock));
-		return SPRT_INVALID_PARAMETER;
-	}
-
-	ret = xlat_change_mem_attributes_ctx(sp_ctx->xlat_ctx_handle,
-					base_va, size, mmap_attr);
-
-	spin_unlock(&(sp_ctx->xlat_ctx_lock));
-
-	/* Convert error codes of xlat_change_mem_attributes_ctx() into SPM. */
-	assert((ret == 0) || (ret == -EINVAL));
-
-	return (ret == 0) ? SPRT_SUCCESS : SPRT_INVALID_PARAMETER;
-}
-
-/*******************************************************************************
- * This function handles all SMCs in the range reserved for SPRT.
- ******************************************************************************/
-static uintptr_t sprt_smc_handler(uint32_t smc_fid, u_register_t x1,
-				  u_register_t x2, u_register_t x3,
-				  u_register_t x4, void *cookie, void *handle,
-				  u_register_t flags)
-{
-	/* SPRT only supported from the Secure world */
-	if (is_caller_non_secure(flags) == SMC_FROM_NON_SECURE) {
-		SMC_RET1(handle, SMC_UNK);
-	}
-
-	assert(handle == cm_get_context(SECURE));
-
-	/*
-	 * Only S-EL0 partitions are supported for now. Make the next ERET into
-	 * the partition jump directly to S-EL0 instead of S-EL1.
-	 */
-	cm_set_elr_spsr_el3(SECURE, read_elr_el1(), read_spsr_el1());
-
-	switch (smc_fid) {
-	case SPRT_VERSION:
-		SMC_RET1(handle, SPRT_VERSION_COMPILED);
-
-	case SPRT_PUT_RESPONSE_AARCH64:
-		spm_sp_synchronous_exit(SPRT_PUT_RESPONSE_AARCH64);
-
-	case SPRT_YIELD_AARCH64:
-		spm_sp_synchronous_exit(SPRT_YIELD_AARCH64);
-
-	case SPRT_MEMORY_PERM_ATTR_GET_AARCH64:
-	{
-		/* Get context of the SP in use by this CPU. */
-		unsigned int linear_id = plat_my_core_pos();
-		sp_context_t *sp_ctx = spm_cpu_get_sp_ctx(linear_id);
-
-		SMC_RET1(handle, sprt_memory_perm_attr_get(sp_ctx, x1));
-	}
-
-	case SPRT_MEMORY_PERM_ATTR_SET_AARCH64:
-	{
-		/* Get context of the SP in use by this CPU. */
-		unsigned int linear_id = plat_my_core_pos();
-		sp_context_t *sp_ctx = spm_cpu_get_sp_ctx(linear_id);
-
-		SMC_RET1(handle, sprt_memory_perm_attr_set(sp_ctx, x1, x2, x3));
-	}
-
-	default:
-		break;
-	}
-
-	WARN("SPRT: Unsupported call 0x%08x\n", smc_fid);
-	SMC_RET1(handle, SPRT_NOT_SUPPORTED);
-}
-
-DECLARE_RT_SVC(
-	sprt_handler,
-	OEN_SPRT_START,
-	OEN_SPRT_END,
-	SMC_TYPE_FAST,
-	NULL,
-	sprt_smc_handler
-);
diff --git a/services/std_svc/spm_mm/aarch64/spm_helpers.S b/services/std_svc/spm_mm/aarch64/spm_mm_helpers.S
similarity index 96%
rename from services/std_svc/spm_mm/aarch64/spm_helpers.S
rename to services/std_svc/spm_mm/aarch64/spm_mm_helpers.S
index aa35811..2c3aaf7 100644
--- a/services/std_svc/spm_mm/aarch64/spm_helpers.S
+++ b/services/std_svc/spm_mm/aarch64/spm_mm_helpers.S
@@ -1,11 +1,11 @@
 /*
- * Copyright (c) 2017, 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 <asm_macros.S>
-#include "../spm_private.h"
+#include "../spm_mm_private.h"
 
 	.global spm_secure_partition_enter
 	.global spm_secure_partition_exit
diff --git a/services/std_svc/spm_mm/aarch64/spm_shim_exceptions.S b/services/std_svc/spm_mm/aarch64/spm_mm_shim_exceptions.S
similarity index 100%
rename from services/std_svc/spm_mm/aarch64/spm_shim_exceptions.S
rename to services/std_svc/spm_mm/aarch64/spm_mm_shim_exceptions.S
diff --git a/services/std_svc/spm_mm/spm.mk b/services/std_svc/spm_mm/spm.mk
deleted file mode 100644
index 3aa10ee..0000000
--- a/services/std_svc/spm_mm/spm.mk
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-ifneq (${SPD},none)
-        $(error "Error: SPD and SPM are incompatible build options.")
-endif
-ifneq (${ARCH},aarch64)
-        $(error "Error: SPM is only supported on aarch64.")
-endif
-
-SPM_SOURCES	:=	$(addprefix services/std_svc/spm_mm/,	\
-			${ARCH}/spm_helpers.S			\
-			${ARCH}/spm_shim_exceptions.S		\
-			spm_main.c				\
-			spm_setup.c				\
-			spm_xlat.c)
-
-
-# Let the top-level Makefile know that we intend to include a BL32 image
-NEED_BL32		:=	yes
-
-# required so that SPM code executing at S-EL0 can access the timer registers
-NS_TIMER_SWITCH		:=	1
diff --git a/services/std_svc/spm_mm/spm_mm.mk b/services/std_svc/spm_mm/spm_mm.mk
new file mode 100644
index 0000000..656488b
--- /dev/null
+++ b/services/std_svc/spm_mm/spm_mm.mk
@@ -0,0 +1,26 @@
+#
+# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifneq (${SPD},none)
+        $(error "Error: SPD and SPM_MM are incompatible build options.")
+endif
+ifneq (${ARCH},aarch64)
+        $(error "Error: SPM_MM is only supported on aarch64.")
+endif
+
+SPM_SOURCES	:=	$(addprefix services/std_svc/spm_mm/,	\
+			${ARCH}/spm_mm_helpers.S			\
+			${ARCH}/spm_mm_shim_exceptions.S		\
+			spm_mm_main.c				\
+			spm_mm_setup.c				\
+			spm_mm_xlat.c)
+
+
+# Let the top-level Makefile know that we intend to include a BL32 image
+NEED_BL32		:=	yes
+
+# required so that SPM code executing at S-EL0 can access the timer registers
+NS_TIMER_SWITCH		:=	1
diff --git a/services/std_svc/spm_mm/spm_main.c b/services/std_svc/spm_mm/spm_mm_main.c
similarity index 85%
rename from services/std_svc/spm_mm/spm_main.c
rename to services/std_svc/spm_mm/spm_mm_main.c
index 7525763..14c0038 100644
--- a/services/std_svc/spm_mm/spm_main.c
+++ b/services/std_svc/spm_mm/spm_mm_main.c
@@ -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
  */
@@ -18,12 +18,11 @@
 #include <lib/utils.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
-#include <services/mm_svc.h>
-#include <services/secure_partition.h>
-#include <services/spm_svc.h>
+#include <services/spm_mm_partition.h>
+#include <services/spm_mm_svc.h>
 #include <smccc_helpers.h>
 
-#include "spm_private.h"
+#include "spm_mm_private.h"
 
 /*******************************************************************************
  * Secure Partition context information.
@@ -86,14 +85,14 @@
  * This function takes an SP context pointer and performs a synchronous entry
  * into it.
  ******************************************************************************/
-static uint64_t spm_sp_synchronous_entry(sp_context_t *sp_ctx)
+static uint64_t spm_sp_synchronous_entry(sp_context_t *ctx)
 {
 	uint64_t rc;
 
-	assert(sp_ctx != NULL);
+	assert(ctx != NULL);
 
 	/* Assign the context of the SP to this CPU */
-	cm_set_context(&(sp_ctx->cpu_ctx), SECURE);
+	cm_set_context(&(ctx->cpu_ctx), SECURE);
 
 	/* Restore the context assigned above */
 	cm_el1_sysregs_context_restore(SECURE);
@@ -104,7 +103,7 @@
 	dsbish();
 
 	/* Enter Secure Partition */
-	rc = spm_secure_partition_enter(&sp_ctx->c_rt_ctx);
+	rc = spm_secure_partition_enter(&ctx->c_rt_ctx);
 
 	/* Save secure state */
 	cm_el1_sysregs_context_save(SECURE);
@@ -157,7 +156,7 @@
 /*******************************************************************************
  * Initialize contexts of all Secure Partitions.
  ******************************************************************************/
-int32_t spm_setup(void)
+int32_t spm_mm_setup(void)
 {
 	sp_context_t *ctx;
 
@@ -185,7 +184,7 @@
 /*******************************************************************************
  * Function to perform a call to a Secure Partition.
  ******************************************************************************/
-uint64_t spm_sp_call(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3)
+uint64_t spm_mm_sp_call(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3)
 {
 	uint64_t rc;
 	sp_context_t *sp_ptr = &sp_ctx;
@@ -223,12 +222,12 @@
 	/* Cookie. Reserved for future use. It must be zero. */
 	if (mm_cookie != 0U) {
 		ERROR("MM_COMMUNICATE: cookie is not zero\n");
-		SMC_RET1(handle, SPM_INVALID_PARAMETER);
+		SMC_RET1(handle, SPM_MM_INVALID_PARAMETER);
 	}
 
 	if (comm_buffer_address == 0U) {
 		ERROR("MM_COMMUNICATE: comm_buffer_address is zero\n");
-		SMC_RET1(handle, SPM_INVALID_PARAMETER);
+		SMC_RET1(handle, SPM_MM_INVALID_PARAMETER);
 	}
 
 	if (comm_size_address != 0U) {
@@ -251,8 +250,8 @@
 	/* Save the Normal world context */
 	cm_el1_sysregs_context_save(NON_SECURE);
 
-	rc = spm_sp_call(smc_fid, comm_buffer_address, comm_size_address,
-			 plat_my_core_pos());
+	rc = spm_mm_sp_call(smc_fid, comm_buffer_address, comm_size_address,
+			    plat_my_core_pos());
 
 	/* Restore non-secure state */
 	cm_el1_sysregs_context_restore(NON_SECURE);
@@ -270,7 +269,7 @@
 /*******************************************************************************
  * Secure Partition Manager SMC handler.
  ******************************************************************************/
-uint64_t spm_smc_handler(uint32_t smc_fid,
+uint64_t spm_mm_smc_handler(uint32_t smc_fid,
 			 uint64_t x1,
 			 uint64_t x2,
 			 uint64_t x3,
@@ -295,29 +294,29 @@
 
 		switch (smc_fid) {
 
-		case SPM_VERSION_AARCH32:
-			SMC_RET1(handle, SPM_VERSION_COMPILED);
+		case SPM_MM_VERSION_AARCH32:
+			SMC_RET1(handle, SPM_MM_VERSION_COMPILED);
 
-		case SP_EVENT_COMPLETE_AARCH64:
+		case MM_SP_EVENT_COMPLETE_AARCH64:
 			spm_sp_synchronous_exit(x1);
 
-		case SP_MEMORY_ATTRIBUTES_GET_AARCH64:
-			INFO("Received SP_MEMORY_ATTRIBUTES_GET_AARCH64 SMC\n");
+		case MM_SP_MEMORY_ATTRIBUTES_GET_AARCH64:
+			INFO("Received MM_SP_MEMORY_ATTRIBUTES_GET_AARCH64 SMC\n");
 
 			if (sp_ctx.state != SP_STATE_RESET) {
-				WARN("SP_MEMORY_ATTRIBUTES_GET_AARCH64 is available at boot time only\n");
-				SMC_RET1(handle, SPM_NOT_SUPPORTED);
+				WARN("MM_SP_MEMORY_ATTRIBUTES_GET_AARCH64 is available at boot time only\n");
+				SMC_RET1(handle, SPM_MM_NOT_SUPPORTED);
 			}
 			SMC_RET1(handle,
 				 spm_memory_attributes_get_smc_handler(
 					 &sp_ctx, x1));
 
-		case SP_MEMORY_ATTRIBUTES_SET_AARCH64:
-			INFO("Received SP_MEMORY_ATTRIBUTES_SET_AARCH64 SMC\n");
+		case MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64:
+			INFO("Received MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64 SMC\n");
 
 			if (sp_ctx.state != SP_STATE_RESET) {
-				WARN("SP_MEMORY_ATTRIBUTES_SET_AARCH64 is available at boot time only\n");
-				SMC_RET1(handle, SPM_NOT_SUPPORTED);
+				WARN("MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64 is available at boot time only\n");
+				SMC_RET1(handle, SPM_MM_NOT_SUPPORTED);
 			}
 			SMC_RET1(handle,
 				 spm_memory_attributes_set_smc_handler(
@@ -340,10 +339,10 @@
 		case MM_COMMUNICATE_AARCH64:
 			return mm_communicate(smc_fid, x1, x2, x3, handle);
 
-		case SP_MEMORY_ATTRIBUTES_GET_AARCH64:
-		case SP_MEMORY_ATTRIBUTES_SET_AARCH64:
+		case MM_SP_MEMORY_ATTRIBUTES_GET_AARCH64:
+		case MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64:
 			/* SMC interfaces reserved for secure callers. */
-			SMC_RET1(handle, SPM_NOT_SUPPORTED);
+			SMC_RET1(handle, SPM_MM_NOT_SUPPORTED);
 
 		default:
 			break;
diff --git a/services/std_svc/spm_mm/spm_private.h b/services/std_svc/spm_mm/spm_mm_private.h
similarity index 92%
rename from services/std_svc/spm_mm/spm_private.h
rename to services/std_svc/spm_mm/spm_mm_private.h
index ba94a4d..45b4789 100644
--- a/services/std_svc/spm_mm/spm_private.h
+++ b/services/std_svc/spm_mm/spm_mm_private.h
@@ -1,11 +1,11 @@
 /*
- * 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
  */
 
-#ifndef SPM_PRIVATE_H
-#define SPM_PRIVATE_H
+#ifndef SPM_MM_PRIVATE_H
+#define SPM_MM_PRIVATE_H
 
 #include <context.h>
 
@@ -68,4 +68,4 @@
 
 #endif /* __ASSEMBLER__ */
 
-#endif /* SPM_PRIVATE_H */
+#endif /* SPM_MM_PRIVATE_H */
diff --git a/services/std_svc/spm_mm/spm_setup.c b/services/std_svc/spm_mm/spm_mm_setup.c
similarity index 90%
rename from services/std_svc/spm_mm/spm_setup.c
rename to services/std_svc/spm_mm/spm_mm_setup.c
index aae6cd5..ccb2f90 100644
--- a/services/std_svc/spm_mm/spm_setup.c
+++ b/services/std_svc/spm_mm/spm_mm_setup.c
@@ -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
  */
@@ -16,10 +16,10 @@
 #include <platform_def.h>
 #include <plat/common/common_def.h>
 #include <plat/common/platform.h>
-#include <services/secure_partition.h>
+#include <services/spm_mm_partition.h>
 
-#include "spm_private.h"
-#include "spm_shim_private.h"
+#include "spm_mm_private.h"
+#include "spm_mm_shim_private.h"
 
 /* Setup context of the Secure Partition */
 void spm_sp_setup(sp_context_t *sp_ctx)
@@ -192,22 +192,22 @@
 	void *shared_buf_ptr = (void *) PLAT_SPM_BUF_BASE;
 
 	/* Copy the boot information into the shared buffer with the SP. */
-	assert((uintptr_t)shared_buf_ptr + sizeof(secure_partition_boot_info_t)
+	assert((uintptr_t)shared_buf_ptr + sizeof(spm_mm_boot_info_t)
 	       <= (PLAT_SPM_BUF_BASE + PLAT_SPM_BUF_SIZE));
 
 	assert(PLAT_SPM_BUF_BASE <= (UINTPTR_MAX - PLAT_SPM_BUF_SIZE + 1));
 
-	const secure_partition_boot_info_t *sp_boot_info =
+	const spm_mm_boot_info_t *sp_boot_info =
 			plat_get_secure_partition_boot_info(NULL);
 
 	assert(sp_boot_info != NULL);
 
 	memcpy((void *) shared_buf_ptr, (const void *) sp_boot_info,
-	       sizeof(secure_partition_boot_info_t));
+	       sizeof(spm_mm_boot_info_t));
 
 	/* Pointer to the MP information from the platform port. */
-	secure_partition_mp_info_t *sp_mp_info =
-		((secure_partition_boot_info_t *) shared_buf_ptr)->mp_info;
+	spm_mm_mp_info_t *sp_mp_info =
+		((spm_mm_boot_info_t *) shared_buf_ptr)->mp_info;
 
 	assert(sp_mp_info != NULL);
 
@@ -215,15 +215,15 @@
 	 * Point the shared buffer MP information pointer to where the info will
 	 * be populated, just after the boot info.
 	 */
-	((secure_partition_boot_info_t *) shared_buf_ptr)->mp_info =
-		(secure_partition_mp_info_t *) ((uintptr_t)shared_buf_ptr
-				+ sizeof(secure_partition_boot_info_t));
+	((spm_mm_boot_info_t *) shared_buf_ptr)->mp_info =
+		(spm_mm_mp_info_t *) ((uintptr_t)shared_buf_ptr
+				+ sizeof(spm_mm_boot_info_t));
 
 	/*
 	 * Update the shared buffer pointer to where the MP information for the
 	 * payload will be populated
 	 */
-	shared_buf_ptr = ((secure_partition_boot_info_t *) shared_buf_ptr)->mp_info;
+	shared_buf_ptr = ((spm_mm_boot_info_t *) shared_buf_ptr)->mp_info;
 
 	/*
 	 * Copy the cpu information into the shared buffer area after the boot
@@ -242,7 +242,7 @@
 	 * Calculate the linear indices of cores in boot information for the
 	 * secure partition and flag the primary CPU
 	 */
-	sp_mp_info = (secure_partition_mp_info_t *) shared_buf_ptr;
+	sp_mp_info = (spm_mm_mp_info_t *) shared_buf_ptr;
 
 	for (unsigned int index = 0; index < sp_boot_info->num_cpus; index++) {
 		u_register_t mpidr = sp_mp_info[index].mpidr;
diff --git a/services/std_svc/spm_mm/spm_shim_private.h b/services/std_svc/spm_mm/spm_mm_shim_private.h
similarity index 76%
rename from services/std_svc/spm_mm/spm_shim_private.h
rename to services/std_svc/spm_mm/spm_mm_shim_private.h
index 7fe9692..0c8d894 100644
--- a/services/std_svc/spm_mm/spm_shim_private.h
+++ b/services/std_svc/spm_mm/spm_mm_shim_private.h
@@ -1,11 +1,11 @@
 /*
- * 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
  */
 
-#ifndef SPM_SHIM_PRIVATE_H
-#define SPM_SHIM_PRIVATE_H
+#ifndef SPM_MM_SHIM_PRIVATE_H
+#define SPM_MM_SHIM_PRIVATE_H
 
 #include <stdint.h>
 
@@ -23,4 +23,4 @@
 #define SPM_SHIM_EXCEPTIONS_SIZE	\
 	(SPM_SHIM_EXCEPTIONS_END - SPM_SHIM_EXCEPTIONS_START)
 
-#endif /* SPM_SHIM_PRIVATE_H */
+#endif /* SPM_MM_SHIM_PRIVATE_H */
diff --git a/services/std_svc/spm_mm/spm_xlat.c b/services/std_svc/spm_mm/spm_mm_xlat.c
similarity index 78%
rename from services/std_svc/spm_mm/spm_xlat.c
rename to services/std_svc/spm_mm/spm_mm_xlat.c
index f54168e..6c02f07 100644
--- a/services/std_svc/spm_mm/spm_xlat.c
+++ b/services/std_svc/spm_mm/spm_mm_xlat.c
@@ -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,11 +11,11 @@
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <platform_def.h>
 #include <plat/common/platform.h>
-#include <services/secure_partition.h>
-#include <services/spm_svc.h>
+#include <services/spm_mm_partition.h>
+#include <services/spm_mm_svc.h>
 
-#include "spm_private.h"
-#include "spm_shim_private.h"
+#include "spm_mm_private.h"
+#include "spm_mm_shim_private.h"
 
 /* Place translation tables by default along with the ones used by BL31. */
 #ifndef PLAT_SP_IMAGE_XLAT_SECTION_NAME
@@ -50,21 +50,21 @@
 {
 	unsigned int tf_attr = 0U;
 
-	unsigned int access = (attributes & SP_MEMORY_ATTRIBUTES_ACCESS_MASK)
-			      >> SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT;
+	unsigned int access = (attributes & MM_SP_MEMORY_ATTRIBUTES_ACCESS_MASK)
+			      >> MM_SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT;
 
-	if (access == SP_MEMORY_ATTRIBUTES_ACCESS_RW) {
+	if (access == MM_SP_MEMORY_ATTRIBUTES_ACCESS_RW) {
 		tf_attr |= MT_RW | MT_USER;
-	} else if (access ==  SP_MEMORY_ATTRIBUTES_ACCESS_RO) {
+	} else if (access ==  MM_SP_MEMORY_ATTRIBUTES_ACCESS_RO) {
 		tf_attr |= MT_RO | MT_USER;
 	} else {
 		/* Other values are reserved. */
-		assert(access ==  SP_MEMORY_ATTRIBUTES_ACCESS_NOACCESS);
+		assert(access == MM_SP_MEMORY_ATTRIBUTES_ACCESS_NOACCESS);
 		/* The only requirement is that there's no access from EL0 */
 		tf_attr |= MT_RO | MT_PRIVILEGED;
 	}
 
-	if ((attributes & SP_MEMORY_ATTRIBUTES_NON_EXEC) == 0) {
+	if ((attributes & MM_SP_MEMORY_ATTRIBUTES_NON_EXEC) == 0) {
 		tf_attr |= MT_EXECUTE;
 	} else {
 		tf_attr |= MT_EXECUTE_NEVER;
@@ -85,21 +85,21 @@
 
 	if ((attr & MT_USER) == 0) {
 		/* No access from EL0. */
-		data_access = SP_MEMORY_ATTRIBUTES_ACCESS_NOACCESS;
+		data_access = MM_SP_MEMORY_ATTRIBUTES_ACCESS_NOACCESS;
 	} else {
 		if ((attr & MT_RW) != 0) {
 			assert(MT_TYPE(attr) != MT_DEVICE);
-			data_access = SP_MEMORY_ATTRIBUTES_ACCESS_RW;
+			data_access = MM_SP_MEMORY_ATTRIBUTES_ACCESS_RW;
 		} else {
-			data_access = SP_MEMORY_ATTRIBUTES_ACCESS_RO;
+			data_access = MM_SP_MEMORY_ATTRIBUTES_ACCESS_RO;
 		}
 	}
 
-	smc_attr |= (data_access & SP_MEMORY_ATTRIBUTES_ACCESS_MASK)
-		    << SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT;
+	smc_attr |= (data_access & MM_SP_MEMORY_ATTRIBUTES_ACCESS_MASK)
+		    << MM_SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT;
 
 	if ((attr & MT_EXECUTE_NEVER) != 0U) {
-		smc_attr |= SP_MEMORY_ATTRIBUTES_NON_EXEC;
+		smc_attr |= MM_SP_MEMORY_ATTRIBUTES_NON_EXEC;
 	}
 
 	return smc_attr;
@@ -123,7 +123,7 @@
 	if (rc == 0) {
 		return (int32_t) smc_mmap_to_smc_attr(attributes);
 	} else {
-		return SPM_INVALID_PARAMETER;
+		return SPM_MM_INVALID_PARAMETER;
 	}
 }
 
@@ -151,5 +151,5 @@
 	/* Convert error codes of xlat_change_mem_attributes_ctx() into SPM. */
 	assert((ret == 0) || (ret == -EINVAL));
 
-	return (ret == 0) ? SPM_SUCCESS : SPM_INVALID_PARAMETER;
+	return (ret == 0) ? SPM_MM_SUCCESS : SPM_MM_INVALID_PARAMETER;
 }
diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c
index 1d80fa3..7787a2f 100644
--- a/services/std_svc/std_svc_setup.c
+++ b/services/std_svc/std_svc_setup.c
@@ -14,7 +14,7 @@
 #include <lib/psci/psci.h>
 #include <lib/runtime_instr.h>
 #include <services/sdei.h>
-#include <services/spm_svc.h>
+#include <services/spm_mm_svc.h>
 #include <services/std_svc.h>
 #include <smccc_helpers.h>
 #include <tools_share/uuid.h>
@@ -45,8 +45,8 @@
 		ret = 1;
 	}
 
-#if ENABLE_SPM
-	if (spm_setup() != 0) {
+#if SPM_MM
+	if (spm_mm_setup() != 0) {
 		ret = 1;
 	}
 #endif
@@ -103,14 +103,14 @@
 		SMC_RET1(handle, ret);
 	}
 
-#if ENABLE_SPM && SPM_MM
+#if SPM_MM
 	/*
 	 * Dispatch SPM calls to SPM SMC handler and return its return
 	 * value
 	 */
-	if (is_spm_fid(smc_fid)) {
-		return spm_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
-				       handle, flags);
+	if (is_spm_mm_fid(smc_fid)) {
+		return spm_mm_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
+					  handle, flags);
 	}
 #endif
 
diff --git a/tools/memory/print_memory_map.py b/tools/memory/print_memory_map.py
new file mode 100755
index 0000000..35cccd3
--- /dev/null
+++ b/tools/memory/print_memory_map.py
@@ -0,0 +1,68 @@
+#!/usr/bin/env python3
+#
+# Copyright (c) 2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+import re
+import os
+import sys
+import operator
+
+# List of folder/map to parse
+bl_images = ['bl1', 'bl2', 'bl31']
+
+# List of symbols to search for
+blx_symbols = ['__BL1_RAM_START__', '__BL1_RAM_END__',
+                '__BL2_END__',
+                '__BL31_END__',
+                '__TEXT_START__', '__TEXT_END__',
+                '__RODATA_START__', '__RODATA_END__',
+                '__DATA_START__', '__DATA_END__',
+                '__STACKS_START__', '__STACKS_END__',
+                '__BSS_END',
+               ]
+
+# Regex to extract address from map file
+address_pattern = re.compile(r"\b0x\w*")
+
+# List of found element: [address, symbol, file]
+address_list = []
+
+# Get the directory from command line or use a default one
+if len(sys.argv) >= 2:
+    build_dir = sys.argv[1]
+else:
+    build_dir = 'build/fvp/debug'
+
+# Extract all the required symbols from the map files
+for image in bl_images:
+    file_path = os.path.join(build_dir, image, '{}.map'.format(image))
+    if os.path.isfile(file_path):
+        with open (file_path, 'rt') as mapfile:
+            for line in mapfile:
+                for symbol in blx_symbols:
+                    if line.find(symbol) > 0 and line.find("ASSERT") < 0:
+                        # Extract address from line
+                        match = address_pattern.search(line)
+                        if match:
+                            address_list.append([match.group(0), symbol, image])
+
+# Sort by address
+address_list.sort(key=operator.itemgetter(0))
+
+# Generate memory view
+print('{:-^87}'.format('Memory Map from: ' + build_dir))
+for address in reversed(address_list):
+    if "bl1" in address[2]:
+        print(address[0], '+{:-^20}+ |{:^20}| |{:^20}|'.format(address[1], '', ''))
+    elif "bl2" in address[2]:
+        print(address[0], '|{:^20}| +{:-^20}+ |{:^20}|'.format('', address[1], ''))
+    elif "bl31" in address[2]:
+        print(address[0], '|{:^20}| |{:^20}| +{:-^20}+'.format('', '', address[1]))
+    else:
+        print(address[0], '|{:^20}| |{:^20}| +{:-^20}+'.format('', '', address[1]))
+
+print('{:^20}{:_^20}   {:_^20}   {:_^20}'.format('', '', '', ''))
+print('{:^20}{:^20}   {:^20}   {:^20}'.format('address', 'bl1', 'bl2', 'bl31'))