Merge "rpi3/4: Add support for offlining CPUs" into integration
diff --git a/Makefile b/Makefile
index d634b33..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)
@@ -236,11 +257,9 @@
 # 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
@@ -251,7 +270,6 @@
 WARNING3 += -Wcast-qual
 WARNING3 += -Wconversion
 WARNING3 += -Wpacked
-WARNING3 += -Wpadded
 WARNING3 += -Wpointer-arith
 WARNING3 += -Wredundant-decls
 WARNING3 += -Wswitch-default
@@ -285,8 +303,9 @@
 ASFLAGS			+=	$(CPPFLAGS) $(ASFLAGS_$(ARCH))			\
 				-ffreestanding -Wa,--fatal-warnings
 TF_CFLAGS		+=	$(CPPFLAGS) $(TF_CFLAGS_$(ARCH))		\
-				-ffreestanding -fno-builtin -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
@@ -301,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
@@ -406,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),)
@@ -624,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
 ################################################################################
@@ -673,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))
@@ -690,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))
@@ -738,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))
@@ -754,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))
@@ -796,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
@@ -990,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
@@ -1029,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/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/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/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/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 cae94b5..5fc1335 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -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
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index fded1e0..d7bb044 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -196,6 +196,10 @@
    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
@@ -231,10 +235,6 @@
    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
@@ -350,6 +350,21 @@
    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``.
@@ -476,6 +491,13 @@
    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
@@ -488,6 +510,9 @@
    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,
@@ -540,6 +565,10 @@
    (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
diff --git a/docs/getting_started/initial-build.rst b/docs/getting_started/initial-build.rst
index 41cd4d1..893aba2 100644
--- a/docs/getting_started/initial-build.rst
+++ b/docs/getting_started/initial-build.rst
@@ -8,13 +8,13 @@
 
    .. code:: shell
 
-       export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
+       export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf-
 
    For AArch32:
 
    .. code:: shell
 
-       export CROSS_COMPILE=<path-to-aarch32-gcc>/bin/arm-eabi-
+       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
@@ -32,7 +32,7 @@
 
    .. code:: shell
 
-       export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
+       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``
@@ -43,7 +43,7 @@
 
    .. code:: shell
 
-       export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
+       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.
diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst
index 17fd546..bb14717 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/getting_started/porting-guide.rst
@@ -1999,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
diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst
index 27ad0ed..3e0c8ff 100644
--- a/docs/getting_started/prerequisites.rst
+++ b/docs/getting_started/prerequisites.rst
@@ -26,7 +26,7 @@
 |TF-A| can be built with any of the following *cross-compiler* toolchains that
 target the Armv7-A or Armv8-A architectures:
 
-- GCC >= 8.3-2019.03 (from the `Arm Developer website`_)
+- GCC >= 9.2-2019.12 (from the `Arm Developer website`_)
 - Clang >= 4.0
 - Arm Compiler >= 6.0
 
diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst
index b6396b9..37010e1 100644
--- a/docs/plat/arm/fvp/index.rst
+++ b/docs/plat/arm/fvp/index.rst
@@ -223,7 +223,7 @@
 
 .. code:: shell
 
-    CROSS_COMPILE=aarch64-linux-gnu-  \
+    CROSS_COMPILE=aarch64-none-elf-  \
     make PLAT=fvp DEBUG=1             \
     RESET_TO_BL31=1                   \
     ARM_LINUX_KERNEL_AS_BL33=1        \
diff --git a/docs/plat/arm/juno/index.rst b/docs/plat/arm/juno/index.rst
index 6429ede..cf328fa 100644
--- a/docs/plat/arm/juno/index.rst
+++ b/docs/plat/arm/juno/index.rst
@@ -136,7 +136,7 @@
 
       .. code:: shell
 
-          export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
+          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.
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/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/security-hardening.rst b/docs/process/security-hardening.rst
index 4967871..a18a792 100644
--- a/docs/process/security-hardening.rst
+++ b/docs/process/security-hardening.rst
@@ -30,9 +30,8 @@
 
   - 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
 
@@ -42,7 +41,7 @@
   - 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/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/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/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/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/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 100%
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
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/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/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/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 dd3c578..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
  */
@@ -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) & \
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 941190f..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
 
@@ -457,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))
@@ -500,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 c00a041..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},					\
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/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/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/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 98dd0a9..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
@@ -116,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 3a9972b..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
 #
@@ -245,10 +245,12 @@
 DYNAMIC_WORKAROUND_CVE_2018_3639	:=	1
 
 # Enable reclaiming of BL31 initialisation code for secondary cores
-# stacks for FVP.
+# stacks for FVP. However, don't enable reclaiming for clang.
 ifneq (${RESET_TO_BL31},1)
+ifeq ($(findstring clang,$(notdir $(CC))),)
 RECLAIM_INIT_CODE	:=	1
 endif
+endif
 
 ifeq (${ENABLE_AMU},1)
 BL31_SOURCES		+=	lib/cpus/aarch64/cpuamu.c		\
@@ -281,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/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/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 acc3797..9d4f05e 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -215,12 +215,17 @@
 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)
@@ -243,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 cfc5359..4a3a22e 100644
--- a/plat/arm/common/arm_gicv3.c
+++ b/plat/arm/common/arm_gicv3.c
@@ -44,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)
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/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/mt8183/drivers/spm/spm.c b/plat/mediatek/mt8183/drivers/spm/spm.c
index 547af57..d6d2344 100644
--- a/plat/mediatek/mt8183/drivers/spm/spm.c
+++ b/plat/mediatek/mt8183/drivers/spm/spm.c
@@ -12,6 +12,12 @@
 
 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)
 
@@ -339,6 +345,11 @@
 	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);
diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c
index a665276..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
@@ -155,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
 	}
 
 	/*
@@ -273,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 a8c70ea..39dc42c 100644
--- a/plat/nvidia/tegra/common/tegra_pm.c
+++ b/plat/nvidia/tegra/common/tegra_pm.c
@@ -244,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/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/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
index e519cdc..8f1deb2 100644
--- a/plat/nvidia/tegra/include/t194/tegra194_private.h
+++ b/plat/nvidia/tegra/include/t194/tegra194_private.h
@@ -1,11 +1,11 @@
 /*
- * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __TEGRA194_PRIVATE_H__
-#define __TEGRA194_PRIVATE_H__
+#ifndef TEGRA194_PRIVATE_H
+#define TEGRA194_PRIVATE_H
 
 void tegra194_cpu_reset_handler(void);
 uint64_t tegra194_get_cpu_reset_handler_base(void);
@@ -13,4 +13,4 @@
 uint64_t tegra194_get_smmu_ctx_offset(void);
 void tegra194_set_system_suspend_entry(void);
 
-#endif /* __TEGRA194_PRIVATE_H__ */
+#endif /* TEGRA194_PRIVATE_H */
diff --git a/plat/nvidia/tegra/include/t194/tegra_def.h b/plat/nvidia/tegra/include/t194/tegra_def.h
index 1a9ba0a..e20b2c6 100644
--- a/plat/nvidia/tegra/include/t194/tegra_def.h
+++ b/plat/nvidia/tegra/include/t194/tegra_def.h
@@ -1,15 +1,21 @@
 /*
- * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __TEGRA_DEF_H__
-#define __TEGRA_DEF_H__
+#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.
@@ -231,4 +237,4 @@
 #define TEGRA_SID_XUSB_VF2			U(0x5f)
 #define TEGRA_SID_XUSB_VF3			U(0x60)
 
-#endif /* __TEGRA_DEF_H__ */
+#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..1433a2e
--- /dev/null
+++ b/plat/nvidia/tegra/include/t194/tegra_mc_def.h
@@ -0,0 +1,650 @@
+/*
+ * 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(id, client) \
+	(~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(id, client) \
+	(~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
+
+/*******************************************************************************
+ * 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 cd2f773..761acde 100644
--- a/plat/nvidia/tegra/include/tegra_private.h
+++ b/plat/nvidia/tegra/include/tegra_private.h
@@ -137,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/t194/drivers/include/mce_private.h b/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h
index 3994b2d..226ab5b 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h
+++ b/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h
@@ -1,11 +1,11 @@
 /*
- * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __MCE_PRIVATE_H__
-#define __MCE_PRIVATE_H__
+#ifndef MCE_PRIVATE_H
+#define MCE_PRIVATE_H
 
 #include <tegra_def.h>
 
@@ -66,10 +66,9 @@
 uint64_t nvg_cache_clean(void);
 uint64_t nvg_cache_clean_inval(void);
 uint64_t nvg_cache_inval_all(void);
-int32_t nvg_roc_clean_cache_trbits(void);
 void nvg_enable_strict_checking_mode(void);
 
 /* MCE helper functions */
 void mce_enable_strict_checking(void);
 
-#endif /* __MCE_PRIVATE_H__ */
+#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
index 6e656f6..e7cf88d 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/include/se.h
+++ b/plat/nvidia/tegra/soc/t194/drivers/include/se.h
@@ -1,13 +1,13 @@
 /*
- * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef __SE_H__
-#define __SE_H__
+#ifndef SE_H
+#define SE_H
 
 int32_t tegra_se_suspend(void);
 void tegra_se_resume(void);
 
-#endif /* __SE_H__ */
+#endif /* SE_H */
diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c
index 1dd1f51..536ed57 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c
+++ b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -165,7 +165,7 @@
 	/* sanity check the core ID value */
 	if (core > (uint32_t)PLATFORM_CORE_COUNT) {
 		ERROR("%s: unknown core id (%d)\n", __func__, core);
-		ret = EINVAL;
+		ret = -EINVAL;
 	} else {
 		/* get a core online */
 		nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_ONLINE_CORE,
@@ -183,15 +183,15 @@
  */
 int32_t nvg_update_ccplex_gsc(uint32_t gsc_idx)
 {
-	int32_t ret;
+	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;
+		ret = -EINVAL;
 	} else {
 		nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_UPDATE_CCPLEX_GSC,
-								(uint64_t)gsc_idx);
+				     (uint64_t)gsc_idx);
 	}
 
 	return ret;
@@ -209,11 +209,12 @@
 			ID_AFR0_EL1_CACHE_OPS_MASK) == 1U) {
 		if (nvg_cache_clean() == 0U) {
 			ERROR("%s: failed\n", __func__);
-			ret = EINVAL;
+			ret = -ENODEV;
 		}
 	} else {
-		ret = EINVAL;
+		ret = -ENOTSUP;
 	}
+
 	return ret;
 }
 
@@ -229,11 +230,12 @@
 			ID_AFR0_EL1_CACHE_OPS_MASK) == 1U) {
 		if (nvg_cache_clean_inval() == 0U) {
 			ERROR("%s: failed\n", __func__);
-			ret = EINVAL;
+			ret = -ENODEV;
 		}
 	} else {
-		ret = EINVAL;
+		ret = -ENOTSUP;
 	}
+
 	return ret;
 }
 
@@ -249,11 +251,12 @@
 			ID_AFR0_EL1_CACHE_OPS_MASK) == 1U) {
 		if (nvg_cache_inval_all() == 0U) {
 			ERROR("%s: failed\n", __func__);
-			ret = EINVAL;
+			ret = -ENODEV;
 		}
 	} else {
-		ret = EINVAL;
+		ret = -ENOTSUP;
 	}
+
 	return ret;
 }
 
@@ -271,8 +274,8 @@
 	    (state != (uint32_t)TEGRA_NVG_CORE_C6) &&
 		(state != (uint32_t)TEGRA_NVG_CORE_C7))
 	{
-		ERROR("%s: unknown cstate (%d)\n", __func__, state);
-		ret = EINVAL;
+		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);
diff --git a/plat/nvidia/tegra/soc/t194/drivers/se/se.c b/plat/nvidia/tegra/soc/t194/drivers/se/se.c
index 3df670c..a9f4610 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/se/se.c
+++ b/plat/nvidia/tegra/soc/t194/drivers/se/se.c
@@ -1,4 +1,5 @@
-/*
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
  * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
diff --git a/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h b/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h
index 7d531bb..a2c5d1c 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h
+++ b/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h
@@ -1,11 +1,12 @@
-/*
- * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+/*
+ * 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__
+#ifndef SE_PRIVATE_H
+#define SE_PRIVATE_H
 
 #include <lib/utils_def.h>
 
@@ -81,4 +82,4 @@
 	mmio_write_32(TEGRA_SE0_BASE + offset, val);
 }
 
-#endif /* __SE_PRIVATE_H__ */
+#endif /* SE_PRIVATE_H */
diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
index 948fade..fa5ba62 100644
--- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
@@ -26,7 +26,6 @@
 #include <tegra_platform.h>
 #include <tegra_private.h>
 
-extern void tegra194_cpu_reset_handler(void);
 extern uint32_t __tegra194_cpu_reset_handler_data,
 		__tegra194_cpu_reset_handler_end;
 
@@ -66,10 +65,10 @@
 			<< TEGRA194_WAKE_TIME_SHIFT;
 
 	/*
-	 * Clean 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
+	 * 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],
@@ -125,7 +124,7 @@
 		val = (stateid_afflvl0 == PSTATE_ID_CORE_IDLE) ?
 			(uint32_t)TEGRA_NVG_CORE_C6 : (uint32_t)TEGRA_NVG_CORE_C7;
 		ret = mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE, (uint64_t)val,
-				percpu_data[cpu].wake_time, 0);
+				t19x_percpu_data[cpu].wake_time, 0);
 		assert(ret == 0);
 
 	} else if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
diff --git a/plat/nvidia/tegra/soc/t194/plat_smmu.c b/plat/nvidia/tegra/soc/t194/plat_smmu.c
index 1696d59..640ef4d 100644
--- a/plat/nvidia/tegra/soc/t194/plat_smmu.c
+++ b/plat/nvidia/tegra/soc/t194/plat_smmu.c
@@ -270,143 +270,8 @@
 	mc_make_sid_override_cfg(MIU2W),
 	mc_make_sid_override_cfg(MIU3R),
 	mc_make_sid_override_cfg(MIU3W),
-	smmu_make_gnsr0_nsec_cfg(CR0),
-	smmu_make_gnsr0_sec_cfg(IDR0),
-	smmu_make_gnsr0_sec_cfg(IDR1),
-	smmu_make_gnsr0_sec_cfg(IDR2),
-	smmu_make_gnsr0_nsec_cfg(GFSR),
-	smmu_make_gnsr0_nsec_cfg(GFSYNR0),
-	smmu_make_gnsr0_nsec_cfg(GFSYNR1),
-	smmu_make_gnsr0_nsec_cfg(TLBGSTATUS),
-	smmu_make_gnsr0_nsec_cfg(PIDR2),
-	smmu_make_smrg_group(0),
-	smmu_make_smrg_group(1),
-	smmu_make_smrg_group(2),
-	smmu_make_smrg_group(3),
-	smmu_make_smrg_group(4),
-	smmu_make_smrg_group(5),
-	smmu_make_smrg_group(6),
-	smmu_make_smrg_group(7),
-	smmu_make_smrg_group(8),
-	smmu_make_smrg_group(9),
-	smmu_make_smrg_group(10),
-	smmu_make_smrg_group(11),
-	smmu_make_smrg_group(12),
-	smmu_make_smrg_group(13),
-	smmu_make_smrg_group(14),
-	smmu_make_smrg_group(15),
-	smmu_make_smrg_group(16),
-	smmu_make_smrg_group(17),
-	smmu_make_smrg_group(18),
-	smmu_make_smrg_group(19),
-	smmu_make_smrg_group(20),
-	smmu_make_smrg_group(21),
-	smmu_make_smrg_group(22),
-	smmu_make_smrg_group(23),
-	smmu_make_smrg_group(24),
-	smmu_make_smrg_group(25),
-	smmu_make_smrg_group(26),
-	smmu_make_smrg_group(27),
-	smmu_make_smrg_group(28),
-	smmu_make_smrg_group(29),
-	smmu_make_smrg_group(30),
-	smmu_make_smrg_group(31),
-	smmu_make_smrg_group(32),
-	smmu_make_smrg_group(33),
-	smmu_make_smrg_group(34),
-	smmu_make_smrg_group(35),
-	smmu_make_smrg_group(36),
-	smmu_make_smrg_group(37),
-	smmu_make_smrg_group(38),
-	smmu_make_smrg_group(39),
-	smmu_make_smrg_group(40),
-	smmu_make_smrg_group(41),
-	smmu_make_smrg_group(42),
-	smmu_make_smrg_group(43),
-	smmu_make_smrg_group(44),
-	smmu_make_smrg_group(45),
-	smmu_make_smrg_group(46),
-	smmu_make_smrg_group(47),
-	smmu_make_smrg_group(48),
-	smmu_make_smrg_group(49),
-	smmu_make_smrg_group(50),
-	smmu_make_smrg_group(51),
-	smmu_make_smrg_group(52),
-	smmu_make_smrg_group(53),
-	smmu_make_smrg_group(54),
-	smmu_make_smrg_group(55),
-	smmu_make_smrg_group(56),
-	smmu_make_smrg_group(57),
-	smmu_make_smrg_group(58),
-	smmu_make_smrg_group(59),
-	smmu_make_smrg_group(60),
-	smmu_make_smrg_group(61),
-	smmu_make_smrg_group(62),
-	smmu_make_smrg_group(63),
-	smmu_make_cb_group(0),
-	smmu_make_cb_group(1),
-	smmu_make_cb_group(2),
-	smmu_make_cb_group(3),
-	smmu_make_cb_group(4),
-	smmu_make_cb_group(5),
-	smmu_make_cb_group(6),
-	smmu_make_cb_group(7),
-	smmu_make_cb_group(8),
-	smmu_make_cb_group(9),
-	smmu_make_cb_group(10),
-	smmu_make_cb_group(11),
-	smmu_make_cb_group(12),
-	smmu_make_cb_group(13),
-	smmu_make_cb_group(14),
-	smmu_make_cb_group(15),
-	smmu_make_cb_group(16),
-	smmu_make_cb_group(17),
-	smmu_make_cb_group(18),
-	smmu_make_cb_group(19),
-	smmu_make_cb_group(20),
-	smmu_make_cb_group(21),
-	smmu_make_cb_group(22),
-	smmu_make_cb_group(23),
-	smmu_make_cb_group(24),
-	smmu_make_cb_group(25),
-	smmu_make_cb_group(26),
-	smmu_make_cb_group(27),
-	smmu_make_cb_group(28),
-	smmu_make_cb_group(29),
-	smmu_make_cb_group(30),
-	smmu_make_cb_group(31),
-	smmu_make_cb_group(32),
-	smmu_make_cb_group(33),
-	smmu_make_cb_group(34),
-	smmu_make_cb_group(35),
-	smmu_make_cb_group(36),
-	smmu_make_cb_group(37),
-	smmu_make_cb_group(38),
-	smmu_make_cb_group(39),
-	smmu_make_cb_group(40),
-	smmu_make_cb_group(41),
-	smmu_make_cb_group(42),
-	smmu_make_cb_group(43),
-	smmu_make_cb_group(44),
-	smmu_make_cb_group(45),
-	smmu_make_cb_group(46),
-	smmu_make_cb_group(47),
-	smmu_make_cb_group(48),
-	smmu_make_cb_group(49),
-	smmu_make_cb_group(50),
-	smmu_make_cb_group(51),
-	smmu_make_cb_group(52),
-	smmu_make_cb_group(53),
-	smmu_make_cb_group(54),
-	smmu_make_cb_group(55),
-	smmu_make_cb_group(56),
-	smmu_make_cb_group(57),
-	smmu_make_cb_group(58),
-	smmu_make_cb_group(59),
-	smmu_make_cb_group(60),
-	smmu_make_cb_group(61),
-	smmu_make_cb_group(62),
-	smmu_make_cb_group(63),
+	smmu_make_cfg(TEGRA_SMMU0_BASE),
+	smmu_make_cfg(TEGRA_SMMU2_BASE),
 	smmu_bypass_cfg,	/* TBU settings */
 	_END_OF_TABLE_,
 };
diff --git a/plat/nvidia/tegra/soc/t194/plat_trampoline.S b/plat/nvidia/tegra/soc/t194/plat_trampoline.S
index 33c7e6f..696a577 100644
--- a/plat/nvidia/tegra/soc/t194/plat_trampoline.S
+++ b/plat/nvidia/tegra/soc/t194/plat_trampoline.S
@@ -12,7 +12,7 @@
 
 #define TEGRA194_STATE_SYSTEM_SUSPEND	0x5C7
 #define TEGRA194_STATE_SYSTEM_RESUME	0x600D
-#define TEGRA194_SMMU_CTX_SIZE		0x490
+#define TEGRA194_SMMU_CTX_SIZE		0x80B
 
 	.align 4
 	.globl	tegra194_cpu_reset_handler
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/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 b4762f3..193d80e 100644
--- a/plat/renesas/rcar/bl2_plat_setup.c
+++ b/plat/renesas/rcar/bl2_plat_setup.c
@@ -415,6 +415,9 @@
 	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) {
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/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/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/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 c80aef6..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'
  */
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/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/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/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
index 85cffcb..6e53bd8 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_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 = &gem_nodes,
-		.num_nodes = ARRAY_SIZE(gem_nodes),
+		.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 []) {
+			EXT_CLK_GEM0_RX_EMIO | CLK_EXTERNAL_PARENT,
+			CLK_NA_PARENT
+		}),
+		.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 []) {
-			CLK_GEM3_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
-			EXT_CLK_GEM3_EMIO | CLK_EXTERNAL_PARENT,
+			EXT_CLK_GEM1_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_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_EMIO)] = {
-		.name = "gem0_emio_clk",
+	[EXT_CLK_INDEX(EXT_CLK_GEM0_TX_EMIO)] = {
+		.name = "gem0_tx_ext",
 	},
-	[EXT_CLK_INDEX(EXT_CLK_GEM1_EMIO)] = {
-		.name = "gem1_emio_clk",
+	[EXT_CLK_INDEX(EXT_CLK_GEM1_TX_EMIO)] = {
+		.name = "gem1_tx_ext",
 	},
-	[EXT_CLK_INDEX(EXT_CLK_GEM2_EMIO)] = {
-		.name = "gem2_emio_clk",
+	[EXT_CLK_INDEX(EXT_CLK_GEM2_TX_EMIO)] = {
+		.name = "gem2_tx_ext",
 	},
-	[EXT_CLK_INDEX(EXT_CLK_GEM3_EMIO)] = {
-		.name = "gem3_emio_clk",
+	[EXT_CLK_INDEX(EXT_CLK_GEM3_TX_EMIO)] = {
+		.name = "gem3_tx_ext",
+	},
+	[EXT_CLK_INDEX(EXT_CLK_GEM0_RX_EMIO)] = {
+		.name = "gem0_rx_ext",
+	},
+	[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;
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
index 9717ca8..48f5a5e 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,
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
index e0b9816..cd6f44f 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
  *
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
index 282ca3d..56c0043 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
  */
@@ -116,6 +116,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 88%
rename from services/std_svc/spm_mm/spm_main.c
rename to services/std_svc/spm_mm/spm_mm_main.c
index 706b69d..14c0038 100644
--- a/services/std_svc/spm_mm/spm_main.c
+++ b/services/std_svc/spm_mm/spm_mm_main.c
@@ -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.
@@ -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'))