Merge pull request #1745 from svenauhagen/bugfix/a8k

Armada8k GPIO Register macro fix
diff --git a/Makefile b/Makefile
index 3de7b3f..4e606a2 100644
--- a/Makefile
+++ b/Makefile
@@ -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
 #
@@ -242,6 +242,7 @@
 TF_LDFLAGS		+=	$(TF_LDFLAGS_$(ARCH))
 
 DTC_FLAGS		+=	-I dts -O dtb
+DTC_CPPFLAGS		+=	-nostdinc -Iinclude -undef -x assembler-with-cpp
 
 ################################################################################
 # Common sources and include directories
@@ -584,7 +585,6 @@
 $(eval $(call assert_boolean,CTX_INCLUDE_AARCH32_REGS))
 $(eval $(call assert_boolean,CTX_INCLUDE_FPREGS))
 $(eval $(call assert_boolean,DEBUG))
-$(eval $(call assert_boolean,DISABLE_PEDANTIC))
 $(eval $(call assert_boolean,DYN_DISABLE_AUTH))
 $(eval $(call assert_boolean,EL3_EXCEPTION_HANDLING))
 $(eval $(call assert_boolean,ENABLE_AMU))
@@ -613,7 +613,7 @@
 $(eval $(call assert_boolean,SAVE_KEYS))
 $(eval $(call assert_boolean,SEPARATE_CODE_AND_RODATA))
 $(eval $(call assert_boolean,SPIN_ON_BL1_EXIT))
-$(eval $(call assert_boolean,SPM_DEPRECATED))
+$(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_ROMLIB))
@@ -667,7 +667,7 @@
 $(eval $(call add_define,SMCCC_MAJOR_VERSION))
 $(eval $(call add_define,SPD_${SPD}))
 $(eval $(call add_define,SPIN_ON_BL1_EXIT))
-$(eval $(call add_define,SPM_DEPRECATED))
+$(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_ROMLIB))
diff --git a/bl1/bl1_private.h b/bl1/bl1_private.h
index bdbf80f..927c7b8 100644
--- a/bl1/bl1_private.h
+++ b/bl1/bl1_private.h
@@ -9,16 +9,7 @@
 
 #include <stdint.h>
 
-#include <lib/utils_def.h>
-
-/*******************************************************************************
- * Declarations of linker defined symbols which will tell us where BL1 lives
- * in Trusted ROM and RAM
- ******************************************************************************/
-IMPORT_SYM(uintptr_t, __BL1_ROM_END__,   BL1_ROM_END);
-
-IMPORT_SYM(uintptr_t, __BL1_RAM_START__, BL1_RAM_BASE);
-IMPORT_SYM(uintptr_t, __BL1_RAM_END__,   BL1_RAM_LIMIT);
+#include <common/bl_common.h>
 
 /******************************************
  * Function prototypes
@@ -36,4 +27,5 @@
 		void *cookie,
 		void *handle,
 		unsigned int flags);
+
 #endif /* BL1_PRIVATE_H */
diff --git a/bl2/bl2_private.h b/bl2/bl2_private.h
index 01f6c6b..b1704d2 100644
--- a/bl2/bl2_private.h
+++ b/bl2/bl2_private.h
@@ -7,22 +7,7 @@
 #ifndef BL2_PRIVATE_H
 #define BL2_PRIVATE_H
 
-#if BL2_IN_XIP_MEM
-
-#include <stdint.h>
-
-/*******************************************************************************
- * Declarations of linker defined symbols which will tell us where BL2 lives
- * in Trusted ROM and RAM
- ******************************************************************************/
-extern uintptr_t __BL2_ROM_END__;
-#define BL2_ROM_END (uintptr_t)(&__BL2_ROM_END__)
-
-extern uintptr_t __BL2_RAM_START__;
-extern uintptr_t __BL2_RAM_END__;
-#define BL2_RAM_BASE (uintptr_t)(&__BL2_RAM_START__)
-#define BL2_RAM_LIMIT (uintptr_t)(&__BL2_RAM_END__)
-#endif
+#include <common/bl_common.h>
 
 /******************************************
  * Forward declarations
diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S
index 5925e0c..1af1962 100644
--- a/bl31/bl31.ld.S
+++ b/bl31/bl31.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
  */
@@ -143,6 +143,10 @@
            "cpu_ops not defined for this platform.")
 
 #if ENABLE_SPM
+#ifndef SPM_SHIM_EXCEPTIONS_VMA
+#define SPM_SHIM_EXCEPTIONS_VMA         RAM
+#endif
+
     /*
      * Exception vectors of the SPM shim layer. They must be aligned to a 2K
      * address, but we need to place them in a separate page so that we can set
@@ -156,7 +160,10 @@
         *(.spm_shim_exceptions)
         . = ALIGN(PAGE_SIZE);
         __SPM_SHIM_EXCEPTIONS_END__ = .;
-    } >RAM
+    } >SPM_SHIM_EXCEPTIONS_VMA AT>RAM
+
+    PROVIDE(__SPM_SHIM_EXCEPTIONS_LMA__ = LOADADDR(spm_shim_exceptions));
+    . = LOADADDR(spm_shim_exceptions) + SIZEOF(spm_shim_exceptions);
 #endif
 
     /*
@@ -240,7 +247,7 @@
          * Time-stamps are stored in normal .bss memory
          *
          * The compiler will allocate enough memory for one CPU's time-stamps,
-         * the remaining memory for other CPU's is allocated by the
+         * the remaining memory for other CPUs is allocated by the
          * linker script
          */
         . = ALIGN(CACHE_WRITEBACK_GRANULE);
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index eddd164..89f5896 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -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
 #
@@ -8,12 +8,12 @@
 # Include SPM Makefile
 ################################################################################
 ifeq (${ENABLE_SPM},1)
-  ifeq (${SPM_DEPRECATED},1)
+  ifeq (${SPM_MM},1)
     ifeq (${EL3_EXCEPTION_HANDLING},0)
       $(error EL3_EXCEPTION_HANDLING must be 1 for SPM support)
     endif
-    $(info Including deprecated SPM makefile)
-    include services/std_svc/spm_deprecated/spm.mk
+    $(info Including makefile of SPM based on MM)
+    include services/std_svc/spm_mm/spm.mk
   else
     $(info Including SPM makefile)
     include services/std_svc/spm/spm.mk
diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c
index 927cda2..da35f75 100644
--- a/bl31/bl31_main.c
+++ b/bl31/bl31_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
  */
@@ -68,7 +68,7 @@
  * before passing control to the bootloader or an Operating System. This
  * function calls runtime_svc_init() which initializes all registered runtime
  * services. The run time services would setup enough context for the core to
- * swtich to the next exception level. When this function returns, the core will
+ * switch to the next exception level. When this function returns, the core will
  * switch to the programmed exception level via. an ERET.
  ******************************************************************************/
 void bl31_main(void)
@@ -96,13 +96,13 @@
 	 * decide which is the next image (BL32 or BL33) and how to execute it.
 	 * If the SPD runtime service is present, it would want to pass control
 	 * to BL32 first in S-EL1. In that case, SPD would have registered a
-	 * function to intialize bl32 where it takes responsibility of entering
+	 * function to initialize bl32 where it takes responsibility of entering
 	 * S-EL1 and returning control back to bl31_main. Once this is done we
 	 * can prepare entry into BL33 as normal.
 	 */
 
 	/*
-	 * If SPD had registerd an init hook, invoke it.
+	 * If SPD had registered an init hook, invoke it.
 	 */
 	if (bl32_init != NULL) {
 		INFO("BL31: Initializing BL32\n");
diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S
index ba9d342..3cd427d 100644
--- a/bl32/sp_min/sp_min.ld.S
+++ b/bl32/sp_min/sp_min.ld.S
@@ -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
  */
@@ -167,7 +167,7 @@
          * Time-stamps are stored in normal .bss memory
          *
          * The compiler will allocate enough memory for one CPU's time-stamps,
-         * the remaining memory for other CPU's is allocated by the
+         * the remaining memory for other CPUs is allocated by the
          * linker script
          */
         . = ALIGN(CACHE_WRITEBACK_GRANULE);
diff --git a/bl32/sp_min/sp_min_main.c b/bl32/sp_min/sp_min_main.c
index 3cb1990..f39e33b 100644
--- a/bl32/sp_min/sp_min_main.c
+++ b/bl32/sp_min/sp_min_main.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
  */
@@ -35,7 +35,7 @@
 static smc_ctx_t sp_min_smc_context[PLATFORM_CORE_COUNT];
 
 /******************************************************************************
- * Define the smccc helper library API's
+ * Define the smccc helper library APIs
  *****************************************************************************/
 void *smc_get_ctx(unsigned int security_state)
 {
diff --git a/bl32/tsp/tsp_main.c b/bl32/tsp/tsp_main.c
index 24efa61..e042d96 100644
--- a/bl32/tsp/tsp_main.c
+++ b/bl32/tsp/tsp_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -362,7 +362,7 @@
 
 	/*
 	 * Request a service back from dispatcher/secure monitor. This call
-	 * return and thereafter resume exectuion
+	 * return and thereafter resume execution
 	 */
 	tsp_get_magic(service_args);
 
@@ -395,7 +395,7 @@
 }
 
 /*******************************************************************************
- * TSP smc abort handler. This function is called when aborting a preemtped
+ * TSP smc abort handler. This function is called when aborting a preempted
  * yielding SMC request. It should cleanup all resources owned by the SMC
  * handler such as locks or dynamically allocated memory so following SMC
  * request are executed in a clean environment.
diff --git a/bl32/tsp/tsp_timer.c b/bl32/tsp/tsp_timer.c
index 3592863..d1ff2b0 100644
--- a/bl32/tsp/tsp_timer.c
+++ b/bl32/tsp/tsp_timer.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -80,7 +80,7 @@
 }
 
 /*******************************************************************************
- * This function restores the timer context post cpu resummption
+ * This function restores the timer context post cpu resumption
  ******************************************************************************/
 void tsp_generic_timer_restore(void)
 {
diff --git a/common/backtrace/backtrace.c b/common/backtrace/backtrace.c
index bf60a08..ecc65c9 100644
--- a/common/backtrace/backtrace.c
+++ b/common/backtrace/backtrace.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
  */
@@ -231,7 +231,7 @@
  * Usage of the trace: addr2line can be used to map the addresses to function
  * and source code location when given the ELF file compiled with debug
  * information. The "-i" flag is highly recommended to improve display of
- * inlined function. The *.dump files generated when buildidng each image can
+ * inlined function. The *.dump files generated when building each image can
  * also be used.
  *
  * WARNING: In case of corrupted stack, this function could display security
diff --git a/common/desc_image_load.c b/common/desc_image_load.c
index ada02f8..405bb83 100644
--- a/common/desc_image_load.c
+++ b/common/desc_image_load.c
@@ -20,11 +20,28 @@
  ******************************************************************************/
 void flush_bl_params_desc(void)
 {
-	flush_dcache_range((uintptr_t)bl_mem_params_desc_ptr,
-			sizeof(*bl_mem_params_desc_ptr) * bl_mem_params_desc_num);
+	flush_bl_params_desc_args(bl_mem_params_desc_ptr,
+		bl_mem_params_desc_num,
+		&next_bl_params);
+}
+
+/*******************************************************************************
+ * This function flushes the data structures specified as arguments so that they
+ * are visible in memory for the next BL image.
+ ******************************************************************************/
+void flush_bl_params_desc_args(bl_mem_params_node_t *mem_params_desc_ptr,
+	unsigned int mem_params_desc_num,
+	bl_params_t *next_bl_params_ptr)
+{
+	assert(mem_params_desc_ptr != NULL);
+	assert(mem_params_desc_num != 0U);
+	assert(next_bl_params_ptr != NULL);
+
+	flush_dcache_range((uintptr_t)mem_params_desc_ptr,
+		sizeof(*mem_params_desc_ptr) * mem_params_desc_num);
 
-	flush_dcache_range((uintptr_t)&next_bl_params,
-			sizeof(next_bl_params));
+	flush_dcache_range((uintptr_t)next_bl_params_ptr,
+			sizeof(*next_bl_params_ptr));
 }
 
 /*******************************************************************************
diff --git a/docs/auth-framework.rst b/docs/auth-framework.rst
index c934824..e0b569f 100644
--- a/docs/auth-framework.rst
+++ b/docs/auth-framework.rst
@@ -160,7 +160,7 @@
 particular image in BL1 or BL2. For each BL image that requires authentication,
 the Generic code asks recursively the Authentication module what is the parent
 image until either an authenticated image or the ROT is reached. Then the
-Generic code calls the IO framewotk to load the image and calls the
+Generic code calls the IO framework to load the image and calls the
 Authentication module to authenticate it, following the CoT from ROT to Image.
 
 TF-A Platform Port (PP)
@@ -422,7 +422,7 @@
 -  ``_name``: a string containing the IPL name for debugging purposes.
 -  ``_init``: initialization function pointer.
 -  ``_check_int``: check image integrity function pointer.
--  ``_get_param``: extract authentication parameter funcion pointer.
+-  ``_get_param``: extract authentication parameter function pointer.
 
 The ``init()`` function will be used to initialize the IPL.
 
@@ -925,7 +925,7 @@
 The mbedTLS library algorithm support is configured by the
 ``TF_MBEDTLS_KEY_ALG`` variable which can take in 3 values: `rsa`, `ecdsa` or
 `rsa+ecdsa`. This variable allows the Makefile to include the corresponding
-sources in the build for the various algorthms. Setting the variable to
+sources in the build for the various algorithms. Setting the variable to
 `rsa+ecdsa` enables support for both rsa and ecdsa algorithms in the mbedTLS
 library.
 
diff --git a/docs/change-log.rst b/docs/change-log.rst
index d329e83..11fcf21 100644
--- a/docs/change-log.rst
+++ b/docs/change-log.rst
@@ -10,7 +10,7 @@
 New Features
 ------------
 
--  Removal of a number of deprecated API's
+-  Removal of a number of deprecated APIs
 
    -  A new Platform Compatibility Policy document has been created which
       references a wiki page that maintains a listing of deprecated
@@ -20,7 +20,7 @@
       from the code base.
 
    -  Various Arm and partner platforms have been updated to remove the use of
-      removed API's in this release.
+      removed APIs in this release.
 
    -  This release is otherwise unchanged from 1.6 release
 
@@ -130,7 +130,7 @@
       the clang linker is not used because it is unable to link TF-A objects
       due to immaturity of clang linker functionality at this time.
 
--  Refactor support API's into Libraries
+-  Refactor support APIs into Libraries
 
    -  Evolve libfdt, mbed TLS library and standard C library sources as
       proper libraries that TF-A may be linked against.
@@ -435,7 +435,7 @@
 
    -  Introduced APIs to get and set the memory attributes of a region.
 
-   -  Added support to manage both priviledge levels in translation regimes that
+   -  Added support to manage both privilege levels in translation regimes that
       describe translations for 2 Exception levels, specifically the EL1&0
       translation regime, and extended the memory map region attributes to
       include specifying Non-privileged access.
@@ -683,7 +683,7 @@
 -  Enhancements to Firmware Update feature:
 
    -  The FWU logic now checks for overlapping images to prevent execution of
-      unauthenticated arbitary code.
+      unauthenticated arbitrary code.
 
    -  Introduced new FWU_SMC_IMAGE_RESET SMC that changes the image loading
       state machine to go from COPYING, COPIED or AUTHENTICATED states to
@@ -855,7 +855,7 @@
 
    -  Essential control registers are fully initialised on EL3 start-up, when
       initialising the non-secure and secure context structures and when
-      preparing to leave EL3 for a lower EL. This gives better alignement with
+      preparing to leave EL3 for a lower EL. This gives better alignment with
       the Arm ARM which states that software must initialise RES0 and RES1
       fields with 0 / 1.
 
@@ -1345,7 +1345,7 @@
 -  It is now possible to specify the name of the FIP at build time by defining
    the ``FIP_NAME`` variable.
 
--  Issues with depedencies on the 'fiptool' makefile target have been
+-  Issues with dependencies on the 'fiptool' makefile target have been
    rectified. The ``fip_create`` tool is now rebuilt whenever its source files
    change.
 
@@ -1376,7 +1376,7 @@
       the secure world. This can be done by setting the build flag
       ``FVP_TSP_RAM_LOCATION`` to the value ``dram``.
 
--  Separate transation tables are created for each boot loader image. The
+-  Separate translation tables are created for each boot loader image. The
    ``IMAGE_BLx`` build options are used to do this. This allows each stage to
    create mappings only for areas in the memory map that it needs.
 
@@ -1530,7 +1530,7 @@
    -  Clarified the platform porting interface to the TSP.
 
    -  Reworked the TSPD setup code to support the alternate BL3-2
-      intialization flow where BL3-1 generic code hands control to BL3-2,
+      initialization flow where BL3-1 generic code hands control to BL3-2,
       rather than expecting the TSPD to hand control directly to BL3-2.
 
    -  Considerable rework to PSCI generic code to support CPU specific
@@ -1569,7 +1569,7 @@
 
 -  Removed the concept of top/bottom image loading. The image loader now
    automatically detects the position of the image inside the current memory
-   layout and updates the layout to minimize fragementation. This resolves the
+   layout and updates the layout to minimize fragmentation. This resolves the
    image loader limitations of previously releases. There are currently no
    plans to support dynamic image loading.
 
diff --git a/docs/coding-guidelines.rst b/docs/coding-guidelines.rst
new file mode 100644
index 0000000..5a30e91
--- /dev/null
+++ b/docs/coding-guidelines.rst
@@ -0,0 +1,553 @@
+Trusted Firmware-A Coding Guidelines
+====================================
+
+.. section-numbering::
+    :suffix: .
+
+.. contents::
+
+The following sections contain TF coding guidelines. They are continually
+evolving and should not be considered "set in stone". Feel free to question them
+and provide feedback.
+
+Some of the guidelines may also apply to other codebases.
+
+**Note:** the existing TF codebase does not necessarily comply with all the
+below guidelines but the intent is for it to do so eventually.
+
+Checkpatch overrides
+--------------------
+
+Some checkpatch warnings in the TF codebase are deliberately ignored. These
+include:
+
+- ``**WARNING: line over 80 characters**``: Although the codebase should
+  generally conform to the 80 character limit this is overly restrictive in some
+  cases.
+
+- ``**WARNING: Use of volatile is usually wrong``: see
+  `Why the “volatile” type class should not be used`_ . Although this document
+  contains some very useful information, there are several legimate uses of the
+  volatile keyword within the TF codebase.
+
+Headers and inclusion
+---------------------
+
+Header guards
+^^^^^^^^^^^^^
+
+For a header file called "some_driver.h" the style used by the Trusted Firmware
+is:
+
+.. code:: c
+
+  #ifndef SOME_DRIVER_H
+  #define SOME_DRIVER_H
+
+  <header content>
+
+  #endif /* SOME_DRIVER_H */
+
+Include statement ordering
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+All header files that are included by a source file must use the following,
+grouped ordering. This is to improve readability (by making it easier to quickly
+read through the list of headers) and maintainability.
+
+#. *System* includes: Header files from the standard *C* library, such as
+   ``stddef.h`` and ``string.h``.
+
+#. *Project* includes: Header files under the ``include/`` directory within TF
+   are *project* includes.
+
+#. *Platform* includes: Header files relating to a single, specific platform,
+   and which are located under the ``plat/<platform_name>`` directory within TF,
+   are *platform* includes.
+
+Within each group, ``#include`` statements must be in alphabetical order,
+taking both the file and directory names into account.
+
+Groups must be separated by a single blank line for clarity.
+
+The example below illustrates the ordering rules using some contrived header
+file names; this type of name reuse should be otherwise avoided.
+.. code:: c
+
+  #include <string.h>
+
+  #include <a_dir/example/a_header.h>
+  #include <a_dir/example/b_header.h>
+  #include <a_dir/test/a_header.h>
+  #include <b_dir/example/a_header.h>
+
+  #include "./a_header.h"
+
+Include statement variants
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Two variants of the ``#include`` directive are acceptable in the TF codebase.
+Correct use of the two styles improves readability by suggesting the location
+of the included header and reducing ambiguity in cases where generic and
+platform-specific headers share a name.
+
+For header files that are in the same directory as the source file that is
+including them, use the ``"..."`` variant.
+
+For header files that are **not** in the same directory as the source file that
+is including them, use the ``<...>`` variant.
+
+Example (bl1_fwu.c):
+.. code:: c
+
+  #include <assert.h>
+  #include <errno.h>
+  #include <string.h>
+
+  #include "bl1_private.h"
+
+Platform include paths
+^^^^^^^^^^^^^^^^^^^^^^
+
+Platforms are allowed to add more include paths to be passed to the compiler.
+The ``PLAT_INCLUDES`` variable is used for this purpose. This is needed in
+particular for the file ``platform_def.h``.
+
+Example:
+.. code:: c
+
+  PLAT_INCLUDES  += -Iinclude/plat/myplat/include
+
+Types and typedefs
+------------------
+
+Use of built-in *C* and *libc* data types
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The TF codebase should be kept as portable as possible, especially since both
+64-bit and 32-bit platforms are supported. To help with this, the following data
+type usage guidelines should be followed:
+
+- Where possible, use the built-in *C* data types for variable storage (for
+  example, ``char``, ``int``, ``long long``, etc) instead of the standard *C99*
+  types. Most code is typically only concerned with the minimum size of the
+  data stored, which the built-in *C* types guarantee.
+
+- Avoid using the exact-size standard *C99* types in general (for example,
+  ``uint16_t``, ``uint32_t``, ``uint64_t``, etc) since they can prevent the
+  compiler from making optimizations. There are legitimate uses for them,
+  for example to represent data of a known structure. When using them in struct
+  definitions, consider how padding in the struct will work across architectures.
+  For example, extra padding may be introduced in AArch32 systems if a struct
+  member crosses a 32-bit boundary.
+
+- Use ``int`` as the default integer type - it's likely to be the fastest on all
+  systems. Also this can be assumed to be 32-bit as a consequence of the
+  `Procedure Call Standard for the Arm Architecture`_ and the `Procedure Call
+  Standard for the Arm 64-bit Architecture`_ .
+
+- Avoid use of ``short`` as this may end up being slower than ``int`` in some
+  systems. If a variable must be exactly 16-bit, use ``int16_t`` or
+  ``uint16_t``.
+
+- Avoid use of ``long``. This is guaranteed to be at least 32-bit but, given
+  that `int` is 32-bit on Arm platforms, there is no use for it. For integers of
+  at least 64-bit, use ``long long``.
+
+- Use ``char`` for storing text. Use ``uint8_t`` for storing other 8-bit data.
+
+- Use ``unsigned`` for integers that can never be negative (counts,
+  indices, sizes, etc). TF intends to comply with MISRA "essential type" coding
+  rules (10.X), where signed and unsigned types are considered different
+  essential types. Choosing the correct type will aid this. MISRA static
+  analysers will pick up any implicit signed/unsigned conversions that may lead
+  to unexpected behaviour.
+
+- For pointer types:
+
+  - If an argument in a function declaration is pointing to a known type then
+    simply use a pointer to that type (for example: ``struct my_struct *``).
+
+  - If a variable (including an argument in a function declaration) is pointing
+    to a general, memory-mapped address, an array of pointers or another
+    structure that is likely to require pointer arithmetic then use
+    ``uintptr_t``. This will reduce the amount of casting required in the code.
+    Avoid using ``unsigned long`` or ``unsigned long long`` for this purpose; it
+    may work but is less portable.
+
+  - For other pointer arguments in a function declaration, use ``void *``. This
+    includes pointers to types that are abstracted away from the known API and
+    pointers to arbitrary data. This allows the calling function to pass a
+    pointer argument to the function without any explicit casting (the cast to
+    ``void *`` is implicit). The function implementation can then do the
+    appropriate casting to a specific type.
+
+  - Use ``ptrdiff_t`` to compare the difference between 2 pointers.
+
+- Use ``size_t`` when storing the ``sizeof()`` something.
+
+- Use ``ssize_t`` when returning the ``sizeof()`` something from a function that
+  can also return an error code; the signed type allows for a negative return
+  code in case of error. This practice should be used sparingly.
+
+- Use ``u_register_t`` when it's important to store the contents of a register
+  in its native size (32-bit in AArch32 and 64-bit in AArch64). This is not a
+  standard *C99* type but is widely available in libc implementations,
+  including the FreeBSD version included with the TF codebase. Where possible,
+  cast the variable to a more appropriate type before interpreting the data. For
+  example, the following struct in ``ep_info.h`` could use this type to minimize
+  the storage required for the set of registers:
+
+.. code:: c
+
+    typedef struct aapcs64_params {
+            u_register_t arg0;
+            u_register_t arg1;
+            u_register_t arg2;
+            u_register_t arg3;
+            u_register_t arg4;
+            u_register_t arg5;
+            u_register_t arg6;
+            u_register_t arg7;
+    } aapcs64_params_t;
+
+
+    If some code wants to operate on ``arg0`` and knows that it represents a
+    32-bit unsigned integer on all systems, cast it to ``unsigned int``.
+
+These guidelines should be updated if additional types are needed.
+
+Avoid anonymous typedefs of structs/enums in headers
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For example, the following definition:
+
+.. code:: c
+
+  typedef struct {
+          int arg1;
+          int arg2;
+  } my_struct_t;
+
+
+is better written as:
+
+.. code:: c
+
+  struct my_struct {
+          int arg1;
+          int arg2;
+  };
+
+This allows function declarations in other header files that depend on the
+struct/enum to forward declare the struct/enum instead of including the
+entire header:
+
+.. code:: c
+
+  #include <my_struct.h>
+  void my_func(my_struct_t *arg);
+
+instead of:
+
+.. code:: c
+
+  struct my_struct;
+  void my_func(struct my_struct *arg);
+
+Some TF definitions use both a struct/enum name **and** a typedef name. This
+is discouraged for new definitions as it makes it difficult for TF to comply
+with MISRA rule 8.3, which states that "All declarations of an object or
+function shall use the same names and type qualifiers".
+
+The Linux coding standards also discourage new typedefs and checkpatch emits
+a warning for this.
+
+Existing typedefs will be retained for compatibility.
+
+Error handling and robustness
+-----------------------------
+
+Using CASSERT to check for compile time data errors
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Where possible, use the ``CASSERT`` macro to check the validity of data known at
+compile time instead of checking validity at runtime, to avoid unnecessary
+runtime code.
+
+For example, this can be used to check that the assembler's and compiler's views
+of the size of an array is the same.
+
+.. code:: c
+
+  #include <cassert.h>
+
+  define MY_STRUCT_SIZE 8 /* Used by assembler source files */
+
+  struct my_struct {
+      uint32_t arg1;
+      uint32_t arg2;
+  };
+
+  CASSERT(MY_STRUCT_SIZE == sizeof(struct my_struct), assert_my_struct_size_mismatch);
+
+
+If ``MY_STRUCT_SIZE`` in the above example were wrong then the compiler would
+emit an error like this:
+
+.. code:: c
+
+  my_struct.h:10:1: error: size of array ‘assert_my_struct_size_mismatch’ is negative
+
+
+Using assert() to check for programming errors
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In general, each secure world TF image (BL1, BL2, BL31 and BL32) should be
+treated as a tightly integrated package; the image builder should be aware of
+and responsible for all functionality within the image, even if code within that
+image is provided by multiple entities. This allows us to be more aggressive in
+interpreting invalid state or bad function arguments as programming errors using
+``assert()``, including arguments passed across platform porting interfaces.
+This is in contrast to code in a Linux environment, which is less tightly
+integrated and may attempt to be more defensive by passing the error back up the
+call stack.
+
+Where possible, badly written TF code should fail early using ``assert()``. This
+helps reduce the amount of untested conditional code. By default these
+statements are not compiled into release builds, although this can be overridden
+using the ``ENABLE_ASSERTIONS`` build flag.
+
+Examples:
+
+- Bad argument supplied to library function
+- Bad argument provided by platform porting function
+- Internal secure world image state is inconsistent
+
+
+Handling integration errors
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Each secure world image may be provided by a different entity (for example, a
+Trusted Boot vendor may provide the BL2 image, a TEE vendor may provide the BL32
+image and the OEM/SoC vendor may provide the other images).
+
+An image may contain bugs that are only visible when the images are integrated.
+The system integrator may not even have access to the debug variants of all the
+images in order to check if asserts are firing. For example, the release variant
+of BL1 may have already been burnt into the SoC. Therefore, TF code that detects
+an integration error should _not_ consider this a programming error, and should
+always take action, even in release builds.
+
+If an integration error is considered non-critical it should be treated as a
+recoverable error. If the error is considered critical it should be treated as
+an unexpected unrecoverable error.
+
+Handling recoverable errors
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The secure world **must not** crash when supplied with bad data from an external
+source. For example, data from the normal world or a hardware device. Similarly,
+the secure world **must not** crash if it detects a non-critical problem within
+itself or the system. It must make every effort to recover from the problem by
+emitting a ``WARN`` message, performing any necessary error handling and
+continuing.
+
+Examples:
+
+- Secure world receives SMC from normal world with bad arguments.
+- Secure world receives SMC from normal world at an unexpected time.
+- BL31 receives SMC from BL32 with bad arguments.
+- BL31 receives SMC from BL32 at unexpected time.
+- Secure world receives recoverable error from hardware device. Retrying the
+  operation may help here.
+- Non-critical secure world service is not functioning correctly.
+- BL31 SPD discovers minor configuration problem with corresponding SP.
+
+Handling unrecoverable errors
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In some cases it may not be possible for the secure world to recover from an
+error. This situation should be handled in one of the following ways:
+
+1. If the unrecoverable error is unexpected then emit an ``ERROR`` message and
+   call ``panic()``. This will end up calling the platform-specific function
+   ``plat_panic_handler()``.
+2. If the unrecoverable error is expected to occur in certain circumstances,
+   then emit an ``ERROR`` message and call the platform-specific function
+   ``plat_error_handler()``.
+
+Cases 1 and 2 are subtly different. A platform may implement ``plat_panic_handler``
+and ``plat_error_handler`` in the same way (for example, by waiting for a secure
+watchdog to time-out or by invoking an interface on the platform's power
+controller to reset the platform). However, ``plat_error_handler`` may take
+additional action for some errors (for example, it may set a flag so the
+platform resets into a different mode). Also, ``plat_panic_handler()`` may
+implement additional debug functionality (for example, invoking a hardware
+breakpoint).
+
+Examples of unexpected unrecoverable errors:
+
+- BL32 receives an unexpected SMC response from BL31 that it is unable to
+  recover from.
+- BL31 Trusted OS SPD code discovers that BL2 has not loaded the corresponding
+  Trusted OS, which is critical for platform operation.
+- Secure world discovers that a critical hardware device is an unexpected and
+  unrecoverable state.
+- Secure world receives an unexpected and unrecoverable error from a critical
+  hardware device.
+- Secure world discovers that it is running on unsupported hardware.
+
+Examples of expected unrecoverable errors:
+
+- BL1/BL2 fails to load the next image due to missing/corrupt firmware on disk.
+- BL1/BL2 fails to authenticate the next image due to an invalid certificate.
+- Secure world continuously receives recoverable errors from a hardware device
+  but is unable to proceed without a valid response.
+
+Handling critical unresponsiveness
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If the secure world is waiting for a response from an external source (for
+example, the normal world or a hardware device) which is critical for continued
+operation, it must not wait indefinitely. It must have a mechanism (for example,
+a secure watchdog) for resetting itself and/or the external source to prevent
+the system from executing in this state indefinitely.
+
+Examples:
+
+- BL1 is waiting for the normal world to raise an SMC to proceed to the next
+  stage of the secure firmware update process.
+- A Trusted OS is waiting for a response from a proxy in the normal world that
+  is critical for continued operation.
+- Secure world is waiting for a hardware response that is critical for continued
+  operation.
+
+Security considerations
+-----------------------
+
+Part of the security of a platform is handling errors correctly, as described in
+the previous section. There are several other security considerations covered in
+this section.
+
+Do not leak secrets to the normal world
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The secure world **must not** leak secrets to the normal world, for example in
+response to an SMC.
+
+Handling Denial of Service attacks
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The secure world **should never** crash or become unusable due to receiving too
+many normal world requests (a *Denial of Service* or *DoS* attack). It should
+have a mechanism for throttling or ignoring normal world requests.
+
+Performance considerations
+--------------------------
+
+Avoid printf and use logging macros
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+``debug.h`` provides logging macros (for example, ``WARN`` and ``ERROR``)
+which wrap ``tf_log`` and which allow the logging call to be compiled-out
+depending on the ``make`` command. Use these macros to avoid print statements
+being compiled unconditionally into the binary.
+
+Each logging macro has a numerical log level:
+
+.. code:: c
+
+  #define LOG_LEVEL_NONE    0
+  #define LOG_LEVEL_ERROR   10
+  #define LOG_LEVEL_NOTICE  20
+  #define LOG_LEVEL_WARNING 30
+  #define LOG_LEVEL_INFO    40
+  #define LOG_LEVEL_VERBOSE 50
+
+
+By default, all logging statements with a log level ``<= LOG_LEVEL_INFO`` will
+be compiled into debug builds and all statements with a log level
+``<= LOG_LEVEL_NOTICE`` will be compiled into release builds. This can be
+overridden from the command line or by the platform makefile (although it may be
+necessary to clean the build directory first). For example, to enable
+``VERBOSE`` logging on FVP:
+
+``make PLAT=fvp LOG_LEVEL=50 all``
+
+Use const data where possible
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For example, the following code:
+
+.. code:: c
+
+  struct my_struct {
+          int arg1;
+          int arg2;
+  };
+
+  void init(struct my_struct *ptr);
+
+  void main(void)
+  {
+          struct my_struct x;
+          x.arg1 = 1;
+          x.arg2 = 2;
+          init(&x);
+  }
+
+is better written as:
+
+.. code:: c
+
+  struct my_struct {
+          int arg1;
+          int arg2;
+  };
+
+  void init(const struct my_struct *ptr);
+
+  void main(void)
+  {
+          const struct my_struct x = { 1, 2 };
+          init(&x);
+  }
+
+This allows the linker to put the data in a read-only data section instead of a
+writeable data section, which may result in a smaller and faster binary. Note
+that this may require dependent functions (``init()`` in the above example) to
+have ``const`` arguments, assuming they don't need to modify the data.
+
+Library and driver code
+-----------------------
+
+TF library code (under ``lib/`` and ``include/lib``) is any code that provides a
+reusable interface to other code, potentially even to code outside of TF.
+
+In some systems drivers must conform to a specific driver framework to provide
+services to the rest of the system. TF has no driver framework and the
+distinction between a driver and library is somewhat subjective.
+
+A driver (under ``drivers/`` and ``include/drivers/``) is defined as code that
+interfaces with hardware via a memory mapped interface.
+
+Some drivers (for example, the Arm CCI driver in ``include/drivers/arm/cci.h``)
+provide a general purpose API to that specific hardware. Other drivers (for
+example, the Arm PL011 console driver in ``drivers/arm/pl011/pl011_console.S``)
+provide a specific hardware implementation of a more abstract library API. In
+the latter case there may potentially be multiple drivers for the same hardware
+device.
+
+Neither libraries nor drivers should depend on platform-specific code. If they
+require platform-specific data (for example, a base address) to operate then
+they should provide an initialization function that takes the platform-specific
+data as arguments.
+
+TF common code (under ``common/`` and ``include/common/``) is code that is re-used
+by other generic (non-platform-specific) TF code. It is effectively internal
+library code.
+
+.. _`Why the “volatile” type class should not be used`: https://www.kernel.org/doc/html/latest/process/volatile-considered-harmful.html
+.. _`Procedure Call Standard for the Arm Architecture`: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042f/IHI0042F_aapcs.pdf
+.. _`Procedure Call Standard for the Arm 64-bit Architecture`: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
diff --git a/docs/firmware-design.rst b/docs/firmware-design.rst
index 21a4d53..06fdbac 100644
--- a/docs/firmware-design.rst
+++ b/docs/firmware-design.rst
@@ -203,7 +203,7 @@
 
    The ``plat_report_exception()`` implementation on the Arm FVP port programs
    the Versatile Express System LED register in the following format to
-   indicate the occurence of an unexpected exception:
+   indicate the occurrence of an unexpected exception:
 
    ::
 
@@ -1684,6 +1684,21 @@
 Note: Loading the BL32 image in TZC secured DRAM doesn't change the memory
 layout of the other images in Trusted SRAM.
 
+CONFIG section in memory layouts shown below contains:
+
+::
+
+    +--------------------+
+    |bl2_mem_params_descs|
+    |--------------------|
+    |     fw_configs     |
+    +--------------------+
+
+``bl2_mem_params_descs`` contains parameters passed from BL2 to next the
+BL image during boot.
+
+``fw_configs`` includes soc_fw_config, tos_fw_config and tb_fw_config.
+
 **FVP with TSP in Trusted SRAM with firmware configs :**
 (These diagrams only cover the AArch64 case)
 
@@ -1708,7 +1723,7 @@
                |          |  <<<<<<<<<<<<<  |----------------|
                |          |  <<<<<<<<<<<<<  |     BL32       |
     0x04002000 +----------+                 +----------------+
-               |fw_configs|
+               |  CONFIG  |
     0x04001000 +----------+
                |  Shared  |
     0x04000000 +----------+
@@ -1745,7 +1760,7 @@
                |              |  <<<<<<<<<<<<<  | BL31 PROGBITS  |
                |              |                 +----------------+
                +--------------+
-               |  fw_configs  |
+               |    CONFIG    |
     0x04001000 +--------------+
                |    Shared    |
     0x04000000 +--------------+
@@ -1779,7 +1794,7 @@
                |          |  <<<<<<<<<<<<<  | BL31 PROGBITS  |
                |          |                 +----------------+
     0x04002000 +----------+
-               |fw_configs|
+               |  CONFIG  |
     0x04001000 +----------+
                |  Shared  |
     0x04000000 +----------+
@@ -1991,7 +2006,7 @@
 The ``psci_non_cpu_pd_nodes`` data structure stores the platform's power domain
 tree information for state management of power domains. By default, this data
 structure is allocated in the coherent memory region in TF-A because it can be
-accessed by multple CPUs, either with caches enabled or disabled.
+accessed by multiple CPUs, either with caches enabled or disabled.
 
 .. code:: c
 
@@ -2031,7 +2046,7 @@
 
 The field ``local_state`` can be concurrently accessed by multiple CPUs in
 different cache states. A Lamport's Bakery lock ``psci_locks`` is used to ensure
-mutual exlusion to this field and a clean and invalidate is needed after it
+mutual exclusion to this field and a clean and invalidate is needed after it
 is written.
 
 Bakery lock data
@@ -2225,7 +2240,7 @@
 execute-never.
 
 This has an impact on memory footprint, as padding bytes need to be introduced
-between the code and read-only data to ensure the segragation of the two. To
+between the code and read-only data to ensure the segregation of the two. To
 limit the memory cost, this flag also changes the memory layout such that the
 code and exception vectors are now contiguous, like so:
 
@@ -2352,12 +2367,12 @@
 
 The build option ``RECLAIM_INIT_CODE`` can be set to mark this boot time code
 with a ``.text.init.*`` attribute which can be filtered and placed suitably
-within the BL image for later reclaimation by the platform. The platform can
-specify the fiter and the memory region for this init section in BL31 via the
+within the BL image for later reclamation by the platform. The platform can
+specify the filter and the memory region for this init section in BL31 via the
 plat.ld.S linker script. For example, on the FVP, this section is placed
 overlapping the secondary CPU stacks so that after the cold boot is done, this
 memory can be reclaimed for the stacks. The init memory section is initially
-mapped with ``RO``, ``EXECUTE`` attributes. After BL31 initilization has
+mapped with ``RO``, ``EXECUTE`` attributes. After BL31 initialization has
 completed, the FVP changes the attributes of this section to ``RW``,
 ``EXECUTE_NEVER`` allowing it to be used for runtime data. The memory attributes
 are changed within the ``bl31_plat_runtime_setup`` platform hook. The init
@@ -2553,7 +2568,7 @@
 
 Platform implementing an Armv7-A system can to define from its target
 Cortex-A architecture through ``ARM_CORTEX_A<X> = yes`` in their
-``plaform.mk`` script. For example ``ARM_CORTEX_A15=yes`` for a
+``platform.mk`` script. For example ``ARM_CORTEX_A15=yes`` for a
 Cortex-A15 target.
 
 Platform can also set ``ARM_WITH_NEON=yes`` to enable neon support.
diff --git a/docs/firmware-update.rst b/docs/firmware-update.rst
index e10e148..3ee57bc 100644
--- a/docs/firmware-update.rst
+++ b/docs/firmware-update.rst
@@ -266,14 +266,14 @@
         if (image_id is invalid) return -EPERM
         if (secure world caller)
             if (image_id state is not RESET) return -EPERM
-            if (image_addr/image_size is not mappped into BL1) return -ENOMEM
+            if (image_addr/image_size is not mapped into BL1) return -ENOMEM
         else // normal world caller
             if (image_id is secure image)
                 if (image_id state is not COPIED) return -EPERM
             else // image_id is non-secure image
                 if (image_id state is not RESET) return -EPERM
                 if (image_addr/image_size is in secure memory) return -ENOMEM
-                if (image_addr/image_size not mappped into BL1) return -ENOMEM
+                if (image_addr/image_size not mapped into BL1) return -ENOMEM
 
 This SMC authenticates the image specified by ``image_id``. If the image is in the
 RESET state, BL1 authenticates the image in place using the provided
diff --git a/docs/plat/nvidia-tegra.rst b/docs/plat/nvidia-tegra.rst
index 56dfacf..90d2ae1 100644
--- a/docs/plat/nvidia-tegra.rst
+++ b/docs/plat/nvidia-tegra.rst
@@ -80,6 +80,10 @@
 uint64\_t tzdram\_base;
 /* UART port ID \*/
 int uart\_id;
+/* L2 ECC parity protection disable flag \*/
+int l2\_ecc\_parity\_prot\_dis;
+/* SHMEM base address for storing the boot logs \*/
+uint64\_t boot\_profiler\_shmem\_base;
 } plat\_params\_from\_bl2\_t;
 
 Power Management
diff --git a/docs/plat/warp7.rst b/docs/plat/warp7.rst
index 51c2609..6c04d91 100644
--- a/docs/plat/warp7.rst
+++ b/docs/plat/warp7.rst
@@ -31,36 +31,84 @@
     make warp7_bl33_defconfig;
     make u-boot.imx arch=ARM CROSS_COMPILE=arm-linux-gnueabihf-
 
-## TF-A:
+## OP-TEE:
 
-https://github.com/ARM-software/arm-trusted-firmware.git
+https://github.com/OP-TEE/optee_os.git
 
 .. code:: shell
 
-    make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=warp7 ARCH=aarch32 ARM_ARCH_MAJOR=7 ARM_CORTEX_A7=yes AARCH32_SP=optee all
-    /path/to/u-boot/tools/mkimage -n /path/to/u-boot/u-boot.cfgout -T imximage -e 0x9df00000 -d ./build/warp7/debug/bl2.bin ./build/warp7/debug/bl2.bin.imx
+    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- PLATFORM=imx PLATFORM_FLAVOR=mx7swarp7 ARCH=arm CFG_PAGEABLE_ADDR=0 CFG_DT_ADDR=0x83000000 CFG_NS_ENTRY_ADDR=0x87800000
 
-## OP-TEE:
+## TF-A:
 
-https://github.com/OP-TEE/optee_os.git
+https://github.com/ARM-software/arm-trusted-firmware.git
 
-.. code:: shell
+The following commands assume that a directory exits in the top-level TFA build
+directory "fiptool_images". "fiptool_images" contains
 
-    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- PLATFORM=imx PLATFORM_FLAVOR=mx7swarp7 ARCH=arm CFG_PAGEABLE_ADDR=0 CFG_DT_ADDR=0x83000000 CFG_NS_ENTRY_ADDR=0x87800000
+- u-boot.bin
+  The binary output from the u-boot instructions above
 
+- tee-header_v2.bin
+- tee-pager_v2.bin
+- tee-pageable_v2.bin
+  Binary outputs from the previous OPTEE build steps
 
-## FIP:
+It is also assumed copy of mbedtls is available on the path path ../mbedtls
+  https://github.com/ARMmbed/mbedtls.git
+  At the time of writing HEAD points to 0592ea772aee48ca1e6d9eb84eca8e143033d973
 
 .. code:: shell
 
     mkdir fiptool_images
-    cp /path/to/uboot/u-boot.bin fiptool_images
     cp /path/to/optee/out/arm-plat-imx/core/tee-header_v2.bin fiptool_images
     cp /path/to/optee/out/arm-plat-imx/core/tee-pager_v2.bin fiptool_images
     cp /path/to/optee/out/arm-plat-imx/core/tee-pageable_v2.bin fiptool_images
+
+    make CROSS_COMPILE=${CROSS_COMPILE} PLAT=warp7 ARCH=aarch32 ARM_ARCH_MAJOR=7 \
+         ARM_CORTEX_A7=yes AARCH32_SP=optee PLAT_WARP7_UART=1 GENERATE_COT=1 \
+         TRUSTED_BOARD_BOOT=1 USE_TBBR_DEFS=1 MBEDTLS_DIR=../mbedtls \
+         NEED_BL32=yes BL32=fiptool_images/tee-header_v2.bin \
+         BL32_EXTRA1=fiptool_images/tee-pager_v2.bin \
+         BL32_EXTRA2=fiptool_images/tee-pageable_v2.bin \
+         BL33=fiptool_images/u-boot.bin certificates all
+
+    /path/to/u-boot/tools/mkimage -n /path/to/u-boot/u-boot.cfgout -T imximage -e 0x9df00000 -d ./build/warp7/debug/bl2.bin ./build/warp7/debug/bl2.bin.imx
+
+## FIP:
+
+.. code:: shell
+
+    cp /path/to/uboot/u-boot.bin fiptool_images
     cp /path/to/linux/arch/boot/dts/imx7s-warp.dtb fiptool_images
-    tools/fiptool/fiptool create --tos-fw fiptool_images/tee-header_v2.bin --tos-fw-extra1 fiptool_images/tee-pager_v2.bin --tos-fw-extra2 fiptool_images/tee-pageable_v2.bin --nt-fw fiptool_images/u-boot.bin --hw-config fiptool_images/imx7s-warp.dtb warp7.fip
+
+    tools/cert_create/cert_create -n --rot-key "build/warp7/debug/rot_key.pem" \
+               --tfw-nvctr 0 \
+               --ntfw-nvctr 0 \
+               --trusted-key-cert fiptool_images/trusted-key-cert.key-crt \
+               --tb-fw=build/warp7/debug/bl2.bin \
+               --tb-fw-cert fiptool_images/trusted-boot-fw.key-crt\
+               --tos-fw fiptool_images/tee-header_v2.bin \
+               --tos-fw-cert fiptool_images/tee-header_v2.bin.crt \
+               --tos-fw-key-cert fiptool_images/tee-header_v2.bin.key-crt \
+               --tos-fw-extra1 fiptool_images/tee-pager_v2.bin \
+               --tos-fw-extra2 fiptool_images/tee-pageable_v2.bin \
+               --nt-fw fiptool_images/u-boot.bin \
+               --nt-fw-cert fiptool_images/u-boot.bin.crt \
+               --nt-fw-key-cert fiptool_images/u-boot.bin.key-crt \
+               --hw-config fiptool_images/imx7s-warp.dtb
 
+    tools/fiptool/fiptool create --tos-fw fiptool_images/tee-header_v2.bin \
+              --tos-fw-extra1 fiptool_images/tee-pager_v2.bin \
+              --tos-fw-extra2 fiptool_images/tee-pageable_v2.bin \
+              --nt-fw fiptool_images/u-boot.bin \
+              --hw-config fiptool_images/imx7s-warp.dtb \
+              --tos-fw-cert fiptool_images/tee-header_v2.bin.crt \
+              --tos-fw-key-cert fiptool_images/tee-header_v2.bin.key-crt \
+              --nt-fw-cert fiptool_images/u-boot.bin.crt \
+              --nt-fw-key-cert fiptool_images/u-boot.bin.key-crt \
+              --trusted-key-cert fiptool_images/trusted-key-cert.key-crt \
+              --tb-fw-cert fiptool_images/trusted-boot-fw.key-crt warp7.fip
 
 # Deploy Images
 
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index f1a26f4..7fc5297 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -390,7 +390,7 @@
 -  **#define : SCP\_BL2\_IMAGE\_ID**
 
    SCP\_BL2 image identifier, used by BL2 to load SCP\_BL2 into secure memory
-   from platform storage before being transfered to the SCP.
+   from platform storage before being transferred to the SCP.
 
 -  **#define : SCP\_FW\_KEY\_CERT\_ID**
 
@@ -439,9 +439,9 @@
 -  **#define : TSP\_SEC\_MEM\_SIZE**
 
    Defines the size of the secure memory used by the BL32 image on the
-   platform. ``TSP_SEC_MEM_BASE`` and ``TSP_SEC_MEM_SIZE`` must fully accomodate
-   the memory required by the BL32 image, defined by ``BL32_BASE`` and
-   ``BL32_LIMIT``.
+   platform. ``TSP_SEC_MEM_BASE`` and ``TSP_SEC_MEM_SIZE`` must fully
+   accommodate the memory required by the BL32 image, defined by ``BL32_BASE``
+   and ``BL32_LIMIT``.
 
 -  **#define : TSP\_IRQ\_SEC\_PHY\_TIMER**
 
@@ -821,11 +821,11 @@
     Argument : void
     Return   : unsigned int
 
-This funtion returns the index of the calling CPU which is used as a
+This function returns the index of the calling CPU which is used as a
 CPU-specific linear index into blocks of memory (for example while allocating
 per-CPU stacks). This function will be invoked very early in the
 initialization sequence which mandates that this function should be
-implemented in assembly and should not rely on the avalability of a C
+implemented in assembly and should not rely on the availability of a C
 runtime environment. This function can clobber x0 - x8 and must preserve
 x9 - x29.
 
@@ -929,7 +929,7 @@
 
 A platform may need to do additional initialization after reset. This function
 allows the platform to do the platform specific intializations. Platform
-specific errata workarounds could also be implemented here. The api should
+specific errata workarounds could also be implemented here. The API should
 preserve the values of callee saved registers x19 to x29.
 
 The default implementation doesn't do anything. If a platform needs to override
@@ -1543,7 +1543,7 @@
 process and is executed only by the primary CPU. BL1 passes control to BL2U at
 ``BL2U_BASE``. BL2U executes in Secure-EL1 and is responsible for:
 
-#. (Optional) Transfering the optional SCP\_BL2U binary image from AP secure
+#. (Optional) Transferring the optional SCP\_BL2U binary image from AP secure
    memory to SCP RAM. BL2U uses the SCP\_BL2U ``image_info`` passed by BL1.
    ``SCP_BL2U_BASE`` defines the address in AP secure memory where SCP\_BL2U
    should be copied from. Subsequent handling of the SCP\_BL2U image is
@@ -1649,7 +1649,7 @@
    implementation.
 
 #. Optionally passing control to the BL32 image, pre-loaded at a platform-
-   specific address by BL2. BL31 exports a set of apis that allow runtime
+   specific address by BL2. BL31 exports a set of APIs that allow runtime
    services to specify the security state in which the next image should be
    executed and run the corresponding image. On ARM platforms, BL31 uses the
    ``bl_params`` list populated by BL2 in memory to do this.
@@ -1800,7 +1800,7 @@
 ``include/lib/xlat_tables/xlat_mmu_helpers.h``.
 
 On DynamIQ systems, this function must not use stack while enabling MMU, which
-is how the function in xlat table library version 2 is implementated.
+is how the function in xlat table library version 2 is implemented.
 
 Function : plat\_get\_syscnt\_freq2() [mandatory]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2030,7 +2030,7 @@
 
 This function returns a pointer to the byte array containing the power domain
 topology tree description. The format and method to construct this array are
-described in `Power Domain Topology Design`_. The BL31 PSCI initilization code
+described in `Power Domain Topology Design`_. The BL31 PSCI initialization code
 requires this array to be described by the platform, either statically or
 dynamically, to initialize the power domain topology tree. In case the array
 is populated dynamically, then plat\_core\_pos\_by\_mpidr() and
@@ -2070,7 +2070,7 @@
 
 Perform the platform-specific actions to enter the standby state for a cpu
 indicated by the passed argument. This provides a fast path for CPU standby
-wherein overheads of PSCI state management and lock acquistion is avoided.
+wherein overheads of PSCI state management and lock acquisition is avoided.
 For this handler to be invoked by the PSCI ``CPU_SUSPEND`` API implementation,
 the suspend state type specified in the ``power-state`` parameter should be
 STANDBY and the target power domain level specified should be the CPU. The
@@ -2345,7 +2345,7 @@
 described in the `IMF Design Guide`_
 
 A platform should export the following APIs to support the IMF. The following
-text briefly describes each api and its implementation in Arm standard
+text briefly describes each API and its implementation in Arm standard
 platforms. The API implementation depends upon the type of interrupt controller
 present in the platform. Arm standard platform layer supports both
 `Arm Generic Interrupt Controller version 2.0 (GICv2)`_
@@ -2552,7 +2552,7 @@
 
 BL31 implements a crash reporting mechanism which prints the various registers
 of the CPU to enable quick crash analysis and debugging. This mechanism relies
-on the platform implementating ``plat_crash_console_init``,
+on the platform implementing ``plat_crash_console_init``,
 ``plat_crash_console_putc`` and ``plat_crash_console_flush``.
 
 The file ``plat/common/aarch64/crash_console_helpers.S`` contains sample
diff --git a/docs/psci-lib-integration-guide.rst b/docs/psci-lib-integration-guide.rst
index d86fc29..1be2240 100644
--- a/docs/psci-lib-integration-guide.rst
+++ b/docs/psci-lib-integration-guide.rst
@@ -240,7 +240,7 @@
 the EL3 Runtime Software may want to perform some bookkeeping during power
 management operations. This function is used to register the ``spd_pm_ops_t``
 (first argument) callbacks with the PSCI library which will be called
-ppropriately during power management. Calling this function is optional and
+appropriately during power management. Calling this function is optional and
 need to be called by the primary CPU during the cold boot sequence after
 ``psci_setup()`` has completed.
 
diff --git a/docs/ras.rst b/docs/ras.rst
index 4c82022..cea74e9 100644
--- a/docs/ras.rst
+++ b/docs/ras.rst
@@ -203,8 +203,8 @@
 Engaging the RAS framework
 --------------------------
 
-Enabling RAS support is a platform choice conjunctional of three distinct but
-related build options:
+Enabling RAS support is a platform choice constructed from three distinct, but
+related, build options:
 
 -  ``RAS_EXTENSION=1`` includes the RAS framework in the run time firmware;
 
@@ -244,7 +244,7 @@
 
 .. __: exception-handling.rst#partitioning-priority-levels
 
-Handling of both `interrrupt`__ and `non-interrupt`__ exceptions follow the
+Handling of both `interrupt`__ and `non-interrupt`__ exceptions follow the
 sequences outlined in the |EHF| documentation. I.e., for interrupts, the
 priority management is implicit; but for non-interrupt exceptions, they're
 explicit using `EHF APIs`__.
diff --git a/docs/secure-partition-manager-design.rst b/docs/secure-partition-manager-design.rst
index 73406b2..3c301d0 100644
--- a/docs/secure-partition-manager-design.rst
+++ b/docs/secure-partition-manager-design.rst
@@ -309,7 +309,7 @@
 allows the Secure Partition to:
 
 - Register with the SPM a service that it provides.
-- Indicate completion of a service request delagated by the SPM
+- Indicate completion of a service request delegated by the SPM
 
 Miscellaneous interfaces
 ------------------------
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index 103f1c7..e22733e 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -86,6 +86,46 @@
 
     git clone https://github.com/ARM-software/arm-trusted-firmware.git
 
+Checking source code style
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Trusted Firmware follows the `Linux Coding Style`_ . When making changes to the
+source, for submission to the project, the source must be in compliance with
+this style guide.
+
+Additional, project-specific guidelines are defined in the `Trusted Firmware-A
+Coding Guidelines`_ document.
+
+To assist with coding style compliance, the project Makefile contains two
+targets which both utilise the `checkpatch.pl` script that ships with the Linux
+source tree. The project also defines certain *checkpatch* options in the
+``.checkpatch.conf`` file in the top-level directory.
+
+**Note:** Checkpatch errors will gate upstream merging of pull requests.
+Checkpatch warnings will not gate merging but should be reviewed and fixed if
+possible.
+
+To check the entire source tree, you must first download copies of
+``checkpatch.pl``, ``spelling.txt`` and ``const_structs.checkpatch`` available
+in the `Linux master tree`_ *scripts* directory, then set the ``CHECKPATCH``
+environment variable to point to ``checkpatch.pl`` (with the other 2 files in
+the same directory) and build the `checkcodebase` target:
+
+::
+
+    make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkcodebase
+
+To just check the style on the files that differ between your local branch and
+the remote master, use:
+
+::
+
+    make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkpatch
+
+If you wish to check your patch against something other than the remote master,
+set the ``BASE_COMMIT`` variable to your desired branch. By default, ``BASE_COMMIT``
+is set to ``origin/master``.
+
 Building TF-A
 -------------
 
@@ -108,7 +148,7 @@
    ``CC`` needs to point to the clang or armclang binary, which will
    also select the clang or armclang assembler. Be aware that the
    GNU linker is used by default.  In case of being needed the linker
-   can be overriden using the ``LD`` variable. Clang linker version 6 is
+   can be overridden using the ``LD`` variable. Clang linker version 6 is
    known to work with TF-A.
 
    In both cases ``CROSS_COMPILE`` should be set as described above.
@@ -357,8 +397,8 @@
    supports the format used by GCC when T32 interworking is disabled. For this
    reason enabling this option in AArch32 will force the compiler to only
    generate A32 code. This option is enabled by default only in AArch64 debug
-   builds, but this behaviour can be overriden in each platform's Makefile or in
-   the build command line.
+   builds, but this behaviour can be overridden in each platform's Makefile or
+   in the build command line.
 
 -  ``ENABLE_MPAM_FOR_LOWER_ELS``: Boolean option to enable lower ELs to use MPAM
    feature. MPAM is an optional Armv8.4 extension that enables various memory
@@ -428,7 +468,7 @@
    handled at EL3, and a panic will result. This is supported only for AArch64
    builds.
 
--  ``FAULT_INJECTION_SUPPORT``: ARMv8.4 externsions introduced support for fault
+-  ``FAULT_INJECTION_SUPPORT``: ARMv8.4 extensions introduced support for fault
    injection from lower ELs, and this build option enables lower ELs to use
    Error Records accessed via System Registers to inject faults. This is
    applicable only to AArch64 builds.
@@ -930,34 +970,6 @@
 
     build/<platform>/<build-type>/bl32.bin
 
-Checking source code style
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-When making changes to the source for submission to the project, the source
-must be in compliance with the Linux style guide, and to assist with this check
-the project Makefile contains two targets, which both utilise the
-``checkpatch.pl`` script that ships with the Linux source tree.
-
-To check the entire source tree, you must first download copies of
-``checkpatch.pl``, ``spelling.txt`` and ``const_structs.checkpatch`` available
-in the `Linux master tree`_ scripts directory, then set the ``CHECKPATCH``
-environment variable to point to ``checkpatch.pl`` (with the other 2 files in
-the same directory) and build the target checkcodebase:
-
-::
-
-    make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkcodebase
-
-To just check the style on the files that differ between your local branch and
-the remote master, use:
-
-::
-
-    make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkpatch
-
-If you wish to check your patch against something other than the remote master,
-set the ``BASE_COMMIT`` variable to your desired branch. By default, ``BASE_COMMIT``
-is set to ``origin/master``.
 
 Building and using the FIP tool
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2054,6 +2066,7 @@
 .. _Instructions for using Linaro's deliverables on Juno: https://community.arm.com/dev-platforms/w/docs/303/juno
 .. _Arm Platforms Portal: https://community.arm.com/dev-platforms/
 .. _Development Studio 5 (DS-5): http://www.arm.com/products/tools/software-tools/ds-5/index.php
+.. _`Linux Coding Style`: https://www.kernel.org/doc/html/latest/process/coding-style.html
 .. _Linux master tree: https://github.com/torvalds/linux/tree/master/
 .. _Dia: https://wiki.gnome.org/Apps/Dia/Download
 .. _here: psci-lib-integration-guide.rst
@@ -2069,3 +2082,4 @@
 .. _Juno Getting Started Guide: http://infocenter.arm.com/help/topic/com.arm.doc.dui0928e/DUI0928E_juno_arm_development_platform_gsg.pdf
 .. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
 .. _Secure Partition Manager Design guide: secure-partition-manager-design.rst
+.. _`Trusted Firmware-A Coding Guidelines`: coding-guidelines.rst
diff --git a/drivers/arm/ccn/ccn.c b/drivers/arm/ccn/ccn.c
index 64b1626..d184054 100644
--- a/drivers/arm/ccn/ccn.c
+++ b/drivers/arm/ccn/ccn.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
  */
@@ -370,7 +370,7 @@
  * system. The state is expected to be one of NO_L3, SF_ONLY, L3_HAM or
  * L3_FAM. Instead of comparing the states reported by all HN-Fs, the state of
  * the first present HN-F node is reported. Since the driver does not export an
- * interface to program them seperately, there is no reason to perform this
+ * interface to program them separately, there is no reason to perform this
  * check. An HN-F could report that the L3 cache is transitioning from one mode
  * to another e.g. HNF_PM_NOL3_2_SFONLY. In this case, the function waits for
  * the transition to complete and reports the final state.
@@ -383,7 +383,7 @@
 	assert(ccn_plat_desc->periphbase);
 
 	/*
-	 * Wait for a L3 cache paritition to enter any run mode. The pstate
+	 * Wait for a L3 cache partition to enter any run mode. The pstate
 	 * parameter is read from an HN-F P-state status register. A non-zero
 	 * value in bits[1:0] means that the cache is transitioning to a run
 	 * mode.
@@ -428,7 +428,7 @@
 	region_id = HNF_REGION_ID_START;
 	FOR_EACH_PRESENT_REGION_ID(region_id, mn_hnf_id_map) {
 		/*
-		 * Wait for a L3 cache paritition to enter a target run
+		 * Wait for a L3 cache partition to enter a target run
 		 * mode. The pstate parameter is read from an HN-F P-state
 		 * status register.
 		 */
@@ -584,7 +584,7 @@
 		return;
 	}
 
-	/* Setting the value of Auxilary Control Register of the Node */
+	/* Setting the value of Auxiliary Control Register of the Node */
 	ccn_reg_write(ccn_plat_desc->periphbase, region_id, reg_offset, val);
 	VERBOSE("Value is successfully written at address 0x%lx.\n",
 			(ccn_plat_desc->periphbase
@@ -611,7 +611,7 @@
 		return ULL(0);
 	}
 
-	/* Setting the value of Auxilary Control Register of the Node */
+	/* Setting the value of Auxiliary Control Register of the Node */
 	val = ccn_reg_read(ccn_plat_desc->periphbase, region_id, reg_offset);
 	VERBOSE("Value is successfully read from address 0x%lx.\n",
 			(ccn_plat_desc->periphbase
diff --git a/plat/arm/css/drivers/mhu/css_mhu.c b/drivers/arm/css/mhu/css_mhu.c
similarity index 96%
rename from plat/arm/css/drivers/mhu/css_mhu.c
rename to drivers/arm/css/mhu/css_mhu.c
index e13818f..b7faf7e 100644
--- a/plat/arm/css/drivers/mhu/css_mhu.c
+++ b/drivers/arm/css/mhu/css_mhu.c
@@ -9,13 +9,10 @@
 #include <platform_def.h>
 
 #include <arch_helpers.h>
+#include <drivers/arm/css/css_mhu.h>
 #include <lib/bakery_lock.h>
 #include <lib/mmio.h>
-
-#include <css_def.h>
-#include <plat_arm.h>
-
-#include "css_mhu.h"
+#include <plat/arm/common/plat_arm.h>
 
 /* SCP MHU secure channel registers */
 #define SCP_INTR_S_STAT		0x200
diff --git a/plat/arm/css/drivers/mhu/css_mhu_doorbell.c b/drivers/arm/css/mhu/css_mhu_doorbell.c
similarity index 78%
rename from plat/arm/css/drivers/mhu/css_mhu_doorbell.c
rename to drivers/arm/css/mhu/css_mhu_doorbell.c
index b3203c2..8858742 100644
--- a/plat/arm/css/drivers/mhu/css_mhu_doorbell.c
+++ b/drivers/arm/css/mhu/css_mhu_doorbell.c
@@ -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
  */
@@ -7,9 +7,8 @@
 #include <platform_def.h>
 
 #include <arch_helpers.h>
-
-#include "css_mhu_doorbell.h"
-#include "../scmi/scmi.h"
+#include <drivers/arm/css/css_mhu_doorbell.h>
+#include <drivers/arm/css/scmi.h>
 
 void mhu_ring_doorbell(struct scmi_channel_plat_info *plat_info)
 {
@@ -32,7 +31,7 @@
 			plat_info->db_modify_mask,
 			plat_info->db_preserve_mask);
 
-	/* clear the access request for the recevier */
+	/* clear the access request for the receiver */
 	MHU_V2_CLEAR_REQUEST(MHUV2_BASE_ADDR);
 
 	return;
diff --git a/plat/arm/css/drivers/scmi/scmi_ap_core_proto.c b/drivers/arm/css/scmi/scmi_ap_core_proto.c
similarity index 97%
rename from plat/arm/css/drivers/scmi/scmi_ap_core_proto.c
rename to drivers/arm/css/scmi/scmi_ap_core_proto.c
index e495dcc..2caccc2 100644
--- a/plat/arm/css/drivers/scmi/scmi_ap_core_proto.c
+++ b/drivers/arm/css/scmi/scmi_ap_core_proto.c
@@ -8,8 +8,8 @@
 
 #include <arch_helpers.h>
 #include <common/debug.h>
+#include <drivers/arm/css/scmi.h>
 
-#include "scmi.h"
 #include "scmi_private.h"
 
 /*
diff --git a/plat/arm/css/drivers/scmi/scmi_common.c b/drivers/arm/css/scmi/scmi_common.c
similarity index 98%
rename from plat/arm/css/drivers/scmi/scmi_common.c
rename to drivers/arm/css/scmi/scmi_common.c
index 1b4ecb2..e2c353d 100644
--- a/plat/arm/css/drivers/scmi/scmi_common.c
+++ b/drivers/arm/css/scmi/scmi_common.c
@@ -8,8 +8,8 @@
 
 #include <arch_helpers.h>
 #include <common/debug.h>
+#include <drivers/arm/css/scmi.h>
 
-#include "scmi.h"
 #include "scmi_private.h"
 
 #if HW_ASSISTED_COHERENCY
diff --git a/plat/arm/css/drivers/scmi/scmi_private.h b/drivers/arm/css/scmi/scmi_private.h
similarity index 100%
rename from plat/arm/css/drivers/scmi/scmi_private.h
rename to drivers/arm/css/scmi/scmi_private.h
diff --git a/plat/arm/css/drivers/scmi/scmi_pwr_dmn_proto.c b/drivers/arm/css/scmi/scmi_pwr_dmn_proto.c
similarity index 97%
rename from plat/arm/css/drivers/scmi/scmi_pwr_dmn_proto.c
rename to drivers/arm/css/scmi/scmi_pwr_dmn_proto.c
index f315621..70165de 100644
--- a/plat/arm/css/drivers/scmi/scmi_pwr_dmn_proto.c
+++ b/drivers/arm/css/scmi/scmi_pwr_dmn_proto.c
@@ -8,8 +8,8 @@
 
 #include <arch_helpers.h>
 #include <common/debug.h>
+#include <drivers/arm/css/scmi.h>
 
-#include "scmi.h"
 #include "scmi_private.h"
 
 /*
diff --git a/plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c b/drivers/arm/css/scmi/scmi_sys_pwr_proto.c
similarity index 97%
rename from plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c
rename to drivers/arm/css/scmi/scmi_sys_pwr_proto.c
index 03c3c06..a27c4a5 100644
--- a/plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c
+++ b/drivers/arm/css/scmi/scmi_sys_pwr_proto.c
@@ -8,8 +8,8 @@
 
 #include <arch_helpers.h>
 #include <common/debug.h>
+#include <drivers/arm/css/scmi.h>
 
-#include "scmi.h"
 #include "scmi_private.h"
 
 /*
diff --git a/plat/arm/css/drivers/scp/css_bom_bootloader.c b/drivers/arm/css/scp/css_bom_bootloader.c
similarity index 96%
rename from plat/arm/css/drivers/scp/css_bom_bootloader.c
rename to drivers/arm/css/scp/css_bom_bootloader.c
index 27c9e1d..1fc1270 100644
--- a/plat/arm/css/drivers/scp/css_bom_bootloader.c
+++ b/drivers/arm/css/scp/css_bom_bootloader.c
@@ -9,13 +9,11 @@
 
 #include <arch_helpers.h>
 #include <common/debug.h>
+#include <drivers/arm/css/css_mhu.h>
+#include <drivers/arm/css/css_scp.h>
+#include <drivers/arm/css/css_scpi.h>
 #include <plat/common/platform.h>
-
-#include <css_def.h>
-
-#include "../mhu/css_mhu.h"
-#include "../scpi/css_scpi.h"
-#include "css_scp.h"
+#include <platform_def.h>
 
 /* ID of the MHU slot used for the BOM protocol */
 #define BOM_MHU_SLOT_ID		0
diff --git a/plat/arm/css/drivers/scp/css_pm_scmi.c b/drivers/arm/css/scp/css_pm_scmi.c
similarity index 98%
rename from plat/arm/css/drivers/scp/css_pm_scmi.c
rename to drivers/arm/css/scp/css_pm_scmi.c
index bd6b595..1966c44 100644
--- a/plat/arm/css/drivers/scp/css_pm_scmi.c
+++ b/drivers/arm/css/scp/css_pm_scmi.c
@@ -9,14 +9,12 @@
 
 #include <arch_helpers.h>
 #include <common/debug.h>
+#include <drivers/arm/css/css_scp.h>
+#include <drivers/arm/css/scmi.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
 #include <plat/common/platform.h>
-
-#include <css_def.h>
-#include <css_pm.h>
-#include <plat_arm.h>
-
-#include "../scmi/scmi.h"
-#include "css_scp.h"
+#include <platform_def.h>
 
 /*
  * This file implements the SCP helper functions using SCMI protocol.
diff --git a/plat/arm/css/drivers/scp/css_pm_scpi.c b/drivers/arm/css/scp/css_pm_scpi.c
similarity index 96%
rename from plat/arm/css/drivers/scp/css_pm_scpi.c
rename to drivers/arm/css/scp/css_pm_scpi.c
index f53ac30..b4019ce 100644
--- a/plat/arm/css/drivers/scp/css_pm_scpi.c
+++ b/drivers/arm/css/scp/css_pm_scpi.c
@@ -8,12 +8,10 @@
 
 #include <arch_helpers.h>
 #include <common/debug.h>
-
-#include <css_pm.h>
-#include <plat_arm.h>
-
-#include "../scpi/css_scpi.h"
-#include "css_scp.h"
+#include <drivers/arm/css/css_scp.h>
+#include <drivers/arm/css/css_scpi.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
 
 /*
  * This file implements the SCP power management functions using SCPI protocol.
diff --git a/plat/arm/css/drivers/scp/css_sds.c b/drivers/arm/css/scp/css_sds.c
similarity index 95%
rename from plat/arm/css/drivers/scp/css_sds.c
rename to drivers/arm/css/scp/css_sds.c
index c152abc..e42ee10 100644
--- a/plat/arm/css/drivers/scp/css_sds.c
+++ b/drivers/arm/css/scp/css_sds.c
@@ -9,13 +9,11 @@
 
 #include <arch_helpers.h>
 #include <common/debug.h>
+#include <drivers/arm/css/css_scp.h>
+#include <drivers/arm/css/sds.h>
 #include <drivers/delay_timer.h>
 #include <plat/common/platform.h>
-
-#include <css_def.h>
-
-#include "css_scp.h"
-#include "../sds/sds.h"
+#include <platform_def.h>
 
 int css_scp_boot_image_xfer(void *image, unsigned int image_size)
 {
diff --git a/plat/arm/css/drivers/scpi/css_scpi.c b/drivers/arm/css/scpi/css_scpi.c
similarity index 98%
rename from plat/arm/css/drivers/scpi/css_scpi.c
rename to drivers/arm/css/scpi/css_scpi.c
index 42bf3b8..4b73265 100644
--- a/plat/arm/css/drivers/scpi/css_scpi.c
+++ b/drivers/arm/css/scpi/css_scpi.c
@@ -9,13 +9,11 @@
 
 #include <arch_helpers.h>
 #include <common/debug.h>
+#include <drivers/arm/css/css_mhu.h>
+#include <drivers/arm/css/css_scpi.h>
 #include <lib/utils.h>
 #include <plat/common/platform.h>
-
-#include <css_def.h>
-
-#include "../mhu/css_mhu.h"
-#include "css_scpi.h"
+#include <platform_def.h>
 
 #define SCPI_SHARED_MEM_SCP_TO_AP	PLAT_CSS_SCP_COM_SHARED_MEM_BASE
 #define SCPI_SHARED_MEM_AP_TO_SCP	(PLAT_CSS_SCP_COM_SHARED_MEM_BASE \
diff --git a/plat/arm/css/drivers/sds/aarch32/sds_helpers.S b/drivers/arm/css/sds/aarch32/sds_helpers.S
similarity index 97%
rename from plat/arm/css/drivers/sds/aarch32/sds_helpers.S
rename to drivers/arm/css/sds/aarch32/sds_helpers.S
index f68cb35..13ff0e1 100644
--- a/plat/arm/css/drivers/sds/aarch32/sds_helpers.S
+++ b/drivers/arm/css/sds/aarch32/sds_helpers.S
@@ -6,8 +6,9 @@
 
 #include <arch.h>
 #include <asm_macros.S>
+#include <drivers/arm/css/sds.h>
 #include <platform_def.h>
-#include "../sds.h"
+
 #include "../sds_private.h"
 
 	.globl	sds_get_primary_cpu_id
diff --git a/plat/arm/css/drivers/sds/aarch64/sds_helpers.S b/drivers/arm/css/sds/aarch64/sds_helpers.S
similarity index 97%
rename from plat/arm/css/drivers/sds/aarch64/sds_helpers.S
rename to drivers/arm/css/sds/aarch64/sds_helpers.S
index 3b9c562..3256c2b 100644
--- a/plat/arm/css/drivers/sds/aarch64/sds_helpers.S
+++ b/drivers/arm/css/sds/aarch64/sds_helpers.S
@@ -6,8 +6,9 @@
 
 #include <arch.h>
 #include <asm_macros.S>
+#include <drivers/arm/css/sds.h>
 #include <platform_def.h>
-#include "../sds.h"
+
 #include "../sds_private.h"
 
 	.globl	sds_get_primary_cpu_id
diff --git a/plat/arm/css/drivers/sds/sds.c b/drivers/arm/css/sds/sds.c
similarity index 98%
rename from plat/arm/css/drivers/sds/sds.c
rename to drivers/arm/css/sds/sds.c
index 3eeb0dc..1fb196c 100644
--- a/plat/arm/css/drivers/sds/sds.c
+++ b/drivers/arm/css/sds/sds.c
@@ -10,9 +10,9 @@
 
 #include <arch_helpers.h>
 #include <common/debug.h>
+#include <drivers/arm/css/sds.h>
+#include <platform_def.h>
 
-#include <css_def.h>
-#include "sds.h"
 #include "sds_private.h"
 
 /*
diff --git a/plat/arm/css/drivers/sds/sds_private.h b/drivers/arm/css/sds/sds_private.h
similarity index 100%
rename from plat/arm/css/drivers/sds/sds_private.h
rename to drivers/arm/css/sds/sds_private.h
diff --git a/plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c b/drivers/arm/fvp/fvp_pwrc.c
similarity index 93%
rename from plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c
rename to drivers/arm/fvp/fvp_pwrc.c
index c48bb07..75a2b66 100644
--- a/plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c
+++ b/drivers/arm/fvp/fvp_pwrc.c
@@ -4,14 +4,11 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <drivers/arm/fvp/fvp_pwrc.h>
 #include <lib/bakery_lock.h>
 #include <lib/mmio.h>
-
-#include <plat_arm.h>
-
-#include "../../fvp_def.h"
-#include "../../fvp_private.h"
-#include "fvp_pwrc.h"
+#include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
 
 /*
  * TODO: Someday there will be a generic power controller api. At the moment
diff --git a/drivers/console/multi_console.c b/drivers/console/multi_console.c
index e94de35..a135959 100644
--- a/drivers/console/multi_console.c
+++ b/drivers/console/multi_console.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
  */
@@ -76,7 +76,7 @@
 	console_t *console;
 
 	for (console = console_list; console != NULL; console = console->next)
-		if (console->flags & console_state) {
+		if ((console->flags & console_state) && console->putc) {
 			int ret = console->putc(c, console);
 			if ((err == ERROR_NO_VALID_CONSOLE) || (ret < err))
 				err = ret;
@@ -93,7 +93,7 @@
 	do {	/* Keep polling while at least one console works correctly. */
 		for (console = console_list; console != NULL;
 		     console = console->next)
-			if (console->flags & console_state) {
+			if ((console->flags & console_state) && console->getc) {
 				int ret = console->getc(console);
 				if (ret >= 0)
 					return ret;
@@ -111,7 +111,7 @@
 	console_t *console;
 
 	for (console = console_list; console != NULL; console = console->next)
-		if (console->flags & console_state) {
+		if ((console->flags & console_state) && console->flush) {
 			int ret = console->flush(console);
 			if ((err == ERROR_NO_VALID_CONSOLE) || (ret < err))
 				err = ret;
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 50e87c1..77d683c 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/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
  */
@@ -300,7 +300,7 @@
 		break;
 	}
 
-	if (ret != 0) {
+	if (ret < 0) {
 		return ret;
 	}
 
@@ -405,7 +405,7 @@
 			return 0;
 		}
 
-		mdelay(1);
+		mdelay(10);
 	}
 
 	ERROR("CMD1 failed after %d retries\n", SEND_OP_COND_MAX_RETRIES);
diff --git a/drivers/partition/partition.c b/drivers/partition/partition.c
index 07869ac..6fa3df0 100644
--- a/drivers/partition/partition.c
+++ b/drivers/partition/partition.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
  */
@@ -16,7 +16,7 @@
 #include <plat/common/platform.h>
 
 static uint8_t mbr_sector[PARTITION_BLOCK_SIZE];
-partition_entry_list_t list;
+static partition_entry_list_t list;
 
 #if LOG_LEVEL >= LOG_LEVEL_VERBOSE
 static void dump_entries(int num)
@@ -75,7 +75,7 @@
 
 /*
  * Load GPT header and check the GPT signature.
- * If partiton numbers could be found, check & update it.
+ * If partition numbers could be found, check & update it.
  */
 static int load_gpt_header(uintptr_t image_handle)
 {
diff --git a/drivers/renesas/rcar/cpld/ulcb_cpld.c b/drivers/renesas/rcar/cpld/ulcb_cpld.c
index 6b03614..4830853 100644
--- a/drivers/renesas/rcar/cpld/ulcb_cpld.c
+++ b/drivers/renesas/rcar/cpld/ulcb_cpld.c
@@ -24,6 +24,9 @@
 #define GPIO_INOUTSEL2		0xE6052004
 #define GPIO_INOUTSEL6		0xE6055404
 
+/* General IO/Interrupt Switching Register */
+#define GPIO_IOINTSEL6		0xE6055400
+
 /* GPIO/perihperal function select */
 #define PFC_GPSR2		0xE6060108
 #define PFC_GPSR6		0xE6060118
@@ -93,6 +96,7 @@
 	gpio_pfc(PFC_GPSR2, SSTBZ);
 	gpio_pfc(PFC_GPSR6, MOSI);
 
+	gpio_set_value(GPIO_IOINTSEL6, SCLK, 0);
 	gpio_set_value(GPIO_OUTDT6, SCLK, 0);
 	gpio_set_value(GPIO_OUTDT2, SSTBZ, 1);
 	gpio_set_value(GPIO_OUTDT6, MOSI, 0);
diff --git a/drivers/renesas/rcar/pwrc/pwrc.c b/drivers/renesas/rcar/pwrc/pwrc.c
index b005caf..d7f0880 100644
--- a/drivers/renesas/rcar/pwrc/pwrc.c
+++ b/drivers/renesas/rcar/pwrc/pwrc.c
@@ -768,3 +768,43 @@
 done:
 	return count;
 }
+
+int32_t rcar_pwrc_cpu_on_check(uint64_t mpidr)
+{
+	uint64_t i;
+	uint64_t j;
+	uint64_t cpu_count;
+	uintptr_t reg_PSTR;
+	uint32_t status;
+	uint64_t my_cpu;
+	int32_t rtn;
+	uint32_t my_cluster_type;
+
+	const uint32_t cluster_type[PLATFORM_CLUSTER_COUNT] = {
+			RCAR_CLUSTER_CA53,
+			RCAR_CLUSTER_CA57
+	};
+	const uintptr_t registerPSTR[PLATFORM_CLUSTER_COUNT] = {
+			RCAR_CA53PSTR,
+			RCAR_CA57PSTR
+	};
+
+	my_cluster_type = rcar_pwrc_get_cluster();
+
+	rtn = 0;
+	my_cpu = mpidr & ((uint64_t)(MPIDR_CPU_MASK));
+	for (i = 0U; i < ((uint64_t)(PLATFORM_CLUSTER_COUNT)); i++) {
+		cpu_count = rcar_pwrc_get_cpu_num(cluster_type[i]);
+		reg_PSTR = registerPSTR[i];
+		for (j = 0U; j < cpu_count; j++) {
+			if ((my_cluster_type != cluster_type[i]) || (my_cpu != j)) {
+				status = mmio_read_32(reg_PSTR) >> (j * 4U);
+				if ((status & 0x00000003U) == 0U) {
+					rtn--;
+				}
+			}
+		}
+	}
+	return (rtn);
+
+}
diff --git a/drivers/renesas/rcar/pwrc/pwrc.h b/drivers/renesas/rcar/pwrc/pwrc.h
index 3cdac69..d4d6fc4 100644
--- a/drivers/renesas/rcar/pwrc/pwrc.h
+++ b/drivers/renesas/rcar/pwrc/pwrc.h
@@ -44,6 +44,7 @@
 void rcar_pwrc_clusteroff(uint64_t mpidr);
 void rcar_pwrc_cpuoff(uint64_t mpidr);
 void rcar_pwrc_cpuon(uint64_t mpidr);
+int32_t rcar_pwrc_cpu_on_check(uint64_t mpidr);
 void rcar_pwrc_setup(void);
 
 uint32_t rcar_pwrc_get_cpu_wkr(uint64_t mpidr);
diff --git a/drivers/rpi3/gpio/rpi3_gpio.c b/drivers/rpi3/gpio/rpi3_gpio.c
new file mode 100644
index 0000000..b39808f
--- /dev/null
+++ b/drivers/rpi3/gpio/rpi3_gpio.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2019, Linaro Limited
+ * Copyright (c) 2019, Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+#include <assert.h>
+#include <lib/mmio.h>
+#include <drivers/delay_timer.h>
+#include <drivers/rpi3/gpio/rpi3_gpio.h>
+
+static struct rpi3_gpio_params rpi3_gpio_params;
+
+static int rpi3_gpio_get_direction(int gpio);
+static void rpi3_gpio_set_direction(int gpio, int direction);
+static int rpi3_gpio_get_value(int gpio);
+static void rpi3_gpio_set_value(int gpio, int value);
+static void rpi3_gpio_set_pull(int gpio, int pull);
+
+static const gpio_ops_t rpi3_gpio_ops = {
+	.get_direction  = rpi3_gpio_get_direction,
+	.set_direction  = rpi3_gpio_set_direction,
+	.get_value      = rpi3_gpio_get_value,
+	.set_value      = rpi3_gpio_set_value,
+	.set_pull       = rpi3_gpio_set_pull,
+};
+
+/**
+ * Get selection of GPIO pinmux settings.
+ *
+ * @param gpio The pin number of GPIO. From 0 to 53.
+ * @return The selection of pinmux. RPI3_GPIO_FUNC_INPUT: input,
+ *                                  RPI3_GPIO_FUNC_OUTPUT: output,
+ *                                  RPI3_GPIO_FUNC_ALT0: alt-0,
+ *                                  RPI3_GPIO_FUNC_ALT1: alt-1,
+ *                                  RPI3_GPIO_FUNC_ALT2: alt-2,
+ *                                  RPI3_GPIO_FUNC_ALT3: alt-3,
+ *                                  RPI3_GPIO_FUNC_ALT4: alt-4,
+ *                                  RPI3_GPIO_FUNC_ALT5: alt-5
+ */
+int rpi3_gpio_get_select(int gpio)
+{
+	int ret;
+	uintptr_t reg_base = rpi3_gpio_params.reg_base;
+	int regN = gpio / 10;
+	int shift = 3 * (gpio % 10);
+	uintptr_t reg_sel = reg_base + RPI3_GPIO_GPFSEL(regN);
+	uint32_t sel = mmio_read_32(reg_sel);
+
+	ret = (sel >> shift) & 0x07;
+
+	return ret;
+}
+
+/**
+ * Set selection of GPIO pinmux settings.
+ *
+ * @param gpio The pin number of GPIO. From 0 to 53.
+ * @param fsel The selection of pinmux. RPI3_GPIO_FUNC_INPUT: input,
+ *                                      RPI3_GPIO_FUNC_OUTPUT: output,
+ *                                      RPI3_GPIO_FUNC_ALT0: alt-0,
+ *                                      RPI3_GPIO_FUNC_ALT1: alt-1,
+ *                                      RPI3_GPIO_FUNC_ALT2: alt-2,
+ *                                      RPI3_GPIO_FUNC_ALT3: alt-3,
+ *                                      RPI3_GPIO_FUNC_ALT4: alt-4,
+ *                                      RPI3_GPIO_FUNC_ALT5: alt-5
+ */
+void rpi3_gpio_set_select(int gpio, int fsel)
+{
+	uintptr_t reg_base = rpi3_gpio_params.reg_base;
+	int regN = gpio / 10;
+	int shift = 3 * (gpio % 10);
+	uintptr_t reg_sel = reg_base + RPI3_GPIO_GPFSEL(regN);
+	uint32_t sel = mmio_read_32(reg_sel);
+	uint32_t mask = U(0x07) << shift;
+
+	sel = (sel & (~mask)) | ((fsel << shift) & mask);
+	mmio_write_32(reg_sel, sel);
+}
+
+static int rpi3_gpio_get_direction(int gpio)
+{
+	int result = rpi3_gpio_get_select(gpio);
+
+	if (result == RPI3_GPIO_FUNC_INPUT)
+		return GPIO_DIR_IN;
+	else if (result == RPI3_GPIO_FUNC_OUTPUT)
+		return GPIO_DIR_OUT;
+
+	return GPIO_DIR_IN;
+}
+
+static void rpi3_gpio_set_direction(int gpio, int direction)
+{
+	switch (direction) {
+	case GPIO_DIR_IN:
+		rpi3_gpio_set_select(gpio, RPI3_GPIO_FUNC_INPUT);
+		break;
+	case GPIO_DIR_OUT:
+		rpi3_gpio_set_select(gpio, RPI3_GPIO_FUNC_OUTPUT);
+		break;
+	}
+}
+
+static int rpi3_gpio_get_value(int gpio)
+{
+	uintptr_t reg_base = rpi3_gpio_params.reg_base;
+	int regN = gpio / 32;
+	int shift = gpio % 32;
+	uintptr_t reg_lev = reg_base + RPI3_GPIO_GPLEV(regN);
+	uint32_t value = mmio_read_32(reg_lev);
+
+	if ((value >> shift) & 0x01)
+		return GPIO_LEVEL_HIGH;
+	return GPIO_LEVEL_LOW;
+}
+
+static void rpi3_gpio_set_value(int gpio, int value)
+{
+	uintptr_t reg_base = rpi3_gpio_params.reg_base;
+	int regN = gpio / 32;
+	int shift = gpio % 32;
+	uintptr_t reg_set = reg_base + RPI3_GPIO_GPSET(regN);
+	uintptr_t reg_clr = reg_base + RPI3_GPIO_GPSET(regN);
+
+	switch (value) {
+	case GPIO_LEVEL_LOW:
+		mmio_write_32(reg_clr, U(1) << shift);
+		break;
+	case GPIO_LEVEL_HIGH:
+		mmio_write_32(reg_set, U(1) << shift);
+		break;
+	}
+}
+
+static void rpi3_gpio_set_pull(int gpio, int pull)
+{
+	uintptr_t reg_base = rpi3_gpio_params.reg_base;
+	int regN = gpio / 32;
+	int shift = gpio % 32;
+	uintptr_t reg_pud = reg_base + RPI3_GPIO_GPPUD;
+	uintptr_t reg_clk = reg_base + RPI3_GPIO_GPPUDCLK(regN);
+
+	switch (pull) {
+	case GPIO_PULL_NONE:
+		mmio_write_32(reg_pud, 0x0);
+		break;
+	case GPIO_PULL_UP:
+		mmio_write_32(reg_pud, 0x2);
+		break;
+	case GPIO_PULL_DOWN:
+		mmio_write_32(reg_pud, 0x1);
+		break;
+	}
+	mdelay(150);
+	mmio_write_32(reg_clk, U(1) << shift);
+	mdelay(150);
+	mmio_write_32(reg_clk, 0x0);
+	mmio_write_32(reg_pud, 0x0);
+}
+
+void rpi3_gpio_init(struct rpi3_gpio_params *params)
+{
+	assert(params != 0);
+	memcpy(&rpi3_gpio_params, params, sizeof(struct rpi3_gpio_params));
+	gpio_init(&rpi3_gpio_ops);
+}
diff --git a/drivers/st/bsec/bsec.c b/drivers/st/bsec/bsec.c
new file mode 100644
index 0000000..aaecf1f
--- /dev/null
+++ b/drivers/st/bsec/bsec.c
@@ -0,0 +1,913 @@
+/*
+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <limits.h>
+
+#include <libfdt.h>
+
+#include <platform_def.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/st/bsec.h>
+#include <lib/mmio.h>
+#include <lib/spinlock.h>
+
+#define BSEC_IP_VERSION_1_0	0x10
+#define BSEC_COMPAT		"st,stm32mp15-bsec"
+
+#define OTP_ACCESS_SIZE (round_up(OTP_MAX_SIZE, __WORD_BIT) / __WORD_BIT)
+
+static uint32_t otp_nsec_access[OTP_ACCESS_SIZE] __unused;
+
+static uint32_t bsec_power_safmem(bool power);
+
+/* BSEC access protection */
+static spinlock_t bsec_spinlock;
+static uintptr_t bsec_base;
+
+static void bsec_lock(void)
+{
+	const uint32_t mask = SCTLR_M_BIT | SCTLR_C_BIT;
+
+	/* Lock is currently required only when MMU and cache are enabled */
+	if ((read_sctlr() & mask) == mask) {
+		spin_lock(&bsec_spinlock);
+	}
+}
+
+static void bsec_unlock(void)
+{
+	const uint32_t mask = SCTLR_M_BIT | SCTLR_C_BIT;
+
+	/* Unlock is required only when MMU and cache are enabled */
+	if ((read_sctlr() & mask) == mask) {
+		spin_unlock(&bsec_spinlock);
+	}
+}
+
+static int bsec_get_dt_node(struct dt_node_info *info)
+{
+	int node;
+
+	node = dt_get_node(info, -1, BSEC_COMPAT);
+	if (node < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	return node;
+}
+
+#if defined(IMAGE_BL32)
+static void enable_non_secure_access(uint32_t otp)
+{
+	otp_nsec_access[otp / __WORD_BIT] |= BIT(otp % __WORD_BIT);
+
+	if (bsec_shadow_register(otp) != BSEC_OK) {
+		panic();
+	}
+}
+
+static bool non_secure_can_access(uint32_t otp)
+{
+	return (otp_nsec_access[otp / __WORD_BIT] &
+		BIT(otp % __WORD_BIT)) != 0;
+}
+
+static int bsec_dt_otp_nsec_access(void *fdt, int bsec_node)
+{
+	int bsec_subnode;
+
+	fdt_for_each_subnode(bsec_subnode, fdt, bsec_node) {
+		const fdt32_t *cuint;
+		uint32_t reg;
+		uint32_t i;
+		uint32_t size;
+		uint8_t status;
+
+		cuint = fdt_getprop(fdt, bsec_subnode, "reg", NULL);
+		if (cuint == NULL) {
+			panic();
+		}
+
+		reg = fdt32_to_cpu(*cuint) / sizeof(uint32_t);
+		if (reg < STM32MP1_UPPER_OTP_START) {
+			continue;
+		}
+
+		status = fdt_get_status(bsec_subnode);
+		if ((status & DT_NON_SECURE) == 0U)  {
+			continue;
+		}
+
+		size = fdt32_to_cpu(*(cuint + 1)) / sizeof(uint32_t);
+
+		if ((fdt32_to_cpu(*(cuint + 1)) % sizeof(uint32_t)) != 0) {
+			size++;
+		}
+
+		for (i = reg; i < (reg + size); i++) {
+			enable_non_secure_access(i);
+		}
+	}
+
+	return 0;
+}
+#endif
+
+static uint32_t otp_bank_offset(uint32_t otp)
+{
+	assert(otp <= STM32MP1_OTP_MAX_ID);
+
+	return ((otp & ~BSEC_OTP_MASK) >> BSEC_OTP_BANK_SHIFT) *
+	       sizeof(uint32_t);
+}
+
+static uint32_t bsec_check_error(uint32_t otp)
+{
+	uint32_t bit = BIT(otp & BSEC_OTP_MASK);
+	uint32_t bank = otp_bank_offset(otp);
+
+	if ((mmio_read_32(bsec_base + BSEC_DISTURBED_OFF + bank) & bit) != 0U) {
+		return BSEC_DISTURBED;
+	}
+
+	if ((mmio_read_32(bsec_base + BSEC_ERROR_OFF + bank) & bit) != 0U) {
+		return BSEC_ERROR;
+	}
+
+	return BSEC_OK;
+}
+
+/*
+ * bsec_probe: initialize BSEC driver.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_probe(void)
+{
+	void *fdt;
+	int node;
+	struct dt_node_info bsec_info;
+
+	if (fdt_get_address(&fdt) == 0) {
+		panic();
+	}
+
+	node = bsec_get_dt_node(&bsec_info);
+	if (node < 0) {
+		panic();
+	}
+
+	bsec_base = bsec_info.base;
+
+#if defined(IMAGE_BL32)
+	bsec_dt_otp_nsec_access(fdt, node);
+#endif
+	return BSEC_OK;
+}
+
+/*
+ * bsec_get_base: return BSEC base address.
+ */
+uint32_t bsec_get_base(void)
+{
+	return bsec_base;
+}
+
+/*
+ * bsec_set_config: enable and configure BSEC.
+ * cfg: pointer to param structure used to set register.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_set_config(struct bsec_config *cfg)
+{
+	uint32_t value;
+	int32_t result;
+
+	value = ((((uint32_t)cfg->freq << BSEC_CONF_FRQ_SHIFT) &
+						BSEC_CONF_FRQ_MASK) |
+		 (((uint32_t)cfg->pulse_width << BSEC_CONF_PRG_WIDTH_SHIFT) &
+						BSEC_CONF_PRG_WIDTH_MASK) |
+		 (((uint32_t)cfg->tread << BSEC_CONF_TREAD_SHIFT) &
+						BSEC_CONF_TREAD_MASK));
+
+	bsec_lock();
+
+	mmio_write_32(bsec_base + BSEC_OTP_CONF_OFF, value);
+
+	bsec_unlock();
+
+	result = bsec_power_safmem((bool)cfg->power &
+				   BSEC_CONF_POWER_UP_MASK);
+	if (result != BSEC_OK) {
+		return result;
+	}
+
+	value = ((((uint32_t)cfg->upper_otp_lock << UPPER_OTP_LOCK_SHIFT) &
+						UPPER_OTP_LOCK_MASK) |
+		 (((uint32_t)cfg->den_lock << DENREG_LOCK_SHIFT) &
+						DENREG_LOCK_MASK) |
+		 (((uint32_t)cfg->prog_lock << GPLOCK_LOCK_SHIFT) &
+						GPLOCK_LOCK_MASK));
+
+	bsec_lock();
+
+	mmio_write_32(bsec_base + BSEC_OTP_LOCK_OFF, value);
+
+	bsec_unlock();
+
+	return BSEC_OK;
+}
+
+/*
+ * bsec_get_config: return config parameters set in BSEC registers.
+ * cfg: config param return.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_get_config(struct bsec_config *cfg)
+{
+	uint32_t value;
+
+	if (cfg == NULL) {
+		return BSEC_INVALID_PARAM;
+	}
+
+	value = mmio_read_32(bsec_base + BSEC_OTP_CONF_OFF);
+	cfg->power = (uint8_t)((value & BSEC_CONF_POWER_UP_MASK) >>
+						BSEC_CONF_POWER_UP_SHIFT);
+	cfg->freq = (uint8_t)((value & BSEC_CONF_FRQ_MASK) >>
+						BSEC_CONF_FRQ_SHIFT);
+	cfg->pulse_width = (uint8_t)((value & BSEC_CONF_PRG_WIDTH_MASK) >>
+						BSEC_CONF_PRG_WIDTH_SHIFT);
+	cfg->tread = (uint8_t)((value & BSEC_CONF_TREAD_MASK) >>
+						BSEC_CONF_TREAD_SHIFT);
+
+	value = mmio_read_32(bsec_base + BSEC_OTP_LOCK_OFF);
+	cfg->upper_otp_lock = (uint8_t)((value & UPPER_OTP_LOCK_MASK) >>
+						UPPER_OTP_LOCK_SHIFT);
+	cfg->den_lock = (uint8_t)((value & DENREG_LOCK_MASK) >>
+						DENREG_LOCK_SHIFT);
+	cfg->prog_lock = (uint8_t)((value & GPLOCK_LOCK_MASK) >>
+						GPLOCK_LOCK_SHIFT);
+
+	return BSEC_OK;
+}
+
+/*
+ * bsec_shadow_register: copy SAFMEM OTP to BSEC data.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_shadow_register(uint32_t otp)
+{
+	uint32_t result;
+	bool power_up = false;
+
+	if (otp > STM32MP1_OTP_MAX_ID) {
+		return BSEC_INVALID_PARAM;
+	}
+
+	/* Check if shadowing of OTP is locked */
+	if (bsec_read_sr_lock(otp)) {
+		VERBOSE("BSEC: OTP %i is locked and will not be refreshed\n",
+			otp);
+	}
+
+	if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) {
+		result = bsec_power_safmem(true);
+
+		if (result != BSEC_OK) {
+			return result;
+		}
+
+		power_up = true;
+	}
+
+	bsec_lock();
+
+	/* Set BSEC_OTP_CTRL_OFF and set ADDR with the OTP value */
+	mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF, otp | BSEC_READ);
+
+	while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) {
+		;
+	}
+
+	result = bsec_check_error(otp);
+
+	bsec_unlock();
+
+	if (power_up) {
+		if (bsec_power_safmem(false) != BSEC_OK) {
+			panic();
+		}
+	}
+
+	return result;
+}
+
+/*
+ * bsec_read_otp: read an OTP data value.
+ * val: read value.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_read_otp(uint32_t *val, uint32_t otp)
+{
+	uint32_t result;
+
+	if (otp > STM32MP1_OTP_MAX_ID) {
+		return BSEC_INVALID_PARAM;
+	}
+
+	bsec_lock();
+
+	*val = mmio_read_32(bsec_base + BSEC_OTP_DATA_OFF +
+			    (otp * sizeof(uint32_t)));
+
+	result = bsec_check_error(otp);
+
+	bsec_unlock();
+
+	return result;
+}
+
+/*
+ * bsec_write_otp: write value in BSEC data register.
+ * val: value to write.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_write_otp(uint32_t val, uint32_t otp)
+{
+	uint32_t result;
+
+	if (otp > STM32MP1_OTP_MAX_ID) {
+		return BSEC_INVALID_PARAM;
+	}
+
+	/* Check if programming of OTP is locked */
+	if (bsec_read_sw_lock(otp)) {
+		VERBOSE("BSEC: OTP %i is locked and write will be ignored\n",
+			otp);
+	}
+
+	bsec_lock();
+
+	mmio_write_32(bsec_base + BSEC_OTP_DATA_OFF +
+		      (otp * sizeof(uint32_t)), val);
+
+	result = bsec_check_error(otp);
+
+	bsec_unlock();
+
+	return result;
+}
+
+/*
+ * bsec_program_otp: program a bit in SAFMEM after the prog.
+ *	The OTP data is not refreshed.
+ * val: value to program.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_program_otp(uint32_t val, uint32_t otp)
+{
+	uint32_t result;
+	bool power_up = false;
+
+	if (otp > STM32MP1_OTP_MAX_ID) {
+		return BSEC_INVALID_PARAM;
+	}
+
+	/* Check if programming of OTP is locked */
+	if (bsec_read_sp_lock(otp)) {
+		WARN("BSEC: OTP locked, prog will be ignored\n");
+	}
+
+	if ((mmio_read_32(bsec_base + BSEC_OTP_LOCK_OFF) &
+	     BIT(BSEC_LOCK_PROGRAM)) != 0U) {
+		WARN("BSEC: GPLOCK activated, prog will be ignored\n");
+	}
+
+	if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) {
+		result = bsec_power_safmem(true);
+
+		if (result != BSEC_OK) {
+			return result;
+		}
+
+		power_up = true;
+	}
+
+	bsec_lock();
+
+	/* Set value in write register */
+	mmio_write_32(bsec_base + BSEC_OTP_WRDATA_OFF, val);
+
+	/* Set BSEC_OTP_CTRL_OFF and set ADDR with the OTP value */
+	mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF, otp | BSEC_WRITE);
+
+	while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) {
+		;
+	}
+
+	if ((bsec_get_status() & BSEC_MODE_PROGFAIL_MASK) != 0U) {
+		result = BSEC_PROG_FAIL;
+	} else {
+		result = bsec_check_error(otp);
+	}
+
+	bsec_unlock();
+
+	if (power_up) {
+		if (bsec_power_safmem(false) != BSEC_OK) {
+			panic();
+		}
+	}
+
+	return result;
+}
+
+/*
+ * bsec_permanent_lock_otp: permanent lock of OTP in SAFMEM.
+ * otp: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_permanent_lock_otp(uint32_t otp)
+{
+	uint32_t result;
+	bool power_up = false;
+	uint32_t data;
+	uint32_t addr;
+
+	if (otp > STM32MP1_OTP_MAX_ID) {
+		return BSEC_INVALID_PARAM;
+	}
+
+	if ((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) {
+		result = bsec_power_safmem(true);
+
+		if (result != BSEC_OK) {
+			return result;
+		}
+
+		power_up = true;
+	}
+
+	if (otp < STM32MP1_UPPER_OTP_START) {
+		addr = otp >> ADDR_LOWER_OTP_PERLOCK_SHIFT;
+		data = DATA_LOWER_OTP_PERLOCK_BIT <<
+		       ((otp & DATA_LOWER_OTP_PERLOCK_MASK) << 1U);
+	} else {
+		addr = (otp >> ADDR_UPPER_OTP_PERLOCK_SHIFT) + 2U;
+		data = DATA_UPPER_OTP_PERLOCK_BIT <<
+		       (otp & DATA_UPPER_OTP_PERLOCK_MASK);
+	}
+
+	bsec_lock();
+
+	/* Set value in write register */
+	mmio_write_32(bsec_base + BSEC_OTP_WRDATA_OFF, data);
+
+	/* Set BSEC_OTP_CTRL_OFF and set ADDR with the OTP value */
+	mmio_write_32(bsec_base + BSEC_OTP_CTRL_OFF,
+		      addr | BSEC_WRITE | BSEC_LOCK);
+
+	while ((bsec_get_status() & BSEC_MODE_BUSY_MASK) != 0U) {
+		;
+	}
+
+	if ((bsec_get_status() & BSEC_MODE_PROGFAIL_MASK) != 0U) {
+		result = BSEC_PROG_FAIL;
+	} else {
+		result = bsec_check_error(otp);
+	}
+
+	bsec_unlock();
+
+	if (power_up) {
+		if (bsec_power_safmem(false) != BSEC_OK) {
+			panic();
+		}
+	}
+
+	return result;
+}
+
+/*
+ * bsec_write_debug_conf: write value in debug feature
+ *	to enable/disable debug service.
+ * val: value to write.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_write_debug_conf(uint32_t val)
+{
+	uint32_t result = BSEC_ERROR;
+	uint32_t masked_val = val & BSEC_DEN_ALL_MSK;
+
+	bsec_lock();
+
+	mmio_write_32(bsec_base + BSEC_DEN_OFF, masked_val);
+
+	if ((mmio_read_32(bsec_base + BSEC_DEN_OFF) ^ masked_val) == 0U) {
+		result = BSEC_OK;
+	}
+
+	bsec_unlock();
+
+	return result;
+}
+
+/*
+ * bsec_read_debug_conf: read debug configuration.
+ */
+uint32_t bsec_read_debug_conf(void)
+{
+	return mmio_read_32(bsec_base + BSEC_DEN_OFF);
+}
+
+/*
+ * bsec_get_status: return status register value.
+ */
+uint32_t bsec_get_status(void)
+{
+	return mmio_read_32(bsec_base + BSEC_OTP_STATUS_OFF);
+}
+
+/*
+ * bsec_get_hw_conf: return hardware configuration.
+ */
+uint32_t bsec_get_hw_conf(void)
+{
+	return mmio_read_32(bsec_base + BSEC_IPHW_CFG_OFF);
+}
+
+/*
+ * bsec_get_version: return BSEC version.
+ */
+uint32_t bsec_get_version(void)
+{
+	return mmio_read_32(bsec_base + BSEC_IPVR_OFF);
+}
+
+/*
+ * bsec_get_id: return BSEC ID.
+ */
+uint32_t bsec_get_id(void)
+{
+	return mmio_read_32(bsec_base + BSEC_IP_ID_OFF);
+}
+
+/*
+ * bsec_get_magic_id: return BSEC magic number.
+ */
+uint32_t bsec_get_magic_id(void)
+{
+	return mmio_read_32(bsec_base + BSEC_IP_MAGIC_ID_OFF);
+}
+
+/*
+ * bsec_write_sr_lock: write shadow-read lock.
+ * otp: OTP number.
+ * value: value to write in the register.
+ *	Must be always 1.
+ * return: true if OTP is locked, else false.
+ */
+bool bsec_write_sr_lock(uint32_t otp, uint32_t value)
+{
+	bool result = false;
+	uint32_t bank = otp_bank_offset(otp);
+	uint32_t bank_value;
+	uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+
+	bsec_lock();
+
+	bank_value = mmio_read_32(bsec_base + BSEC_SRLOCK_OFF + bank);
+
+	if ((bank_value & otp_mask) == value) {
+		/*
+		 * In case of write don't need to write,
+		 * the lock is already set.
+		 */
+		if (value != 0U) {
+			result = true;
+		}
+	} else {
+		if (value != 0U) {
+			bank_value = bank_value | otp_mask;
+		} else {
+			bank_value = bank_value & ~otp_mask;
+		}
+
+		/*
+		 * We can write 0 in all other OTP
+		 * if the lock is activated in one of other OTP.
+		 * Write 0 has no effect.
+		 */
+		mmio_write_32(bsec_base + BSEC_SRLOCK_OFF + bank, bank_value);
+		result = true;
+	}
+
+	bsec_unlock();
+
+	return result;
+}
+
+/*
+ * bsec_read_sr_lock: read shadow-read lock.
+ * otp: OTP number.
+ * return: true if otp is locked, else false.
+ */
+bool bsec_read_sr_lock(uint32_t otp)
+{
+	uint32_t bank = otp_bank_offset(otp);
+	uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+	uint32_t bank_value = mmio_read_32(bsec_base + BSEC_SRLOCK_OFF + bank);
+
+	return (bank_value & otp_mask) != 0U;
+}
+
+/*
+ * bsec_write_sw_lock: write shadow-write lock.
+ * otp: OTP number.
+ * value: Value to write in the register.
+ *	Must be always 1.
+ * return: true if OTP is locked, else false.
+ */
+bool bsec_write_sw_lock(uint32_t otp, uint32_t value)
+{
+	bool result = false;
+	uint32_t bank = otp_bank_offset(otp);
+	uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+	uint32_t bank_value;
+
+	bsec_lock();
+
+	bank_value = mmio_read_32(bsec_base + BSEC_SWLOCK_OFF + bank);
+
+	if ((bank_value & otp_mask) == value) {
+		/*
+		 * In case of write don't need to write,
+		 * the lock is already set.
+		 */
+		if (value != 0U) {
+			result = true;
+		}
+	} else {
+		if (value != 0U) {
+			bank_value = bank_value | otp_mask;
+		} else {
+			bank_value = bank_value & ~otp_mask;
+		}
+
+		/*
+		 * We can write 0 in all other OTP
+		 * if the lock is activated in one of other OTP.
+		 * Write 0 has no effect.
+		 */
+		mmio_write_32(bsec_base + BSEC_SWLOCK_OFF + bank, bank_value);
+		result = true;
+	}
+
+	bsec_unlock();
+
+	return result;
+}
+
+/*
+ * bsec_read_sw_lock: read shadow-write lock.
+ * otp: OTP number.
+ * return: true if OTP is locked, else false.
+ */
+bool bsec_read_sw_lock(uint32_t otp)
+{
+	uint32_t bank = otp_bank_offset(otp);
+	uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+	uint32_t bank_value = mmio_read_32(bsec_base + BSEC_SWLOCK_OFF + bank);
+
+	return (bank_value & otp_mask) != 0U;
+}
+
+/*
+ * bsec_write_sp_lock: write shadow-program lock.
+ * otp: OTP number.
+ * value: Value to write in the register.
+ *	Must be always 1.
+ * return: true if OTP is locked, else false.
+ */
+bool bsec_write_sp_lock(uint32_t otp, uint32_t value)
+{
+	bool result = false;
+	uint32_t bank = otp_bank_offset(otp);
+	uint32_t bank_value;
+	uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+
+	bsec_lock();
+
+	bank_value = mmio_read_32(bsec_base + BSEC_SPLOCK_OFF + bank);
+
+	if ((bank_value & otp_mask) == value) {
+		/*
+		 * In case of write don't need to write,
+		 * the lock is already set.
+		 */
+		if (value != 0U) {
+			result = true;
+		}
+	} else {
+		if (value != 0U) {
+			bank_value = bank_value | otp_mask;
+		} else {
+			bank_value = bank_value & ~otp_mask;
+		}
+
+		/*
+		 * We can write 0 in all other OTP
+		 * if the lock is activated in one of other OTP.
+		 * Write 0 has no effect.
+		 */
+		mmio_write_32(bsec_base + BSEC_SPLOCK_OFF + bank, bank_value);
+		result = true;
+	}
+
+	bsec_unlock();
+
+	return result;
+}
+
+/*
+ * bsec_read_sp_lock: read shadow-program lock.
+ * otp: OTP number.
+ * return: true if OTP is locked, else false.
+ */
+bool bsec_read_sp_lock(uint32_t otp)
+{
+	uint32_t bank = otp_bank_offset(otp);
+	uint32_t otp_mask = BIT(otp & BSEC_OTP_MASK);
+	uint32_t bank_value = mmio_read_32(bsec_base + BSEC_SPLOCK_OFF + bank);
+
+	return (bank_value & otp_mask) != 0U;
+}
+
+/*
+ * bsec_wr_lock: Read permanent lock status.
+ * otp: OTP number.
+ * return: true if OTP is locked, else false.
+ */
+bool bsec_wr_lock(uint32_t otp)
+{
+	uint32_t bank = otp_bank_offset(otp);
+	uint32_t lock_bit = BIT(otp & BSEC_OTP_MASK);
+
+	if ((mmio_read_32(bsec_base + BSEC_WRLOCK_OFF + bank) &
+	     lock_bit) != 0U) {
+		/*
+		 * In case of write don't need to write,
+		 * the lock is already set.
+		 */
+		return true;
+	}
+
+	return false;
+}
+
+/*
+ * bsec_otp_lock: Lock Upper OTP or Global programming or debug enable
+ * service: Service to lock see header file.
+ * value: Value to write must always set to 1 (only use for debug purpose).
+ * return: BSEC_OK if succeed.
+ */
+uint32_t bsec_otp_lock(uint32_t service, uint32_t value)
+{
+	uintptr_t reg = bsec_base + BSEC_OTP_LOCK_OFF;
+
+	switch (service) {
+	case BSEC_LOCK_UPPER_OTP:
+		mmio_write_32(reg, value << BSEC_LOCK_UPPER_OTP);
+		break;
+	case BSEC_LOCK_DEBUG:
+		mmio_write_32(reg, value << BSEC_LOCK_DEBUG);
+		break;
+	case BSEC_LOCK_PROGRAM:
+		mmio_write_32(reg, value << BSEC_LOCK_PROGRAM);
+		break;
+	default:
+		return BSEC_INVALID_PARAM;
+	}
+
+	return BSEC_OK;
+}
+
+/*
+ * bsec_power_safmem: Activate or deactivate SAFMEM power.
+ * power: true to power up, false to power down.
+ * return: BSEC_OK if succeed.
+ */
+static uint32_t bsec_power_safmem(bool power)
+{
+	uint32_t register_val;
+	uint32_t timeout = BSEC_TIMEOUT_VALUE;
+
+	bsec_lock();
+
+	register_val = mmio_read_32(bsec_base + BSEC_OTP_CONF_OFF);
+
+	if (power) {
+		register_val |= BSEC_CONF_POWER_UP_MASK;
+	} else {
+		register_val &= ~BSEC_CONF_POWER_UP_MASK;
+	}
+
+	mmio_write_32(bsec_base + BSEC_OTP_CONF_OFF, register_val);
+
+	/* Waiting loop */
+	if (power) {
+		while (((bsec_get_status() & BSEC_MODE_PWR_MASK) == 0U) &&
+		       (timeout != 0U)) {
+			timeout--;
+		}
+	} else {
+		while (((bsec_get_status() & BSEC_MODE_PWR_MASK) != 0U) &&
+		       (timeout != 0U)) {
+			timeout--;
+		}
+	}
+
+	bsec_unlock();
+
+	if (timeout == 0U) {
+		return BSEC_TIMEOUT;
+	}
+
+	return BSEC_OK;
+}
+
+/*
+ * bsec_mode_is_closed_device: read OTP secure sub-mode.
+ * return: false if open_device and true of closed_device.
+ */
+bool bsec_mode_is_closed_device(void)
+{
+	uint32_t value;
+
+	if ((bsec_shadow_register(DATA0_OTP) != BSEC_OK) ||
+	    (bsec_read_otp(&value, DATA0_OTP) != BSEC_OK)) {
+		return true;
+	}
+
+	return (value & DATA0_OTP_SECURED) == DATA0_OTP_SECURED;
+}
+
+/*
+ * bsec_shadow_read_otp: Load OTP from SAFMEM and provide its value
+ * otp_value: read value.
+ * word: OTP number.
+ * return value: BSEC_OK if no error.
+ */
+uint32_t bsec_shadow_read_otp(uint32_t *otp_value, uint32_t word)
+{
+	uint32_t result;
+
+	result = bsec_shadow_register(word);
+	if (result != BSEC_OK) {
+		ERROR("BSEC: %u Shadowing Error %i\n", word, result);
+		return result;
+	}
+
+	result = bsec_read_otp(otp_value, word);
+	if (result != BSEC_OK) {
+		ERROR("BSEC: %u Read Error %i\n", word, result);
+	}
+
+	return result;
+}
+
+/*
+ * bsec_check_nsec_access_rights: check non-secure access rights to target OTP.
+ * otp: OTP number.
+ * return: BSEC_OK if authorized access.
+ */
+uint32_t bsec_check_nsec_access_rights(uint32_t otp)
+{
+#if defined(IMAGE_BL32)
+	if (otp > STM32MP1_OTP_MAX_ID) {
+		return BSEC_INVALID_PARAM;
+	}
+
+	if (otp >= STM32MP1_UPPER_OTP_START) {
+		/* Check if BSEC is in OTP-SECURED closed_device state. */
+		if (bsec_mode_is_closed_device()) {
+			if (!non_secure_can_access(otp)) {
+				return BSEC_ERROR;
+			}
+		}
+	}
+#endif
+
+	return BSEC_OK;
+}
+
diff --git a/drivers/st/clk/stm32mp1_clkfunc.c b/drivers/st/clk/stm32mp1_clkfunc.c
index 1d92271..19dfe1b 100644
--- a/drivers/st/clk/stm32mp1_clkfunc.c
+++ b/drivers/st/clk/stm32mp1_clkfunc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -32,10 +32,18 @@
 };
 
 /*******************************************************************************
+ * This function returns the RCC node in the device tree.
+ ******************************************************************************/
+static int fdt_get_rcc_node(void *fdt)
+{
+	return fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
+}
+
+/*******************************************************************************
  * This function reads the frequency of an oscillator from its name.
  * It reads the value indicated inside the device tree.
- * Returns 0 if success, and a negative value else.
- * If success, value is stored in the second parameter.
+ * Returns 0 on success, and a negative FDT/ERRNO error code on failure.
+ * On success, value is stored in the second parameter.
  ******************************************************************************/
 int fdt_osc_read_freq(const char *name, uint32_t *freq)
 {
@@ -127,7 +135,7 @@
 
 /*******************************************************************************
  * This function reads a value of a oscillator property from its id.
- * Returns value if success, and a default value if property not found.
+ * Returns value on success, and a default value if property not found.
  * Default value is passed as parameter.
  ******************************************************************************/
 uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id,
@@ -240,7 +248,7 @@
 /*******************************************************************************
  * This function gets the subnode offset in rcc-clk section from its name.
  * It reads the values indicated inside the device tree.
- * Returns offset if success, and a negative value else.
+ * Returns offset on success, and a negative FDT/ERRNO error code on failure.
  ******************************************************************************/
 int fdt_rcc_subnode_offset(const char *name)
 {
@@ -251,7 +259,7 @@
 		return -ENOENT;
 	}
 
-	node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
+	node = fdt_get_rcc_node(fdt);
 	if (node < 0) {
 		return -FDT_ERR_NOTFOUND;
 	}
@@ -280,7 +288,7 @@
 		return NULL;
 	}
 
-	node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
+	node = fdt_get_rcc_node(fdt);
 	if (node < 0) {
 		return NULL;
 	}
@@ -297,7 +305,7 @@
 /*******************************************************************************
  * This function gets the secure status for rcc node.
  * It reads secure-status in device tree.
- * Returns 1 if rcc is available from secure world, 0 else.
+ * Returns true if rcc is available from secure world, false if not.
  ******************************************************************************/
 bool fdt_get_rcc_secure_status(void)
 {
@@ -308,18 +316,18 @@
 		return false;
 	}
 
-	node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_COMPAT);
+	node = fdt_get_rcc_node(fdt);
 	if (node < 0) {
 		return false;
 	}
 
-	return fdt_check_secure_status(node);
+	return (fdt_get_status(node) & DT_SECURE) != 0U;
 }
 
 /*******************************************************************************
  * This function reads the stgen base address.
  * It reads the value indicated inside the device tree.
- * Returns address if success, and NULL value else.
+ * Returns address on success, and NULL value on failure.
  ******************************************************************************/
 uintptr_t fdt_get_stgen_base(void)
 {
@@ -347,7 +355,7 @@
 /*******************************************************************************
  * This function gets the clock ID of the given node.
  * It reads the value indicated inside the device tree.
- * Returns ID if success, and a negative value else.
+ * Returns ID on success, and a negative FDT/ERRNO error code on failure.
  ******************************************************************************/
 int fdt_get_clock_id(int node)
 {
diff --git a/drivers/st/ddr/stm32mp1_ddr.c b/drivers/st/ddr/stm32mp1_ddr.c
index aca0450..79aff6e 100644
--- a/drivers/st/ddr/stm32mp1_ddr.c
+++ b/drivers/st/ddr/stm32mp1_ddr.c
@@ -1,9 +1,10 @@
 /*
- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
 
+#include <errno.h>
 #include <stddef.h>
 
 #include <platform_def.h>
@@ -12,10 +13,10 @@
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <drivers/delay_timer.h>
+#include <drivers/st/stm32mp_pmic.h>
 #include <drivers/st/stm32mp1_clk.h>
 #include <drivers/st/stm32mp1_ddr.h>
 #include <drivers/st/stm32mp1_ddr_regs.h>
-#include <drivers/st/stm32mp1_pmic.h>
 #include <drivers/st/stm32mp1_pwr.h>
 #include <drivers/st/stm32mp1_ram.h>
 #include <drivers/st/stm32mp1_rcc.h>
@@ -233,40 +234,67 @@
 
 static const struct ddr_reg_info ddr_registers[REG_TYPE_NB] = {
 	[REG_REG] = {
-		"static", ddr_reg, ARRAY_SIZE(ddr_reg), DDR_BASE
+		.name = "static",
+		.desc = ddr_reg,
+		.size = ARRAY_SIZE(ddr_reg),
+		.base = DDR_BASE
 	},
 	[REG_TIMING] = {
-		"timing", ddr_timing, ARRAY_SIZE(ddr_timing), DDR_BASE
+		.name = "timing",
+		.desc = ddr_timing,
+		.size = ARRAY_SIZE(ddr_timing),
+		.base = DDR_BASE
 	},
 	[REG_PERF] = {
-		"perf", ddr_perf, ARRAY_SIZE(ddr_perf), DDR_BASE
+		.name = "perf",
+		.desc = ddr_perf,
+		.size = ARRAY_SIZE(ddr_perf),
+		.base = DDR_BASE
 	},
 	[REG_MAP] = {
-		"map", ddr_map, ARRAY_SIZE(ddr_map), DDR_BASE
+		.name = "map",
+		.desc = ddr_map,
+		.size = ARRAY_SIZE(ddr_map),
+		.base = DDR_BASE
 	},
 	[REGPHY_REG] = {
-		"static", ddrphy_reg, ARRAY_SIZE(ddrphy_reg), DDRPHY_BASE
+		.name = "static",
+		.desc = ddrphy_reg,
+		.size = ARRAY_SIZE(ddrphy_reg),
+		.base = DDRPHY_BASE
 	},
 	[REGPHY_TIMING] = {
-		"timing", ddrphy_timing, ARRAY_SIZE(ddrphy_timing), DDRPHY_BASE
+		.name = "timing",
+		.desc = ddrphy_timing,
+		.size = ARRAY_SIZE(ddrphy_timing),
+		.base = DDRPHY_BASE
 	},
 	[REGPHY_CAL] = {
-		"cal", ddrphy_cal, ARRAY_SIZE(ddrphy_cal), DDRPHY_BASE
+		.name = "cal",
+		.desc = ddrphy_cal,
+		.size = ARRAY_SIZE(ddrphy_cal),
+		.base = DDRPHY_BASE
 	},
 	[REG_DYN] = {
-		"dyn", ddr_dyn, ARRAY_SIZE(ddr_dyn), DDR_BASE
+		.name = "dyn",
+		.desc = ddr_dyn,
+		.size = ARRAY_SIZE(ddr_dyn),
+		.base = DDR_BASE
 	},
 	[REGPHY_DYN] = {
-		"dyn", ddrphy_dyn, ARRAY_SIZE(ddrphy_dyn), DDRPHY_BASE
+		.name = "dyn",
+		.desc = ddrphy_dyn,
+		.size = ARRAY_SIZE(ddrphy_dyn),
+		.base = DDRPHY_BASE
 	},
 };
 
-static uint32_t get_base_addr(const struct ddr_info *priv, enum base_type base)
+static uintptr_t get_base_addr(const struct ddr_info *priv, enum base_type base)
 {
 	if (base == DDRPHY_BASE) {
-		return (uint32_t)priv->phy;
+		return (uintptr_t)priv->phy;
 	} else {
-		return (uint32_t)priv->ctl;
+		return (uintptr_t)priv->ctl;
 	}
 }
 
@@ -275,21 +303,22 @@
 		    const void *param)
 {
 	unsigned int i;
-	unsigned int *ptr, value;
+	unsigned int value;
 	enum base_type base = ddr_registers[type].base;
-	uint32_t base_addr = get_base_addr(priv, base);
+	uintptr_t base_addr = get_base_addr(priv, base);
 	const struct reg_desc *desc = ddr_registers[type].desc;
 
 	VERBOSE("init %s\n", ddr_registers[type].name);
 	for (i = 0; i < ddr_registers[type].size; i++) {
-		ptr = (unsigned int *)(base_addr + desc[i].offset);
+		uintptr_t ptr = base_addr + desc[i].offset;
+
 		if (desc[i].par_offset == INVALID_OFFSET) {
 			ERROR("invalid parameter offset for %s", desc[i].name);
 			panic();
 		} else {
-			value = *((uint32_t *)((uint32_t)param +
+			value = *((uint32_t *)((uintptr_t)param +
 					       desc[i].par_offset));
-			mmio_write_32((uint32_t)ptr, value);
+			mmio_write_32(ptr, value);
 		}
 	}
 }
@@ -305,15 +334,15 @@
 	time0 = start;
 
 	do {
-		pgsr = mmio_read_32((uint32_t)&phy->pgsr);
+		pgsr = mmio_read_32((uintptr_t)&phy->pgsr);
 		time = get_timer(start);
 		if (time != time0) {
-			VERBOSE("  > [0x%x] pgsr = 0x%x &\n",
-				(uint32_t)&phy->pgsr, pgsr);
-			VERBOSE("    [0x%x] pir = 0x%x (time=%x)\n",
-				(uint32_t)&phy->pir,
-				mmio_read_32((uint32_t)&phy->pir),
-				(uint32_t)time);
+			VERBOSE("  > [0x%lx] pgsr = 0x%x &\n",
+				(uintptr_t)&phy->pgsr, pgsr);
+			VERBOSE("    [0x%lx] pir = 0x%x (time=%lx)\n",
+				(uintptr_t)&phy->pir,
+				mmio_read_32((uintptr_t)&phy->pir),
+				time);
 		}
 
 		time0 = time;
@@ -341,18 +370,18 @@
 			error++;
 		}
 	} while ((pgsr & DDRPHYC_PGSR_IDONE) == 0U && error == 0);
-	VERBOSE("\n[0x%x] pgsr = 0x%x\n",
-		(uint32_t)&phy->pgsr, pgsr);
+	VERBOSE("\n[0x%lx] pgsr = 0x%x\n",
+		(uintptr_t)&phy->pgsr, pgsr);
 }
 
 static void stm32mp1_ddrphy_init(struct stm32mp1_ddrphy *phy, uint32_t pir)
 {
 	uint32_t pir_init = pir | DDRPHYC_PIR_INIT;
 
-	mmio_write_32((uint32_t)&phy->pir, pir_init);
-	VERBOSE("[0x%x] pir = 0x%x -> 0x%x\n",
-		(uint32_t)&phy->pir, pir_init,
-		mmio_read_32((uint32_t)&phy->pir));
+	mmio_write_32((uintptr_t)&phy->pir, pir_init);
+	VERBOSE("[0x%lx] pir = 0x%x -> 0x%x\n",
+		(uintptr_t)&phy->pir, pir_init,
+		mmio_read_32((uintptr_t)&phy->pir));
 
 	/* Need to wait 10 configuration clock before start polling */
 	udelay(10);
@@ -364,9 +393,9 @@
 /* Start quasi dynamic register update */
 static void stm32mp1_start_sw_done(struct stm32mp1_ddrctl *ctl)
 {
-	mmio_clrbits_32((uint32_t)&ctl->swctl, DDRCTRL_SWCTL_SW_DONE);
-	VERBOSE("[0x%x] swctl = 0x%x\n",
-		(uint32_t)&ctl->swctl,  mmio_read_32((uint32_t)&ctl->swctl));
+	mmio_clrbits_32((uintptr_t)&ctl->swctl, DDRCTRL_SWCTL_SW_DONE);
+	VERBOSE("[0x%lx] swctl = 0x%x\n",
+		(uintptr_t)&ctl->swctl,  mmio_read_32((uintptr_t)&ctl->swctl));
 }
 
 /* Wait quasi dynamic register update */
@@ -375,15 +404,15 @@
 	unsigned long start;
 	uint32_t swstat;
 
-	mmio_setbits_32((uint32_t)&ctl->swctl, DDRCTRL_SWCTL_SW_DONE);
-	VERBOSE("[0x%x] swctl = 0x%x\n",
-		(uint32_t)&ctl->swctl, mmio_read_32((uint32_t)&ctl->swctl));
+	mmio_setbits_32((uintptr_t)&ctl->swctl, DDRCTRL_SWCTL_SW_DONE);
+	VERBOSE("[0x%lx] swctl = 0x%x\n",
+		(uintptr_t)&ctl->swctl, mmio_read_32((uintptr_t)&ctl->swctl));
 
 	start = get_timer(0);
 	do {
-		swstat = mmio_read_32((uint32_t)&ctl->swstat);
-		VERBOSE("[0x%x] swstat = 0x%x ",
-			(uint32_t)&ctl->swstat, swstat);
+		swstat = mmio_read_32((uintptr_t)&ctl->swstat);
+		VERBOSE("[0x%lx] swstat = 0x%x ",
+			(uintptr_t)&ctl->swstat, swstat);
 		VERBOSE("timer in ms 0x%x = start 0x%lx\r",
 			get_timer(0), start);
 		if (get_timer(start) > plat_get_syscnt_freq2()) {
@@ -391,8 +420,8 @@
 		}
 	} while ((swstat & DDRCTRL_SWSTAT_SW_DONE_ACK) == 0U);
 
-	VERBOSE("[0x%x] swstat = 0x%x\n",
-		(uint32_t)&ctl->swstat, swstat);
+	VERBOSE("[0x%lx] swstat = 0x%x\n",
+		(uintptr_t)&ctl->swstat, swstat);
 }
 
 /* Wait quasi dynamic register update */
@@ -406,11 +435,11 @@
 
 	start = get_timer(0);
 	for ( ; ; ) {
-		stat = mmio_read_32((uint32_t)&priv->ctl->stat);
+		stat = mmio_read_32((uintptr_t)&priv->ctl->stat);
 		operating_mode = stat & DDRCTRL_STAT_OPERATING_MODE_MASK;
 		selref_type = stat & DDRCTRL_STAT_SELFREF_TYPE_MASK;
-		VERBOSE("[0x%x] stat = 0x%x\n",
-			(uint32_t)&priv->ctl->stat, stat);
+		VERBOSE("[0x%lx] stat = 0x%x\n",
+			(uintptr_t)&priv->ctl->stat, stat);
 		VERBOSE("timer in ms 0x%x = start 0x%lx\r",
 			get_timer(0), start);
 		if (get_timer(start) > plat_get_syscnt_freq2()) {
@@ -441,8 +470,8 @@
 		}
 	}
 
-	VERBOSE("[0x%x] stat = 0x%x\n",
-		(uint32_t)&priv->ctl->stat, stat);
+	VERBOSE("[0x%lx] stat = 0x%x\n",
+		(uintptr_t)&priv->ctl->stat, stat);
 }
 
 /* Mode Register Writes (MRW or MRS) */
@@ -459,7 +488,7 @@
 	 *    No write should be performed to MRCTRL0 and MRCTRL1
 	 *    if MRSTAT.mr_wr_busy = 1.
 	 */
-	while ((mmio_read_32((uint32_t)&priv->ctl->mrstat) &
+	while ((mmio_read_32((uintptr_t)&priv->ctl->mrstat) &
 		DDRCTRL_MRSTAT_MR_WR_BUSY) != 0U) {
 		;
 	}
@@ -472,14 +501,14 @@
 		  DDRCTRL_MRCTRL0_MR_RANK_ALL |
 		  (((uint32_t)addr << DDRCTRL_MRCTRL0_MR_ADDR_SHIFT) &
 		   DDRCTRL_MRCTRL0_MR_ADDR_MASK);
-	mmio_write_32((uint32_t)&priv->ctl->mrctrl0, mrctrl0);
-	VERBOSE("[0x%x] mrctrl0 = 0x%x (0x%x)\n",
-		(uint32_t)&priv->ctl->mrctrl0,
-		mmio_read_32((uint32_t)&priv->ctl->mrctrl0), mrctrl0);
-	mmio_write_32((uint32_t)&priv->ctl->mrctrl1, data);
-	VERBOSE("[0x%x] mrctrl1 = 0x%x\n",
-		(uint32_t)&priv->ctl->mrctrl1,
-		mmio_read_32((uint32_t)&priv->ctl->mrctrl1));
+	mmio_write_32((uintptr_t)&priv->ctl->mrctrl0, mrctrl0);
+	VERBOSE("[0x%lx] mrctrl0 = 0x%x (0x%x)\n",
+		(uintptr_t)&priv->ctl->mrctrl0,
+		mmio_read_32((uintptr_t)&priv->ctl->mrctrl0), mrctrl0);
+	mmio_write_32((uintptr_t)&priv->ctl->mrctrl1, data);
+	VERBOSE("[0x%lx] mrctrl1 = 0x%x\n",
+		(uintptr_t)&priv->ctl->mrctrl1,
+		mmio_read_32((uintptr_t)&priv->ctl->mrctrl1));
 
 	/*
 	 * 3. In a separate APB transaction, write the MRCTRL0.mr_wr to 1. This
@@ -489,22 +518,22 @@
 	 *    initiated until it is deasserted.
 	 */
 	mrctrl0 |= DDRCTRL_MRCTRL0_MR_WR;
-	mmio_write_32((uint32_t)&priv->ctl->mrctrl0, mrctrl0);
+	mmio_write_32((uintptr_t)&priv->ctl->mrctrl0, mrctrl0);
 
-	while ((mmio_read_32((uint32_t)&priv->ctl->mrstat) &
+	while ((mmio_read_32((uintptr_t)&priv->ctl->mrstat) &
 	       DDRCTRL_MRSTAT_MR_WR_BUSY) != 0U) {
 		;
 	}
 
-	VERBOSE("[0x%x] mrctrl0 = 0x%x\n",
-		(uint32_t)&priv->ctl->mrctrl0, mrctrl0);
+	VERBOSE("[0x%lx] mrctrl0 = 0x%x\n",
+		(uintptr_t)&priv->ctl->mrctrl0, mrctrl0);
 }
 
 /* Switch DDR3 from DLL-on to DLL-off */
 static void stm32mp1_ddr3_dll_off(struct ddr_info *priv)
 {
-	uint32_t mr1 = mmio_read_32((uint32_t)&priv->phy->mr1);
-	uint32_t mr2 = mmio_read_32((uint32_t)&priv->phy->mr2);
+	uint32_t mr1 = mmio_read_32((uintptr_t)&priv->phy->mr1);
+	uint32_t mr2 = mmio_read_32((uintptr_t)&priv->phy->mr2);
 	uint32_t dbgcam;
 
 	VERBOSE("mr1: 0x%x\n", mr1);
@@ -514,10 +543,10 @@
 	 * 1. Set the DBG1.dis_hif = 1.
 	 *    This prevents further reads/writes being received on the HIF.
 	 */
-	mmio_setbits_32((uint32_t)&priv->ctl->dbg1, DDRCTRL_DBG1_DIS_HIF);
-	VERBOSE("[0x%x] dbg1 = 0x%x\n",
-		(uint32_t)&priv->ctl->dbg1,
-		mmio_read_32((uint32_t)&priv->ctl->dbg1));
+	mmio_setbits_32((uintptr_t)&priv->ctl->dbg1, DDRCTRL_DBG1_DIS_HIF);
+	VERBOSE("[0x%lx] dbg1 = 0x%x\n",
+		(uintptr_t)&priv->ctl->dbg1,
+		mmio_read_32((uintptr_t)&priv->ctl->dbg1));
 
 	/*
 	 * 2. Ensure all commands have been flushed from the uMCTL2 by polling
@@ -528,9 +557,9 @@
 	 *    DBGCAM.dbg_hpr_q_depth = 0.
 	 */
 	do {
-		dbgcam = mmio_read_32((uint32_t)&priv->ctl->dbgcam);
-		VERBOSE("[0x%x] dbgcam = 0x%x\n",
-			(uint32_t)&priv->ctl->dbgcam, dbgcam);
+		dbgcam = mmio_read_32((uintptr_t)&priv->ctl->dbgcam);
+		VERBOSE("[0x%lx] dbgcam = 0x%x\n",
+			(uintptr_t)&priv->ctl->dbgcam, dbgcam);
 	} while ((((dbgcam & DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY) ==
 		   DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY)) &&
 		 ((dbgcam & DDRCTRL_DBGCAM_DBG_Q_DEPTH) == 0U));
@@ -574,11 +603,11 @@
 	 *    PWRCTL.selfref_sw = 1, and polling STAT.operating_mode to ensure
 	 *    the DDRC has entered self-refresh.
 	 */
-	mmio_setbits_32((uint32_t)&priv->ctl->pwrctl,
+	mmio_setbits_32((uintptr_t)&priv->ctl->pwrctl,
 			DDRCTRL_PWRCTL_SELFREF_SW);
-	VERBOSE("[0x%x] pwrctl = 0x%x\n",
-		(uint32_t)&priv->ctl->pwrctl,
-		mmio_read_32((uint32_t)&priv->ctl->pwrctl));
+	VERBOSE("[0x%lx] pwrctl = 0x%x\n",
+		(uintptr_t)&priv->ctl->pwrctl,
+		mmio_read_32((uintptr_t)&priv->ctl->pwrctl));
 
 	/*
 	 * 8. Wait until STAT.operating_mode[1:0]==11 indicating that the
@@ -594,10 +623,10 @@
 	 */
 	stm32mp1_start_sw_done(priv->ctl);
 
-	mmio_setbits_32((uint32_t)&priv->ctl->mstr, DDRCTRL_MSTR_DLL_OFF_MODE);
-	VERBOSE("[0x%x] mstr = 0x%x\n",
-		(uint32_t)&priv->ctl->mstr,
-		mmio_read_32((uint32_t)&priv->ctl->mstr));
+	mmio_setbits_32((uintptr_t)&priv->ctl->mstr, DDRCTRL_MSTR_DLL_OFF_MODE);
+	VERBOSE("[0x%lx] mstr = 0x%x\n",
+		(uintptr_t)&priv->ctl->mstr,
+		mmio_read_32((uintptr_t)&priv->ctl->mstr));
 
 	stm32mp1_wait_sw_done_ack(priv->ctl);
 
@@ -611,26 +640,26 @@
 
 	/* Change Bypass Mode Frequency Range */
 	if (stm32mp1_clk_get_rate(DDRPHYC) < 100000000U) {
-		mmio_clrbits_32((uint32_t)&priv->phy->dllgcr,
+		mmio_clrbits_32((uintptr_t)&priv->phy->dllgcr,
 				DDRPHYC_DLLGCR_BPS200);
 	} else {
-		mmio_setbits_32((uint32_t)&priv->phy->dllgcr,
+		mmio_setbits_32((uintptr_t)&priv->phy->dllgcr,
 				DDRPHYC_DLLGCR_BPS200);
 	}
 
-	mmio_setbits_32((uint32_t)&priv->phy->acdllcr, DDRPHYC_ACDLLCR_DLLDIS);
+	mmio_setbits_32((uintptr_t)&priv->phy->acdllcr, DDRPHYC_ACDLLCR_DLLDIS);
 
-	mmio_setbits_32((uint32_t)&priv->phy->dx0dllcr,
+	mmio_setbits_32((uintptr_t)&priv->phy->dx0dllcr,
 			DDRPHYC_DXNDLLCR_DLLDIS);
-	mmio_setbits_32((uint32_t)&priv->phy->dx1dllcr,
+	mmio_setbits_32((uintptr_t)&priv->phy->dx1dllcr,
 			DDRPHYC_DXNDLLCR_DLLDIS);
-	mmio_setbits_32((uint32_t)&priv->phy->dx2dllcr,
+	mmio_setbits_32((uintptr_t)&priv->phy->dx2dllcr,
 			DDRPHYC_DXNDLLCR_DLLDIS);
-	mmio_setbits_32((uint32_t)&priv->phy->dx3dllcr,
+	mmio_setbits_32((uintptr_t)&priv->phy->dx3dllcr,
 			DDRPHYC_DXNDLLCR_DLLDIS);
 
 	/* 12. Exit the self-refresh state by setting PWRCTL.selfref_sw = 0. */
-	mmio_clrbits_32((uint32_t)&priv->ctl->pwrctl,
+	mmio_clrbits_32((uintptr_t)&priv->ctl->pwrctl,
 			DDRCTRL_PWRCTL_SELFREF_SW);
 	stm32mp1_wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_NORMAL);
 
@@ -646,20 +675,20 @@
 	 */
 
 	/* 15. Write DBG1.dis_hif = 0 to re-enable reads and writes. */
-	mmio_clrbits_32((uint32_t)&priv->ctl->dbg1, DDRCTRL_DBG1_DIS_HIF);
-	VERBOSE("[0x%x] dbg1 = 0x%x\n",
-		(uint32_t)&priv->ctl->dbg1,
-		mmio_read_32((uint32_t)&priv->ctl->dbg1));
+	mmio_clrbits_32((uintptr_t)&priv->ctl->dbg1, DDRCTRL_DBG1_DIS_HIF);
+	VERBOSE("[0x%lx] dbg1 = 0x%x\n",
+		(uintptr_t)&priv->ctl->dbg1,
+		mmio_read_32((uintptr_t)&priv->ctl->dbg1));
 }
 
 static void stm32mp1_refresh_disable(struct stm32mp1_ddrctl *ctl)
 {
 	stm32mp1_start_sw_done(ctl);
 	/* Quasi-dynamic register update*/
-	mmio_setbits_32((uint32_t)&ctl->rfshctl3,
+	mmio_setbits_32((uintptr_t)&ctl->rfshctl3,
 			DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH);
-	mmio_clrbits_32((uint32_t)&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN);
-	mmio_clrbits_32((uint32_t)&ctl->dfimisc,
+	mmio_clrbits_32((uintptr_t)&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN);
+	mmio_clrbits_32((uintptr_t)&ctl->dfimisc,
 			DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
 	stm32mp1_wait_sw_done_ack(ctl);
 }
@@ -669,14 +698,14 @@
 {
 	stm32mp1_start_sw_done(ctl);
 	if ((rfshctl3 & DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH) == 0U) {
-		mmio_clrbits_32((uint32_t)&ctl->rfshctl3,
+		mmio_clrbits_32((uintptr_t)&ctl->rfshctl3,
 				DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH);
 	}
 	if ((pwrctl & DDRCTRL_PWRCTL_POWERDOWN_EN) != 0U) {
-		mmio_setbits_32((uint32_t)&ctl->pwrctl,
+		mmio_setbits_32((uintptr_t)&ctl->pwrctl,
 				DDRCTRL_PWRCTL_POWERDOWN_EN);
 	}
-	mmio_setbits_32((uint32_t)&ctl->dfimisc,
+	mmio_setbits_32((uintptr_t)&ctl->dfimisc,
 			DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
 	stm32mp1_wait_sw_done_ack(ctl);
 }
@@ -694,12 +723,14 @@
 		       struct stm32mp1_ddr_config *config)
 {
 	uint32_t pir;
-	int ret;
+	int ret = -EINVAL;
 
 	if ((config->c_reg.mstr & DDRCTRL_MSTR_DDR3) != 0U) {
 		ret = board_ddr_power_init(STM32MP_DDR3);
-	} else {
+	} else if ((config->c_reg.mstr & DDRCTRL_MSTR_LPDDR2) != 0U) {
 		ret = board_ddr_power_init(STM32MP_LPDDR2);
+	} else {
+		ERROR("DDR type not supported\n");
 	}
 
 	if (ret != 0) {
@@ -707,7 +738,7 @@
 	}
 
 	VERBOSE("name = %s\n", config->info.name);
-	VERBOSE("speed = %d MHz\n", config->info.speed);
+	VERBOSE("speed = %d kHz\n", config->info.speed);
 	VERBOSE("size  = 0x%x\n", config->info.size);
 
 	/* DDR INIT SEQUENCE */
@@ -746,11 +777,11 @@
 
 	/* 1.5. initialize registers ddr_umctl2 */
 	/* Stop uMCTL2 before PHY is ready */
-	mmio_clrbits_32((uint32_t)&priv->ctl->dfimisc,
+	mmio_clrbits_32((uintptr_t)&priv->ctl->dfimisc,
 			DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
-	VERBOSE("[0x%x] dfimisc = 0x%x\n",
-		(uint32_t)&priv->ctl->dfimisc,
-		mmio_read_32((uint32_t)&priv->ctl->dfimisc));
+	VERBOSE("[0x%lx] dfimisc = 0x%x\n",
+		(uintptr_t)&priv->ctl->dfimisc,
+		mmio_read_32((uintptr_t)&priv->ctl->dfimisc));
 
 	set_reg(priv, REG_REG, &config->c_reg);
 
@@ -759,23 +790,23 @@
 	     (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE))
 	    == (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE)) {
 		VERBOSE("deactivate DLL OFF in mstr\n");
-		mmio_clrbits_32((uint32_t)&priv->ctl->mstr,
+		mmio_clrbits_32((uintptr_t)&priv->ctl->mstr,
 				DDRCTRL_MSTR_DLL_OFF_MODE);
-		VERBOSE("[0x%x] mstr = 0x%x\n",
-			(uint32_t)&priv->ctl->mstr,
-			mmio_read_32((uint32_t)&priv->ctl->mstr));
+		VERBOSE("[0x%lx] mstr = 0x%x\n",
+			(uintptr_t)&priv->ctl->mstr,
+			mmio_read_32((uintptr_t)&priv->ctl->mstr));
 	}
 
 	set_reg(priv, REG_TIMING, &config->c_timing);
 	set_reg(priv, REG_MAP, &config->c_map);
 
 	/* Skip CTRL init, SDRAM init is done by PHY PUBL */
-	mmio_clrsetbits_32((uint32_t)&priv->ctl->init0,
+	mmio_clrsetbits_32((uintptr_t)&priv->ctl->init0,
 			   DDRCTRL_INIT0_SKIP_DRAM_INIT_MASK,
 			   DDRCTRL_INIT0_SKIP_DRAM_INIT_NORMAL);
-	VERBOSE("[0x%x] init0 = 0x%x\n",
-		(uint32_t)&priv->ctl->init0,
-		mmio_read_32((uint32_t)&priv->ctl->init0));
+	VERBOSE("[0x%lx] init0 = 0x%x\n",
+		(uintptr_t)&priv->ctl->init0,
+		mmio_read_32((uintptr_t)&priv->ctl->init0));
 
 	set_reg(priv, REG_PERF, &config->c_perf);
 
@@ -797,10 +828,10 @@
 	     (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE))
 	    == (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE)) {
 		VERBOSE("deactivate DLL OFF in mr1\n");
-		mmio_clrbits_32((uint32_t)&priv->phy->mr1, BIT(0));
-		VERBOSE("[0x%x] mr1 = 0x%x\n",
-			(uint32_t)&priv->phy->mr1,
-			mmio_read_32((uint32_t)&priv->phy->mr1));
+		mmio_clrbits_32((uintptr_t)&priv->phy->mr1, BIT(0));
+		VERBOSE("[0x%lx] mr1 = 0x%x\n",
+			(uintptr_t)&priv->phy->mr1,
+			mmio_read_32((uintptr_t)&priv->phy->mr1));
 	}
 
 	/*
@@ -830,11 +861,11 @@
 	 */
 	stm32mp1_start_sw_done(priv->ctl);
 
-	mmio_setbits_32((uint32_t)&priv->ctl->dfimisc,
+	mmio_setbits_32((uintptr_t)&priv->ctl->dfimisc,
 			DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
-	VERBOSE("[0x%x] dfimisc = 0x%x\n",
-		(uint32_t)&priv->ctl->dfimisc,
-		mmio_read_32((uint32_t)&priv->ctl->dfimisc));
+	VERBOSE("[0x%lx] dfimisc = 0x%x\n",
+		(uintptr_t)&priv->ctl->dfimisc,
+		mmio_read_32((uintptr_t)&priv->ctl->dfimisc));
 
 	stm32mp1_wait_sw_done_ack(priv->ctl);
 
@@ -884,14 +915,16 @@
 				 config->c_reg.pwrctl);
 
 	/* Enable uMCTL2 AXI port 0 */
-	mmio_setbits_32((uint32_t)&priv->ctl->pctrl_0, DDRCTRL_PCTRL_N_PORT_EN);
-	VERBOSE("[0x%x] pctrl_0 = 0x%x\n",
-		(uint32_t)&priv->ctl->pctrl_0,
-		mmio_read_32((uint32_t)&priv->ctl->pctrl_0));
+	mmio_setbits_32((uintptr_t)&priv->ctl->pctrl_0,
+			DDRCTRL_PCTRL_N_PORT_EN);
+	VERBOSE("[0x%lx] pctrl_0 = 0x%x\n",
+		(uintptr_t)&priv->ctl->pctrl_0,
+		mmio_read_32((uintptr_t)&priv->ctl->pctrl_0));
 
 	/* Enable uMCTL2 AXI port 1 */
-	mmio_setbits_32((uint32_t)&priv->ctl->pctrl_1, DDRCTRL_PCTRL_N_PORT_EN);
-	VERBOSE("[0x%x] pctrl_1 = 0x%x\n",
-		(uint32_t)&priv->ctl->pctrl_1,
-		mmio_read_32((uint32_t)&priv->ctl->pctrl_1));
+	mmio_setbits_32((uintptr_t)&priv->ctl->pctrl_1,
+			DDRCTRL_PCTRL_N_PORT_EN);
+	VERBOSE("[0x%lx] pctrl_1 = 0x%x\n",
+		(uintptr_t)&priv->ctl->pctrl_1,
+		mmio_read_32((uintptr_t)&priv->ctl->pctrl_1));
 }
diff --git a/drivers/st/ddr/stm32mp1_ram.c b/drivers/st/ddr/stm32mp1_ram.c
index 127b6c7..e65fbea 100644
--- a/drivers/st/ddr/stm32mp1_ram.c
+++ b/drivers/st/ddr/stm32mp1_ram.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
@@ -25,7 +25,7 @@
 
 static struct ddr_info ddr_priv_data;
 
-int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint16_t mem_speed)
+int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed)
 {
 	unsigned long ddrphy_clk, ddr_clk, mem_speed_hz;
 
@@ -33,10 +33,10 @@
 
 	ddrphy_clk = stm32mp1_clk_get_rate(DDRPHYC);
 
-	VERBOSE("DDR: mem_speed (%d MHz), RCC %ld MHz\n",
-		mem_speed, ddrphy_clk / 1000U / 1000U);
+	VERBOSE("DDR: mem_speed (%d kHz), RCC %ld kHz\n",
+		mem_speed, ddrphy_clk / 1000U);
 
-	mem_speed_hz = (uint32_t)mem_speed * 1000U * 1000U;
+	mem_speed_hz = mem_speed * 1000U;
 
 	/* Max 10% frequency delta */
 	if (ddrphy_clk > mem_speed_hz) {
@@ -44,9 +44,9 @@
 	} else {
 		ddr_clk = mem_speed_hz - ddrphy_clk;
 	}
-	if (ddr_clk > mem_speed_hz) {
-		ERROR("DDR expected freq %d MHz, current is %ld MHz\n",
-		      mem_speed, ddrphy_clk / 1000U / 1000U);
+	if (ddr_clk > (mem_speed_hz / 10)) {
+		ERROR("DDR expected freq %d kHz, current is %ld kHz\n",
+		      mem_speed, ddrphy_clk / 1000U);
 		return -1;
 	}
 	return 0;
@@ -208,11 +208,16 @@
 		return -EINVAL;
 	}
 
-	config.info.speed =
-		(uint16_t)fdt_read_uint32_default(node, "st,mem-speed",
-						  STM32MP1_DDR_SPEED_DFLT);
-	config.info.size = fdt_read_uint32_default(node, "st,mem-size",
-						   STM32MP1_DDR_SIZE_DFLT);
+	config.info.speed = fdt_read_uint32_default(node, "st,mem-speed", 0);
+	if (!config.info.speed) {
+		VERBOSE("%s: no st,mem-speed\n", __func__);
+		return -EINVAL;
+	}
+	config.info.size = fdt_read_uint32_default(node, "st,mem-size", 0);
+	if (!config.info.size) {
+		VERBOSE("%s: no st,mem-size\n", __func__);
+		return -EINVAL;
+	}
 	config.info.name = fdt_getprop(fdt, node, "st,mem-name", &len);
 	if (config.info.name == NULL) {
 		VERBOSE("%s: no st,mem-name\n", __func__);
@@ -222,7 +227,7 @@
 
 	for (idx = 0; idx < ARRAY_SIZE(param); idx++) {
 		ret = fdt_read_uint32_array(node, param[idx].name,
-					    (void *)((uint32_t)&config +
+					    (void *)((uintptr_t)&config +
 						     param[idx].offset),
 					    param[idx].size);
 
@@ -261,8 +266,8 @@
 	VERBOSE("%s : ram size(%x, %x)\n", __func__,
 		(uint32_t)priv->info.base, (uint32_t)priv->info.size);
 
-	dcsw_op_all(DC_OP_CISW);
 	write_sctlr(read_sctlr() & ~SCTLR_C_BIT);
+	dcsw_op_all(DC_OP_CISW);
 
 	uret = ddr_test_data_bus();
 	if (uret != 0U) {
diff --git a/drivers/st/gpio/stm32_gpio.c b/drivers/st/gpio/stm32_gpio.c
index 9591e37..d217c45 100644
--- a/drivers/st/gpio/stm32_gpio.c
+++ b/drivers/st/gpio/stm32_gpio.c
@@ -1,87 +1,276 @@
 /*
- * Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <assert.h>
+#include <errno.h>
 #include <stdbool.h>
 
+#include <libfdt.h>
+
+#include <platform_def.h>
+
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <drivers/st/stm32_gpio.h>
+#include <drivers/st/stm32mp1_clk.h>
+#include <drivers/st/stm32mp1_clkfunc.h>
 #include <lib/mmio.h>
+#include <lib/utils_def.h>
 
-static bool check_gpio(uint32_t bank, uint32_t pin)
+#define DT_GPIO_BANK_SHIFT	12
+#define DT_GPIO_BANK_MASK	GENMASK(16, 12)
+#define DT_GPIO_PIN_SHIFT	8
+#define DT_GPIO_PIN_MASK	GENMASK(11, 8)
+#define DT_GPIO_MODE_MASK	GENMASK(7, 0)
+
+/*******************************************************************************
+ * This function gets GPIO bank node in DT.
+ * Returns node offset if status is okay in DT, else return 0
+ ******************************************************************************/
+static int ckeck_gpio_bank(void *fdt, uint32_t bank, int pinctrl_node)
 {
-	if (pin > GPIO_PIN_MAX) {
-		ERROR("%s: wrong pin number (%d)\n", __func__, pin);
-		return false;
-	}
+	int pinctrl_subnode;
+	uint32_t bank_offset = stm32_get_gpio_bank_offset(bank);
 
-	if ((bank > GPIO_BANK_K) && (bank != GPIO_BANK_Z)) {
-		ERROR("%s: wrong GPIO bank number (%d)\n", __func__, bank);
-		return false;
+	fdt_for_each_subnode(pinctrl_subnode, fdt, pinctrl_node) {
+		const fdt32_t *cuint;
+
+		if (fdt_getprop(fdt, pinctrl_subnode,
+				"gpio-controller", NULL) == NULL) {
+			continue;
+		}
+
+		cuint = fdt_getprop(fdt, pinctrl_subnode, "reg", NULL);
+		if (cuint == NULL) {
+			continue;
+		}
+
+		if ((fdt32_to_cpu(*cuint) == bank_offset) &&
+		    (fdt_get_status(pinctrl_subnode) != DT_DISABLED)) {
+			return pinctrl_subnode;
+		}
 	}
 
-	return true;
+	return 0;
 }
 
-void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed,
-	      uint32_t pull, uint32_t alternate)
+/*******************************************************************************
+ * This function gets the pin settings from DT information.
+ * When analyze and parsing is done, set the GPIO registers.
+ * Returns 0 on success and a negative FDT error code on failure.
+ ******************************************************************************/
+static int dt_set_gpio_config(void *fdt, int node, uint8_t status)
 {
-	volatile uint32_t bank_address;
+	const fdt32_t *cuint, *slewrate;
+	int len;
+	int pinctrl_node;
+	uint32_t i;
+	uint32_t speed = GPIO_SPEED_LOW;
+	uint32_t pull = GPIO_NO_PULL;
 
-	if (!check_gpio(bank, pin)) {
-		return;
+	cuint = fdt_getprop(fdt, node, "pinmux", &len);
+	if (cuint == NULL) {
+		return -FDT_ERR_NOTFOUND;
 	}
 
-	if (bank == GPIO_BANK_Z) {
-		bank_address = STM32_GPIOZ_BANK;
+	pinctrl_node = fdt_parent_offset(fdt, fdt_parent_offset(fdt, node));
+	if (pinctrl_node < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	slewrate = fdt_getprop(fdt, node, "slew-rate", NULL);
+	if (slewrate != NULL) {
+		speed = fdt32_to_cpu(*slewrate);
+	}
+
+	if (fdt_getprop(fdt, node, "bias-pull-up", NULL) != NULL) {
+		pull = GPIO_PULL_UP;
+	} else if (fdt_getprop(fdt, node, "bias-pull-down", NULL) != NULL) {
+		pull = GPIO_PULL_DOWN;
 	} else {
-		bank_address = STM32_GPIOA_BANK +
-			(bank * STM32_GPIO_BANK_OFFSET);
+		VERBOSE("No bias configured in node %d\n", node);
+	}
+
+	for (i = 0U; i < ((uint32_t)len / sizeof(uint32_t)); i++) {
+		uint32_t pincfg;
+		uint32_t bank;
+		uint32_t pin;
+		uint32_t mode;
+		uint32_t alternate = GPIO_ALTERNATE_(0);
+		int bank_node;
+		int clk;
+
+		pincfg = fdt32_to_cpu(*cuint);
+		cuint++;
+
+		bank = (pincfg & DT_GPIO_BANK_MASK) >> DT_GPIO_BANK_SHIFT;
+
+		pin = (pincfg & DT_GPIO_PIN_MASK) >> DT_GPIO_PIN_SHIFT;
+
+		mode = pincfg & DT_GPIO_MODE_MASK;
+
+		switch (mode) {
+		case 0:
+			mode = GPIO_MODE_INPUT;
+			break;
+		case 1 ... 16:
+			alternate = mode - 1U;
+			mode = GPIO_MODE_ALTERNATE;
+			break;
+		case 17:
+			mode = GPIO_MODE_ANALOG;
+			break;
+		default:
+			mode = GPIO_MODE_OUTPUT;
+			break;
+		}
+
+		if (fdt_getprop(fdt, node, "drive-open-drain", NULL) != NULL) {
+			mode |= GPIO_OPEN_DRAIN;
+		}
+
+		bank_node = ckeck_gpio_bank(fdt, bank, pinctrl_node);
+		if (bank_node == 0) {
+			ERROR("PINCTRL inconsistent in DT\n");
+			panic();
+		}
+
+		clk = fdt_get_clock_id(bank_node);
+		if (clk < 0) {
+			return -FDT_ERR_NOTFOUND;
+		}
+
+		/* Platform knows the clock: assert it is okay */
+		assert((unsigned long)clk == stm32_get_gpio_bank_clock(bank));
+
+		set_gpio(bank, pin, mode, speed, pull, alternate, status);
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
+ * This function gets the pin settings from DT information.
+ * When analyze and parsing is done, set the GPIO registers.
+ * Returns 0 on success and a negative FDT/ERRNO error code on failure.
+ ******************************************************************************/
+int dt_set_pinctrl_config(int node)
+{
+	const fdt32_t *cuint;
+	int lenp = 0;
+	uint32_t i;
+	uint8_t status = fdt_get_status(node);
+	void *fdt;
+
+	if (fdt_get_address(&fdt) == 0) {
+		return -ENOENT;
+	}
+
+	if (status == DT_DISABLED) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	cuint = fdt_getprop(fdt, node, "pinctrl-0", &lenp);
+	if (cuint == NULL) {
+		return -FDT_ERR_NOTFOUND;
 	}
 
+	for (i = 0; i < ((uint32_t)lenp / 4U); i++) {
+		int p_node, p_subnode;
+
-	mmio_clrbits_32(bank_address + GPIO_MODE_OFFSET,
+		p_node = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
+		if (p_node < 0) {
+			return -FDT_ERR_NOTFOUND;
+		}
+
+		fdt_for_each_subnode(p_subnode, fdt, p_node) {
+			int ret = dt_set_gpio_config(fdt, p_subnode, status);
+
+			if (ret < 0) {
+				return ret;
+			}
+		}
+
+		cuint++;
+	}
+
+	return 0;
+}
+
+void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed,
+	      uint32_t pull, uint32_t alternate, uint8_t status)
+{
+	uintptr_t base = stm32_get_gpio_bank_base(bank);
+	unsigned long clock = stm32_get_gpio_bank_clock(bank);
+
+	assert(pin <= GPIO_PIN_MAX);
+
+	stm32mp1_clk_enable(clock);
+
+	mmio_clrbits_32(base + GPIO_MODE_OFFSET,
 			((uint32_t)GPIO_MODE_MASK << (pin << 1)));
-	mmio_setbits_32(bank_address + GPIO_MODE_OFFSET,
+	mmio_setbits_32(base + GPIO_MODE_OFFSET,
 			(mode & ~GPIO_OPEN_DRAIN) << (pin << 1));
 
 	if ((mode & GPIO_OPEN_DRAIN) != 0U) {
-		mmio_setbits_32(bank_address + GPIO_TYPE_OFFSET,
-				BIT(pin));
+		mmio_setbits_32(base + GPIO_TYPE_OFFSET, BIT(pin));
+	} else {
+		mmio_clrbits_32(base + GPIO_TYPE_OFFSET, BIT(pin));
 	}
 
-	mmio_clrbits_32(bank_address + GPIO_SPEED_OFFSET,
+	mmio_clrbits_32(base + GPIO_SPEED_OFFSET,
 			((uint32_t)GPIO_SPEED_MASK << (pin << 1)));
-	mmio_setbits_32(bank_address + GPIO_SPEED_OFFSET, speed << (pin << 1));
+	mmio_setbits_32(base + GPIO_SPEED_OFFSET, speed << (pin << 1));
 
-	mmio_clrbits_32(bank_address + GPIO_PUPD_OFFSET,
+	mmio_clrbits_32(base + GPIO_PUPD_OFFSET,
 			((uint32_t)GPIO_PULL_MASK << (pin << 1)));
-	mmio_setbits_32(bank_address + GPIO_PUPD_OFFSET, pull << (pin << 1));
+	mmio_setbits_32(base + GPIO_PUPD_OFFSET, pull << (pin << 1));
 
 	if (pin < GPIO_ALT_LOWER_LIMIT) {
-		mmio_clrbits_32(bank_address + GPIO_AFRL_OFFSET,
+		mmio_clrbits_32(base + GPIO_AFRL_OFFSET,
 				((uint32_t)GPIO_ALTERNATE_MASK << (pin << 2)));
-		mmio_setbits_32(bank_address + GPIO_AFRL_OFFSET,
+		mmio_setbits_32(base + GPIO_AFRL_OFFSET,
 				alternate << (pin << 2));
 	} else {
-		mmio_clrbits_32(bank_address + GPIO_AFRH_OFFSET,
+		mmio_clrbits_32(base + GPIO_AFRH_OFFSET,
 				((uint32_t)GPIO_ALTERNATE_MASK <<
 				 ((pin - GPIO_ALT_LOWER_LIMIT) << 2)));
-		mmio_setbits_32(bank_address + GPIO_AFRH_OFFSET,
+		mmio_setbits_32(base + GPIO_AFRH_OFFSET,
 				alternate << ((pin - GPIO_ALT_LOWER_LIMIT) <<
 					      2));
 	}
 
 	VERBOSE("GPIO %u mode set to 0x%x\n", bank,
-		mmio_read_32(bank_address + GPIO_MODE_OFFSET));
+		mmio_read_32(base + GPIO_MODE_OFFSET));
 	VERBOSE("GPIO %u speed set to 0x%x\n", bank,
-		mmio_read_32(bank_address + GPIO_SPEED_OFFSET));
+		mmio_read_32(base + GPIO_SPEED_OFFSET));
 	VERBOSE("GPIO %u mode pull to 0x%x\n", bank,
-		mmio_read_32(bank_address + GPIO_PUPD_OFFSET));
+		mmio_read_32(base + GPIO_PUPD_OFFSET));
 	VERBOSE("GPIO %u mode alternate low to 0x%x\n", bank,
-		mmio_read_32(bank_address + GPIO_AFRL_OFFSET));
+		mmio_read_32(base + GPIO_AFRL_OFFSET));
 	VERBOSE("GPIO %u mode alternate high to 0x%x\n", bank,
-		mmio_read_32(bank_address + GPIO_AFRH_OFFSET));
+		mmio_read_32(base + GPIO_AFRH_OFFSET));
+
+	stm32mp1_clk_disable((unsigned long)clock);
+}
+
+void set_gpio_secure_cfg(uint32_t bank, uint32_t pin, bool secure)
+{
+	uintptr_t base = stm32_get_gpio_bank_base(bank);
+	int clock = stm32_get_gpio_bank_clock(bank);
+
+	assert(pin <= GPIO_PIN_MAX);
+
+	stm32mp1_clk_enable((unsigned long)clock);
+
+	if (secure) {
+		mmio_setbits_32(base + GPIO_SECR_OFFSET, BIT(pin));
+	} else {
+		mmio_clrbits_32(base + GPIO_SECR_OFFSET, BIT(pin));
+	}
+
+	stm32mp1_clk_disable((unsigned long)clock);
 }
diff --git a/drivers/st/pmic/stm32_i2c.c b/drivers/st/i2c/stm32_i2c.c
similarity index 99%
rename from drivers/st/pmic/stm32_i2c.c
rename to drivers/st/i2c/stm32_i2c.c
index f861ba2..2be7afe 100644
--- a/drivers/st/pmic/stm32_i2c.c
+++ b/drivers/st/i2c/stm32_i2c.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
diff --git a/drivers/st/io/io_stm32image.c b/drivers/st/io/io_stm32image.c
index 0164a2d..dc2977d 100644
--- a/drivers/st/io/io_stm32image.c
+++ b/drivers/st/io/io_stm32image.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
  */
@@ -94,6 +94,8 @@
 	for (i = 0; i < STM32_PART_NUM; i++) {
 		memcpy(stm32image_dev.part_info[i].name,
 		       device_info->part_info[i].name, MAX_PART_NAME_SIZE);
+		stm32image_dev.part_info[i].binary_type =
+			device_info->part_info[i].binary_type;
 		stm32image_dev.part_info[i].part_offset =
 			device_info->part_info[i].part_offset;
 		stm32image_dev.part_info[i].bkp_offset =
@@ -193,21 +195,29 @@
 		result = io_read(backend_handle, (uintptr_t)header,
 				 MAX_LBA_SIZE, (size_t *)&bytes_read);
 		if (result != 0) {
-			ERROR("%s: io_read (%i)\n", __func__, result);
-			break;
+			if (current_part->bkp_offset == 0U) {
+				ERROR("%s: io_read (%i)\n", __func__, result);
+			}
+			header->magic = 0;
 		}
 
 		if ((header->magic != BOOT_API_IMAGE_HEADER_MAGIC_NB) ||
 		    (header->binary_type != current_part->binary_type) ||
 		    (header->image_length >= stm32image_dev.device_size)) {
-			WARN("%s: partition %s wrong header\n",
-			     __func__, current_part->name);
+			VERBOSE("%s: partition %s not found at %x\n",
+				__func__, current_part->name, *stm32_img);
+
+			if (current_part->bkp_offset == 0U) {
+				result = -ENOMEM;
+				break;
+			}
 
 			/* Header not correct, check next offset for backup */
 			*stm32_img += current_part->bkp_offset;
 			if (*stm32_img > stm32image_dev.device_size) {
 				/* No backup found, end of device reached */
-				WARN("Out of memory\n");
+				WARN("%s : partition %s not found\n",
+				     __func__, current_part->name);
 				result = -ENOMEM;
 				break;
 			}
@@ -221,9 +231,13 @@
 		return result;
 	}
 
-	*length = header->image_length;
+	if (header->image_length < stm32image_dev.lba_size) {
+		*length = stm32image_dev.lba_size;
+	} else {
+		*length = header->image_length;
+	}
 
-	INFO("STM32 Image size : %i\n", *length);
+	INFO("STM32 Image size : %lu\n", (unsigned long)*length);
 
 	return 0;
 }
@@ -266,11 +280,10 @@
 static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer,
 				     size_t length, size_t *length_read)
 {
-	int result = 0, offset, local_length = 0;
+	int result = 0;
 	uint8_t *local_buffer = (uint8_t *)buffer;
 	boot_api_image_header_t *header =
 		(boot_api_image_header_t *)first_lba_buffer;
-	uintptr_t backend_handle;
 
 	assert(entity != NULL);
 	assert(buffer != 0U);
@@ -279,8 +292,17 @@
 	*length_read = 0U;
 
 	while (*length_read == 0U) {
+		int offset;
+		int local_length;
+		uintptr_t backend_handle;
+
 		if (header->magic != BOOT_API_IMAGE_HEADER_MAGIC_NB) {
 			/* Check for backup as image is corrupted */
+			if (current_part->bkp_offset == 0U) {
+				result = -ENOMEM;
+				break;
+			}
+
 			*stm32_img += current_part->bkp_offset;
 			if (*stm32_img >= stm32image_dev.device_size) {
 				/* End of device reached */
@@ -342,8 +364,8 @@
 		if (result != 0) {
 			ERROR("%s: io_read (%i)\n", __func__, result);
 			*length_read = 0;
-			io_close(backend_handle);
-			break;
+			header->magic = 0;
+			continue;
 		}
 
 		result = check_header(header, buffer);
@@ -351,8 +373,6 @@
 			ERROR("Header check failed\n");
 			*length_read = 0;
 			header->magic = 0;
-			io_close(backend_handle);
-			break;
 		}
 
 		io_close(backend_handle);
diff --git a/drivers/st/mmc/stm32_sdmmc2.c b/drivers/st/mmc/stm32_sdmmc2.c
index 05f5ae1..57812d8 100644
--- a/drivers/st/mmc/stm32_sdmmc2.c
+++ b/drivers/st/mmc/stm32_sdmmc2.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,6 +17,7 @@
 #include <common/debug.h>
 #include <drivers/delay_timer.h>
 #include <drivers/mmc.h>
+#include <drivers/st/stm32_gpio.h>
 #include <drivers/st/stm32_sdmmc2.h>
 #include <drivers/st/stm32mp1_clk.h>
 #include <drivers/st/stm32mp1_rcc.h>
@@ -470,12 +471,11 @@
 	}
 
 	/* Prepare CMD 16*/
-	mmio_write_32(base + SDMMC_DTIMER, UINT32_MAX);
+	mmio_write_32(base + SDMMC_DTIMER, 0);
 
 	mmio_write_32(base + SDMMC_DLENR, 0);
 
-	mmio_clrsetbits_32(base + SDMMC_DCTRLR,
-			   SDMMC_DCTRLR_CLEAR_MASK, SDMMC_DCTRLR_DTDIR);
+	mmio_write_32(base + SDMMC_DCTRLR, 0);
 
 	zeromem(&cmd, sizeof(struct mmc_cmd));
 
@@ -643,7 +643,7 @@
 		return -FDT_ERR_NOTFOUND;
 	}
 
-	if (fdt_check_status(sdmmc_node) == 0) {
+	if (fdt_get_status(sdmmc_node) == DT_DISABLED) {
 		return -FDT_ERR_NOTFOUND;
 	}
 
@@ -667,15 +667,15 @@
 	cuint++;
 	sdmmc2_params.reset_id = fdt32_to_cpu(*cuint);
 
-	if ((fdt_getprop(fdt, sdmmc_node, "st,pin-ckin", NULL)) != NULL) {
+	if ((fdt_getprop(fdt, sdmmc_node, "st,use-ckin", NULL)) != NULL) {
 		sdmmc2_params.pin_ckin = SDMMC_CLKCR_SELCLKRX_0;
 	}
 
-	if ((fdt_getprop(fdt, sdmmc_node, "st,dirpol", NULL)) != NULL) {
+	if ((fdt_getprop(fdt, sdmmc_node, "st,sig-dir", NULL)) != NULL) {
 		sdmmc2_params.dirpol = SDMMC_POWER_DIRPOL;
 	}
 
-	if ((fdt_getprop(fdt, sdmmc_node, "st,negedge", NULL)) != NULL) {
+	if ((fdt_getprop(fdt, sdmmc_node, "st,neg-edge", NULL)) != NULL) {
 		sdmmc2_params.negedge = SDMMC_CLKCR_NEGEDGE;
 	}
 
diff --git a/drivers/st/pmic/stm32mp1_pmic.c b/drivers/st/pmic/stm32mp_pmic.c
similarity index 69%
rename from drivers/st/pmic/stm32mp1_pmic.c
rename to drivers/st/pmic/stm32mp_pmic.c
index c5bdfc0..6beabc1 100644
--- a/drivers/st/pmic/stm32mp1_pmic.c
+++ b/drivers/st/pmic/stm32mp_pmic.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,10 +13,10 @@
 
 #include <common/debug.h>
 #include <drivers/delay_timer.h>
+#include <drivers/st/stm32mp_pmic.h>
 #include <drivers/st/stm32_gpio.h>
 #include <drivers/st/stm32mp1_clk.h>
-#include <drivers/st/stm32mp1_pmic.h>
-#include <drivers/st/stpmu1.h>
+#include <drivers/st/stpmic1.h>
 #include <lib/mmio.h>
 #include <lib/utils_def.h>
 
@@ -27,23 +27,23 @@
 
 #define MASK_RESET_BUCK3		BIT(2)
 
-#define STPMU1_LDO12356_OUTPUT_MASK	(uint8_t)(GENMASK(6, 2))
-#define STPMU1_LDO12356_OUTPUT_SHIFT	2
-#define STPMU1_LDO3_MODE		(uint8_t)(BIT(7))
-#define STPMU1_LDO3_DDR_SEL		31U
-#define STPMU1_LDO3_1800000		(9U << STPMU1_LDO12356_OUTPUT_SHIFT)
+#define STPMIC1_LDO12356_OUTPUT_MASK	(uint8_t)(GENMASK(6, 2))
+#define STPMIC1_LDO12356_OUTPUT_SHIFT	2
+#define STPMIC1_LDO3_MODE		(uint8_t)(BIT(7))
+#define STPMIC1_LDO3_DDR_SEL		31U
+#define STPMIC1_LDO3_1800000		(9U << STPMIC1_LDO12356_OUTPUT_SHIFT)
 
-#define STPMU1_BUCK_OUTPUT_SHIFT	2
-#define STPMU1_BUCK3_1V8		(39U << STPMU1_BUCK_OUTPUT_SHIFT)
+#define STPMIC1_BUCK_OUTPUT_SHIFT	2
+#define STPMIC1_BUCK3_1V8		(39U << STPMIC1_BUCK_OUTPUT_SHIFT)
 
-#define STPMU1_DEFAULT_START_UP_DELAY_MS	1
+#define STPMIC1_DEFAULT_START_UP_DELAY_MS	1
 
 static struct i2c_handle_s i2c_handle;
 static uint32_t pmic_i2c_addr;
 
 static int dt_get_pmic_node(void *fdt)
 {
-	return fdt_node_offset_by_compatible(fdt, -1, "st,stpmu1");
+	return fdt_node_offset_by_compatible(fdt, -1, "st,stpmic1");
 }
 
 bool dt_check_pmic(void)
@@ -61,7 +61,7 @@
 		return false;
 	}
 
-	return fdt_check_status(node);
+	return fdt_get_status(node);
 }
 
 static int dt_pmic_i2c_config(struct dt_node_info *i2c_info)
@@ -138,16 +138,16 @@
 		voltage = (uint16_t)(fdt32_to_cpu(*cuint) / 1000U);
 		node_name = fdt_get_name(fdt, regulator_node, NULL);
 
-		if (stpmu1_is_regulator_enabled(node_name) == 0U) {
+		if (stpmic1_is_regulator_enabled(node_name) == 0U) {
 			int status;
 
-			status = stpmu1_regulator_voltage_set(node_name,
-							      voltage);
+			status = stpmic1_regulator_voltage_set(node_name,
+							       voltage);
 			if (status != 0) {
 				return status;
 			}
 
-			status = stpmu1_regulator_enable(node_name);
+			status = stpmic1_regulator_enable(node_name);
 			if (status != 0) {
 				return status;
 			}
@@ -204,7 +204,7 @@
 		panic();
 	}
 
-	stpmu1_bind_i2c(&i2c_handle, (uint16_t)pmic_i2c_addr);
+	stpmic1_bind_i2c(&i2c_handle, (uint16_t)pmic_i2c_addr);
 }
 
 void initialize_pmic(void)
@@ -214,7 +214,7 @@
 
 	initialize_pmic_i2c();
 
-	status = stpmu1_register_read(VERSION_STATUS_REG, &read_val);
+	status = stpmic1_register_read(VERSION_STATUS_REG, &read_val);
 	if (status != 0) {
 		panic();
 	}
@@ -222,7 +222,7 @@
 	INFO("PMIC version = 0x%x\n", read_val);
 
 	/* Keep VDD on during the reset cycle */
-	status = stpmu1_register_update(MASK_RESET_BUCK_REG,
+	status = stpmic1_register_update(MASK_RESET_BUCK_REG,
 					MASK_RESET_BUCK3,
 					MASK_RESET_BUCK3);
 	if (status != 0) {
@@ -239,45 +239,46 @@
 	switch (ddr_type) {
 	case STM32MP_DDR3:
 		/* Set LDO3 to sync mode */
-		status = stpmu1_register_read(LDO3_CONTROL_REG, &read_val);
+		status = stpmic1_register_read(LDO3_CONTROL_REG, &read_val);
 		if (status != 0) {
 			return status;
 		}
 
-		read_val &= ~STPMU1_LDO3_MODE;
-		read_val &= ~STPMU1_LDO12356_OUTPUT_MASK;
-		read_val |= STPMU1_LDO3_DDR_SEL << STPMU1_LDO12356_OUTPUT_SHIFT;
+		read_val &= ~STPMIC1_LDO3_MODE;
+		read_val &= ~STPMIC1_LDO12356_OUTPUT_MASK;
+		read_val |= STPMIC1_LDO3_DDR_SEL <<
+			    STPMIC1_LDO12356_OUTPUT_SHIFT;
 
-		status = stpmu1_register_write(LDO3_CONTROL_REG, read_val);
+		status = stpmic1_register_write(LDO3_CONTROL_REG, read_val);
 		if (status != 0) {
 			return status;
 		}
 
-		status = stpmu1_regulator_voltage_set("buck2", 1350);
+		status = stpmic1_regulator_voltage_set("buck2", 1350);
 		if (status != 0) {
 			return status;
 		}
 
-		status = stpmu1_regulator_enable("buck2");
+		status = stpmic1_regulator_enable("buck2");
 		if (status != 0) {
 			return status;
 		}
 
-		mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+		mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
 
-		status = stpmu1_regulator_enable("vref_ddr");
+		status = stpmic1_regulator_enable("vref_ddr");
 		if (status != 0) {
 			return status;
 		}
 
-		mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+		mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
 
-		status = stpmu1_regulator_enable("ldo3");
+		status = stpmic1_regulator_enable("ldo3");
 		if (status != 0) {
 			return status;
 		}
 
-		mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+		mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
 		break;
 
 	case STM32MP_LPDDR2:
@@ -286,57 +287,57 @@
 		 * Set LDO3 to bypass mode if BUCK3 = 1.8V
 		 * Set LDO3 to normal mode if BUCK3 != 1.8V
 		 */
-		status = stpmu1_register_read(BUCK3_CONTROL_REG, &read_val);
+		status = stpmic1_register_read(BUCK3_CONTROL_REG, &read_val);
 		if (status != 0) {
 			return status;
 		}
 
-		if ((read_val & STPMU1_BUCK3_1V8) == STPMU1_BUCK3_1V8) {
+		if ((read_val & STPMIC1_BUCK3_1V8) == STPMIC1_BUCK3_1V8) {
 			buck3_at_1v8 = true;
 		}
 
-		status = stpmu1_register_read(LDO3_CONTROL_REG, &read_val);
+		status = stpmic1_register_read(LDO3_CONTROL_REG, &read_val);
 		if (status != 0) {
 			return status;
 		}
 
-		read_val &= ~STPMU1_LDO3_MODE;
-		read_val &= ~STPMU1_LDO12356_OUTPUT_MASK;
-		read_val |= STPMU1_LDO3_1800000;
+		read_val &= ~STPMIC1_LDO3_MODE;
+		read_val &= ~STPMIC1_LDO12356_OUTPUT_MASK;
+		read_val |= STPMIC1_LDO3_1800000;
 		if (buck3_at_1v8) {
-			read_val |= STPMU1_LDO3_MODE;
+			read_val |= STPMIC1_LDO3_MODE;
 		}
 
-		status = stpmu1_register_write(LDO3_CONTROL_REG, read_val);
+		status = stpmic1_register_write(LDO3_CONTROL_REG, read_val);
 		if (status != 0) {
 			return status;
 		}
 
-		status = stpmu1_regulator_voltage_set("buck2", 1200);
+		status = stpmic1_regulator_voltage_set("buck2", 1200);
 		if (status != 0) {
 			return status;
 		}
 
-		status = stpmu1_regulator_enable("ldo3");
+		status = stpmic1_regulator_enable("ldo3");
 		if (status != 0) {
 			return status;
 		}
 
-		mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+		mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
 
-		status = stpmu1_regulator_enable("buck2");
+		status = stpmic1_regulator_enable("buck2");
 		if (status != 0) {
 			return status;
 		}
 
-		mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+		mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
 
-		status = stpmu1_regulator_enable("vref_ddr");
+		status = stpmic1_regulator_enable("vref_ddr");
 		if (status != 0) {
 			return status;
 		}
 
-		mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+		mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS);
 		break;
 
 	default:
diff --git a/drivers/st/pmic/stpmic1.c b/drivers/st/pmic/stpmic1.c
new file mode 100644
index 0000000..465996d
--- /dev/null
+++ b/drivers/st/pmic/stpmic1.c
@@ -0,0 +1,762 @@
+/*
+ * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+#include <common/debug.h>
+#include <drivers/st/stpmic1.h>
+#include <plat/common/platform.h>
+
+struct regul_struct {
+	const char *dt_node_name;
+	const uint16_t *voltage_table;
+	uint8_t voltage_table_size;
+	uint8_t control_reg;
+	uint8_t low_power_reg;
+	uint8_t pull_down_reg;
+	uint8_t pull_down;
+	uint8_t mask_reset_reg;
+	uint8_t mask_reset;
+};
+
+static struct i2c_handle_s *pmic_i2c_handle;
+static uint16_t pmic_i2c_addr;
+
+/* Voltage tables in mV */
+static const uint16_t buck1_voltage_table[] = {
+	725,
+	725,
+	725,
+	725,
+	725,
+	725,
+	750,
+	775,
+	800,
+	825,
+	850,
+	875,
+	900,
+	925,
+	950,
+	975,
+	1000,
+	1025,
+	1050,
+	1075,
+	1100,
+	1125,
+	1150,
+	1175,
+	1200,
+	1225,
+	1250,
+	1275,
+	1300,
+	1325,
+	1350,
+	1375,
+	1400,
+	1425,
+	1450,
+	1475,
+	1500,
+	1500,
+	1500,
+	1500,
+	1500,
+	1500,
+	1500,
+	1500,
+	1500,
+	1500,
+	1500,
+	1500,
+	1500,
+	1500,
+	1500,
+	1500,
+	1500,
+	1500,
+	1500,
+	1500,
+	1500,
+	1500,
+	1500,
+	1500,
+	1500,
+	1500,
+	1500,
+	1500,
+};
+
+static const uint16_t buck2_voltage_table[] = {
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1050,
+	1050,
+	1100,
+	1100,
+	1150,
+	1150,
+	1200,
+	1200,
+	1250,
+	1250,
+	1300,
+	1300,
+	1350,
+	1350,
+	1400,
+	1400,
+	1450,
+	1450,
+	1500,
+};
+
+static const uint16_t buck3_voltage_table[] = {
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1000,
+	1100,
+	1100,
+	1100,
+	1100,
+	1200,
+	1200,
+	1200,
+	1200,
+	1300,
+	1300,
+	1300,
+	1300,
+	1400,
+	1400,
+	1400,
+	1400,
+	1500,
+	1600,
+	1700,
+	1800,
+	1900,
+	2000,
+	2100,
+	2200,
+	2300,
+	2400,
+	2500,
+	2600,
+	2700,
+	2800,
+	2900,
+	3000,
+	3100,
+	3200,
+	3300,
+	3400,
+};
+
+static const uint16_t buck4_voltage_table[] = {
+	600,
+	625,
+	650,
+	675,
+	700,
+	725,
+	750,
+	775,
+	800,
+	825,
+	850,
+	875,
+	900,
+	925,
+	950,
+	975,
+	1000,
+	1025,
+	1050,
+	1075,
+	1100,
+	1125,
+	1150,
+	1175,
+	1200,
+	1225,
+	1250,
+	1275,
+	1300,
+	1300,
+	1350,
+	1350,
+	1400,
+	1400,
+	1450,
+	1450,
+	1500,
+	1600,
+	1700,
+	1800,
+	1900,
+	2000,
+	2100,
+	2200,
+	2300,
+	2400,
+	2500,
+	2600,
+	2700,
+	2800,
+	2900,
+	3000,
+	3100,
+	3200,
+	3300,
+	3400,
+	3500,
+	3600,
+	3700,
+	3800,
+	3900,
+};
+
+static const uint16_t ldo1_voltage_table[] = {
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1800,
+	1900,
+	2000,
+	2100,
+	2200,
+	2300,
+	2400,
+	2500,
+	2600,
+	2700,
+	2800,
+	2900,
+	3000,
+	3100,
+	3200,
+	3300,
+};
+
+static const uint16_t ldo2_voltage_table[] = {
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1800,
+	1900,
+	2000,
+	2100,
+	2200,
+	2300,
+	2400,
+	2500,
+	2600,
+	2700,
+	2800,
+	2900,
+	3000,
+	3100,
+	3200,
+	3300,
+};
+
+static const uint16_t ldo3_voltage_table[] = {
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1800,
+	1900,
+	2000,
+	2100,
+	2200,
+	2300,
+	2400,
+	2500,
+	2600,
+	2700,
+	2800,
+	2900,
+	3000,
+	3100,
+	3200,
+	3300,
+	3300,
+	3300,
+	3300,
+	3300,
+	3300,
+	3300,
+	500,
+	0xFFFF, /* VREFDDR */
+};
+
+static const uint16_t ldo5_voltage_table[] = {
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1700,
+	1800,
+	1900,
+	2000,
+	2100,
+	2200,
+	2300,
+	2400,
+	2500,
+	2600,
+	2700,
+	2800,
+	2900,
+	3000,
+	3100,
+	3200,
+	3300,
+	3400,
+	3500,
+	3600,
+	3700,
+	3800,
+	3900,
+};
+
+static const uint16_t ldo6_voltage_table[] = {
+	900,
+	1000,
+	1100,
+	1200,
+	1300,
+	1400,
+	1500,
+	1600,
+	1700,
+	1800,
+	1900,
+	2000,
+	2100,
+	2200,
+	2300,
+	2400,
+	2500,
+	2600,
+	2700,
+	2800,
+	2900,
+	3000,
+	3100,
+	3200,
+	3300,
+};
+
+static const uint16_t ldo4_voltage_table[] = {
+	3300,
+};
+
+static const uint16_t vref_ddr_voltage_table[] = {
+	3300,
+};
+
+/* Table of Regulators in PMIC SoC */
+static const struct regul_struct regulators_table[] = {
+	{
+		.dt_node_name	= "buck1",
+		.voltage_table	= buck1_voltage_table,
+		.voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
+		.control_reg	= BUCK1_CONTROL_REG,
+		.low_power_reg	= BUCK1_PWRCTRL_REG,
+		.pull_down_reg	= BUCK_PULL_DOWN_REG,
+		.pull_down	= BUCK1_PULL_DOWN_SHIFT,
+		.mask_reset_reg	= MASK_RESET_BUCK_REG,
+		.mask_reset	= BUCK1_MASK_RESET,
+	},
+	{
+		.dt_node_name	= "buck2",
+		.voltage_table	= buck2_voltage_table,
+		.voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
+		.control_reg	= BUCK2_CONTROL_REG,
+		.low_power_reg	= BUCK2_PWRCTRL_REG,
+		.pull_down_reg	= BUCK_PULL_DOWN_REG,
+		.pull_down	= BUCK2_PULL_DOWN_SHIFT,
+		.mask_reset_reg	= MASK_RESET_BUCK_REG,
+		.mask_reset	= BUCK2_MASK_RESET,
+	},
+	{
+		.dt_node_name	= "buck3",
+		.voltage_table	= buck3_voltage_table,
+		.voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
+		.control_reg	= BUCK3_CONTROL_REG,
+		.low_power_reg	= BUCK3_PWRCTRL_REG,
+		.pull_down_reg	= BUCK_PULL_DOWN_REG,
+		.pull_down	= BUCK3_PULL_DOWN_SHIFT,
+		.mask_reset_reg	= MASK_RESET_BUCK_REG,
+		.mask_reset	= BUCK3_MASK_RESET,
+	},
+	{
+		.dt_node_name	= "buck4",
+		.voltage_table	= buck4_voltage_table,
+		.voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
+		.control_reg	= BUCK4_CONTROL_REG,
+		.low_power_reg	= BUCK4_PWRCTRL_REG,
+		.pull_down_reg	= BUCK_PULL_DOWN_REG,
+		.pull_down	= BUCK4_PULL_DOWN_SHIFT,
+		.mask_reset_reg	= MASK_RESET_BUCK_REG,
+		.mask_reset	= BUCK4_MASK_RESET,
+	},
+	{
+		.dt_node_name	= "ldo1",
+		.voltage_table	= ldo1_voltage_table,
+		.voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
+		.control_reg	= LDO1_CONTROL_REG,
+		.low_power_reg	= LDO1_PWRCTRL_REG,
+		.mask_reset_reg	= MASK_RESET_LDO_REG,
+		.mask_reset	= LDO1_MASK_RESET,
+	},
+	{
+		.dt_node_name	= "ldo2",
+		.voltage_table	= ldo2_voltage_table,
+		.voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
+		.control_reg	= LDO2_CONTROL_REG,
+		.low_power_reg	= LDO2_PWRCTRL_REG,
+		.mask_reset_reg	= MASK_RESET_LDO_REG,
+		.mask_reset	= LDO2_MASK_RESET,
+	},
+	{
+		.dt_node_name	= "ldo3",
+		.voltage_table	= ldo3_voltage_table,
+		.voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
+		.control_reg	= LDO3_CONTROL_REG,
+		.low_power_reg	= LDO3_PWRCTRL_REG,
+		.mask_reset_reg	= MASK_RESET_LDO_REG,
+		.mask_reset	= LDO3_MASK_RESET,
+	},
+	{
+		.dt_node_name	= "ldo4",
+		.voltage_table	= ldo4_voltage_table,
+		.voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
+		.control_reg	= LDO4_CONTROL_REG,
+		.low_power_reg	= LDO4_PWRCTRL_REG,
+		.mask_reset_reg	= MASK_RESET_LDO_REG,
+		.mask_reset	= LDO4_MASK_RESET,
+	},
+	{
+		.dt_node_name	= "ldo5",
+		.voltage_table	= ldo5_voltage_table,
+		.voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
+		.control_reg	= LDO5_CONTROL_REG,
+		.low_power_reg	= LDO5_PWRCTRL_REG,
+		.mask_reset_reg	= MASK_RESET_LDO_REG,
+		.mask_reset	= LDO5_MASK_RESET,
+	},
+	{
+		.dt_node_name	= "ldo6",
+		.voltage_table	= ldo6_voltage_table,
+		.voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
+		.control_reg	= LDO6_CONTROL_REG,
+		.low_power_reg	= LDO6_PWRCTRL_REG,
+		.mask_reset_reg	= MASK_RESET_LDO_REG,
+		.mask_reset	= LDO6_MASK_RESET,
+	},
+	{
+		.dt_node_name	= "vref_ddr",
+		.voltage_table	= vref_ddr_voltage_table,
+		.voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
+		.control_reg	= VREF_DDR_CONTROL_REG,
+		.low_power_reg	= VREF_DDR_PWRCTRL_REG,
+		.mask_reset_reg	= MASK_RESET_LDO_REG,
+		.mask_reset	= VREF_DDR_MASK_RESET,
+	},
+};
+
+#define MAX_REGUL	ARRAY_SIZE(regulators_table)
+
+static const struct regul_struct *get_regulator_data(const char *name)
+{
+	uint8_t i;
+
+	for (i = 0 ; i < MAX_REGUL ; i++) {
+		if (strncmp(name, regulators_table[i].dt_node_name,
+			    strlen(regulators_table[i].dt_node_name)) == 0) {
+			return &regulators_table[i];
+		}
+	}
+
+	/* Regulator not found */
+	panic();
+	return NULL;
+}
+
+static uint8_t voltage_to_index(const char *name, uint16_t millivolts)
+{
+	const struct regul_struct *regul = get_regulator_data(name);
+	uint8_t i;
+
+	for (i = 0 ; i < regul->voltage_table_size ; i++) {
+		if (regul->voltage_table[i] == millivolts) {
+			return i;
+		}
+	}
+
+	/* Voltage not found */
+	panic();
+
+	return 0;
+}
+
+int stpmic1_powerctrl_on(void)
+{
+	return stpmic1_register_update(MAIN_CONTROL_REG, PWRCTRL_PIN_VALID,
+				       PWRCTRL_PIN_VALID);
+}
+
+int stpmic1_switch_off(void)
+{
+	return stpmic1_register_update(MAIN_CONTROL_REG, 1,
+				       SOFTWARE_SWITCH_OFF_ENABLED);
+}
+
+int stpmic1_regulator_enable(const char *name)
+{
+	const struct regul_struct *regul = get_regulator_data(name);
+
+	return stpmic1_register_update(regul->control_reg, BIT(0), BIT(0));
+}
+
+int stpmic1_regulator_disable(const char *name)
+{
+	const struct regul_struct *regul = get_regulator_data(name);
+
+	return stpmic1_register_update(regul->control_reg, 0, BIT(0));
+}
+
+uint8_t stpmic1_is_regulator_enabled(const char *name)
+{
+	uint8_t val;
+	const struct regul_struct *regul = get_regulator_data(name);
+
+	if (stpmic1_register_read(regul->control_reg, &val) != 0) {
+		panic();
+	}
+
+	return (val & 0x1U);
+}
+
+int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts)
+{
+	uint8_t voltage_index = voltage_to_index(name, millivolts);
+	const struct regul_struct *regul = get_regulator_data(name);
+	uint8_t mask;
+
+	/* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
+	if (strncmp(name, "buck", 4) == 0) {
+		mask = BUCK_VOLTAGE_MASK;
+	} else if ((strncmp(name, "ldo", 3) == 0) &&
+		   (strncmp(name, "ldo4", 4) != 0)) {
+		mask = LDO_VOLTAGE_MASK;
+	} else {
+		return 0;
+	}
+
+	return stpmic1_register_update(regul->control_reg,
+				       voltage_index << LDO_BUCK_VOLTAGE_SHIFT,
+				       mask);
+}
+
+int stpmic1_regulator_pull_down_set(const char *name)
+{
+	const struct regul_struct *regul = get_regulator_data(name);
+
+	if (regul->pull_down_reg != 0) {
+		return stpmic1_register_update(regul->pull_down_reg,
+					       BIT(regul->pull_down),
+					       LDO_BUCK_PULL_DOWN_MASK <<
+					       regul->pull_down);
+	}
+
+	return 0;
+}
+
+int stpmic1_regulator_mask_reset_set(const char *name)
+{
+	const struct regul_struct *regul = get_regulator_data(name);
+
+	return stpmic1_register_update(regul->mask_reset_reg,
+				       BIT(regul->mask_reset),
+				       LDO_BUCK_RESET_MASK <<
+				       regul->mask_reset);
+}
+
+int stpmic1_regulator_voltage_get(const char *name)
+{
+	const struct regul_struct *regul = get_regulator_data(name);
+	uint8_t value;
+	uint8_t mask;
+
+	/* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */
+	if (strncmp(name, "buck", 4) == 0) {
+		mask = BUCK_VOLTAGE_MASK;
+	} else if ((strncmp(name, "ldo", 3) == 0) &&
+		   (strncmp(name, "ldo4", 4) != 0)) {
+		mask = LDO_VOLTAGE_MASK;
+	} else {
+		return 0;
+	}
+
+	if (stpmic1_register_read(regul->control_reg, &value))
+		return -1;
+
+	value = (value & mask) >> LDO_BUCK_VOLTAGE_SHIFT;
+
+	if (value > regul->voltage_table_size)
+		return -1;
+
+	return (int)regul->voltage_table[value];
+}
+
+int stpmic1_register_read(uint8_t register_id,  uint8_t *value)
+{
+	return stm32_i2c_mem_read(pmic_i2c_handle, pmic_i2c_addr,
+				  (uint16_t)register_id, I2C_MEMADD_SIZE_8BIT,
+				  value, 1, 100000);
+}
+
+int stpmic1_register_write(uint8_t register_id, uint8_t value)
+{
+	int status;
+
+	status = stm32_i2c_mem_write(pmic_i2c_handle, pmic_i2c_addr,
+				     (uint16_t)register_id,
+				     I2C_MEMADD_SIZE_8BIT, &value, 1, 100000);
+
+#if ENABLE_ASSERTIONS
+	if (status != 0) {
+		return status;
+	}
+
+	if ((register_id != WATCHDOG_CONTROL_REG) && (register_id <= 0x40U)) {
+		uint8_t readval;
+
+		status = stpmic1_register_read(register_id, &readval);
+		if (status != 0) {
+			return status;
+		}
+
+		if (readval != value) {
+			return -1;
+		}
+	}
+#endif
+
+	return status;
+}
+
+int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
+{
+	int status;
+	uint8_t val;
+
+	status = stpmic1_register_read(register_id, &val);
+	if (status != 0) {
+		return status;
+	}
+
+	val = (val & ~mask) | (value & mask);
+
+	return stpmic1_register_write(register_id, val);
+}
+
+void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
+{
+	pmic_i2c_handle = i2c_handle;
+	pmic_i2c_addr = i2c_addr;
+}
+
+void stpmic1_dump_regulators(void)
+{
+	uint32_t i;
+
+	for (i = 0U; i < MAX_REGUL; i++) {
+		const char *name __unused = regulators_table[i].dt_node_name;
+
+		VERBOSE("PMIC regul %s: %sable, %dmV",
+			name,
+			stpmic1_is_regulator_enabled(name) ? "en" : "dis",
+			stpmic1_regulator_voltage_get(name));
+	}
+}
+
+int stpmic1_get_version(unsigned long *version)
+{
+	int rc;
+	uint8_t read_val;
+
+	rc = stpmic1_register_read(VERSION_STATUS_REG, &read_val);
+	if (rc) {
+		return -1;
+	}
+
+	*version = (unsigned long)read_val;
+
+	return 0;
+}
diff --git a/drivers/st/pmic/stpmu1.c b/drivers/st/pmic/stpmu1.c
deleted file mode 100644
index 9c36bf6..0000000
--- a/drivers/st/pmic/stpmu1.c
+++ /dev/null
@@ -1,601 +0,0 @@
-/*
- * Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <string.h>
-
-#include <common/debug.h>
-#include <drivers/st/stpmu1.h>
-#include <plat/common/platform.h>
-
-struct regul_struct {
-	const char *dt_node_name;
-	const uint16_t *voltage_table;
-	uint8_t voltage_table_size;
-	uint8_t control_reg;
-	uint8_t low_power_reg;
-};
-
-static struct i2c_handle_s *stpmu_i2c_handle;
-static uint16_t stpmu_i2c_addr;
-
-/* Voltage tables in mV */
-static const uint16_t buck1_voltage_table[] = {
-	600,
-	625,
-	650,
-	675,
-	700,
-	725,
-	750,
-	775,
-	800,
-	825,
-	850,
-	875,
-	900,
-	925,
-	950,
-	975,
-	1000,
-	1025,
-	1050,
-	1075,
-	1100,
-	1125,
-	1150,
-	1175,
-	1200,
-	1225,
-	1250,
-	1275,
-	1300,
-	1325,
-	1350,
-	1350,
-};
-
-static const uint16_t buck2_voltage_table[] = {
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1050,
-	1050,
-	1100,
-	1100,
-	1150,
-	1150,
-	1200,
-	1200,
-	1250,
-	1250,
-	1300,
-	1300,
-	1350,
-	1350,
-	1400,
-	1400,
-	1450,
-	1450,
-	1500,
-};
-
-static const uint16_t buck3_voltage_table[] = {
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1000,
-	1100,
-	1100,
-	1100,
-	1100,
-	1200,
-	1200,
-	1200,
-	1200,
-	1300,
-	1300,
-	1300,
-	1300,
-	1400,
-	1400,
-	1400,
-	1400,
-	1500,
-	1600,
-	1700,
-	1800,
-	1900,
-	2000,
-	2100,
-	2200,
-	2300,
-	2400,
-	2500,
-	2600,
-	2700,
-	2800,
-	2900,
-	3000,
-	3100,
-	3200,
-	3300,
-	3400,
-};
-
-static const uint16_t buck4_voltage_table[] = {
-	600,
-	625,
-	650,
-	675,
-	700,
-	725,
-	750,
-	775,
-	800,
-	825,
-	850,
-	875,
-	900,
-	925,
-	950,
-	975,
-	1000,
-	1025,
-	1050,
-	1075,
-	1100,
-	1125,
-	1150,
-	1175,
-	1200,
-	1225,
-	1250,
-	1275,
-	1300,
-	1300,
-	1350,
-	1350,
-	1400,
-	1400,
-	1450,
-	1450,
-	1500,
-	1600,
-	1700,
-	1800,
-	1900,
-	2000,
-	2100,
-	2200,
-	2300,
-	2400,
-	2500,
-	2600,
-	2700,
-	2800,
-	2900,
-	3000,
-	3100,
-	3200,
-	3300,
-	3400,
-	3500,
-	3600,
-	3700,
-	3800,
-	3900,
-};
-
-static const uint16_t ldo1_voltage_table[] = {
-	1700,
-	1700,
-	1700,
-	1700,
-	1700,
-	1700,
-	1700,
-	1700,
-	1700,
-	1800,
-	1900,
-	2000,
-	2100,
-	2200,
-	2300,
-	2400,
-	2500,
-	2600,
-	2700,
-	2800,
-	2900,
-	3000,
-	3100,
-	3200,
-	3300,
-};
-
-static const uint16_t ldo2_voltage_table[] = {
-	1700,
-	1700,
-	1700,
-	1700,
-	1700,
-	1700,
-	1700,
-	1700,
-	1700,
-	1800,
-	1900,
-	2000,
-	2100,
-	2200,
-	2300,
-	2400,
-	2500,
-	2600,
-	2700,
-	2800,
-	2900,
-	3000,
-	3100,
-	3200,
-	3300,
-};
-
-static const uint16_t ldo3_voltage_table[] = {
-	1700,
-	1700,
-	1700,
-	1700,
-	1700,
-	1700,
-	1700,
-	1700,
-	1700,
-	1800,
-	1900,
-	2000,
-	2100,
-	2200,
-	2300,
-	2400,
-	2500,
-	2600,
-	2700,
-	2800,
-	2900,
-	3000,
-	3100,
-	3200,
-	3300,
-	3300,
-	3300,
-	3300,
-	3300,
-	3300,
-	3300,
-	0xFFFF, /* VREFDDR */
-};
-
-static const uint16_t ldo5_voltage_table[] = {
-	1700,
-	1700,
-	1700,
-	1700,
-	1700,
-	1700,
-	1700,
-	1700,
-	1700,
-	1800,
-	1900,
-	2000,
-	2100,
-	2200,
-	2300,
-	2400,
-	2500,
-	2600,
-	2700,
-	2800,
-	2900,
-	3000,
-	3100,
-	3200,
-	3300,
-	3400,
-	3500,
-	3600,
-	3700,
-	3800,
-	3900,
-};
-
-static const uint16_t ldo6_voltage_table[] = {
-	900,
-	1000,
-	1100,
-	1200,
-	1300,
-	1400,
-	1500,
-	1600,
-	1700,
-	1800,
-	1900,
-	2000,
-	2100,
-	2200,
-	2300,
-	2400,
-	2500,
-	2600,
-	2700,
-	2800,
-	2900,
-	3000,
-	3100,
-	3200,
-	3300,
-};
-
-static const uint16_t ldo4_voltage_table[] = {
-	3300,
-};
-
-static const uint16_t vref_ddr_voltage_table[] = {
-	3300,
-};
-
-/* Table of Regulators in PMIC SoC */
-static const struct regul_struct regulators_table[] = {
-	{
-		.dt_node_name	= "buck1",
-		.voltage_table	= buck1_voltage_table,
-		.voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
-		.control_reg	= BUCK1_CONTROL_REG,
-		.low_power_reg	= BUCK1_PWRCTRL_REG,
-	},
-	{
-		.dt_node_name	= "buck2",
-		.voltage_table	= buck2_voltage_table,
-		.voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
-		.control_reg	= BUCK2_CONTROL_REG,
-		.low_power_reg	= BUCK2_PWRCTRL_REG,
-	},
-	{
-		.dt_node_name	= "buck3",
-		.voltage_table	= buck3_voltage_table,
-		.voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
-		.control_reg	= BUCK3_CONTROL_REG,
-		.low_power_reg	= BUCK3_PWRCTRL_REG,
-	},
-	{
-		.dt_node_name	= "buck4",
-		.voltage_table	= buck4_voltage_table,
-		.voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
-		.control_reg	= BUCK4_CONTROL_REG,
-		.low_power_reg	= BUCK4_PWRCTRL_REG,
-	},
-	{
-		.dt_node_name	= "ldo1",
-		.voltage_table	= ldo1_voltage_table,
-		.voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
-		.control_reg	= LDO1_CONTROL_REG,
-		.low_power_reg	= LDO1_PWRCTRL_REG,
-	},
-	{
-		.dt_node_name	= "ldo2",
-		.voltage_table	= ldo2_voltage_table,
-		.voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
-		.control_reg	= LDO2_CONTROL_REG,
-		.low_power_reg	= LDO2_PWRCTRL_REG,
-	},
-	{
-		.dt_node_name	= "ldo3",
-		.voltage_table	= ldo3_voltage_table,
-		.voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
-		.control_reg	= LDO3_CONTROL_REG,
-		.low_power_reg	= LDO3_PWRCTRL_REG,
-	},
-	{
-		.dt_node_name	= "ldo4",
-		.voltage_table	= ldo4_voltage_table,
-		.voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
-		.control_reg	= LDO4_CONTROL_REG,
-		.low_power_reg	= LDO4_PWRCTRL_REG,
-	},
-	{
-		.dt_node_name	= "ldo5",
-		.voltage_table	= ldo5_voltage_table,
-		.voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
-		.control_reg	= LDO5_CONTROL_REG,
-		.low_power_reg	= LDO5_PWRCTRL_REG,
-	},
-	{
-		.dt_node_name	= "ldo6",
-		.voltage_table	= ldo6_voltage_table,
-		.voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
-		.control_reg	= LDO6_CONTROL_REG,
-		.low_power_reg	= LDO6_PWRCTRL_REG,
-	},
-	{
-		.dt_node_name	= "vref_ddr",
-		.voltage_table	= vref_ddr_voltage_table,
-		.voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
-		.control_reg	= VREF_DDR_CONTROL_REG,
-		.low_power_reg	= VREF_DDR_PWRCTRL_REG,
-	},
-};
-
-#define MAX_REGUL  ARRAY_SIZE(regulators_table)
-
-static const struct regul_struct *stpmu1_get_regulator_data(const char *name)
-{
-	uint8_t i;
-
-	for (i = 0 ; i < MAX_REGUL ; i++) {
-		if (strncmp(name, regulators_table[i].dt_node_name,
-			    strlen(regulators_table[i].dt_node_name)) == 0) {
-			return &regulators_table[i];
-		}
-	}
-
-	/* Regulator not found */
-	panic();
-	return NULL;
-}
-
-static uint8_t stpmu1_voltage_find_index(const char *name,
-					 uint16_t millivolts)
-{
-	const struct regul_struct *regul = stpmu1_get_regulator_data(name);
-	uint8_t i;
-
-	for (i = 0 ; i < regul->voltage_table_size ; i++) {
-		if (regul->voltage_table[i] == millivolts) {
-			return i;
-		}
-	}
-
-	/* Voltage not found */
-	panic();
-
-	return 0;
-}
-
-int stpmu1_switch_off(void)
-{
-	return stpmu1_register_update(MAIN_CONTROL_REG, 1,
-				      SOFTWARE_SWITCH_OFF_ENABLED);
-}
-
-int stpmu1_regulator_enable(const char *name)
-{
-	const struct regul_struct *regul = stpmu1_get_regulator_data(name);
-
-	return stpmu1_register_update(regul->control_reg, BIT(0), BIT(0));
-}
-
-int stpmu1_regulator_disable(const char *name)
-{
-	const struct regul_struct *regul = stpmu1_get_regulator_data(name);
-
-	return stpmu1_register_update(regul->control_reg, 0, BIT(0));
-}
-
-uint8_t stpmu1_is_regulator_enabled(const char *name)
-{
-	uint8_t val;
-	const struct regul_struct *regul = stpmu1_get_regulator_data(name);
-
-	if (stpmu1_register_read(regul->control_reg, &val) != 0) {
-		panic();
-	}
-
-	return (val & 0x1U);
-}
-
-int stpmu1_regulator_voltage_set(const char *name, uint16_t millivolts)
-{
-	uint8_t voltage_index = stpmu1_voltage_find_index(name, millivolts);
-	const struct regul_struct *regul = stpmu1_get_regulator_data(name);
-
-	return stpmu1_register_update(regul->control_reg, voltage_index << 2,
-				      0xFC);
-}
-
-int stpmu1_register_read(uint8_t register_id,  uint8_t *value)
-{
-	return stm32_i2c_mem_read(stpmu_i2c_handle, stpmu_i2c_addr,
-				    (uint16_t)register_id, I2C_MEMADD_SIZE_8BIT,
-				    value, 1, 100000);
-}
-
-int stpmu1_register_write(uint8_t register_id, uint8_t value)
-{
-	int status;
-
-	status = stm32_i2c_mem_write(stpmu_i2c_handle, stpmu_i2c_addr,
-				     (uint16_t)register_id,
-				     I2C_MEMADD_SIZE_8BIT, &value, 1, 100000);
-
-	if (status != 0) {
-		return status;
-	}
-
-	if ((register_id != WATCHDOG_CONTROL_REG) && (register_id <= 0x40U)) {
-		uint8_t readval;
-
-		status = stpmu1_register_read(register_id, &readval);
-		if (status != 0) {
-			return status;
-		}
-
-		if (readval != value) {
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
-int stpmu1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
-{
-	int status;
-	uint8_t val;
-
-	status = stpmu1_register_read(register_id, &val);
-	if (status != 0) {
-		return status;
-	}
-
-	/* Clear bits to update */
-	val &= ~mask;
-
-	/* Update appropriate bits*/
-	val |= (value & mask);
-
-	/* Send new value on I2C Bus */
-	return stpmu1_register_write(register_id, val);
-}
-
-void stpmu1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
-{
-	stpmu_i2c_handle = i2c_handle;
-	stpmu_i2c_addr = i2c_addr;
-}
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_e3.c b/drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_e3.c
index 62997bc..c289c88 100644
--- a/drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_e3.c
+++ b/drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_e3.c
@@ -1137,13 +1137,13 @@
 
    /*  ddr backupmode end */
    if (ddrBackup) {
-      NOTICE("[WARM_BOOT]");
+      NOTICE("BL2: [WARM_BOOT]\n");
    } else {
-      NOTICE("[COLD_BOOT]");
+      NOTICE("BL2: [COLD_BOOT]\n");
    } /*  ddrBackup */
    err = rcar_dram_update_boot_status(ddrBackup);
    if (err) {
-      NOTICE("[BOOT_STATUS_UPDATE_ERROR]");
+      NOTICE("BL2: [BOOT_STATUS_UPDATE_ERROR]\n");
       return INITDRAM_ERR_I;
    } /*  err */
 
@@ -1672,9 +1672,9 @@
     md = *((volatile uint32_t*)RST_MODEMR);
     ddr = (md & 0x00080000) >> 19;
     if (ddr == 0x0) {
-	NOTICE("BL2: DDR1584(%s)", RCAR_E3_DDR_VERSION);
+	NOTICE("BL2: DDR1584(%s)\n", RCAR_E3_DDR_VERSION);
     } else if(ddr == 0x1){
-	NOTICE("BL2: DDR1856(%s)", RCAR_E3_DDR_VERSION);
+	NOTICE("BL2: DDR1856(%s)\n", RCAR_E3_DDR_VERSION);
     } /*  ddr */
 
     rcar_dram_get_boot_status(&ddrBackup);
@@ -1691,8 +1691,6 @@
         failcount = 1;
     } /*  dataL */
 
-    NOTICE("..%d\n", failcount); /*  rev.0.05 */
-
     if (failcount == 0) {
 	return INITDRAM_OK;
     } else {
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram.c b/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram.c
index 78f0f11..f4bfdde 100644
--- a/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram.c
+++ b/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram.c
@@ -2826,7 +2826,7 @@
 	set_freqchgack(0);
 
 	if (timeout) {
-		FATAL_MSG("Time out[2]");
+		FATAL_MSG("BL2: Time out[2]\n");
 		return (1);
 	}
 	return (0);
@@ -3012,13 +3012,13 @@
 	***********************************************************************/
 #ifdef DDR_BACKUPMODE
 	if (ddrBackup) {
-		NOTICE("[WARM_BOOT]");
+		NOTICE("BL2: [WARM_BOOT]\n");
 	} else {
-		NOTICE("[COLD_BOOT]");
+		NOTICE("BL2: [COLD_BOOT]\n");
 	}
 	err = rcar_dram_update_boot_status(ddrBackup);
 	if (err) {
-		NOTICE("[BOOT_STATUS_UPDATE_ERROR]");
+		NOTICE("BL2: [BOOT_STATUS_UPDATE_ERROR]\n");
 		return INITDRAM_ERR_I;
 	}
 #endif
diff --git a/drivers/synopsys/ufs/dw_ufs.c b/drivers/synopsys/ufs/dw_ufs.c
index c7c8fc2..6bed981 100644
--- a/drivers/synopsys/ufs/dw_ufs.c
+++ b/drivers/synopsys/ufs/dw_ufs.c
@@ -183,7 +183,7 @@
 	return 0;
 }
 
-const ufs_ops_t dw_ufs_ops = {
+static const ufs_ops_t dw_ufs_ops = {
 	.phy_init		= dwufs_phy_init,
 	.phy_set_pwr_mode	= dwufs_phy_set_pwr_mode,
 };
diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c
index 2351c9b..b2c1046 100644
--- a/drivers/ufs/ufs.c
+++ b/drivers/ufs/ufs.c
@@ -591,7 +591,7 @@
 	ufs_query(QUERY_WRITE_DESC, idn, index, 0, buf, size);
 }
 
-void ufs_read_capacity(int lun, unsigned int *num, unsigned int *size)
+static void ufs_read_capacity(int lun, unsigned int *num, unsigned int *size)
 {
 	utp_utrd_t utrd;
 	resp_upiu_t *resp;
diff --git a/fdts/stm32mp15-ddr.dtsi b/fdts/stm32mp15-ddr.dtsi
index be4e2c3..1a5c51c 100644
--- a/fdts/stm32mp15-ddr.dtsi
+++ b/fdts/stm32mp15-ddr.dtsi
@@ -5,7 +5,7 @@
 
 / {
 	soc {
-		ddr: ddr@0x5A003000{
+		ddr: ddr@5A003000{
 
 			compatible = "st,stm32mp1-ddr";
 
diff --git a/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi b/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi
index 58a4cdc..82e7104 100644
--- a/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi
+++ b/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi
@@ -3,7 +3,7 @@
  * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
  */
 
-/* STM32MP157C ED1 and ED2 BOARD configuration
+/* STM32MP157C ED1 BOARD configuration
  * 2x DDR3L 4Gb each, 16-bit, 533MHz, Single Die Package in flyby topology.
  * Reference used NT5CC256M16DP-DI from NANYA
  *
@@ -15,10 +15,11 @@
  * timing mode	optimized
  * Scheduling/QoS options : type = 2
  * address mapping : RBC
+ * Tc > + 85C : N
  */
 
-#define DDR_MEM_NAME "DDR3-1066 bin G 2x4Gb 533MHz v1.39"
-#define DDR_MEM_SPEED 533
+#define DDR_MEM_NAME "DDR3-1066/888 bin G 2x4Gb 533MHz v1.41"
+#define DDR_MEM_SPEED 533000
 #define DDR_MEM_SIZE 0x40000000
 
 #define DDR_MSTR 0x00040401
@@ -62,7 +63,7 @@
 #define DDR_ADDRMAP11 0x00000000
 #define DDR_ODTCFG 0x06000600
 #define DDR_ODTMAP 0x00000001
-#define DDR_SCHED 0x00001201
+#define DDR_SCHED 0x00000C01
 #define DDR_SCHED1 0x00000000
 #define DDR_PERFHPR1 0x01000001
 #define DDR_PERFLPR1 0x08000200
@@ -74,15 +75,15 @@
 #define DDR_PCCFG 0x00000010
 #define DDR_PCFGR_0 0x00010000
 #define DDR_PCFGW_0 0x00000000
-#define DDR_PCFGQOS0_0 0x02100B03
+#define DDR_PCFGQOS0_0 0x02100C03
 #define DDR_PCFGQOS1_0 0x00800100
-#define DDR_PCFGWQOS0_0 0x01100B03
+#define DDR_PCFGWQOS0_0 0x01100C03
 #define DDR_PCFGWQOS1_0 0x01000200
 #define DDR_PCFGR_1 0x00010000
 #define DDR_PCFGW_1 0x00000000
-#define DDR_PCFGQOS0_1 0x02100B03
-#define DDR_PCFGQOS1_1 0x00800000
-#define DDR_PCFGWQOS0_1 0x01100B03
+#define DDR_PCFGQOS0_1 0x02100C03
+#define DDR_PCFGQOS1_1 0x00800040
+#define DDR_PCFGWQOS0_1 0x01100C03
 #define DDR_PCFGWQOS1_1 0x01000200
 #define DDR_PGCR 0x01442E02
 #define DDR_PTR0 0x0022AA5B
diff --git a/fdts/stm32mp157-pinctrl.dtsi b/fdts/stm32mp157-pinctrl.dtsi
index 21bd34e..9dcd7b5 100644
--- a/fdts/stm32mp157-pinctrl.dtsi
+++ b/fdts/stm32mp157-pinctrl.dtsi
@@ -3,13 +3,14 @@
  * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
  * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
  */
-
 #include <dt-bindings/pinctrl/stm32-pinfunc.h>
+
 / {
 	soc {
-		pinctrl: pin-controller {
+		pinctrl: pin-controller@50002000 {
 			#address-cells = <1>;
 			#size-cells = <1>;
+			compatible = "st,stm32mp157-pinctrl";
 			ranges = <0 0x50002000 0xa400>;
 			pins-are-numbered;
 
@@ -134,54 +135,76 @@
 				status = "disabled";
 			};
 
-			uart4_pins_a: uart4@0 {
+			qspi_bk1_pins_a: qspi-bk1-0 {
 				pins1 {
-					pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX */
+					pinmux = <STM32_PINMUX('F', 8, AF10)>, /* QSPI_BK1_IO0 */
+						 <STM32_PINMUX('F', 9, AF10)>, /* QSPI_BK1_IO1 */
+						 <STM32_PINMUX('F', 7, AF9)>, /* QSPI_BK1_IO2 */
+						 <STM32_PINMUX('F', 6, AF9)>; /* QSPI_BK1_IO3 */
 					bias-disable;
 					drive-push-pull;
-					slew-rate = <0>;
+					slew-rate = <1>;
 				};
 				pins2 {
-					pinmux = <STM32_PINMUX('B', 2, AF8)>; /* UART4_RX */
-					bias-disable;
+					pinmux = <STM32_PINMUX('B', 6, AF10)>; /* QSPI_BK1_NCS */
+					bias-pull-up;
+					drive-push-pull;
+					slew-rate = <1>;
 				};
 			};
 
-			usart3_pins_a: usart3@0 {
+			qspi_bk2_pins_a: qspi-bk2-0 {
 				pins1 {
-					pinmux = <STM32_PINMUX('B', 10, AF7)>, /* USART3_TX */
-						 <STM32_PINMUX('G', 8, AF8)>; /* USART3_RTS */
+					pinmux = <STM32_PINMUX('H', 2, AF9)>, /* QSPI_BK2_IO0 */
+						 <STM32_PINMUX('H', 3, AF9)>, /* QSPI_BK2_IO1 */
+						 <STM32_PINMUX('G', 10, AF11)>, /* QSPI_BK2_IO2 */
+						 <STM32_PINMUX('G', 7, AF11)>; /* QSPI_BK2_IO3 */
 					bias-disable;
 					drive-push-pull;
-					slew-rate = <0>;
+					slew-rate = <1>;
 				};
 				pins2 {
-					pinmux = <STM32_PINMUX('B', 12, AF8)>, /* USART3_RX */
-						 <STM32_PINMUX('I', 10, AF8)>; /* USART3_CTS_NSS */
-					bias-disable;
+					pinmux = <STM32_PINMUX('C', 0, AF10)>; /* QSPI_BK2_NCS */
+					bias-pull-up;
+					drive-push-pull;
+					slew-rate = <1>;
 				};
 			};
 
-			sdmmc1_b4_pins_a: sdmmc1-b4@0 {
+			qspi_clk_pins_a: qspi-clk-0 {
 				pins {
+					pinmux = <STM32_PINMUX('F', 10, AF9)>; /* QSPI_CLK */
+					bias-disable;
+					drive-push-pull;
+					slew-rate = <3>;
+				};
+			};
+
+			sdmmc1_b4_pins_a: sdmmc1-b4-0 {
+				pins1 {
 					pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
 						 <STM32_PINMUX('C', 9, AF12)>, /* SDMMC1_D1 */
 						 <STM32_PINMUX('C', 10, AF12)>, /* SDMMC1_D2 */
 						 <STM32_PINMUX('C', 11, AF12)>, /* SDMMC1_D3 */
-						 <STM32_PINMUX('C', 12, AF12)>, /* SDMMC1_CK */
 						 <STM32_PINMUX('D', 2, AF12)>; /* SDMMC1_CMD */
-					slew-rate = <3>;
+					slew-rate = <1>;
 					drive-push-pull;
 					bias-disable;
 				};
+				pins2 {
+					pinmux = <STM32_PINMUX('C', 12, AF12)>; /* SDMMC1_CK */
+					slew-rate = <2>;
+					drive-push-pull;
+					bias-disable;
+				};
 			};
 
-			sdmmc1_dir_pins_a: sdmmc1-dir@0 {
+			sdmmc1_dir_pins_a: sdmmc1-dir-0 {
 				pins1 {
 					pinmux = <STM32_PINMUX('F', 2, AF11)>, /* SDMMC1_D0DIR */
 						 <STM32_PINMUX('C', 7, AF8)>, /* SDMMC1_D123DIR */
 						 <STM32_PINMUX('B', 9, AF11)>; /* SDMMC1_CDIR */
-					slew-rate = <3>;
+					slew-rate = <1>;
 					drive-push-pull;
 					bias-pull-up;
 				};
@@ -191,36 +214,85 @@
 				};
 			};
 
-			sdmmc2_b4_pins_a: sdmmc2-b4@0 {
-				pins {
+			sdmmc1_dir_pins_b: sdmmc1-dir-1 {
+				pins1 {
+					pinmux = <STM32_PINMUX('E', 12, AF8)>, /* SDMMC1_D0DIR */
+						 <STM32_PINMUX('E', 14, AF11)>, /* SDMMC1_D123DIR */
+						 <STM32_PINMUX('B', 9, AF11)>; /* SDMMC1_CDIR */
+					slew-rate = <3>;
+					drive-push-pull;
+					bias-pull-up;
+				};
+				pins2 {
+					pinmux = <STM32_PINMUX('E', 4, AF8)>; /* SDMMC1_CKIN */
+					bias-pull-up;
+				};
+			};
+
+			sdmmc2_b4_pins_a: sdmmc2-b4-0 {
+				pins1 {
 					pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
 						 <STM32_PINMUX('B', 15, AF9)>, /* SDMMC2_D1 */
 						 <STM32_PINMUX('B', 3, AF9)>, /* SDMMC2_D2 */
 						 <STM32_PINMUX('B', 4, AF9)>, /* SDMMC2_D3 */
-						 <STM32_PINMUX('E', 3, AF9)>, /* SDMMC2_CK */
 						 <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
-					slew-rate = <3>;
+					slew-rate = <1>;
+					drive-push-pull;
+					bias-pull-up;
+				};
+				pins2 {
+					pinmux = <STM32_PINMUX('E', 3, AF9)>; /* SDMMC2_CK */
+					slew-rate = <2>;
 					drive-push-pull;
 					bias-pull-up;
 				};
 			};
 
-			sdmmc2_d47_pins_a: sdmmc2-d47@0 {
+			sdmmc2_d47_pins_a: sdmmc2-d47-0 {
 				pins {
 					pinmux = <STM32_PINMUX('A', 8, AF9)>, /* SDMMC2_D4 */
 						 <STM32_PINMUX('A', 9, AF10)>, /* SDMMC2_D5 */
 						 <STM32_PINMUX('E', 5, AF9)>, /* SDMMC2_D6 */
 						 <STM32_PINMUX('D', 3, AF9)>; /* SDMMC2_D7 */
-					slew-rate = <3>;
+					slew-rate = <1>;
 					drive-push-pull;
 					bias-pull-up;
 				};
 			};
+
+			uart4_pins_a: uart4-0 {
+				pins1 {
+					pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX */
+					bias-disable;
+					drive-push-pull;
+					slew-rate = <0>;
+				};
+				pins2 {
+					pinmux = <STM32_PINMUX('B', 2, AF8)>; /* UART4_RX */
+					bias-disable;
+				};
+			};
+
+			usart3_pins_a: usart3-0 {
+				pins1 {
+					pinmux = <STM32_PINMUX('B', 10, AF7)>, /* USART3_TX */
+						 <STM32_PINMUX('G', 8, AF8)>; /* USART3_RTS */
+					bias-disable;
+					drive-push-pull;
+					slew-rate = <0>;
+				};
+				pins2 {
+					pinmux = <STM32_PINMUX('B', 12, AF8)>, /* USART3_RX */
+						 <STM32_PINMUX('I', 10, AF8)>; /* USART3_CTS_NSS */
+					bias-disable;
+				};
+			};
 		};
 
-		pinctrl_z: pin-controller-z {
+		pinctrl_z: pin-controller-z@54004000 {
 			#address-cells = <1>;
 			#size-cells = <1>;
+			compatible = "st,stm32mp157-z-pinctrl";
 			ranges = <0 0x54004000 0x400>;
 			pins-are-numbered;
 
@@ -236,7 +308,7 @@
 				status = "disabled";
 			};
 
-			i2c4_pins_a: i2c4@0 {
+			i2c4_pins_a: i2c4-0 {
 				pins {
 					pinmux = <STM32_PINMUX('Z', 4, AF6)>, /* I2C4_SCL */
 						 <STM32_PINMUX('Z', 5, AF6)>; /* I2C4_SDA */
diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts
index e3dabe8..a97e805 100644
--- a/fdts/stm32mp157c-ed1.dts
+++ b/fdts/stm32mp157c-ed1.dts
@@ -3,20 +3,26 @@
  * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
  * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
  */
-
 /dts-v1/;
 
 #include "stm32mp157c.dtsi"
 #include "stm32mp157caa-pinctrl.dtsi"
 
 / {
-	model = "STMicroelectronics STM32MP157C-ED1 pmic eval daughter";
+	model = "STMicroelectronics STM32MP157C eval daughter";
 	compatible = "st,stm32mp157c-ed1", "st,stm32mp157";
 
 	chosen {
-		bootargs = "earlyprintk console=ttyS3,115200 root=/dev/ram";
-		stdout-path = "serial3:115200n8";
+		stdout-path = "serial0:115200n8";
 	};
+
+	aliases {
+		serial0 = &uart4;
+	};
+};
+
+&clk_hse {
+	st,digbypass;
 };
 
 &i2c4 {
@@ -26,62 +32,113 @@
 	i2c-scl-falling-time-ns = <20>;
 	status = "okay";
 
-	pmic: stpmu1@33 {
-		compatible = "st,stpmu1";
+	pmic: stpmic@33 {
+		compatible = "st,stpmic1";
 		reg = <0x33>;
+		interrupts-extended = <&exti_pwr 55 IRQ_TYPE_EDGE_FALLING>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
 		status = "okay";
 
-		st,main_control_register = <0x04>;
-		st,vin_control_register = <0xc0>;
-		st,usb_control_register = <0x30>;
+		st,main-control-register = <0x04>;
+		st,vin-control-register = <0xc0>;
+		st,usb-control-register = <0x30>;
 
 		regulators {
-			compatible = "st,stpmu1-regulators";
+			compatible = "st,stpmic1-regulators";
+
+			ldo1-supply = <&v3v3>;
+			ldo2-supply = <&v3v3>;
+			ldo3-supply = <&vdd_ddr>;
+			ldo5-supply = <&v3v3>;
+			ldo6-supply = <&v3v3>;
+
+			vddcore: buck1 {
+				regulator-name = "vddcore";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-always-on;
+				regulator-initial-mode = <0>;
+				regulator-over-current-protection;
+			};
+
+			vdd_ddr: buck2 {
+				regulator-name = "vdd_ddr";
+				regulator-min-microvolt = <1350000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-always-on;
+				regulator-initial-mode = <0>;
+				regulator-over-current-protection;
+			};
+
+			vdd: buck3 {
+				regulator-name = "vdd";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+				st,mask-reset;
+				regulator-initial-mode = <0>;
+				regulator-over-current-protection;
+			};
 
 			v3v3: buck4 {
 				regulator-name = "v3v3";
 				regulator-min-microvolt = <3300000>;
 				regulator-max-microvolt = <3300000>;
-				regulator-boot-on;
+				regulator-always-on;
 				regulator-over-current-protection;
-				regulator-initial-mode = <8>;
+				regulator-initial-mode = <0>;
+			};
+
+			vdda: ldo1 {
+				regulator-name = "vdda";
+				regulator-min-microvolt = <2900000>;
+				regulator-max-microvolt = <2900000>;
+			};
 
-				regulator-state-standby {
-					regulator-suspend-microvolt = <3300000>;
-					regulator-unchanged-in-suspend;
-					regulator-mode = <8>;
-				};
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-				regulator-state-disk {
-					regulator-off-in-suspend;
-				};
+			v2v8: ldo2 {
+				regulator-name = "v2v8";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
 			};
 
+			vtt_ddr: ldo3 {
+				regulator-name = "vtt_ddr";
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <750000>;
+				regulator-always-on;
+				regulator-over-current-protection;
+			};
+
+			vdd_usb: ldo4 {
+				regulator-name = "vdd_usb";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+			};
+
 			vdd_sd: ldo5 {
 				regulator-name = "vdd_sd";
 				regulator-min-microvolt = <2900000>;
 				regulator-max-microvolt = <2900000>;
 				regulator-boot-on;
+			};
 
-				regulator-state-standby {
-					regulator-suspend-microvolt = <2900000>;
-					regulator-unchanged-in-suspend;
-				};
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-				regulator-state-disk {
-					regulator-off-in-suspend;
-				};
+			v1v8: ldo6 {
+				regulator-name = "v1v8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+
+			vref_ddr: vref_ddr {
+				regulator-name = "vref_ddr";
+				regulator-always-on;
+				regulator-over-current-protection;
 			};
 		};
 	};
 };
 
 &iwdg2 {
-	instance = <2>;
 	timeout-sec = <32>;
 	status = "okay";
 };
@@ -90,14 +147,19 @@
 	status = "okay";
 };
 
+&rtc {
+	status = "okay";
+};
+
 &sdmmc1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>;
 	broken-cd;
-	st,dirpol;
-	st,negedge;
-	st,pin-ckin;
+	st,sig-dir;
+	st,neg-edge;
+	st,use-ckin;
 	bus-width = <4>;
+	vmmc-supply = <&vdd_sd>;
 	sd-uhs-sdr12;
 	sd-uhs-sdr25;
 	sd-uhs-sdr50;
@@ -112,16 +174,17 @@
 	non-removable;
 	no-sd;
 	no-sdio;
-	st,dirpol;
-	st,negedge;
+	st,neg-edge;
 	bus-width = <8>;
+	vmmc-supply = <&v3v3>;
+	vqmmc-supply = <&v3v3>;
+	mmc-ddr-3_3v;
 	status = "okay";
 };
 
 &uart4 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart4_pins_a>;
-	resets = <&rcc UART4_R>;
 	status = "okay";
 };
 
@@ -157,6 +220,7 @@
 
 /* CLOCK init */
 &rcc {
+	secure-status = "disabled";
 	st,clksrc = <
 		CLK_MPU_PLL1P
 		CLK_AXI_PLL2P
@@ -186,7 +250,7 @@
 		CLK_FMC_ACLK
 		CLK_QSPI_ACLK
 		CLK_ETH_DISABLED
-		CLK_SDMMC12_PLL3R
+		CLK_SDMMC12_PLL4P
 		CLK_DSI_DSIPLL
 		CLK_STGEN_HSE
 		CLK_USBPHY_HSE
@@ -195,7 +259,7 @@
 		CLK_SPI45_HSI
 		CLK_SPI6_HSI
 		CLK_I2C46_HSI
-		CLK_SDMMC3_PLL3R
+		CLK_SDMMC3_PLL4P
 		CLK_USBO_USBPHY
 		CLK_ADC_CKPER
 		CLK_CEC_LSE
@@ -206,17 +270,17 @@
 		CLK_UART35_HSI
 		CLK_UART6_HSI
 		CLK_UART78_HSI
-		CLK_SPDIF_PLL3Q
+		CLK_SPDIF_PLL4P
 		CLK_FDCAN_PLL4Q
 		CLK_SAI1_PLL3Q
 		CLK_SAI2_PLL3Q
 		CLK_SAI3_PLL3Q
 		CLK_SAI4_PLL3Q
-		CLK_RNG1_CSI
-		CLK_RNG2_CSI
+		CLK_RNG1_LSI
+		CLK_RNG2_LSI
 		CLK_LPTIM1_PCLK1
 		CLK_LPTIM23_PCLK3
-		CLK_LPTIM45_PCLK3
+		CLK_LPTIM45_LSE
 	>;
 
 	/* VCO = 1300.0 MHz => P = 650 (CPU) */
@@ -231,15 +295,15 @@
 		frac = < 0x1400 >;
 	};
 
-	/* VCO = 786.4 MHz => P = 197, Q = 49, R = 98 */
+	/* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */
 	pll3: st,pll@2 {
-		cfg = < 2 97 3 15 7 PQR(1,1,1) >;
-		frac = < 0x9ba >;
+		cfg = < 1 33 1 16 36 PQR(1,1,1) >;
+		frac = < 0x1a04 >;
 	};
 
-	/* VCO = 508.0 MHz => P = 56, Q = 56, R = 56 */
+	/* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */
 	pll4: st,pll@3 {
-		cfg = < 5 126 8 8 8 PQR(1,1,1) >;
+		cfg = < 3 98 5 7 7 PQR(1,1,1) >;
 	};
 };
 
diff --git a/fdts/stm32mp157c-ev1.dts b/fdts/stm32mp157c-ev1.dts
index 98a9d35..cfde8ed 100644
--- a/fdts/stm32mp157c-ev1.dts
+++ b/fdts/stm32mp157c-ev1.dts
@@ -3,23 +3,65 @@
  * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
  * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
  */
-
 /dts-v1/;
+
 #include "stm32mp157c-ed1.dts"
 
 / {
-	model = "STMicroelectronics STM32MP157C-EV1 pmic eval daughter on eval mother";
+	model = "STMicroelectronics STM32MP157C eval daughter on eval mother";
 	compatible = "st,stm32mp157c-ev1", "st,stm32mp157c-ed1", "st,stm32mp157";
 
 	chosen {
-		bootargs = "earlyprintk console=ttyS3,115200 root=/dev/ram";
-		stdout-path = "serial3:115200n8";
+		stdout-path = "serial0:115200n8";
+	};
+
+	aliases {
+		serial1 = &usart3;
+	};
+};
+
+&fmc {
+	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>;
+	reg = <0x58003000 0x1000>, <0x70000000 0x4000000>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	flash0: mx66l51235l@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-rx-bus-width = <4>;
+		spi-max-frequency = <108000000>;
+		#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 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&usart3_pins_a>;
-	resets = <&rcc USART3_R>;
 	status = "disabled";
 };
diff --git a/fdts/stm32mp157c.dtsi b/fdts/stm32mp157c.dtsi
index 8b13c0e..0ec7ecb 100644
--- a/fdts/stm32mp157c.dtsi
+++ b/fdts/stm32mp157c.dtsi
@@ -3,7 +3,7 @@
  * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
  * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
  */
-
+#include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/clock/stm32mp1-clks.h>
 #include <dt-bindings/reset/stm32mp1-resets.h>
 
@@ -11,15 +11,12 @@
 	#address-cells = <1>;
 	#size-cells = <1>;
 
-	aliases {
-		serial0 = &usart1;
-		serial1 = &usart2;
-		serial2 = &usart3;
-		serial3 = &uart4;
-		serial4 = &uart5;
-		serial5 = &usart6;
-		serial6 = &uart7;
-		serial7 = &uart8;
+	intc: interrupt-controller@a0021000 {
+		compatible = "arm,cortex-a7-gic";
+		#interrupt-cells = <3>;
+		interrupt-controller;
+		reg = <0xa0021000 0x1000>,
+		      <0xa0022000 0x2000>;
 	};
 
 	clocks {
@@ -56,7 +53,7 @@
 		clk_i2s_ckin: i2s_ckin {
 			#clock-cells = <0>;
 			compatible = "fixed-clock";
-			clock-frequency = <64000000>;
+			clock-frequency = <0>;
 		};
 
 		clk_dsi_phy: ck_dsi_phy {
@@ -64,31 +61,28 @@
 			compatible = "fixed-clock";
 			clock-frequency = <0>;
 		};
-
-		clk_usbo_48m: ck_usbo_48m {
-			#clock-cells = <0>;
-			compatible = "fixed-clock";
-			clock-frequency = <48000000>;
-		};
 	};
 
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <1>;
 		#size-cells = <1>;
+		interrupt-parent = <&intc>;
 		ranges;
 
 		usart2: serial@4000e000 {
-			compatible = "st,stm32h7-usart";
+			compatible = "st,stm32h7-uart";
 			reg = <0x4000e000 0x400>;
 			clocks = <&rcc USART2_K>;
+			resets = <&rcc USART2_R>;
 			status = "disabled";
 		};
 
 		usart3: serial@4000f000 {
-			compatible = "st,stm32h7-usart";
+			compatible = "st,stm32h7-uart";
 			reg = <0x4000f000 0x400>;
 			clocks = <&rcc USART3_K>;
+			resets = <&rcc USART3_R>;
 			status = "disabled";
 		};
 
@@ -96,6 +90,7 @@
 			compatible = "st,stm32h7-uart";
 			reg = <0x40010000 0x400>;
 			clocks = <&rcc UART4_K>;
+			resets = <&rcc UART4_R>;
 			status = "disabled";
 		};
 
@@ -103,6 +98,7 @@
 			compatible = "st,stm32h7-uart";
 			reg = <0x40011000 0x400>;
 			clocks = <&rcc UART5_K>;
+			resets = <&rcc UART5_R>;
 			status = "disabled";
 		};
 
@@ -111,6 +107,7 @@
 			compatible = "st,stm32h7-uart";
 			reg = <0x40018000 0x400>;
 			clocks = <&rcc UART7_K>;
+			resets = <&rcc UART7_R>;
 			status = "disabled";
 		};
 
@@ -118,21 +115,23 @@
 			compatible = "st,stm32h7-uart";
 			reg = <0x40019000 0x400>;
 			clocks = <&rcc UART8_K>;
+			resets = <&rcc UART8_R>;
 			status = "disabled";
 		};
 
 		usart6: serial@44003000 {
-			compatible = "st,stm32h7-usart";
+			compatible = "st,stm32h7-uart";
 			reg = <0x44003000 0x400>;
 			clocks = <&rcc USART6_K>;
+			resets = <&rcc USART6_R>;
 			status = "disabled";
 		};
 
 		sdmmc3: sdmmc@48004000 {
 			compatible = "st,stm32-sdmmc2";
 			reg = <0x48004000 0x400>, <0x48005000 0x400>;
-			reg-names = "sdmmc", "delay";
 			clocks = <&rcc SDMMC3_K>;
+			clock-names = "apb_pclk";
 			resets = <&rcc SDMMC3_R>;
 			cap-sd-highspeed;
 			cap-mmc-highspeed;
@@ -141,19 +140,36 @@
 		};
 
 		rcc: rcc@50000000 {
-			compatible = "syscon", "st,stm32mp1-rcc";
+			compatible = "st,stm32mp1-rcc", "syscon";
+			reg = <0x50000000 0x1000>;
 			#clock-cells = <1>;
 			#reset-cells = <1>;
-			reg = <0x50000000 0x1000>;
+			interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
-		rcc_reboot: rcc-reboot@50000000 {
-				compatible = "syscon-reboot";
-				regmap = <&rcc>;
-				offset = <0x404>;
-				mask = <0x1>;
+		pwr: pwr@50001000 {
+			compatible = "st,stm32mp1-pwr", "syscon", "simple-mfd";
+			reg = <0x50001000 0x400>;
 		};
 
+		exti: interrupt-controller@5000d000 {
+			compatible = "st,stm32mp1-exti", "syscon";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			reg = <0x5000d000 0x400>;
+
+			/* exti_pwr is an extra interrupt controller used for
+			 * EXTI 55 to 60. It's mapped on pwr interrupt
+			 * controller.
+			 */
+			exti_pwr: exti-pwr {
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				interrupt-parent = <&pwr>;
+				st,irq-number = <6>;
+			};
+		};
+
 		rng1: rng@54003000 {
 			compatible = "st,stm32-rng";
 			reg = <0x54003000 0x400>;
@@ -162,13 +178,15 @@
 			status = "disabled";
 		};
 
-		fmc_nand: fmc_nand@58002000 {
-			compatible = "st,stm32mp1-fmc";
+		fmc: nand-controller@58002000 {
+			compatible = "st,stm32mp15-fmc2";
 			reg = <0x58002000 0x1000>,
-			      <0x80000000 0x40000>,
-			      <0x81000000 0x40000>,
-			      <0x88000000 0x40000>,
-			      <0x89000000 0x40000>;
+			      <0x80000000 0x1000>,
+			      <0x88010000 0x1000>,
+			      <0x88020000 0x1000>,
+			      <0x81000000 0x1000>,
+			      <0x89010000 0x1000>,
+			      <0x89020000 0x1000>;
 			clocks = <&rcc FMC_K>;
 			resets = <&rcc FMC_R>;
 			status = "disabled";
@@ -177,15 +195,17 @@
 		qspi: qspi@58003000 {
 			compatible = "st,stm32f469-qspi";
 			reg = <0x58003000 0x1000>, <0x70000000 0x10000000>;
+			reg-names = "qspi", "qspi_mm";
 			clocks = <&rcc QSPI_K>;
+			resets = <&rcc QSPI_R>;
 			status = "disabled";
 		};
 
 		sdmmc1: sdmmc@58005000 {
 			compatible = "st,stm32-sdmmc2";
 			reg = <0x58005000 0x1000>, <0x58006000 0x1000>;
-			reg-names = "sdmmc", "delay";
 			clocks = <&rcc SDMMC1_K>;
+			clock-names = "apb_pclk";
 			resets = <&rcc SDMMC1_R>;
 			cap-sd-highspeed;
 			cap-mmc-highspeed;
@@ -196,8 +216,8 @@
 		sdmmc2: sdmmc@58007000 {
 			compatible = "st,stm32-sdmmc2";
 			reg = <0x58007000 0x1000>, <0x58008000 0x1000>;
-			reg-names = "sdmmc", "delay";
 			clocks = <&rcc SDMMC2_K>;
+			clock-names = "apb_pclk";
 			resets = <&rcc SDMMC2_R>;
 			cap-sd-highspeed;
 			cap-mmc-highspeed;
@@ -205,7 +225,7 @@
 			status = "disabled";
 		};
 
-		iwdg2: iwdg@5a002000 {
+		iwdg2: watchdog@5a002000 {
 			compatible = "st,stm32mp1-iwdg";
 			reg = <0x5a002000 0x400>;
 			clocks = <&rcc IWDG2>, <&rcc CK_LSI>;
@@ -214,15 +234,34 @@
 		};
 
 		usart1: serial@5c000000 {
-			compatible = "st,stm32h7-usart";
+			compatible = "st,stm32h7-uart";
 			reg = <0x5c000000 0x400>;
+			interrupt-names = "event", "wakeup";
+			interrupts-extended = <&intc GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
+					      <&exti 26 1>;
 			clocks = <&rcc USART1_K>;
+			resets = <&rcc USART1_R>;
 			status = "disabled";
 		};
 
+		spi6: spi@5c001000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "st,stm32h7-spi";
+			reg = <0x5c001000 0x400>;
+			interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&rcc SPI6_K>;
+			resets = <&rcc SPI6_R>;
+			status = "disabled";
+		};
+
 		i2c4: i2c@5c002000 {
 			compatible = "st,stm32f7-i2c";
 			reg = <0x5c002000 0x400>;
+			interrupt-names = "event", "error", "wakeup";
+			interrupts-extended = <&intc GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>,
+					      <&exti 24 1>;
 			clocks = <&rcc I2C4_K>;
 			resets = <&rcc I2C4_R>;
 			#address-cells = <1>;
@@ -235,6 +274,36 @@
 			reg = <0x5c004000 0x400>;
 			clocks = <&rcc RTCAPB>, <&rcc RTC>;
 			clock-names = "pclk", "rtc_ck";
+			interrupts-extended = <&intc GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+					      <&exti 19 1>;
+			status = "disabled";
+		};
+
+		bsec: nvmem@5c005000 {
+			compatible = "st,stm32mp15-bsec";
+			reg = <0x5c005000 0x400>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ts_cal1: calib@5c {
+				reg = <0x5c 0x2>;
+			};
+			ts_cal2: calib@5e {
+				reg = <0x5e 0x2>;
+			};
+		};
+
+		i2c6: i2c@5c009000 {
+			compatible = "st,stm32f7-i2c";
+			reg = <0x5c009000 0x400>;
+			interrupt-names = "event", "error", "wakeup";
+			interrupts-extended = <&intc GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+					      <&exti 54 1>;
+			clocks = <&rcc I2C6_K>;
+			resets = <&rcc I2C6_R>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
 		};
 	};
 };
diff --git a/fdts/stm32mp157caa-pinctrl.dtsi b/fdts/stm32mp157caa-pinctrl.dtsi
index 774561a..9b9cd08 100644
--- a/fdts/stm32mp157caa-pinctrl.dtsi
+++ b/fdts/stm32mp157caa-pinctrl.dtsi
@@ -7,8 +7,8 @@
 #include "stm32mp157-pinctrl.dtsi"
 / {
 	soc {
-		pinctrl: pin-controller {
-			compatible = "st,stm32mp157caa-pinctrl";
+		pinctrl: pin-controller@50002000 {
+			st,package = <STM32MP157CAA>;
 
 			gpioa: gpio@50002000 {
 				status = "okay";
@@ -77,8 +77,8 @@
 			};
 		};
 
-		pinctrl_z: pin-controller-z {
-			compatible = "st,stm32mp157caa-z-pinctrl";
+		pinctrl_z: pin-controller-z@54004000 {
+			st,package = <STM32MP157CAA>;
 
 			gpioz: gpio@54004000 {
 				status = "okay";
diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h
index cbe272c..4af3e90 100644
--- a/include/arch/aarch32/arch.h
+++ b/include/arch/aarch32/arch.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
  */
@@ -94,12 +94,16 @@
 /* CSSELR definitions */
 #define LEVEL_SHIFT		U(1)
 
-/* ID_PFR0 AMU definitions */
+/* ID_MMFR4 definitions */
+#define ID_MMFR4_CNP_SHIFT	U(12)
+#define ID_MMFR4_CNP_LENGTH	U(4)
+#define ID_MMFR4_CNP_MASK	U(0xf)
+
+/* ID_PFR0 definitions */
 #define ID_PFR0_AMU_SHIFT	U(20)
 #define ID_PFR0_AMU_LENGTH	U(4)
 #define ID_PFR0_AMU_MASK	U(0xf)
 
-/* ID_PFR0 DIT definitions */
 #define ID_PFR0_DIT_SHIFT	U(24)
 #define ID_PFR0_DIT_LENGTH	U(4)
 #define ID_PFR0_DIT_MASK	U(0xf)
@@ -475,6 +479,7 @@
 #define DCISW		p15, 0, c7, c6, 2
 #define CTR		p15, 0, c0, c0, 1
 #define CNTFRQ		p15, 0, c14, c0, 0
+#define ID_MMFR4	p15, 0, c0, c2, 6
 #define ID_PFR0		p15, 0, c0, c1, 0
 #define ID_PFR1		p15, 0, c0, c1, 1
 #define MAIR0		p15, 0, c10, c2, 0
diff --git a/include/arch/aarch32/arch_features.h b/include/arch/aarch32/arch_features.h
new file mode 100644
index 0000000..d934102
--- /dev/null
+++ b/include/arch/aarch32/arch_features.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ARCH_FEATURES_H
+#define ARCH_FEATURES_H
+
+#include <stdbool.h>
+
+#include <arch_helpers.h>
+
+static inline bool is_armv8_2_ttcnp_present(void)
+{
+	return ((read_id_mmfr4() >> ID_MMFR4_CNP_SHIFT) &
+		ID_MMFR4_CNP_MASK) != 0U;
+}
+
+#endif /* ARCH_FEATURES_H */
diff --git a/include/arch/aarch32/arch_helpers.h b/include/arch/aarch32/arch_helpers.h
index c2773c1..64ddc86 100644
--- a/include/arch/aarch32/arch_helpers.h
+++ b/include/arch/aarch32/arch_helpers.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -214,6 +214,7 @@
  ******************************************************************************/
 DEFINE_COPROCR_READ_FUNC(mpidr, MPIDR)
 DEFINE_COPROCR_READ_FUNC(midr, MIDR)
+DEFINE_COPROCR_READ_FUNC(id_mmfr4, ID_MMFR4)
 DEFINE_COPROCR_READ_FUNC(id_pfr0, ID_PFR0)
 DEFINE_COPROCR_READ_FUNC(id_pfr1, ID_PFR1)
 DEFINE_COPROCR_READ_FUNC(isr, ISR)
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 8a44d83..76c3e27 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -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
  */
@@ -156,10 +156,6 @@
 #define ID_AA64PFR0_GIC_WIDTH	U(4)
 #define ID_AA64PFR0_GIC_MASK	((ULL(1) << ID_AA64PFR0_GIC_WIDTH) - ULL(1))
 
-/* ID_AA64MMFR0_EL1 definitions */
-#define ID_AA64MMFR0_EL1_PARANGE_SHIFT	U(0)
-#define ID_AA64MMFR0_EL1_PARANGE_MASK	ULL(0xf)
-
 /* ID_AA64ISAR1_EL1 definitions */
 #define ID_AA64ISAR1_GPI_SHIFT	U(28)
 #define ID_AA64ISAR1_GPI_WIDTH	U(4)
@@ -179,6 +175,10 @@
 #define ID_AA64ISAR1_APA_MASK \
 	(((ULL(1) << ID_AA64ISAR1_APA_WIDTH) - ULL(1)) << ID_AA64ISAR1_APA_SHIFT)
 
+/* ID_AA64MMFR0_EL1 definitions */
+#define ID_AA64MMFR0_EL1_PARANGE_SHIFT	U(0)
+#define ID_AA64MMFR0_EL1_PARANGE_MASK	ULL(0xf)
+
 #define PARANGE_0000	U(32)
 #define PARANGE_0001	U(36)
 #define PARANGE_0010	U(40)
@@ -202,6 +202,15 @@
 #define ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED	ULL(0x1)
 #define ID_AA64MMFR0_EL1_TGRAN16_NOT_SUPPORTED	ULL(0x0)
 
+/* ID_AA64MMFR2_EL1 definitions */
+#define ID_AA64MMFR2_EL1		S3_0_C0_C7_2
+
+#define ID_AA64MMFR2_EL1_ST_SHIFT	U(28)
+#define ID_AA64MMFR2_EL1_ST_MASK	ULL(0xf)
+
+#define ID_AA64MMFR2_EL1_CNP_SHIFT	U(0)
+#define ID_AA64MMFR2_EL1_CNP_MASK	ULL(0xf)
+
 /* ID_AA64PFR1_EL1 definitions */
 #define ID_AA64PFR1_EL1_SSBS_SHIFT	U(4)
 #define ID_AA64PFR1_EL1_SSBS_MASK	ULL(0xf)
@@ -422,6 +431,7 @@
 
 #define TCR_TxSZ_MIN		ULL(16)
 #define TCR_TxSZ_MAX		ULL(39)
+#define TCR_TxSZ_MAX_TTST	ULL(48)
 
 /* (internal) physical address size bits in EL3/EL1 */
 #define TCR_PS_BITS_4GB		ULL(0x0)
diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h
new file mode 100644
index 0000000..9bf43bf
--- /dev/null
+++ b/include/arch/aarch64/arch_features.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ARCH_FEATURES_H
+#define ARCH_FEATURES_H
+
+#include <stdbool.h>
+
+#include <arch_helpers.h>
+
+static inline bool is_armv8_2_ttcnp_present(void)
+{
+	return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_CNP_SHIFT) &
+		ID_AA64MMFR2_EL1_CNP_MASK) != 0U;
+}
+
+static inline bool is_armv8_4_ttst_present(void)
+{
+	return ((read_id_aa64mmfr2_el1() >> ID_AA64MMFR2_EL1_ST_SHIFT) &
+		ID_AA64MMFR2_EL1_ST_MASK) == 1U;
+}
+
+#endif /* ARCH_FEATURES_H */
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index b912b42..4e459bb 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -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
  */
@@ -185,6 +185,7 @@
 DEFINE_SYSREG_READ_FUNC(id_aa64isar1_el1)
 DEFINE_SYSREG_READ_FUNC(id_aa64pfr0_el1)
 DEFINE_SYSREG_READ_FUNC(id_aa64dfr0_el1)
+DEFINE_SYSREG_READ_FUNC(id_afr0_el1)
 DEFINE_SYSREG_READ_FUNC(CurrentEl)
 DEFINE_SYSREG_READ_FUNC(ctr_el0)
 DEFINE_SYSREG_RW_FUNCS(daif)
@@ -449,6 +450,9 @@
 DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc0_el1, ERXMISC0_EL1)
 DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc1_el1, ERXMISC1_EL1)
 
+/* Armv8.2 Registers */
+DEFINE_RENAME_SYSREG_READ_FUNC(id_aa64mmfr2_el1, ID_AA64MMFR2_EL1)
+
 /* Armv8.3 Pointer Authentication Registers */
 DEFINE_RENAME_SYSREG_RW_FUNCS(apgakeylo_el1, APGAKeyLo_EL1)
 
diff --git a/include/common/bl_common.h b/include/common/bl_common.h
index c12b08b..f7b3b9c 100644
--- a/include/common/bl_common.h
+++ b/include/common/bl_common.h
@@ -78,7 +78,12 @@
 IMPORT_SYM(unsigned long, __RO_END__,		BL_CODE_END);
 #endif
 
-#if defined(IMAGE_BL2)
+#if defined(IMAGE_BL1)
+IMPORT_SYM(uintptr_t, __BL1_ROM_END__,   BL1_ROM_END);
+
+IMPORT_SYM(uintptr_t, __BL1_RAM_START__, BL1_RAM_BASE);
+IMPORT_SYM(uintptr_t, __BL1_RAM_END__,   BL1_RAM_LIMIT);
+#elif defined(IMAGE_BL2)
 IMPORT_SYM(unsigned long, __BL2_END__,		BL2_END);
 #elif defined(IMAGE_BL2U)
 IMPORT_SYM(unsigned long, __BL2U_END__,		BL2U_END);
@@ -89,6 +94,17 @@
 IMPORT_SYM(unsigned long, __BL32_END__,		BL32_END);
 #endif /* IMAGE_BLX */
 
+/* The following symbols are only exported from the BL2 at EL3 linker script. */
+#if BL2_IN_XIP_MEM && defined(IMAGE_BL2)
+extern uintptr_t __BL2_ROM_END__;
+#define BL2_ROM_END (uintptr_t)(&__BL2_ROM_END__)
+
+extern uintptr_t __BL2_RAM_START__;
+extern uintptr_t __BL2_RAM_END__;
+#define BL2_RAM_BASE (uintptr_t)(&__BL2_RAM_START__)
+#define BL2_RAM_LIMIT (uintptr_t)(&__BL2_RAM_END__)
+#endif /* BL2_IN_XIP_MEM */
+
 /*
  * The next 2 constants identify the extents of the coherent memory region.
  * These addresses are used by the MMU setup code and therefore they must be
diff --git a/include/common/desc_image_load.h b/include/common/desc_image_load.h
index f2f26ea..e46eb27 100644
--- a/include/common/desc_image_load.h
+++ b/include/common/desc_image_load.h
@@ -31,6 +31,9 @@
 
 /* BL image loading utility functions */
 void flush_bl_params_desc(void);
+void flush_bl_params_desc_args(bl_mem_params_node_t *mem_params_desc_ptr,
+	unsigned int mem_params_desc_num,
+	bl_params_t *next_bl_params_ptr);
 int get_bl_params_node_index(unsigned int image_id);
 bl_mem_params_node_t *get_bl_mem_params_node(unsigned int image_id);
 bl_load_info_t *get_bl_load_info_from_mem_params_desc(void);
diff --git a/plat/arm/css/drivers/mhu/css_mhu.h b/include/drivers/arm/css/css_mhu.h
similarity index 100%
rename from plat/arm/css/drivers/mhu/css_mhu.h
rename to include/drivers/arm/css/css_mhu.h
diff --git a/plat/arm/css/drivers/mhu/css_mhu_doorbell.h b/include/drivers/arm/css/css_mhu_doorbell.h
similarity index 100%
rename from plat/arm/css/drivers/mhu/css_mhu_doorbell.h
rename to include/drivers/arm/css/css_mhu_doorbell.h
diff --git a/plat/arm/css/drivers/scp/css_scp.h b/include/drivers/arm/css/css_scp.h
similarity index 100%
rename from plat/arm/css/drivers/scp/css_scp.h
rename to include/drivers/arm/css/css_scp.h
diff --git a/plat/arm/css/drivers/scpi/css_scpi.h b/include/drivers/arm/css/css_scpi.h
similarity index 100%
rename from plat/arm/css/drivers/scpi/css_scpi.h
rename to include/drivers/arm/css/css_scpi.h
diff --git a/plat/arm/css/drivers/scmi/scmi.h b/include/drivers/arm/css/scmi.h
similarity index 100%
rename from plat/arm/css/drivers/scmi/scmi.h
rename to include/drivers/arm/css/scmi.h
diff --git a/plat/arm/css/drivers/sds/sds.h b/include/drivers/arm/css/sds.h
similarity index 100%
rename from plat/arm/css/drivers/sds/sds.h
rename to include/drivers/arm/css/sds.h
diff --git a/plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.h b/include/drivers/arm/fvp/fvp_pwrc.h
similarity index 98%
rename from plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.h
rename to include/drivers/arm/fvp/fvp_pwrc.h
index 324f3e2..ca173f3 100644
--- a/plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.h
+++ b/include/drivers/arm/fvp/fvp_pwrc.h
@@ -37,6 +37,8 @@
 
 #ifndef __ASSEMBLY__
 
+#include <stdint.h>
+
 /*******************************************************************************
  * Function & variable prototypes
  ******************************************************************************/
diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h
index 2382697..72221ac 100644
--- a/include/drivers/arm/gicv3.h
+++ b/include/drivers/arm/gicv3.h
@@ -84,6 +84,7 @@
 #define GICR_PCPUBASE_SHIFT	0x11
 #define GICR_SGIBASE_OFFSET	U(65536)	/* 64 KB */
 #define GICR_CTLR		U(0x0)
+#define GICR_IIDR		U(0x04)
 #define GICR_TYPER		U(0x08)
 #define GICR_WAKER		U(0x14)
 #define GICR_PROPBASER		U(0x70)
diff --git a/include/drivers/rpi3/gpio/rpi3_gpio.h b/include/drivers/rpi3/gpio/rpi3_gpio.h
new file mode 100644
index 0000000..159a2e0
--- /dev/null
+++ b/include/drivers/rpi3/gpio/rpi3_gpio.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2019, Linaro Limited
+ * Copyright (c) 2019, Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RPI3_GPIO_H
+#define RPI3_GPIO_H
+
+#include <stdint.h>
+#include <drivers/gpio.h>
+
+struct rpi3_gpio_params {
+	uintptr_t       reg_base;
+};
+
+void rpi3_gpio_init(struct rpi3_gpio_params *params);
+int rpi3_gpio_get_select(int gpio);
+void rpi3_gpio_set_select(int gpio, int fsel);
+
+#define RPI3_GPIO_GPFSEL(n)	((n) * U(0x04))
+#define RPI3_GPIO_GPSET(n)	(((n) * U(0x04)) + U(0x1C))
+#define RPI3_GPIO_GPCLR(n)	(((n) * U(0x04)) + U(0x28))
+#define RPI3_GPIO_GPLEV(n) 	(((n) * U(0x04)) + U(0x34))
+#define RPI3_GPIO_GPPUD		U(0x94)
+#define RPI3_GPIO_GPPUDCLK(n)	(((n) * U(0x04)) + U(0x98))
+
+#define RPI3_GPIO_FUNC_INPUT	U(0)
+#define RPI3_GPIO_FUNC_OUTPUT	U(1)
+#define RPI3_GPIO_FUNC_ALT0	U(4)
+#define RPI3_GPIO_FUNC_ALT1	U(5)
+#define RPI3_GPIO_FUNC_ALT2	U(6)
+#define RPI3_GPIO_FUNC_ALT3	U(7)
+#define RPI3_GPIO_FUNC_ALT4	U(3)
+#define RPI3_GPIO_FUNC_ALT5	U(2)
+
+#endif  /* RPI3_GPIO_H */
diff --git a/include/drivers/st/bsec.h b/include/drivers/st/bsec.h
new file mode 100644
index 0000000..2171550
--- /dev/null
+++ b/include/drivers/st/bsec.h
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BSEC_H
+#define BSEC_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <lib/utils_def.h>
+
+/*
+ * IP configuration
+ */
+#define BSEC_OTP_MASK			GENMASK(4, 0)
+#define BSEC_OTP_BANK_SHIFT		5
+#define BSEC_TIMEOUT_VALUE		0xFFFF
+
+#define ADDR_LOWER_OTP_PERLOCK_SHIFT	0x03
+#define DATA_LOWER_OTP_PERLOCK_BIT	0x03U /* 2 significants bits are used */
+#define DATA_LOWER_OTP_PERLOCK_MASK	GENMASK(2, 0)
+#define ADDR_UPPER_OTP_PERLOCK_SHIFT	0x04
+#define DATA_UPPER_OTP_PERLOCK_BIT	0x01U /* 1 significants bits are used */
+#define DATA_UPPER_OTP_PERLOCK_MASK	GENMASK(3, 0)
+
+/*
+ * Return status
+ */
+#define BSEC_OK				0U
+#define BSEC_ERROR			0xFFFFFFFFU
+#define BSEC_DISTURBED			0xFFFFFFFEU
+#define BSEC_INVALID_PARAM		0xFFFFFFFCU
+#define BSEC_PROG_FAIL			0xFFFFFFFBU
+#define BSEC_LOCK_FAIL			0xFFFFFFFAU
+#define BSEC_WRITE_FAIL			0xFFFFFFF9U
+#define BSEC_SHADOW_FAIL		0xFFFFFFF8U
+#define BSEC_TIMEOUT			0xFFFFFFF7U
+
+/*
+ * BSEC REGISTER OFFSET (base relative)
+ */
+#define BSEC_OTP_CONF_OFF		0x000U
+#define BSEC_OTP_CTRL_OFF		0x004U
+#define BSEC_OTP_WRDATA_OFF		0x008U
+#define BSEC_OTP_STATUS_OFF		0x00CU
+#define BSEC_OTP_LOCK_OFF		0x010U
+#define BSEC_DEN_OFF			0x014U
+#define BSEC_DISTURBED_OFF		0x01CU
+#define BSEC_DISTURBED1_OFF		0x020U
+#define BSEC_DISTURBED2_OFF		0x024U
+#define BSEC_ERROR_OFF			0x034U
+#define BSEC_ERROR1_OFF			0x038U
+#define BSEC_ERROR2_OFF			0x03CU
+#define BSEC_WRLOCK_OFF			0x04CU /* Safmem permanent lock */
+#define BSEC_WRLOCK1_OFF		0x050U
+#define BSEC_WRLOCK2_OFF		0x054U
+#define BSEC_SPLOCK_OFF			0x064U /* Program safmem sticky lock */
+#define BSEC_SPLOCK1_OFF		0x068U
+#define BSEC_SPLOCK2_OFF		0x06CU
+#define BSEC_SWLOCK_OFF			0x07CU /* Write in OTP sticky lock */
+#define BSEC_SWLOCK1_OFF		0x080U
+#define BSEC_SWLOCK2_OFF		0x084U
+#define BSEC_SRLOCK_OFF			0x094U /* Shadowing sticky lock */
+#define BSEC_SRLOCK1_OFF		0x098U
+#define BSEC_SRLOCK2_OFF		0x09CU
+#define BSEC_JTAG_IN_OFF		0x0ACU
+#define BSEC_JTAG_OUT_OFF		0x0B0U
+#define BSEC_SCRATCH_OFF		0x0B4U
+#define BSEC_OTP_DATA_OFF		0x200U
+#define BSEC_IPHW_CFG_OFF		0xFF0U
+#define BSEC_IPVR_OFF			0xFF4U
+#define BSEC_IP_ID_OFF			0xFF8U
+#define BSEC_IP_MAGIC_ID_OFF		0xFFCU
+
+/*
+ * BSEC_CONFIGURATION Register
+ */
+#define BSEC_CONF_POWER_UP_MASK		BIT(0)
+#define BSEC_CONF_POWER_UP_SHIFT	0
+#define BSEC_CONF_FRQ_MASK		GENMASK(2, 1)
+#define BSEC_CONF_FRQ_SHIFT		1
+#define BSEC_CONF_PRG_WIDTH_MASK	GENMASK(6, 3)
+#define BSEC_CONF_PRG_WIDTH_SHIFT	3
+#define BSEC_CONF_TREAD_MASK		GENMASK(8, 7)
+#define BSEC_CONF_TREAD_SHIFT		7
+
+/*
+ * BSEC_CONTROL Register
+ */
+#define BSEC_READ			0x000U
+#define BSEC_WRITE			0x100U
+#define BSEC_LOCK			0x200U
+
+/*
+ * BSEC_OTP_LOCK register
+ */
+#define UPPER_OTP_LOCK_MASK		BIT(0)
+#define UPPER_OTP_LOCK_SHIFT		0
+#define DENREG_LOCK_MASK		BIT(2)
+#define DENREG_LOCK_SHIFT		2
+#define GPLOCK_LOCK_MASK		BIT(4)
+#define GPLOCK_LOCK_SHIFT		4
+
+/*
+ * BSEC_OTP_STATUS Register
+ */
+#define BSEC_MODE_STATUS_MASK		GENMASK(2, 0)
+#define BSEC_MODE_BUSY_MASK		BIT(3)
+#define BSEC_MODE_PROGFAIL_MASK		BIT(4)
+#define BSEC_MODE_PWR_MASK		BIT(5)
+#define BSEC_MODE_BIST1_LOCK_MASK	BIT(6)
+#define BSEC_MODE_BIST2_LOCK_MASK	BIT(7)
+
+/* OTP MODE*/
+#define BSEC_MODE_OPEN1			0x00
+#define BSEC_MODE_SECURED		0x01
+#define BSEC_MODE_OPEN2			0x02
+#define BSEC_MODE_INVALID		0x04
+
+/* BSEC_DENABLE Register */
+#define BSEC_HDPEN			BIT(4)
+#define BSEC_SPIDEN			BIT(5)
+#define BSEC_SPINDEN			BIT(6)
+#define BSEC_DBGSWGEN			BIT(10)
+#define BSEC_DEN_ALL_MSK		GENMASK(10, 0)
+
+/* BSEC_FENABLE Register */
+#define BSEC_FEN_ALL_MSK		GENMASK(14, 0)
+
+/*
+ * OTP Lock services definition
+ * Value must corresponding to the bit number in the register
+ */
+#define BSEC_LOCK_UPPER_OTP		0x00
+#define BSEC_LOCK_DEBUG			0x02
+#define BSEC_LOCK_PROGRAM		0x03
+
+/* Values for struct bsec_config::freq */
+#define FREQ_10_20_MHZ			0x0
+#define FREQ_20_30_MHZ			0x1
+#define FREQ_30_45_MHZ			0x2
+#define FREQ_45_67_MHZ			0x3
+
+/*
+ * Device info structure, providing device-specific functions and a means of
+ * adding driver-specific state
+ */
+struct bsec_config {
+	uint8_t tread;		/* SAFMEM Reading current level default 0 */
+	uint8_t pulse_width;	/* SAFMEM Programming pulse width default 1 */
+	uint8_t freq;		/* SAFMEM CLOCK see freq value define
+				 * default FREQ_45_67_MHZ
+				 */
+	uint8_t power;		/* Power up SAFMEM. 1 power up, 0 power off */
+	uint8_t prog_lock;	/* Programming Sticky lock
+				 * 1 programming is locked until next reset
+				 */
+	uint8_t den_lock;	/* Debug enable sticky lock
+				 * 1 debug enable is locked until next reset
+				 */
+	uint8_t upper_otp_lock;	/* Shadowing of upper OTP sticky lock
+				 * 1 shadowing of upper OTP is locked
+				 * until next reset
+				 */
+};
+
+uint32_t bsec_probe(void);
+uint32_t bsec_get_base(void);
+
+uint32_t bsec_set_config(struct bsec_config *cfg);
+uint32_t bsec_get_config(struct bsec_config *cfg);
+
+uint32_t bsec_shadow_register(uint32_t otp);
+uint32_t bsec_read_otp(uint32_t *val, uint32_t otp);
+uint32_t bsec_write_otp(uint32_t val, uint32_t otp);
+uint32_t bsec_program_otp(uint32_t val, uint32_t otp);
+uint32_t bsec_permanent_lock_otp(uint32_t otp);
+
+uint32_t bsec_write_debug_conf(uint32_t val);
+uint32_t bsec_read_debug_conf(void);
+uint32_t bsec_write_feature_conf(uint32_t val);
+uint32_t bsec_read_feature_conf(uint32_t *val);
+
+uint32_t bsec_get_status(void);
+uint32_t bsec_get_hw_conf(void);
+uint32_t bsec_get_version(void);
+uint32_t bsec_get_id(void);
+uint32_t bsec_get_magic_id(void);
+
+bool bsec_write_sr_lock(uint32_t otp, uint32_t value);
+bool bsec_read_sr_lock(uint32_t otp);
+bool bsec_write_sw_lock(uint32_t otp, uint32_t value);
+bool bsec_read_sw_lock(uint32_t otp);
+bool bsec_write_sp_lock(uint32_t otp, uint32_t value);
+bool bsec_read_sp_lock(uint32_t otp);
+bool bsec_wr_lock(uint32_t otp);
+uint32_t bsec_otp_lock(uint32_t service, uint32_t value);
+
+bool bsec_mode_is_closed_device(void);
+uint32_t bsec_shadow_read_otp(uint32_t *otp_value, uint32_t word);
+uint32_t bsec_check_nsec_access_rights(uint32_t otp);
+
+#endif /* BSEC_H */
diff --git a/include/drivers/st/stm32_gpio.h b/include/drivers/st/stm32_gpio.h
index acd95ec..4320eaf 100644
--- a/include/drivers/st/stm32_gpio.h
+++ b/include/drivers/st/stm32_gpio.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,10 +9,6 @@
 
 #include <lib/utils_def.h>
 
-#define STM32_GPIOA_BANK	U(0x50002000)
-#define STM32_GPIOZ_BANK	U(0x54004000)
-#define STM32_GPIO_BANK_OFFSET	U(0x1000)
-
 #define GPIO_MODE_OFFSET	U(0x00)
 #define GPIO_TYPE_OFFSET	U(0x04)
 #define GPIO_SPEED_OFFSET	U(0x08)
@@ -20,56 +16,14 @@
 #define GPIO_BSRR_OFFSET	U(0x18)
 #define GPIO_AFRL_OFFSET	U(0x20)
 #define GPIO_AFRH_OFFSET	U(0x24)
+#define GPIO_SECR_OFFSET	U(0x30)
 
 #define GPIO_ALT_LOWER_LIMIT	U(0x08)
 
-#define GPIO_BANK_A		U(0x00)
-#define GPIO_BANK_B		U(0x01)
-#define GPIO_BANK_C		U(0x02)
-#define GPIO_BANK_D		U(0x03)
-#define GPIO_BANK_E		U(0x04)
-#define GPIO_BANK_F		U(0x05)
-#define GPIO_BANK_G		U(0x06)
-#define GPIO_BANK_H		U(0x07)
-#define GPIO_BANK_I		U(0x08)
-#define GPIO_BANK_J		U(0x09)
-#define GPIO_BANK_K		U(0x0A)
-#define GPIO_BANK_Z		U(0x19)
+#define GPIO_PIN_(_x)		U(_x)
+#define GPIO_PIN_MAX		GPIO_PIN_(15)
 
-#define GPIO_PIN_0		U(0x00)
-#define GPIO_PIN_1		U(0x01)
-#define GPIO_PIN_2		U(0x02)
-#define GPIO_PIN_3		U(0x03)
-#define GPIO_PIN_4		U(0x04)
-#define GPIO_PIN_5		U(0x05)
-#define GPIO_PIN_6		U(0x06)
-#define GPIO_PIN_7		U(0x07)
-#define GPIO_PIN_8		U(0x08)
-#define GPIO_PIN_9		U(0x09)
-#define GPIO_PIN_10		U(0x0A)
-#define GPIO_PIN_11		U(0x0B)
-#define GPIO_PIN_12		U(0x0C)
-#define GPIO_PIN_13		U(0x0D)
-#define GPIO_PIN_14		U(0x0E)
-#define GPIO_PIN_15		U(0x0F)
-#define GPIO_PIN_MAX		GPIO_PIN_15
-
-#define GPIO_ALTERNATE_0	0x00
-#define GPIO_ALTERNATE_1	0x01
-#define GPIO_ALTERNATE_2	0x02
-#define GPIO_ALTERNATE_3	0x03
-#define GPIO_ALTERNATE_4	0x04
-#define GPIO_ALTERNATE_5	0x05
-#define GPIO_ALTERNATE_6	0x06
-#define GPIO_ALTERNATE_7	0x07
-#define GPIO_ALTERNATE_8	0x08
-#define GPIO_ALTERNATE_9	0x09
-#define GPIO_ALTERNATE_10	0x0A
-#define GPIO_ALTERNATE_11	0x0B
-#define GPIO_ALTERNATE_12	0x0C
-#define GPIO_ALTERNATE_13	0x0D
-#define GPIO_ALTERNATE_14	0x0E
-#define GPIO_ALTERNATE_15	0x0F
+#define GPIO_ALTERNATE_(_x)	U(_x)
 #define GPIO_ALTERNATE_MASK	U(0x0F)
 
 #define GPIO_MODE_INPUT		0x00
@@ -82,8 +36,8 @@
 
 #define GPIO_SPEED_LOW		0x00
 #define GPIO_SPEED_MEDIUM	0x01
-#define GPIO_SPEED_FAST		0x02
-#define GPIO_SPEED_HIGH		0x03
+#define GPIO_SPEED_HIGH		0x02
+#define GPIO_SPEED_VERY_HIGH	0x03
 #define GPIO_SPEED_MASK		U(0x03)
 
 #define GPIO_NO_PULL		0x00
@@ -94,8 +48,10 @@
 #ifndef __ASSEMBLY__
 #include <stdint.h>
 
+int dt_set_pinctrl_config(int node);
 void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed,
-	      uint32_t pull, uint32_t alternate);
+	      uint32_t pull, uint32_t alternate, uint8_t status);
+void set_gpio_secure_cfg(uint32_t bank, uint32_t pin, bool secure);
 #endif /*__ASSEMBLY__*/
 
 #endif /* STM32_GPIO_H */
diff --git a/include/drivers/st/stm32mp1_ddr.h b/include/drivers/st/stm32mp1_ddr.h
index 363e302..4ab37d6 100644
--- a/include/drivers/st/stm32mp1_ddr.h
+++ b/include/drivers/st/stm32mp1_ddr.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
@@ -153,7 +153,7 @@
 
 struct stm32mp1_ddr_info {
 	const char *name;
-	uint16_t speed; /* in MHZ */
+	uint32_t speed; /* in kHZ */
 	uint32_t size;  /* Memory size in byte = col * row * width */
 };
 
@@ -168,7 +168,7 @@
 	struct stm32mp1_ddrphy_cal p_cal;
 };
 
-int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint16_t mem_speed);
+int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed);
 void stm32mp1_ddr_init(struct ddr_info *priv,
 		       struct stm32mp1_ddr_config *config);
 #endif /* STM32MP1_DDR_H */
diff --git a/include/drivers/st/stm32mp1_ddr_regs.h b/include/drivers/st/stm32mp1_ddr_regs.h
index bfcd5e2..342239a 100644
--- a/include/drivers/st/stm32mp1_ddr_regs.h
+++ b/include/drivers/st/stm32mp1_ddr_regs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  */
@@ -247,11 +247,14 @@
 #define DDRCTRL_DBGSTAT				0x310
 #define DDRCTRL_SWCTL				0x320
 #define DDRCTRL_SWSTAT				0x324
+#define DDRCTRL_PSTAT				0x3FC
 #define DDRCTRL_PCTRL_0				0x490
 #define DDRCTRL_PCTRL_1				0x540
 
 /* DDR Controller Register fields */
 #define DDRCTRL_MSTR_DDR3			BIT(0)
+#define DDRCTRL_MSTR_LPDDR2			BIT(2)
+#define DDRCTRL_MSTR_LPDDR3			BIT(3)
 #define DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK	GENMASK(13, 12)
 #define DDRCTRL_MSTR_DATA_BUS_WIDTH_FULL	0
 #define DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF	BIT(12)
@@ -269,7 +272,7 @@
 /* Only one rank supported */
 #define DDRCTRL_MRCTRL0_MR_RANK_SHIFT		4
 #define DDRCTRL_MRCTRL0_MR_RANK_ALL \
-		(0x1U << DDRCTRL_MRCTRL0_MR_RANK_SHIFT)
+					BIT(DDRCTRL_MRCTRL0_MR_RANK_SHIFT)
 #define DDRCTRL_MRCTRL0_MR_ADDR_SHIFT		12
 #define DDRCTRL_MRCTRL0_MR_ADDR_MASK		GENMASK(15, 12)
 #define DDRCTRL_MRCTRL0_MR_WR			BIT(31)
@@ -367,6 +370,7 @@
 
 #define DDRPHYC_DLLGCR_BPS200			BIT(23)
 
+#define DDRPHYC_ACDLLCR_DLLSRST			BIT(30)
 #define DDRPHYC_ACDLLCR_DLLDIS			BIT(31)
 
 #define DDRPHYC_PTR0_TDLLSRST_OFFSET		0
diff --git a/include/drivers/st/stm32mp1_rcc.h b/include/drivers/st/stm32mp1_rcc.h
index fd406c5..2f29e84 100644
--- a/include/drivers/st/stm32mp1_rcc.h
+++ b/include/drivers/st/stm32mp1_rcc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -68,6 +68,14 @@
 #define RCC_MP_AHB6ENCLRR		U(0x21C)
 #define RCC_MP_TZAHB6ENSETR		U(0x220)
 #define RCC_MP_TZAHB6ENCLRR		U(0x224)
+#define RCC_MC_APB4ENSETR		U(0x280)
+#define RCC_MC_APB4ENCLRR		U(0x284)
+#define RCC_MC_APB5ENSETR		U(0x288)
+#define RCC_MC_APB5ENCLRR		U(0x28C)
+#define RCC_MC_AHB5ENSETR		U(0x290)
+#define RCC_MC_AHB5ENCLRR		U(0x294)
+#define RCC_MC_AHB6ENSETR		U(0x298)
+#define RCC_MC_AHB6ENCLRR		U(0x29C)
 #define RCC_MP_APB4LPENSETR		U(0x300)
 #define RCC_MP_APB4LPENCLRR		U(0x304)
 #define RCC_MP_APB5LPENSETR		U(0x308)
@@ -78,6 +86,14 @@
 #define RCC_MP_AHB6LPENCLRR		U(0x31C)
 #define RCC_MP_TZAHB6LPENSETR		U(0x320)
 #define RCC_MP_TZAHB6LPENCLRR		U(0x324)
+#define RCC_MC_APB4LPENSETR		U(0x380)
+#define RCC_MC_APB4LPENCLRR		U(0x384)
+#define RCC_MC_APB5LPENSETR		U(0x388)
+#define RCC_MC_APB5LPENCLRR		U(0x38C)
+#define RCC_MC_AHB5LPENSETR		U(0x390)
+#define RCC_MC_AHB5LPENCLRR		U(0x394)
+#define RCC_MC_AHB6LPENSETR		U(0x398)
+#define RCC_MC_AHB6LPENCLRR		U(0x39C)
 #define RCC_BR_RSTSCLRR			U(0x400)
 #define RCC_MP_GRSTCSETR		U(0x404)
 #define RCC_MP_RSTSCLRR			U(0x408)
@@ -162,6 +178,22 @@
 #define RCC_MP_AHB4ENCLRR		U(0xA2C)
 #define RCC_MP_MLAHBENSETR		U(0xA38)
 #define RCC_MP_MLAHBENCLRR		U(0xA3C)
+#define RCC_MC_APB1ENSETR		U(0xA80)
+#define RCC_MC_APB1ENCLRR		U(0xA84)
+#define RCC_MC_APB2ENSETR		U(0xA88)
+#define RCC_MC_APB2ENCLRR		U(0xA8C)
+#define RCC_MC_APB3ENSETR		U(0xA90)
+#define RCC_MC_APB3ENCLRR		U(0xA94)
+#define RCC_MC_AHB2ENSETR		U(0xA98)
+#define RCC_MC_AHB2ENCLRR		U(0xA9C)
+#define RCC_MC_AHB3ENSETR		U(0xAA0)
+#define RCC_MC_AHB3ENCLRR		U(0xAA4)
+#define RCC_MC_AHB4ENSETR		U(0xAA8)
+#define RCC_MC_AHB4ENCLRR		U(0xAAC)
+#define RCC_MC_AXIMENSETR		U(0xAB0)
+#define RCC_MC_AXIMENCLRR		U(0xAB4)
+#define RCC_MC_MLAHBENSETR		U(0xAB8)
+#define RCC_MC_MLAHBENCLRR		U(0xABC)
 #define RCC_MP_APB1LPENSETR		U(0xB00)
 #define RCC_MP_APB1LPENCLRR		U(0xB04)
 #define RCC_MP_APB2LPENSETR		U(0xB08)
@@ -178,10 +210,31 @@
 #define RCC_MP_AXIMLPENCLRR		U(0xB34)
 #define RCC_MP_MLAHBLPENSETR		U(0xB38)
 #define RCC_MP_MLAHBLPENCLRR		U(0xB3C)
+#define RCC_MC_APB1LPENSETR		U(0xB80)
+#define RCC_MC_APB1LPENCLRR		U(0xB84)
+#define RCC_MC_APB2LPENSETR		U(0xB88)
+#define RCC_MC_APB2LPENCLRR		U(0xB8C)
+#define RCC_MC_APB3LPENSETR		U(0xB90)
+#define RCC_MC_APB3LPENCLRR		U(0xB94)
+#define RCC_MC_AHB2LPENSETR		U(0xB98)
+#define RCC_MC_AHB2LPENCLRR		U(0xB9C)
+#define RCC_MC_AHB3LPENSETR		U(0xBA0)
+#define RCC_MC_AHB3LPENCLRR		U(0xBA4)
+#define RCC_MC_AHB4LPENSETR		U(0xBA8)
+#define RCC_MC_AHB4LPENCLRR		U(0xBAC)
+#define RCC_MC_AXIMLPENSETR		U(0xBB0)
+#define RCC_MC_AXIMLPENCLRR		U(0xBB4)
+#define RCC_MC_MLAHBLPENSETR		U(0xBB8)
+#define RCC_MC_MLAHBLPENCLRR		U(0xBBC)
+#define RCC_MC_RSTSCLRR			U(0xC00)
+#define RCC_MC_CIER			U(0xC14)
+#define RCC_MC_CIFR			U(0xC18)
 #define RCC_VERR			U(0xFF4)
 #define RCC_IDR				U(0xFF8)
 #define RCC_SIDR			U(0xFFC)
 
+#define RCC_OFFSET_MASK			GENMASK(11, 0)
+
 /* Values for RCC_TZCR register */
 #define RCC_TZCR_TZEN			BIT(0)
 
@@ -221,6 +274,9 @@
 #define RCC_MPUDIV_MASK			GENMASK(2, 0)
 #define RCC_AXIDIV_MASK			GENMASK(2, 0)
 
+/* Used for TIMER Prescaler */
+#define RCC_TIMGXPRER_TIMGXPRE		BIT(0)
+
 /* Offset between RCC_MP_xxxENSETR and RCC_MP_xxxENCLRR registers */
 #define RCC_MP_ENCLRR_OFFSET		U(4)
 
@@ -228,6 +284,7 @@
 #define RCC_BDCR_LSEON			BIT(0)
 #define RCC_BDCR_LSEBYP			BIT(1)
 #define RCC_BDCR_LSERDY			BIT(2)
+#define RCC_BDCR_DIGBYP			BIT(3)
 #define RCC_BDCR_LSEDRV_MASK		GENMASK(5, 4)
 #define RCC_BDCR_LSEDRV_SHIFT		4
 #define RCC_BDCR_LSECSSON		BIT(8)
@@ -243,6 +300,7 @@
 /* Used for all RCC_PLL<n>CR registers */
 #define RCC_PLLNCR_PLLON		BIT(0)
 #define RCC_PLLNCR_PLLRDY		BIT(1)
+#define RCC_PLLNCR_SSCG_CTRL		BIT(2)
 #define RCC_PLLNCR_DIVPEN		BIT(4)
 #define RCC_PLLNCR_DIVQEN		BIT(5)
 #define RCC_PLLNCR_DIVREN		BIT(6)
@@ -281,8 +339,12 @@
 
 /* Used for RCC_OCENSETR and RCC_OCENCLRR registers */
 #define RCC_OCENR_HSION			BIT(0)
+#define RCC_OCENR_HSIKERON		BIT(1)
 #define RCC_OCENR_CSION			BIT(4)
+#define RCC_OCENR_CSIKERON		BIT(5)
+#define RCC_OCENR_DIGBYP		BIT(7)
 #define RCC_OCENR_HSEON			BIT(8)
+#define RCC_OCENR_HSEKERON		BIT(9)
 #define RCC_OCENR_HSEBYP		BIT(10)
 #define RCC_OCENR_HSECSSON		BIT(11)
 
@@ -319,6 +381,16 @@
 
 /* Fields of RCC_HSICFGR register */
 #define RCC_HSICFGR_HSIDIV_MASK		GENMASK(1, 0)
+#define RCC_HSICFGR_HSITRIM_SHIFT	8
+#define RCC_HSICFGR_HSITRIM_MASK	GENMASK(14, 8)
+#define RCC_HSICFGR_HSICAL_SHIFT	16
+#define RCC_HSICFGR_HSICAL_MASK		GENMASK(27, 16)
+
+/* Fields of RCC_CSICFGR register */
+#define RCC_CSICFGR_CSITRIM_SHIFT	8
+#define RCC_CSICFGR_CSITRIM_MASK	GENMASK(12, 8)
+#define RCC_CSICFGR_CSICAL_SHIFT	16
+#define RCC_CSICFGR_CSICAL_MASK		GENMASK(23, 16)
 
 /* Used for RCC_MCO related operations */
 #define RCC_MCOCFG_MCOON		BIT(12)
@@ -330,22 +402,36 @@
 #define RCC_DBGCFGR_DBGCKEN		BIT(8)
 
 /* RCC register fields for reset reasons */
-#define  RCC_MP_RSTSCLRR_PORRSTF	BIT(0)
-#define  RCC_MP_RSTSCLRR_BORRSTF	BIT(1)
-#define  RCC_MP_RSTSCLRR_PADRSTF	BIT(2)
-#define  RCC_MP_RSTSCLRR_HCSSRSTF	BIT(3)
-#define  RCC_MP_RSTSCLRR_VCORERSTF	BIT(4)
-#define  RCC_MP_RSTSCLRR_MPSYSRSTF	BIT(6)
-#define  RCC_MP_RSTSCLRR_IWDG1RSTF	BIT(8)
-#define  RCC_MP_RSTSCLRR_IWDG2RSTF	BIT(9)
-#define  RCC_MP_RSTSCLRR_STDBYRSTF	BIT(11)
-#define  RCC_MP_RSTSCLRR_CSTDBYRSTF	BIT(12)
+#define RCC_MP_RSTSCLRR_PORRSTF		BIT(0)
+#define RCC_MP_RSTSCLRR_BORRSTF		BIT(1)
+#define RCC_MP_RSTSCLRR_PADRSTF		BIT(2)
+#define RCC_MP_RSTSCLRR_HCSSRSTF	BIT(3)
+#define RCC_MP_RSTSCLRR_VCORERSTF	BIT(4)
+#define RCC_MP_RSTSCLRR_MPSYSRSTF	BIT(6)
+#define RCC_MP_RSTSCLRR_MCSYSRSTF	BIT(7)
+#define RCC_MP_RSTSCLRR_IWDG1RSTF	BIT(8)
+#define RCC_MP_RSTSCLRR_IWDG2RSTF	BIT(9)
+#define RCC_MP_RSTSCLRR_STDBYRSTF	BIT(11)
+#define RCC_MP_RSTSCLRR_CSTDBYRSTF	BIT(12)
+#define RCC_MP_RSTSCLRR_MPUP0RSTF	BIT(13)
+#define RCC_MP_RSTSCLRR_MPUP1RSTF	BIT(14)
 
 /* Global Reset Register */
 #define RCC_MP_GRSTCSETR_MPSYSRST	BIT(0)
+#define RCC_MP_GRSTCSETR_MPUP0RST	BIT(4)
+#define RCC_MP_GRSTCSETR_MPUP1RST	BIT(5)
 
 /* Clock Source Interrupt Flag Register */
 #define RCC_MP_CIFR_MASK		U(0x110F1F)
+#define RCC_MP_CIFR_LSIRDYF		BIT(0)
+#define RCC_MP_CIFR_LSERDYF		BIT(1)
+#define RCC_MP_CIFR_HSIRDYF		BIT(2)
+#define RCC_MP_CIFR_HSERDYF		BIT(3)
+#define RCC_MP_CIFR_CSIRDYF		BIT(4)
+#define RCC_MP_CIFR_PLL1DYF		BIT(8)
+#define RCC_MP_CIFR_PLL2DYF		BIT(9)
+#define RCC_MP_CIFR_PLL3DYF		BIT(10)
+#define RCC_MP_CIFR_PLL4DYF		BIT(11)
 #define RCC_MP_CIFR_WKUPF		BIT(20)
 
 /* Stop Request Set Register */
@@ -362,7 +448,29 @@
 /* Values of RCC_MP_APB1ENSETR register */
 #define RCC_MP_APB1ENSETR_UART4EN	BIT(16)
 
+/* Values of RCC_MP_APB5ENSETR register */
+#define RCC_MP_APB5ENSETR_SPI6EN	BIT(0)
+#define RCC_MP_APB5ENSETR_I2C4EN	BIT(2)
+#define RCC_MP_APB5ENSETR_I2C6EN	BIT(3)
+#define RCC_MP_APB5ENSETR_USART1EN	BIT(4)
+#define RCC_MP_APB5ENSETR_RTCAPBEN	BIT(8)
+#define RCC_MP_APB5ENSETR_IWDG1APBEN	BIT(15)
+
 /* Values of RCC_MP_AHB4ENSETR register */
 #define RCC_MP_AHB4ENSETR_GPIOGEN	BIT(6)
+#define RCC_MP_AHB4ENSETR_GPIOHEN	BIT(7)
+
+/* Values of RCC_MP_AHB5ENSETR register */
+#define RCC_MP_AHB5ENSETR_GPIOZEN	BIT(0)
+#define RCC_MP_AHB5ENSETR_CRYP1EN	BIT(4)
+#define RCC_MP_AHB5ENSETR_HASH1EN	BIT(5)
+#define RCC_MP_AHB5ENSETR_RNG1EN	BIT(6)
+
+/* Values of RCC_MP_IWDGFZSETR register */
+#define RCC_MP_IWDGFZSETR_IWDG1		BIT(0)
+#define RCC_MP_IWDGFZSETR_IWDG2		BIT(1)
+
+/* Values of RCC_PWRLPDLYCR register */
+#define RCC_PWRLPDLYCR_PWRLP_DLY_MASK	GENMASK(21, 0)
 
 #endif /* STM32MP1_RCC_H */
diff --git a/include/drivers/st/stm32mp1_pmic.h b/include/drivers/st/stm32mp_pmic.h
similarity index 67%
rename from include/drivers/st/stm32mp1_pmic.h
rename to include/drivers/st/stm32mp_pmic.h
index 75f8e61..700039b 100644
--- a/include/drivers/st/stm32mp1_pmic.h
+++ b/include/drivers/st/stm32mp_pmic.h
@@ -1,11 +1,11 @@
 /*
- * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef STM32MP1_PMIC_H
-#define STM32MP1_PMIC_H
+#ifndef STM32MP_PMIC_H
+#define STM32MP_PMIC_H
 
 #include <stdbool.h>
 
@@ -17,4 +17,4 @@
 void initialize_pmic(void);
 int pmic_ddr_power_init(enum ddr_type ddr_type);
 
-#endif /* STM32MP1_PMIC_H */
+#endif /* STM32MP_PMIC_H */
diff --git a/include/drivers/st/stpmu1.h b/include/drivers/st/stpmic1.h
similarity index 70%
rename from include/drivers/st/stpmu1.h
rename to include/drivers/st/stpmic1.h
index e75d9a6..f7e293b 100644
--- a/include/drivers/st/stpmu1.h
+++ b/include/drivers/st/stpmic1.h
@@ -1,11 +1,11 @@
 /*
- * Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef STPMU1_H
-#define STPMU1_H
+#ifndef STPMIC1_H
+#define STPMIC1_H
 
 #include <drivers/st/stm32_i2c.h>
 #include <lib/utils_def.h>
@@ -84,18 +84,40 @@
 #define ITSOURCE2_REG			0xB1U
 #define ITSOURCE3_REG			0xB2U
 #define ITSOURCE4_REG			0xB3U
+
+/* Registers masks */
 #define LDO_VOLTAGE_MASK		0x7CU
 #define BUCK_VOLTAGE_MASK		0xFCU
 #define LDO_BUCK_VOLTAGE_SHIFT		2
-#define LDO_ENABLE_MASK			0x01U
-#define BUCK_ENABLE_MASK		0x01U
-#define BUCK_HPLP_ENABLE_MASK		0x02U
-#define LDO_HPLP_ENABLE_MASK		0x02U
+#define LDO_BUCK_ENABLE_MASK		0x01U
+#define LDO_BUCK_HPLP_ENABLE_MASK	0x02U
 #define LDO_BUCK_HPLP_SHIFT		1
 #define LDO_BUCK_RANK_MASK		0x01U
 #define LDO_BUCK_RESET_MASK		0x01U
 #define LDO_BUCK_PULL_DOWN_MASK		0x03U
 
+/* Pull down register */
+#define BUCK1_PULL_DOWN_SHIFT		0
+#define BUCK2_PULL_DOWN_SHIFT		2
+#define BUCK3_PULL_DOWN_SHIFT		4
+#define BUCK4_PULL_DOWN_SHIFT		6
+#define VREF_DDR_PULL_DOWN_SHIFT	4
+
+/* Buck Mask reset register */
+#define BUCK1_MASK_RESET		0
+#define BUCK2_MASK_RESET		1
+#define BUCK3_MASK_RESET		2
+#define BUCK4_MASK_RESET		3
+
+/* LDO Mask reset register */
+#define LDO1_MASK_RESET			0
+#define LDO2_MASK_RESET			1
+#define LDO3_MASK_RESET			2
+#define LDO4_MASK_RESET			3
+#define LDO5_MASK_RESET			4
+#define LDO6_MASK_RESET			5
+#define VREF_DDR_MASK_RESET		6
+
 /* Main PMIC Control Register (MAIN_CONTROL_REG) */
 #define ICC_EVENT_ENABLED		BIT(4)
 #define PWRCTRL_POLARITY_HIGH		BIT(3)
@@ -127,14 +149,21 @@
 #define SWIN_SWOUT_ENABLED		BIT(2)
 #define USBSW_OTG_SWITCH_ENABLED	BIT(1)
 
-int stpmu1_switch_off(void);
-int stpmu1_register_read(uint8_t register_id, uint8_t *value);
-int stpmu1_register_write(uint8_t register_id, uint8_t value);
-int stpmu1_register_update(uint8_t register_id, uint8_t value, uint8_t mask);
-int stpmu1_regulator_enable(const char *name);
-int stpmu1_regulator_disable(const char *name);
-uint8_t stpmu1_is_regulator_enabled(const char *name);
-int stpmu1_regulator_voltage_set(const char *name, uint16_t millivolts);
-void stpmu1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr);
+int stpmic1_powerctrl_on(void);
+int stpmic1_switch_off(void);
+int stpmic1_register_read(uint8_t register_id, uint8_t *value);
+int stpmic1_register_write(uint8_t register_id, uint8_t value);
+int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask);
+int stpmic1_regulator_enable(const char *name);
+int stpmic1_regulator_disable(const char *name);
+uint8_t stpmic1_is_regulator_enabled(const char *name);
+int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts);
+int stpmic1_regulator_voltage_get(const char *name);
+int stpmic1_regulator_pull_down_set(const char *name);
+int stpmic1_regulator_mask_reset_set(const char *name);
+void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr);
+
+int stpmic1_get_version(unsigned long *version);
+void stpmic1_dump_regulators(void);
 
-#endif /* STPMU1_H */
+#endif /* STPMIC1_H */
diff --git a/include/dt-bindings/interrupt-controller/arm-gic.h b/include/dt-bindings/interrupt-controller/arm-gic.h
new file mode 100644
index 0000000..aa9158c
--- /dev/null
+++ b/include/dt-bindings/interrupt-controller/arm-gic.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
+/*
+ * This header provides constants for the ARM GIC.
+ */
+
+#ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_ARM_GIC_H
+#define _DT_BINDINGS_INTERRUPT_CONTROLLER_ARM_GIC_H
+
+/* interrupt specifier cell 0 */
+
+#define GIC_SPI 0
+#define GIC_PPI 1
+
+#define IRQ_TYPE_NONE		0
+#define IRQ_TYPE_EDGE_RISING	1
+#define IRQ_TYPE_EDGE_FALLING	2
+#define IRQ_TYPE_EDGE_BOTH	(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)
+#define IRQ_TYPE_LEVEL_HIGH	4
+#define IRQ_TYPE_LEVEL_LOW	8
+
+#endif
diff --git a/include/dt-bindings/pinctrl/stm32-pinfunc.h b/include/dt-bindings/pinctrl/stm32-pinfunc.h
index e2f1f1b..7f6e4b9 100644
--- a/include/dt-bindings/pinctrl/stm32-pinfunc.h
+++ b/include/dt-bindings/pinctrl/stm32-pinfunc.h
@@ -32,4 +32,10 @@
 
 #define STM32_PINMUX(port, line, mode) (((PIN_NO(port, line)) << 8) | (mode))
 
+/*  package information */
+#define STM32MP157CAA	0x1
+#define STM32MP157CAB	0x2
+#define STM32MP157CAC	0x4
+#define STM32MP157CAD	0x8
+
 #endif /* _DT_BINDINGS_STM32_PINFUNC_H */
diff --git a/include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h b/include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h
index a333d1e..30eb5e9 100644
--- a/include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h
+++ b/include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h
@@ -63,8 +63,7 @@
  * is 1.
  *
  * Note that this macro assumes that the given virtual address space size is
- * valid. Therefore, the caller is expected to check it is the case using the
- * CHECK_VIRT_ADDR_SPACE_SIZE() macro first.
+ * valid.
  */
 #define GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_sz)			\
 	(((_virt_addr_space_sz) > (ULL(1) << L1_XLAT_ADDRESS_SHIFT)) ?	\
diff --git a/include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h b/include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h
index cc5624c..3014c8f 100644
--- a/include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h
+++ b/include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h
@@ -43,14 +43,22 @@
  * state.
  *
  * TCR.TxSZ is calculated as 64 minus the width of said address space.
- * The value of TCR.TxSZ must be in the range 16 to 39 [1], which means that
- * the virtual address space width must be in the range 48 to 25 bits.
+ * The value of TCR.TxSZ must be in the range 16 to 39 [1] or 48 [2],
+ * depending on Small Translation Table Support which means that
+ * the virtual address space width must be in the range 48 to 25 or 16 bits.
  *
  * [1] See the ARMv8-A Architecture Reference Manual (DDI 0487A.j) for more
  * information:
  * Page 1730: 'Input address size', 'For all translation stages'.
+ * [2] See section 12.2.55 in the ARMv8-A Architecture Reference Manual
+ * (DDI 0487D.a)
  */
+/* Maximum value of TCR_ELx.T(0,1)SZ is 39 */
 #define MIN_VIRT_ADDR_SPACE_SIZE	(ULL(1) << (U(64) - TCR_TxSZ_MAX))
+
+/* Maximum value of TCR_ELx.T(0,1)SZ is 48 */
+#define MIN_VIRT_ADDR_SPACE_SIZE_TTST	\
+				(ULL(1) << (U(64) - TCR_TxSZ_MAX_TTST))
 #define MAX_VIRT_ADDR_SPACE_SIZE	(ULL(1) << (U(64) - TCR_TxSZ_MIN))
 
 /*
@@ -58,9 +66,13 @@
  * virtual address space size. For a 4 KB page size,
  * - level 0 supports virtual address spaces of widths 48 to 40 bits;
  * - level 1 from 39 to 31;
- * - level 2 from 30 to 25.
+ * - level 2 from 30 to 22.
+ * - level 3 from 21 to 16.
  *
- * Wider or narrower address spaces are not supported. As a result, level 3
+ * Small Translation Table (Armv8.4-TTST) support allows the starting level
+ * of the translation table from 3 for 4KB granularity. See section 12.2.55 in
+ * the ARMv8-A Architecture Reference Manual (DDI 0487D.a). In Armv8.3 and below
+ * wider or narrower address spaces are not supported. As a result, level 3
  * cannot be used as initial lookup level with 4 KB granularity. See section
  * D4.2.5 in the ARMv8-A Architecture Reference Manual (DDI 0487A.j) for more
  * information.
@@ -71,13 +83,14 @@
  * is 1.
  *
  * Note that this macro assumes that the given virtual address space size is
- * valid. Therefore, the caller is expected to check it is the case using the
- * CHECK_VIRT_ADDR_SPACE_SIZE() macro first.
+ * valid.
  */
 #define GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_sz)		\
 	(((_virt_addr_space_sz) > (ULL(1) << L0_XLAT_ADDRESS_SHIFT))	\
 	? 0U								\
-	 : (((_virt_addr_space_sz) > (ULL(1) << L1_XLAT_ADDRESS_SHIFT))	\
-	 ? 1U : 2U))
+	: (((_virt_addr_space_sz) > (ULL(1) << L1_XLAT_ADDRESS_SHIFT))	\
+	? 1U								\
+	: (((_virt_addr_space_sz) > (ULL(1) << L2_XLAT_ADDRESS_SHIFT))	\
+	? 2U : 3U)))
 
 #endif /* XLAT_TABLES_AARCH64_H */
diff --git a/include/lib/xlat_tables/xlat_tables_arch.h b/include/lib/xlat_tables/xlat_tables_arch.h
index 251b020..7237534 100644
--- a/include/lib/xlat_tables/xlat_tables_arch.h
+++ b/include/lib/xlat_tables/xlat_tables_arch.h
@@ -14,18 +14,6 @@
 #endif
 
 /*
- * Evaluates to 1 if the given virtual address space size is valid, or 0 if it's
- * not.
- *
- * A valid size is one that is a power of 2 and is within the architectural
- * limits. Not that these limits are different for AArch32 and AArch64.
- */
-#define CHECK_VIRT_ADDR_SPACE_SIZE(size)			\
-	(((unsigned long long)(size) >= MIN_VIRT_ADDR_SPACE_SIZE) &&	\
-	((unsigned long long)(size) <= MAX_VIRT_ADDR_SPACE_SIZE) &&	\
-	IS_POWER_OF_TWO(size))
-
-/*
  * Evaluates to 1 if the given physical address space size is a power of 2,
  * or 0 if it's not.
  */
diff --git a/include/lib/xlat_tables/xlat_tables_v2_helpers.h b/include/lib/xlat_tables/xlat_tables_v2_helpers.h
index ce5cf82..6a1be32 100644
--- a/include/lib/xlat_tables/xlat_tables_v2_helpers.h
+++ b/include/lib/xlat_tables/xlat_tables_v2_helpers.h
@@ -125,9 +125,6 @@
 #define REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, _mmap_count,		\
 			_xlat_tables_count, _virt_addr_space_size,	\
 			_phy_addr_space_size, _xlat_regime, _section_name)\
-	CASSERT(CHECK_VIRT_ADDR_SPACE_SIZE(_virt_addr_space_size),	\
-		assert_invalid_virtual_addr_space_size_for_##_ctx_name);\
-									\
 	CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(_phy_addr_space_size),	\
 		assert_invalid_physical_addr_space_sizefor_##_ctx_name);\
 									\
diff --git a/include/plat/arm/board/common/board_css_def.h b/include/plat/arm/board/common/board_css_def.h
index 6cca389..a77ea96 100644
--- a/include/plat/arm/board/common/board_css_def.h
+++ b/include/plat/arm/board/common/board_css_def.h
@@ -8,11 +8,10 @@
 #define BOARD_CSS_DEF_H
 
 #include <lib/utils_def.h>
+#include <plat/arm/board/common/v2m_def.h>
+#include <plat/arm/soc/common/soc_css_def.h>
 #include <plat/common/common_def.h>
 
-#include <soc_css_def.h>
-#include <v2m_def.h>
-
 /*
  * Definitions common to all ARM CSS-based development platforms
  */
diff --git a/include/plat/arm/board/common/v2m_def.h b/include/plat/arm/board/common/v2m_def.h
index c5de407..6a6979c 100644
--- a/include/plat/arm/board/common/v2m_def.h
+++ b/include/plat/arm/board/common/v2m_def.h
@@ -6,7 +6,7 @@
 #ifndef V2M_DEF_H
 #define V2M_DEF_H
 
-#include <lib/xlat_tables/xlat_tables_compat.h>
+#include <lib/utils_def.h>
 
 /* V2M motherboard system registers & offsets */
 #define V2M_SYSREGS_BASE		UL(0x1c010000)
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 4e9c70a..62623c1 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -6,8 +6,6 @@
 #ifndef ARM_DEF_H
 #define ARM_DEF_H
 
-#include <platform_def.h>
-
 #include <arch.h>
 #include <common/interrupt_props.h>
 #include <common/tbbr/tbbr_img_def.h>
@@ -350,7 +348,20 @@
  * and limit. Leave enough space of BL2 meminfo.
  */
 #define ARM_TB_FW_CONFIG_BASE		(ARM_BL_RAM_BASE + sizeof(meminfo_t))
-#define ARM_TB_FW_CONFIG_LIMIT		(ARM_BL_RAM_BASE + PAGE_SIZE)
+#define ARM_TB_FW_CONFIG_LIMIT		(ARM_BL_RAM_BASE + (PAGE_SIZE / 2U))
+
+/*
+ * Boot parameters passed from BL2 to BL31/BL32 are stored here
+ */
+#define ARM_BL2_MEM_DESC_BASE		ARM_TB_FW_CONFIG_LIMIT
+#define ARM_BL2_MEM_DESC_LIMIT		(ARM_BL2_MEM_DESC_BASE +	\
+							(PAGE_SIZE / 2U))
+
+/*
+ * Define limit of firmware configuration memory:
+ * ARM_TB_FW_CONFIG + ARM_BL2_MEM_DESC memory
+ */
+#define ARM_FW_CONFIG_LIMIT		(ARM_BL_RAM_BASE + PAGE_SIZE)
 
 /*******************************************************************************
  * BL1 specific defines.
@@ -445,7 +456,7 @@
  * SP_MIN is the only BL image in SRAM. Allocate the whole of SRAM (excluding
  * the page reserved for fw_configs) to BL32
  */
-#  define BL32_BASE			ARM_TB_FW_CONFIG_LIMIT
+#  define BL32_BASE			ARM_FW_CONFIG_LIMIT
 #  define BL32_LIMIT			(ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)
 # else
 /* Put BL32 below BL2 in the Trusted SRAM.*/
@@ -483,7 +494,7 @@
 #  define TSP_SEC_MEM_BASE		ARM_BL_RAM_BASE
 #  define TSP_SEC_MEM_SIZE		ARM_BL_RAM_SIZE
 #  define TSP_PROGBITS_LIMIT		BL31_BASE
-#  define BL32_BASE			ARM_TB_FW_CONFIG_LIMIT
+#  define BL32_BASE			ARM_FW_CONFIG_LIMIT
 #  define BL32_LIMIT			BL31_BASE
 # elif ARM_TSP_RAM_LOCATION_ID == ARM_TRUSTED_DRAM_ID
 #  define TSP_SEC_MEM_BASE		PLAT_ARM_TRUSTED_DRAM_BASE
diff --git a/include/plat/arm/common/arm_spm_def.h b/include/plat/arm/common/arm_spm_def.h
index bdcbc96..16c806b 100644
--- a/include/plat/arm/common/arm_spm_def.h
+++ b/include/plat/arm/common/arm_spm_def.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
  */
@@ -9,8 +9,6 @@
 #include <lib/utils_def.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
 
-#include <arm_def.h>
-
 /*
  * Reserve 4 MiB for binaries of Secure Partitions and Resource Description
  * blobs.
@@ -34,7 +32,7 @@
 #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_DEPRECATED
+#if SPM_MM
 
 /*
  * If BL31 is placed in DRAM, place the Secure Partition in DRAM right after the
@@ -88,12 +86,12 @@
  * requests. Mapped as RW and NS. Placed after the shared memory between EL3 and
  * S-EL0.
  */
-#define ARM_SP_IMAGE_NS_BUF_BASE	(PLAT_SPM_BUF_BASE + PLAT_SPM_BUF_SIZE)
-#define ARM_SP_IMAGE_NS_BUF_SIZE	ULL(0x10000)
+#define PLAT_SP_IMAGE_NS_BUF_BASE	(PLAT_SPM_BUF_BASE + PLAT_SPM_BUF_SIZE)
+#define PLAT_SP_IMAGE_NS_BUF_SIZE	ULL(0x10000)
 #define ARM_SP_IMAGE_NS_BUF_MMAP	MAP_REGION2(				\
-						ARM_SP_IMAGE_NS_BUF_BASE,	\
-						ARM_SP_IMAGE_NS_BUF_BASE,	\
-						ARM_SP_IMAGE_NS_BUF_SIZE,	\
+						PLAT_SP_IMAGE_NS_BUF_BASE,	\
+						PLAT_SP_IMAGE_NS_BUF_BASE,	\
+						PLAT_SP_IMAGE_NS_BUF_SIZE,	\
 						MT_RW_DATA | MT_NS | MT_USER,	\
 						PAGE_SIZE)
 
@@ -123,7 +121,7 @@
 /* Total number of memory regions with distinct properties */
 #define ARM_SP_IMAGE_NUM_MEM_REGIONS	6
 
-#endif /* SPM_DEPRECATED */
+#endif /* SPM_MM */
 
 /* Cookies passed to the Secure Partition at boot. Not used by ARM platforms. */
 #define PLAT_SPM_COOKIE_0		ULL(0)
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 6281608..9d6786f 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.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
  */
@@ -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_DEPRECATED
+#if ENABLE_SPM && SPM_MM
 #define ARM_TZC_REGIONS_DEF						\
 	{ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END,			\
 		TZC_REGION_S_RDWR, 0},					\
@@ -46,8 +46,8 @@
 		PLAT_ARM_TZC_NS_DEV_ACCESS}, 				\
 	{ARM_DRAM2_BASE, ARM_DRAM2_END, ARM_TZC_NS_DRAM_S_ACCESS,	\
 		PLAT_ARM_TZC_NS_DEV_ACCESS},				\
-	{ARM_SP_IMAGE_NS_BUF_BASE, (ARM_SP_IMAGE_NS_BUF_BASE +		\
-		ARM_SP_IMAGE_NS_BUF_SIZE) - 1, TZC_REGION_S_NONE,	\
+	{PLAT_SP_IMAGE_NS_BUF_BASE, (PLAT_SP_IMAGE_NS_BUF_BASE +	\
+		PLAT_SP_IMAGE_NS_BUF_SIZE) - 1, TZC_REGION_S_NONE,	\
 		PLAT_ARM_TZC_NS_DEV_ACCESS}
 
 #else
@@ -188,6 +188,7 @@
 uint32_t arm_get_spsr_for_bl32_entry(void);
 uint32_t arm_get_spsr_for_bl33_entry(void);
 int arm_bl2_handle_post_image_load(unsigned int image_id);
+struct bl_params *arm_get_next_bl_params(void);
 
 /* BL2 at EL3 functions */
 void arm_bl2_el3_early_platform_setup(void);
diff --git a/include/plat/arm/css/common/css_def.h b/include/plat/arm/css/common/css_def.h
index 6b355a4..575db04 100644
--- a/include/plat/arm/css/common/css_def.h
+++ b/include/plat/arm/css/common/css_def.h
@@ -11,8 +11,6 @@
 #include <drivers/arm/gic_common.h>
 #include <drivers/arm/tzc400.h>
 
-#include <arm_def.h>
-
 /*************************************************************************
  * Definitions common to all ARM Compute SubSystems (CSS)
  *************************************************************************/
diff --git a/include/services/mm_svc.h b/include/services/mm_svc.h
index c81e904..c111326 100644
--- a/include/services/mm_svc.h
+++ b/include/services/mm_svc.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,7 +7,7 @@
 #ifndef MM_SVC_H
 #define MM_SVC_H
 
-#if SPM_DEPRECATED
+#if SPM_MM
 
 #include <lib/utils_def.h>
 
@@ -30,6 +30,6 @@
 #define MM_COMMUNICATE_AARCH64		U(0xC4000041)
 #define MM_COMMUNICATE_AARCH32		U(0x84000041)
 
-#endif /* SPM_DEPRECATED */
+#endif /* SPM_MM */
 
 #endif /* MM_SVC_H */
diff --git a/include/services/secure_partition.h b/include/services/secure_partition.h
index 47f6368..0510f80 100644
--- a/include/services/secure_partition.h
+++ b/include/services/secure_partition.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
  */
@@ -7,7 +7,7 @@
 #ifndef SECURE_PARTITION_H
 #define SECURE_PARTITION_H
 
-#if SPM_DEPRECATED
+#if SPM_MM
 
 #include <stdint.h>
 
@@ -49,6 +49,6 @@
 	secure_partition_mp_info_t	*mp_info;
 } secure_partition_boot_info_t;
 
-#endif /* SPM_DEPRECATED */
+#endif /* SPM_MM */
 
 #endif /* SECURE_PARTITION_H */
diff --git a/include/services/spm_svc.h b/include/services/spm_svc.h
index fcb409b..57912e8 100644
--- a/include/services/spm_svc.h
+++ b/include/services/spm_svc.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
  */
@@ -7,7 +7,7 @@
 #ifndef SPM_SVC_H
 #define SPM_SVC_H
 
-#if SPM_DEPRECATED
+#if SPM_MM
 
 #include <lib/utils_def.h>
 
@@ -61,7 +61,7 @@
 #define SPM_DENIED		-3
 #define SPM_NO_MEMORY		-5
 
-#endif /* SPM_DEPRECATED */
+#endif /* SPM_MM */
 
 #ifndef __ASSEMBLY__
 
@@ -69,7 +69,7 @@
 
 int32_t spm_setup(void);
 
-#if SPM_DEPRECATED
+#if SPM_MM
 
 uint64_t spm_smc_handler(uint32_t smc_fid,
 			 uint64_t x1,
@@ -83,7 +83,7 @@
 /* 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_DEPRECATED */
+#endif /* SPM_MM */
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/lib/aarch32/arm32_aeabi_divmod.c b/lib/aarch32/arm32_aeabi_divmod.c
index a8f2e74..0b36cb6 100644
--- a/lib/aarch32/arm32_aeabi_divmod.c
+++ b/lib/aarch32/arm32_aeabi_divmod.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
  */
@@ -18,12 +18,12 @@
  *     unsigned denominator);
  */
 
-/* struct qr - stores qutient/remainder to handle divmod EABI interfaces. */
+/* struct qr - stores quotient/remainder to handle divmod EABI interfaces. */
 struct qr {
 	unsigned int q;		/* computed quotient */
 	unsigned int r;		/* computed remainder */
-	unsigned int q_n;	/* specficies if quotient shall be negative */
-	unsigned int r_n;	/* specficies if remainder shall be negative */
+	unsigned int q_n;	/* specifies if quotient shall be negative */
+	unsigned int r_n;	/* specifies if remainder shall be negative */
 };
 
 static void uint_div_qr(unsigned int numerator, unsigned int denominator,
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 8a5764c..b956491 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.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
  */
@@ -55,7 +55,7 @@
  * The security state to initialize is determined by the SECURE attribute
  * of the entry_point_info.
  *
- * The EE and ST attributes are used to configure the endianess and secure
+ * The EE and ST attributes are used to configure the endianness and secure
  * timer availability for the new execution context.
  *
  * To prepare the register state for entry call cm_prepare_el3_exit() and
@@ -124,7 +124,7 @@
 
 #ifdef IMAGE_BL31
 	/*
-	 * SCR_EL3.IRQ, SCR_EL3.FIQ: Enable the physical FIQ and IRQ rounting as
+	 * SCR_EL3.IRQ, SCR_EL3.FIQ: Enable the physical FIQ and IRQ routing as
 	 *  indicated by the interrupt routing model for BL31.
 	 */
 	scr_el3 |= get_scr_el3_from_routing_model(security_state);
@@ -175,7 +175,7 @@
 
 	/*
 	 * Store the initialised SCTLR_EL1 value in the cpu_context - SCTLR_EL2
-	 * and other EL2 registers are set up by cm_preapre_ns_entry() as they
+	 * and other EL2 registers are set up by cm_prepare_ns_entry() as they
 	 * are not part of the stored cpu_context.
 	 */
 	write_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_elx);
@@ -350,7 +350,7 @@
 					| CPTR_EL2_TFP_BIT));
 
 			/*
-			 * Initiliase CNTHCTL_EL2. All fields are
+			 * Initialise CNTHCTL_EL2. All fields are
 			 * architecturally UNKNOWN on reset and are set to zero
 			 * except for field(s) listed below.
 			 *
diff --git a/lib/utils/mem_region.c b/lib/utils/mem_region.c
index 662f6a0..08bccf6 100644
--- a/lib/utils/mem_region.c
+++ b/lib/utils/mem_region.c
@@ -6,7 +6,9 @@
 
 #include <assert.h>
 
+#include <common/debug.h>
 #include <lib/utils.h>
+#include <lib/xlat_tables/xlat_tables_compat.h>
 
 /*
  * All the regions defined in mem_region_t must have the following properties
diff --git a/lib/xlat_tables/aarch32/xlat_tables.c b/lib/xlat_tables/aarch32/xlat_tables.c
index 468a9e7..4b01b9b 100644
--- a/lib/xlat_tables/aarch32/xlat_tables.c
+++ b/lib/xlat_tables/aarch32/xlat_tables.c
@@ -55,6 +55,11 @@
 {
 	unsigned long long max_pa;
 	uintptr_t max_va;
+
+	assert(PLAT_VIRT_ADDR_SPACE_SIZE >= MIN_VIRT_ADDR_SPACE_SIZE);
+	assert(PLAT_VIRT_ADDR_SPACE_SIZE <= MAX_VIRT_ADDR_SPACE_SIZE);
+	assert(IS_POWER_OF_TWO(PLAT_VIRT_ADDR_SPACE_SIZE));
+
 	print_mmap();
 	init_xlation_table(0U, base_xlation_table, XLAT_TABLE_LEVEL_BASE,
 						&max_va, &max_pa);
diff --git a/lib/xlat_tables/aarch64/xlat_tables.c b/lib/xlat_tables/aarch64/xlat_tables.c
index 71f491a..e64fd3e 100644
--- a/lib/xlat_tables/aarch64/xlat_tables.c
+++ b/lib/xlat_tables/aarch64/xlat_tables.c
@@ -10,7 +10,7 @@
 #include <platform_def.h>
 
 #include <arch.h>
-#include <arch_helpers.h>
+#include <arch_features.h>
 #include <common/bl_common.h>
 #include <lib/utils.h>
 #include <lib/xlat_tables/xlat_tables.h>
@@ -79,6 +79,21 @@
 
 	return (1ULL << pa_range_bits_arr[pa_range]) - 1ULL;
 }
+
+/*
+ * Return minimum virtual address space size supported by the architecture
+ */
+static uintptr_t xlat_get_min_virt_addr_space_size(void)
+{
+	uintptr_t ret;
+
+	if (is_armv8_4_ttst_present())
+		ret = MIN_VIRT_ADDR_SPACE_SIZE_TTST;
+	else
+		ret = MIN_VIRT_ADDR_SPACE_SIZE;
+
+	return ret;
+}
 #endif /* ENABLE_ASSERTIONS */
 
 unsigned int xlat_arch_current_el(void)
@@ -104,6 +119,12 @@
 {
 	unsigned long long max_pa;
 	uintptr_t max_va;
+
+	assert(PLAT_VIRT_ADDR_SPACE_SIZE >=
+		(xlat_get_min_virt_addr_space_size() - 1U));
+	assert(PLAT_VIRT_ADDR_SPACE_SIZE <= MAX_VIRT_ADDR_SPACE_SIZE);
+	assert(IS_POWER_OF_TWO(PLAT_VIRT_ADDR_SPACE_SIZE));
+
 	print_mmap();
 	init_xlation_table(0U, base_xlation_table, XLAT_TABLE_LEVEL_BASE,
 			   &max_va, &max_pa);
diff --git a/lib/xlat_tables/xlat_tables_private.h b/lib/xlat_tables/xlat_tables_private.h
index 4390f34..82bc70c 100644
--- a/lib/xlat_tables/xlat_tables_private.h
+++ b/lib/xlat_tables/xlat_tables_private.h
@@ -16,9 +16,6 @@
 #error xlat tables v2 must be used with HW_ASSISTED_COHERENCY
 #endif
 
-CASSERT(CHECK_VIRT_ADDR_SPACE_SIZE(PLAT_VIRT_ADDR_SPACE_SIZE),
-	assert_valid_virt_addr_space_size);
-
 CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(PLAT_PHY_ADDR_SPACE_SIZE),
 	assert_valid_phy_addr_space_size);
 
diff --git a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
index 349b6c4..b69c670 100644
--- a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.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
  */
@@ -10,6 +10,7 @@
 #include <platform_def.h>
 
 #include <arch.h>
+#include <arch_features.h>
 #include <arch_helpers.h>
 #include <lib/cassert.h>
 #include <lib/utils_def.h>
@@ -44,6 +45,14 @@
 	/* Physical address space size for long descriptor format. */
 	return (1ULL << 40) - 1ULL;
 }
+
+/*
+ * Return minimum virtual address space size supported by the architecture
+ */
+uintptr_t xlat_get_min_virt_addr_space_size(void)
+{
+	return MIN_VIRT_ADDR_SPACE_SIZE;
+}
 #endif /* ENABLE_ASSERTIONS*/
 
 bool is_mmu_enabled_ctx(const xlat_ctx_t *ctx)
@@ -192,7 +201,12 @@
 	if (max_va != UINT32_MAX) {
 		uintptr_t virtual_addr_space_size = max_va + 1U;
 
-		assert(CHECK_VIRT_ADDR_SPACE_SIZE(virtual_addr_space_size));
+		assert(virtual_addr_space_size >=
+			xlat_get_min_virt_addr_space_size());
+		assert(virtual_addr_space_size <=
+			MAX_VIRT_ADDR_SPACE_SIZE);
+		assert(IS_POWER_OF_TWO(virtual_addr_space_size));
+
 		/*
 		 * __builtin_ctzll(0) is undefined but here we are guaranteed
 		 * that virtual_addr_space_size is in the range [1, UINT32_MAX].
@@ -219,13 +233,10 @@
 	/* Set TTBR0 bits as well */
 	ttbr0 = (uint64_t)(uintptr_t) base_table;
 
-#if ARM_ARCH_AT_LEAST(8, 2)
-	/*
-	 * Enable CnP bit so as to share page tables with all PEs. This
-	 * is mandatory for ARMv8.2 implementations.
-	 */
-	ttbr0 |= TTBR_CNP_BIT;
-#endif
+	if (is_armv8_2_ttcnp_present()) {
+		/* Enable CnP bit so as to share page tables with all PEs. */
+		ttbr0 |= TTBR_CNP_BIT;
+	}
 
 	/* Now populate MMU configuration */
 	params[MMU_CFG_MAIR] = mair;
diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
index a803d83..e7593dd 100644
--- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.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
  */
@@ -9,6 +9,7 @@
 #include <stdint.h>
 
 #include <arch.h>
+#include <arch_features.h>
 #include <arch_helpers.h>
 #include <lib/cassert.h>
 #include <lib/utils_def.h>
@@ -100,6 +101,21 @@
 
 	return (1ULL << pa_range_bits_arr[pa_range]) - 1ULL;
 }
+
+/*
+ * Return minimum virtual address space size supported by the architecture
+ */
+uintptr_t xlat_get_min_virt_addr_space_size(void)
+{
+	uintptr_t ret;
+
+	if (is_armv8_4_ttst_present())
+		ret = MIN_VIRT_ADDR_SPACE_SIZE_TTST;
+	else
+		ret = MIN_VIRT_ADDR_SPACE_SIZE;
+
+	return ret;
+}
 #endif /* ENABLE_ASSERTIONS*/
 
 bool is_mmu_enabled_ctx(const xlat_ctx_t *ctx)
@@ -220,7 +236,11 @@
 	assert(max_va < ((uint64_t)UINTPTR_MAX));
 
 	virtual_addr_space_size = (uintptr_t)max_va + 1U;
-	assert(CHECK_VIRT_ADDR_SPACE_SIZE(virtual_addr_space_size));
+
+	assert(virtual_addr_space_size >=
+		xlat_get_min_virt_addr_space_size());
+	assert(virtual_addr_space_size <= MAX_VIRT_ADDR_SPACE_SIZE);
+	assert(IS_POWER_OF_TWO(virtual_addr_space_size));
 
 	/*
 	 * __builtin_ctzll(0) is undefined but here we are guaranteed that
@@ -266,13 +286,10 @@
 	/* Set TTBR bits as well */
 	ttbr0 = (uint64_t) base_table;
 
-#if ARM_ARCH_AT_LEAST(8, 2)
-	/*
-	 * Enable CnP bit so as to share page tables with all PEs. This
-	 * is mandatory for ARMv8.2 implementations.
-	 */
-	ttbr0 |= TTBR_CNP_BIT;
-#endif
+	if (is_armv8_2_ttcnp_present()) {
+		/* Enable CnP bit so as to share page tables with all PEs. */
+		ttbr0 |= TTBR_CNP_BIT;
+	}
 
 	params[MMU_CFG_MAIR] = mair;
 	params[MMU_CFG_TCR] = tcr;
diff --git a/lib/xlat_tables_v2/xlat_tables_core.c b/lib/xlat_tables_v2/xlat_tables_core.c
index c49554f..4820b4f 100644
--- a/lib/xlat_tables_v2/xlat_tables_core.c
+++ b/lib/xlat_tables_v2/xlat_tables_core.c
@@ -1146,6 +1146,11 @@
 
 	mmap_region_t *mm = ctx->mmap;
 
+	assert(ctx->va_max_address >=
+		(xlat_get_min_virt_addr_space_size() - 1U));
+	assert(ctx->va_max_address <= (MAX_VIRT_ADDR_SPACE_SIZE - 1U));
+	assert(IS_POWER_OF_TWO(ctx->va_max_address + 1U));
+
 	xlat_mmap_print(mm);
 
 	/* All tables must be zeroed before mapping any region. */
diff --git a/lib/xlat_tables_v2/xlat_tables_private.h b/lib/xlat_tables_v2/xlat_tables_private.h
index fc70955..70ef395 100644
--- a/lib/xlat_tables_v2/xlat_tables_private.h
+++ b/lib/xlat_tables_v2/xlat_tables_private.h
@@ -102,4 +102,9 @@
 /* Returns true if the data cache is enabled at the current EL. */
 bool is_dcache_enabled(void);
 
+/*
+ * Returns minimum virtual address space size supported by the architecture
+ */
+uintptr_t xlat_get_min_virt_addr_space_size(void);
+
 #endif /* XLAT_TABLES_PRIVATE_H */
diff --git a/maintainers.rst b/maintainers.rst
index 37766ed..f53dda5 100644
--- a/maintainers.rst
+++ b/maintainers.rst
@@ -144,6 +144,13 @@
 :F: docs/plat/imx8.rst
 :F: plat/imx/
 
+NXP i.MX8M platform port
+------------------------
+:M: Jacky Bai <ping.bai@nxp.com>
+:G: `JackyBai`_
+:F: doc/plat/imx8m.rst
+:F: plat/imx/imx8m/
+
 OP-TEE dispatcher
 -----------------
 :M: Jens Wiklander <jens.wiklander@linaro.org>
@@ -241,6 +248,7 @@
 .. _etienne-lms: https://github.com/etienne-lms
 .. _glneo: https://github.com/glneo
 .. _hzhuang1: https://github.com/hzhuang1
+.. _JackyBai: https://github.com/JackyBai
 .. _jenswi-linaro: https://github.com/jenswi-linaro
 .. _ldts: https://github.com/ldts
 .. _niej: https://github.com/niej
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index d60a5bf..73b84c3 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -216,10 +216,11 @@
 $(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2))))
 $(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
 $(eval IMAGE := IMAGE_BL$(call uppercase,$(3)))
+$(eval BL_CFLAGS := $(BL$(call uppercase,$(3))_CFLAGS))
 
 $(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | bl$(3)_dirs
 	$$(ECHO) "  CC      $$<"
-	$$(Q)$$(CC) $$(TF_CFLAGS) $$(CFLAGS) -D$(IMAGE) $(MAKE_DEP) -c $$< -o $$@
+	$$(Q)$$(CC) $$(TF_CFLAGS) $$(CFLAGS) $(BL_CFLAGS) -D$(IMAGE) $(MAKE_DEP) -c $$< -o $$@
 
 -include $(DEP)
 
@@ -463,7 +464,7 @@
 $(DOBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | fdt_dirs
 	$${ECHO} "  CPP     $$<"
 	$(eval DTBS       := $(addprefix $(1)/,$(call SOURCES_TO_DTBS,$(2))))
-	$$(Q)$$(CPP) $$(CPPFLAGS) -x assembler-with-cpp -MT $(DTBS) -MMD -MF $(DTSDEP) -o $(DPRE) $$<
+	$$(Q)$$(PP) $$(DTC_CPPFLAGS) -MT $(DTBS) -MMD -MF $(DTSDEP) -o $(DPRE) $$<
 	$${ECHO} "  DTC     $$<"
 	$$(Q)$$(DTC) $$(DTC_FLAGS) -i fdts -d $(DTBDEP) -o $$@ $(DPRE)
 
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index a55e729..8ef1bb9 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -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
 #
@@ -162,8 +162,8 @@
 # For including the Secure Partition Manager
 ENABLE_SPM			:= 0
 
-# Use the deprecated SPM based on MM
-SPM_DEPRECATED			:= 1
+# Use the SPM based on MM
+SPM_MM				:= 1
 
 # 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.
diff --git a/plat/arm/board/common/aarch32/board_arm_helpers.S b/plat/arm/board/common/aarch32/board_arm_helpers.S
index 320bfb3..8c63693 100644
--- a/plat/arm/board/common/aarch32/board_arm_helpers.S
+++ b/plat/arm/board/common/aarch32/board_arm_helpers.S
@@ -6,7 +6,7 @@
 
 #include <asm_macros.S>
 #include <common/bl_common.h>
-#include <v2m_def.h>
+#include <platform_def.h>
 
 	.globl  plat_report_exception
 
diff --git a/plat/arm/board/common/aarch64/board_arm_helpers.S b/plat/arm/board/common/aarch64/board_arm_helpers.S
index 5a90524..cde6b00 100644
--- a/plat/arm/board/common/aarch64/board_arm_helpers.S
+++ b/plat/arm/board/common/aarch64/board_arm_helpers.S
@@ -6,7 +6,7 @@
 
 #include <asm_macros.S>
 #include <common/bl_common.h>
-#include <v2m_def.h>
+#include <platform_def.h>
 
 	.globl  plat_report_exception
 
diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c
index 64ca3c3..e3c6805 100644
--- a/plat/arm/board/common/board_arm_trusted_boot.c
+++ b/plat/arm/board/common/board_arm_trusted_boot.c
@@ -11,8 +11,7 @@
 #include <lib/cassert.h>
 #include <plat/common/platform.h>
 #include <tools_share/tbbr_oid.h>
-
-#include <arm_def.h>
+#include <platform_def.h>
 
 /* SHA256 algorithm */
 #define SHA256_BYTES			32
diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk
index 487aad7..b98dfd4 100644
--- a/plat/arm/board/common/board_common.mk
+++ b/plat/arm/board/common/board_common.mk
@@ -4,8 +4,6 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-PLAT_INCLUDES		+=	-Iinclude/plat/arm/board/common/
-
 PLAT_BL_COMMON_SOURCES	+=	drivers/arm/pl011/${ARCH}/pl011_console.S	\
 				plat/arm/board/common/${ARCH}/board_arm_helpers.S
 
diff --git a/plat/arm/board/fvp/aarch32/fvp_helpers.S b/plat/arm/board/fvp/aarch32/fvp_helpers.S
index 5d88546..9985c1d 100644
--- a/plat/arm/board/fvp/aarch32/fvp_helpers.S
+++ b/plat/arm/board/fvp/aarch32/fvp_helpers.S
@@ -6,9 +6,8 @@
 
 #include <arch.h>
 #include <asm_macros.S>
+#include <drivers/arm/fvp/fvp_pwrc.h>
 #include <platform_def.h>
-#include "../drivers/pwrc/fvp_pwrc.h"
-#include "../fvp_def.h"
 
 	.globl	plat_secondary_cold_boot_setup
 	.globl	plat_get_my_entrypoint
diff --git a/plat/arm/board/fvp/aarch64/fvp_helpers.S b/plat/arm/board/fvp/aarch64/fvp_helpers.S
index 0f90515..09f19f6 100644
--- a/plat/arm/board/fvp/aarch64/fvp_helpers.S
+++ b/plat/arm/board/fvp/aarch64/fvp_helpers.S
@@ -8,10 +8,8 @@
 #include <asm_macros.S>
 #include <drivers/arm/gicv2.h>
 #include <drivers/arm/gicv3.h>
+#include <drivers/arm/fvp/fvp_pwrc.h>
 #include <platform_def.h>
-#include <v2m_def.h>
-#include "../drivers/pwrc/fvp_pwrc.h"
-#include "../fvp_def.h"
 
 	.globl	plat_secondary_cold_boot_setup
 	.globl	plat_get_my_entrypoint
diff --git a/plat/arm/board/fvp/fvp_bl1_setup.c b/plat/arm/board/fvp/fvp_bl1_setup.c
index d6e82f5..75090e8 100644
--- a/plat/arm/board/fvp/fvp_bl1_setup.c
+++ b/plat/arm/board/fvp/fvp_bl1_setup.c
@@ -5,10 +5,9 @@
  */
 
 #include <common/tbbr/tbbr_img_def.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <plat_arm.h>
-
 #include "fvp_private.h"
 
 /*******************************************************************************
diff --git a/plat/arm/board/fvp/fvp_bl2_el3_setup.c b/plat/arm/board/fvp/fvp_bl2_el3_setup.c
index 69f2f7a..7def56a 100644
--- a/plat/arm/board/fvp/fvp_bl2_el3_setup.c
+++ b/plat/arm/board/fvp/fvp_bl2_el3_setup.c
@@ -4,7 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
+
 #include "fvp_private.h"
 
 void bl2_el3_early_platform_setup(u_register_t arg0 __unused,
diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c
index 13e74fd..d280949 100644
--- a/plat/arm/board/fvp/fvp_bl2_setup.c
+++ b/plat/arm/board/fvp/fvp_bl2_setup.c
@@ -7,11 +7,10 @@
 #include <drivers/arm/sp804_delay_timer.h>
 #include <drivers/generic_delay_timer.h>
 #include <lib/mmio.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
+#include <platform_def.h>
 
-#include <plat_arm.h>
-#include <v2m_def.h>
-#include "fvp_def.h"
 #include "fvp_private.h"
 
 void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3)
diff --git a/plat/arm/board/fvp/fvp_bl2u_setup.c b/plat/arm/board/fvp/fvp_bl2u_setup.c
index c51e287..a8db055 100644
--- a/plat/arm/board/fvp/fvp_bl2u_setup.c
+++ b/plat/arm/board/fvp/fvp_bl2u_setup.c
@@ -4,10 +4,10 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
+#include <platform_def.h>
 
-#include <plat_arm.h>
-#include "fvp_def.h"
 #include "fvp_private.h"
 
 void bl2u_early_platform_setup(struct meminfo *mem_layout, void *plat_info)
diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c
index 5f2121c..7f28b20 100644
--- a/plat/arm/board/fvp/fvp_bl31_setup.c
+++ b/plat/arm/board/fvp/fvp_bl31_setup.c
@@ -5,10 +5,10 @@
  */
 
 #include <drivers/arm/smmu_v3.h>
+#include <plat/arm/common/arm_config.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <arm_config.h>
-#include <plat_arm.h>
 #include "fvp_private.h"
 
 void __init bl31_early_platform_setup2(u_register_t arg0,
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index 31a61de..b885b47 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.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
  */
@@ -12,16 +12,12 @@
 #include <drivers/arm/gicv2.h>
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables_compat.h>
+#include <plat/arm/common/arm_config.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
+#include <platform_def.h>
 #include <services/secure_partition.h>
 
-#include <arm_config.h>
-#include <arm_def.h>
-#include <arm_spm_def.h>
-#include <plat_arm.h>
-#include <v2m_def.h>
-
-#include "../fvp_def.h"
 #include "fvp_private.h"
 
 /* Defines for GIC Driver build time selection */
@@ -98,10 +94,10 @@
 	ARM_MAP_BL1_RW,
 #endif
 #endif /* TRUSTED_BOARD_BOOT */
-#if ENABLE_SPM && SPM_DEPRECATED
+#if ENABLE_SPM && SPM_MM
 	ARM_SP_IMAGE_MMAP,
 #endif
-#if ENABLE_SPM && !SPM_DEPRECATED
+#if ENABLE_SPM && !SPM_MM
 	PLAT_MAP_SP_PACKAGE_MEM_RW,
 #endif
 #if ARM_BL31_IN_DRAM
@@ -129,16 +125,16 @@
 	MAP_DEVICE0,
 	MAP_DEVICE1,
 	ARM_V2M_MAP_MEM_PROTECT,
-#if ENABLE_SPM && SPM_DEPRECATED
+#if ENABLE_SPM && SPM_MM
 	ARM_SPM_BUF_EL3_MMAP,
 #endif
-#if ENABLE_SPM && !SPM_DEPRECATED
+#if ENABLE_SPM && !SPM_MM
 	PLAT_MAP_SP_PACKAGE_MEM_RO,
 #endif
 	{0}
 };
 
-#if ENABLE_SPM && defined(IMAGE_BL31) && SPM_DEPRECATED
+#if ENABLE_SPM && 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,				\
@@ -192,7 +188,7 @@
 }
 #endif
 
-#if ENABLE_SPM && defined(IMAGE_BL31) && SPM_DEPRECATED
+#if ENABLE_SPM && defined(IMAGE_BL31) && SPM_MM
 /*
  * Boot information passed to a secure partition during initialisation. Linear
  * indices in MP information will be filled at runtime.
@@ -218,12 +214,12 @@
 	.sp_image_base       = ARM_SP_IMAGE_BASE,
 	.sp_stack_base       = PLAT_SP_IMAGE_STACK_BASE,
 	.sp_heap_base        = ARM_SP_IMAGE_HEAP_BASE,
-	.sp_ns_comm_buf_base = ARM_SP_IMAGE_NS_BUF_BASE,
+	.sp_ns_comm_buf_base = PLAT_SP_IMAGE_NS_BUF_BASE,
 	.sp_shared_buf_base  = PLAT_SPM_BUF_BASE,
 	.sp_image_size       = ARM_SP_IMAGE_SIZE,
 	.sp_pcpu_stack_size  = PLAT_SP_IMAGE_STACK_PCPU_SIZE,
 	.sp_heap_size        = ARM_SP_IMAGE_HEAP_SIZE,
-	.sp_ns_comm_buf_size = ARM_SP_IMAGE_NS_BUF_SIZE,
+	.sp_ns_comm_buf_size = PLAT_SP_IMAGE_NS_BUF_SIZE,
 	.sp_shared_buf_size  = PLAT_SPM_BUF_SIZE,
 	.num_sp_mem_regions  = ARM_SP_IMAGE_NUM_MEM_REGIONS,
 	.num_cpus            = PLATFORM_CORE_COUNT,
diff --git a/plat/arm/board/fvp/fvp_io_storage.c b/plat/arm/board/fvp/fvp_io_storage.c
index e186b30..9c4c1d5 100644
--- a/plat/arm/board/fvp/fvp_io_storage.c
+++ b/plat/arm/board/fvp/fvp_io_storage.c
@@ -11,10 +11,9 @@
 #include <drivers/io/io_semihosting.h>
 #include <drivers/io/io_storage.h>
 #include <lib/semihosting.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/common_def.h>
 
-#include <plat_arm.h>
-
 /* Semihosting filenames */
 #define BL2_IMAGE_NAME			"bl2.bin"
 #define BL31_IMAGE_NAME			"bl31.bin"
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c
index 7da246b..ecf0b01 100644
--- a/plat/arm/board/fvp/fvp_pm.c
+++ b/plat/arm/board/fvp/fvp_pm.c
@@ -10,18 +10,15 @@
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <drivers/arm/gicv3.h>
+#include <drivers/arm/fvp/fvp_pwrc.h>
 #include <lib/extensions/spe.h>
 #include <lib/mmio.h>
 #include <lib/psci/psci.h>
+#include <plat/arm/common/arm_config.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
-
-#include <arm_config.h>
-#include <plat_arm.h>
-#include <v2m_def.h>
+#include <platform_def.h>
 
-#include "../../../../drivers/arm/gic/v3/gicv3_private.h"
-#include "drivers/pwrc/fvp_pwrc.h"
-#include "fvp_def.h"
 #include "fvp_private.h"
 
 
diff --git a/plat/arm/board/fvp/fvp_private.h b/plat/arm/board/fvp/fvp_private.h
index e7dea99..3d96537 100644
--- a/plat/arm/board/fvp/fvp_private.h
+++ b/plat/arm/board/fvp/fvp_private.h
@@ -7,7 +7,7 @@
 #ifndef FVP_PRIVATE_H
 #define FVP_PRIVATE_H
 
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
 
 /*******************************************************************************
  * Function and variable prototypes
diff --git a/plat/arm/board/fvp/fvp_security.c b/plat/arm/board/fvp/fvp_security.c
index 028522c..80ec217 100644
--- a/plat/arm/board/fvp/fvp_security.c
+++ b/plat/arm/board/fvp/fvp_security.c
@@ -4,8 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <arm_config.h>
-#include <plat_arm.h>
+#include <plat/arm/common/arm_config.h>
+#include <plat/arm/common/plat_arm.h>
 
 /*
  * We assume that all security programming is done by the primary core.
diff --git a/plat/arm/board/fvp/fvp_topology.c b/plat/arm/board/fvp/fvp_topology.c
index 3384a2f..9823fb3 100644
--- a/plat/arm/board/fvp/fvp_topology.c
+++ b/plat/arm/board/fvp/fvp_topology.c
@@ -7,13 +7,12 @@
 #include <platform_def.h>
 
 #include <arch.h>
+#include <drivers/arm/fvp/fvp_pwrc.h>
 #include <lib/cassert.h>
+#include <plat/arm/common/arm_config.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <plat_arm.h>
-#include <arm_config.h>
-#include "drivers/pwrc/fvp_pwrc.h"
-
 /* The FVP power domain tree descriptor */
 static unsigned char fvp_power_domain_tree_desc[FVP_CLUSTER_COUNT + 2];
 
diff --git a/plat/arm/board/fvp/fvp_trusted_boot.c b/plat/arm/board/fvp/fvp_trusted_boot.c
index c18bfb2..0d160cb 100644
--- a/plat/arm/board/fvp/fvp_trusted_boot.c
+++ b/plat/arm/board/fvp/fvp_trusted_boot.c
@@ -9,10 +9,9 @@
 #include <string.h>
 
 #include <plat/common/platform.h>
+#include <platform_def.h>
 #include <tools_share/tbbr_oid.h>
 
-#include "fvp_def.h"
-
 /*
  * Store a new non-volatile counter value. On some FVP versions, the
  * non-volatile counters are RO. On these versions we expect the values in the
diff --git a/plat/arm/board/fvp/include/plat.ld.S b/plat/arm/board/fvp/include/plat.ld.S
index ad2d46c..f024f55 100644
--- a/plat/arm/board/fvp/include/plat.ld.S
+++ b/plat/arm/board/fvp/include/plat.ld.S
@@ -6,7 +6,7 @@
 #ifndef PLAT_LD_S
 #define PLAT_LD_S
 
-#include <arm_tzc_dram.ld.S>
-#include <arm_reclaim_init.ld.S>
+#include <plat/arm/common/arm_tzc_dram.ld.S>
+#include <plat/arm/common/arm_reclaim_init.ld.S>
 
 #endif /* PLAT_LD_S */
diff --git a/plat/arm/board/fvp/include/plat_macros.S b/plat/arm/board/fvp/include/plat_macros.S
index 6be8b09..57f5924 100644
--- a/plat/arm/board/fvp/include/plat_macros.S
+++ b/plat/arm/board/fvp/include/plat_macros.S
@@ -7,8 +7,7 @@
 #define PLAT_MACROS_S
 
 #include <arm_macros.S>
-#include <v2m_def.h>
-#include "../fvp_def.h"
+#include <platform_def.h>
 
 	/* ---------------------------------------------
 	 * The below required platform porting macro
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index ca4bd53..fcf363d 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/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
  */
@@ -7,25 +7,13 @@
 #ifndef PLATFORM_DEF_H
 #define PLATFORM_DEF_H
 
-/* Enable the dynamic translation tables library. */
-#ifdef AARCH32
-# if defined(IMAGE_BL32) && RESET_TO_SP_MIN
-#  define PLAT_XLAT_TABLES_DYNAMIC     1
-# endif
-#else
-# if defined(IMAGE_BL31) && (RESET_TO_BL31 || (ENABLE_SPM && !SPM_DEPRECATED))
-#  define PLAT_XLAT_TABLES_DYNAMIC     1
-# endif
-#endif /* AARCH32 */
-
 #include <drivers/arm/tzc400.h>
 #include <lib/utils_def.h>
+#include <plat/arm/board/common/v2m_def.h>
+#include <plat/arm/common/arm_def.h>
+#include <plat/arm/common/arm_spm_def.h>
 #include <plat/common/common_def.h>
 
-#include <arm_def.h>
-#include <arm_spm_def.h>
-#include <v2m_def.h>
-
 #include "../fvp_def.h"
 
 /* Required platform porting definitions */
@@ -125,7 +113,7 @@
  * calculated using the current BL31 PROGBITS debug size plus the sizes of
  * BL2 and BL1-RW
  */
-#if ENABLE_SPM && !SPM_DEPRECATED
+#if ENABLE_SPM && !SPM_MM
 #define PLAT_ARM_MAX_BL31_SIZE		UL(0x60000)
 #else
 #define PLAT_ARM_MAX_BL31_SIZE		UL(0x3B000)
@@ -271,8 +259,8 @@
 #define PLAT_ARM_PRIVATE_SDEI_EVENTS	ARM_SDEI_PRIVATE_EVENTS
 #define PLAT_ARM_SHARED_SDEI_EVENTS	ARM_SDEI_SHARED_EVENTS
 
-#define PLAT_ARM_SP_IMAGE_STACK_BASE	(ARM_SP_IMAGE_NS_BUF_BASE +	\
-					 ARM_SP_IMAGE_NS_BUF_SIZE)
+#define PLAT_ARM_SP_IMAGE_STACK_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE +	\
+					 PLAT_SP_IMAGE_NS_BUF_SIZE)
 
 #define PLAT_SP_PRI			PLAT_RAS_PRI
 
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 3b60daa..f79ac46 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -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
 #
@@ -146,14 +146,14 @@
 BL2U_SOURCES		+=	plat/arm/board/fvp/fvp_bl2u_setup.c		\
 				${FVP_SECURITY_SOURCES}
 
-BL31_SOURCES		+=	drivers/arm/smmu/smmu_v3.c			\
+BL31_SOURCES		+=	drivers/arm/fvp/fvp_pwrc.c			\
+				drivers/arm/smmu/smmu_v3.c			\
 				drivers/cfi/v2m/v2m_flash.c			\
 				lib/utils/mem_region.c				\
 				plat/arm/board/fvp/fvp_bl31_setup.c		\
 				plat/arm/board/fvp/fvp_pm.c			\
 				plat/arm/board/fvp/fvp_topology.c		\
 				plat/arm/board/fvp/aarch64/fvp_helpers.S	\
-				plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c	\
 				plat/arm/common/arm_nor_psci_mem_protect.c	\
 				${FVP_CPU_LIBS}					\
 				${FVP_GIC_SOURCES}				\
@@ -231,6 +231,22 @@
     NEED_BL32 := yes
 endif
 
+# Enable the dynamic translation tables library.
+ifeq (${ARCH},aarch32)
+    ifeq (${RESET_TO_SP_MIN},1)
+        BL32_CFLAGS	+=	-DPLAT_XLAT_TABLES_DYNAMIC=1
+    endif
+else
+    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
+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/sp_min/fvp_sp_min_setup.c b/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
index 7c89c27..88c91e6 100644
--- a/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
+++ b/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c
@@ -4,7 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
+
 #include "../fvp_private.h"
 
 void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1,
diff --git a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
index 8b17c9b..0250a5f 100644
--- a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
+++ b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
@@ -5,10 +5,10 @@
 #
 
 # SP_MIN source files specific to FVP platform
-BL32_SOURCES		+=	drivers/cfi/v2m/v2m_flash.c			\
+BL32_SOURCES		+=	drivers/arm/fvp/fvp_pwrc.c			\
+				drivers/cfi/v2m/v2m_flash.c			\
 				lib/utils/mem_region.c				\
 				plat/arm/board/fvp/aarch32/fvp_helpers.S	\
-				plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c	\
 				plat/arm/board/fvp/fvp_pm.c			\
 				plat/arm/board/fvp/fvp_topology.c		\
 				plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c	\
diff --git a/plat/arm/board/fvp/tsp/fvp_tsp_setup.c b/plat/arm/board/fvp/tsp/fvp_tsp_setup.c
index 86d265a..3c8a963 100644
--- a/plat/arm/board/fvp/tsp/fvp_tsp_setup.c
+++ b/plat/arm/board/fvp/tsp/fvp_tsp_setup.c
@@ -4,7 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
+
 #include "../fvp_private.h"
 
 void tsp_early_platform_setup(void)
diff --git a/plat/arm/board/fvp/tsp/tsp-fvp.mk b/plat/arm/board/fvp/tsp/tsp-fvp.mk
index 861fe72..ab3f225 100644
--- a/plat/arm/board/fvp/tsp/tsp-fvp.mk
+++ b/plat/arm/board/fvp/tsp/tsp-fvp.mk
@@ -5,8 +5,8 @@
 #
 
 # TSP source files specific to FVP platform
-BL32_SOURCES		+=	plat/arm/board/fvp/aarch64/fvp_helpers.S	\
-				plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c	\
+BL32_SOURCES		+=	drivers/arm/fvp/fvp_pwrc.c			\
+				plat/arm/board/fvp/aarch64/fvp_helpers.S	\
 				plat/arm/board/fvp/fvp_topology.c		\
 				plat/arm/board/fvp/tsp/fvp_tsp_setup.c		\
 				${FVP_GIC_SOURCES}
diff --git a/plat/arm/board/juno/aarch32/juno_helpers.S b/plat/arm/board/juno/aarch32/juno_helpers.S
index 080a8dd..8f9561c 100644
--- a/plat/arm/board/juno/aarch32/juno_helpers.S
+++ b/plat/arm/board/juno/aarch32/juno_helpers.S
@@ -11,9 +11,7 @@
 #include <cortex_a57.h>
 #include <cortex_a72.h>
 #include <cpu_macros.S>
-#include <v2m_def.h>
-#include "../juno_def.h"
-
+#include <platform_def.h>
 
 	.globl	plat_reset_handler
 	.globl	plat_arm_calc_core_pos
diff --git a/plat/arm/board/juno/aarch64/juno_helpers.S b/plat/arm/board/juno/aarch64/juno_helpers.S
index 373f2fc..c94fa3e 100644
--- a/plat/arm/board/juno/aarch64/juno_helpers.S
+++ b/plat/arm/board/juno/aarch64/juno_helpers.S
@@ -11,10 +11,7 @@
 #include <cortex_a57.h>
 #include <cortex_a72.h>
 #include <cpu_macros.S>
-#include <css_def.h>
-#include <v2m_def.h>
-#include "../juno_def.h"
-
+#include <platform_def.h>
 
 	.globl	plat_reset_handler
 	.globl	plat_arm_calc_core_pos
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index ed82879..ddbc9b7 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/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
  */
@@ -7,29 +7,17 @@
 #ifndef PLATFORM_DEF_H
 #define PLATFORM_DEF_H
 
-/* Enable the dynamic translation tables library. */
-#ifdef AARCH32
-# if defined(IMAGE_BL32) && RESET_TO_SP_MIN
-#  define PLAT_XLAT_TABLES_DYNAMIC     1
-# endif
-#else
-# if defined(IMAGE_BL31) && RESET_TO_BL31
-#  define PLAT_XLAT_TABLES_DYNAMIC     1
-# endif
-#endif /* AARCH32 */
-
-
 #include <drivers/arm/tzc400.h>
 #if TRUSTED_BOARD_BOOT
 #include <drivers/auth/mbedtls/mbedtls_config.h>
 #endif
+#include <plat/arm/board/common/board_css_def.h>
+#include <plat/arm/board/common/v2m_def.h>
+#include <plat/arm/common/arm_def.h>
+#include <plat/arm/css/common/css_def.h>
+#include <plat/arm/soc/common/soc_css_def.h>
 #include <plat/common/common_def.h>
 
-#include <arm_def.h>
-#include <board_css_def.h>
-#include <css_def.h>
-#include <soc_css_def.h>
-#include <v2m_def.h>
 #include "../juno_def.h"
 
 /* Required platform porting definitions */
@@ -143,7 +131,7 @@
 #elif TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA
 # define PLAT_ARM_MAX_BL2_SIZE		UL(0x1D000)
 #else
-# define PLAT_ARM_MAX_BL2_SIZE		UL(0x1C000)
+# define PLAT_ARM_MAX_BL2_SIZE		UL(0x1D000)
 #endif
 #else
 # define PLAT_ARM_MAX_BL2_SIZE		UL(0xF000)
diff --git a/plat/arm/board/juno/juno_bl1_setup.c b/plat/arm/board/juno/juno_bl1_setup.c
index e751ab6..f72a6ff 100644
--- a/plat/arm/board/juno/juno_bl1_setup.c
+++ b/plat/arm/board/juno/juno_bl1_setup.c
@@ -9,12 +9,11 @@
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <common/tbbr/tbbr_img_def.h>
+#include <drivers/arm/css/sds.h>
 #include <drivers/arm/sp805.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
-
-#include <plat_arm.h>
-#include <sds.h>
-#include <v2m_def.h>
+#include <platform_def.h>
 
 void juno_reset_to_aarch32_state(void);
 
diff --git a/plat/arm/board/juno/juno_bl2_setup.c b/plat/arm/board/juno/juno_bl2_setup.c
index 56f05eb..95ef77c 100644
--- a/plat/arm/board/juno/juno_bl2_setup.c
+++ b/plat/arm/board/juno/juno_bl2_setup.c
@@ -8,8 +8,7 @@
 
 #include <common/bl_common.h>
 #include <common/desc_image_load.h>
-
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
 
 #if JUNO_AARCH32_EL3_RUNTIME
 /*******************************************************************************
diff --git a/plat/arm/board/juno/juno_common.c b/plat/arm/board/juno/juno_common.c
index 2e6b011..118c19a 100644
--- a/plat/arm/board/juno/juno_common.c
+++ b/plat/arm/board/juno/juno_common.c
@@ -3,8 +3,9 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-#include <arm_def.h>
-#include <plat_arm.h>
+
+#include <platform_def.h>
+#include <plat/arm/common/plat_arm.h>
 
 /*
  * Table of memory regions for different BL stages to map using the MMU.
diff --git a/plat/arm/board/juno/juno_err.c b/plat/arm/board/juno/juno_err.c
index 69daa1a..f80ff24 100644
--- a/plat/arm/board/juno/juno_err.c
+++ b/plat/arm/board/juno/juno_err.c
@@ -8,8 +8,7 @@
 
 #include <arch_helpers.h>
 #include <plat/common/platform.h>
-
-#include <v2m_def.h>
+#include <platform_def.h>
 
 /*
  * Juno error handler
diff --git a/plat/arm/board/juno/juno_pm.c b/plat/arm/board/juno/juno_pm.c
index dbf7b6c..cc80651 100644
--- a/plat/arm/board/juno/juno_pm.c
+++ b/plat/arm/board/juno/juno_pm.c
@@ -4,8 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <plat_arm.h>
-#include <scmi.h>
+#include <drivers/arm/css/scmi.h>
+#include <plat/arm/common/plat_arm.h>
 
 const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops)
 {
diff --git a/plat/arm/board/juno/juno_security.c b/plat/arm/board/juno/juno_security.c
index b0df837..9d7f0e4 100644
--- a/plat/arm/board/juno/juno_security.c
+++ b/plat/arm/board/juno/juno_security.c
@@ -7,10 +7,10 @@
 #include <common/debug.h>
 #include <drivers/arm/nic_400.h>
 #include <lib/mmio.h>
+#include <platform_def.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/soc/common/soc_css.h>
 
-#include <plat_arm.h>
-#include <soc_css.h>
-#include "juno_def.h"
 #include "juno_tzmp1_def.h"
 
 #ifdef JUNO_TZMP1
diff --git a/plat/arm/board/juno/juno_stack_protector.c b/plat/arm/board/juno/juno_stack_protector.c
index ff05b5d..236eb5b 100644
--- a/plat/arm/board/juno/juno_stack_protector.c
+++ b/plat/arm/board/juno/juno_stack_protector.c
@@ -7,9 +7,9 @@
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <lib/utils.h>
+#include <platform_def.h>
 
 #include "juno_decl.h"
-#include "juno_def.h"
 
 u_register_t plat_get_stack_protector_canary(void)
 {
diff --git a/plat/arm/board/juno/juno_topology.c b/plat/arm/board/juno/juno_topology.c
index 51b99ac..ca5c344 100644
--- a/plat/arm/board/juno/juno_topology.c
+++ b/plat/arm/board/juno/juno_topology.c
@@ -4,14 +4,12 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <drivers/arm/css/css_mhu_doorbell.h>
+#include <drivers/arm/css/scmi.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
 #include <plat/common/platform.h>
-
-#include <arm_def.h>
-#include <css_pm.h>
-#include <plat_arm.h>
-#include "juno_def.h"
-#include "../../css/drivers/scmi/scmi.h"
-#include "../../css/drivers/mhu/css_mhu_doorbell.h"
+#include <platform_def.h>
 
 #if CSS_USE_SCMI_SDS_DRIVER
 static scmi_channel_plat_info_t juno_scmi_plat_info = {
diff --git a/plat/arm/board/juno/juno_trng.c b/plat/arm/board/juno/juno_trng.c
index 505fb02..7869d3e 100644
--- a/plat/arm/board/juno/juno_trng.c
+++ b/plat/arm/board/juno/juno_trng.c
@@ -9,9 +9,9 @@
 
 #include <lib/mmio.h>
 #include <lib/utils_def.h>
+#include <platform_def.h>
 
 #include "juno_decl.h"
-#include "juno_def.h"
 
 #define NSAMPLE_CLOCKS	1 /* min 1 cycle, max 231 cycles */
 #define NRETRIES	5
diff --git a/plat/arm/board/juno/juno_tzmp1_def.h b/plat/arm/board/juno/juno_tzmp1_def.h
index 5d0978c..4186d02 100644
--- a/plat/arm/board/juno/juno_tzmp1_def.h
+++ b/plat/arm/board/juno/juno_tzmp1_def.h
@@ -7,8 +7,6 @@
 #ifndef JUNO_TZMP1_DEF_H
 #define JUNO_TZMP1_DEF_H
 
-#include <plat_arm.h>
-
 /*
  * Public memory regions for both protected and non-protected mode
  *
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index aec2b9b..6575811 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -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
 #
@@ -26,9 +26,7 @@
 # SCP during power management operations and for SCP RAM Firmware transfer.
 CSS_USE_SCMI_SDS_DRIVER		:=	1
 
-PLAT_INCLUDES		:=	-Iplat/arm/board/juno/include		\
-				-Iplat/arm/css/drivers/scmi		\
-				-Iplat/arm/css/drivers/sds
+PLAT_INCLUDES		:=	-Iplat/arm/board/juno/include
 
 PLAT_BL_COMMON_SOURCES	:=	plat/arm/board/juno/${ARCH}/juno_helpers.S \
 				plat/arm/board/juno/juno_common.c
@@ -88,7 +86,7 @@
 				${JUNO_SECURITY_SOURCES}
 
 ifeq (${CSS_USE_SCMI_SDS_DRIVER},1)
-BL1_SOURCES		+=	plat/arm/css/drivers/sds/sds.c
+BL1_SOURCES		+=	drivers/arm/css/sds/sds.c
 endif
 
 endif
@@ -134,6 +132,17 @@
 # Do not enable SVE
 ENABLE_SVE_FOR_NS		:=	0
 
+# Enable the dynamic translation tables library.
+ifeq (${ARCH},aarch32)
+    ifeq (${RESET_TO_SP_MIN},1)
+        BL32_CFLAGS	+=	-DPLAT_XLAT_TABLES_DYNAMIC=1
+    endif
+else
+    ifeq (${RESET_TO_BL31},1)
+        BL31_CFLAGS	+=	-DPLAT_XLAT_TABLES_DYNAMIC=1
+    endif
+endif
+
 include plat/arm/board/common/board_common.mk
 include plat/arm/common/arm_common.mk
 include plat/arm/soc/common/soc_css.mk
diff --git a/plat/arm/board/n1sdp/include/platform_def.h b/plat/arm/board/n1sdp/include/platform_def.h
index 1556ac7..7b8c367 100644
--- a/plat/arm/board/n1sdp/include/platform_def.h
+++ b/plat/arm/board/n1sdp/include/platform_def.h
@@ -7,8 +7,9 @@
 #ifndef PLATFORM_DEF_H
 #define PLATFORM_DEF_H
 
-#include <arm_def.h>
-#include <css_def.h>
+#include <plat/arm/board/common/v2m_def.h>
+#include <plat/arm/common/arm_def.h>
+#include <plat/arm/css/common/css_def.h>
 
 /* UART related constants */
 #define PLAT_ARM_BOOT_UART_BASE			0x2A400000
diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
index d044b7c..18a0dea 100644
--- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
+++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
@@ -6,9 +6,9 @@
 
 #include <platform_def.h>
 
-#include "../../css/drivers/scmi/scmi.h"
-#include "../../css/drivers/mhu/css_mhu_doorbell.h"
-#include <plat_arm.h>
+#include <drivers/arm/css/css_mhu_doorbell.h>
+#include <drivers/arm/css/scmi.h>
+#include <plat/arm/common/plat_arm.h>
 
 static scmi_channel_plat_info_t n1sdp_scmi_plat_info = {
 		.scmi_mbx_mem = N1SDP_SCMI_PAYLOAD_BASE,
diff --git a/plat/arm/board/n1sdp/n1sdp_plat.c b/plat/arm/board/n1sdp/n1sdp_plat.c
index 3bf1fe6..6905896 100644
--- a/plat/arm/board/n1sdp/n1sdp_plat.c
+++ b/plat/arm/board/n1sdp/n1sdp_plat.c
@@ -8,11 +8,9 @@
 
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <arm_def.h>
-#include <plat_arm.h>
-
 /*
  * Table of regions to map using the MMU.
  * Replace or extend the below regions as required
diff --git a/plat/arm/board/n1sdp/n1sdp_topology.c b/plat/arm/board/n1sdp/n1sdp_topology.c
index c3b4550..edf1170 100644
--- a/plat/arm/board/n1sdp/n1sdp_topology.c
+++ b/plat/arm/board/n1sdp/n1sdp_topology.c
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
 
 /* Topology */
 typedef struct n1sdp_topology {
diff --git a/plat/arm/common/arm_bl1_fwu.c b/plat/arm/common/arm_bl1_fwu.c
index cd92aa8..124c1af 100644
--- a/plat/arm/common/arm_bl1_fwu.c
+++ b/plat/arm/common/arm_bl1_fwu.c
@@ -13,10 +13,9 @@
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <lib/utils.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <plat_arm.h>
-
 /* Struct to keep track of usable memory */
 typedef struct bl1_mem_info {
 	uintptr_t mem_base;
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index e28211c..fd4809c 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -14,13 +14,9 @@
 #include <drivers/arm/sp805.h>
 #include <lib/utils.h>
 #include <lib/xlat_tables/xlat_tables_compat.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <arm_def.h>
-#include <plat_arm.h>
-
-#include "../../../bl1/bl1_private.h"
-
 /* Weak definitions may be overridden in specific ARM standard platform */
 #pragma weak bl1_early_platform_setup
 #pragma weak bl1_plat_arch_setup
diff --git a/plat/arm/common/arm_bl2_el3_setup.c b/plat/arm/common/arm_bl2_el3_setup.c
index 0c1f63e..0c01c87 100644
--- a/plat/arm/common/arm_bl2_el3_setup.c
+++ b/plat/arm/common/arm_bl2_el3_setup.c
@@ -7,10 +7,9 @@
 #include <assert.h>
 
 #include <drivers/generic_delay_timer.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
-
-#include <arm_def.h>
-#include <plat_arm.h>
+#include <platform_def.h>
 
 #pragma weak bl2_el3_early_platform_setup
 #pragma weak bl2_el3_plat_arch_setup
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 9319004..32617f6 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -18,11 +18,9 @@
 #include <lib/optee_utils.h>
 #endif
 #include <lib/utils.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <arm_def.h>
-#include <plat_arm.h>
-
 /* Data structure which holds the extents of the trusted SRAM for BL2 */
 static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
 
diff --git a/plat/arm/common/arm_bl2u_setup.c b/plat/arm/common/arm_bl2u_setup.c
index 0dc66e6..9f44b9e 100644
--- a/plat/arm/common/arm_bl2u_setup.c
+++ b/plat/arm/common/arm_bl2u_setup.c
@@ -12,11 +12,9 @@
 #include <arch_helpers.h>
 #include <common/bl_common.h>
 #include <drivers/generic_delay_timer.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <arm_def.h>
-#include <plat_arm.h>
-
 /* Weak definitions may be overridden in specific ARM standard platform */
 #pragma weak bl2u_platform_setup
 #pragma weak bl2u_early_platform_setup
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index 41151c2..8e1a263 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -15,10 +15,9 @@
 #include <lib/mmio.h>
 #include <lib/utils.h>
 #include <lib/xlat_tables/xlat_tables_compat.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
-
-#include <arm_def.h>
-#include <plat_arm.h>
+#include <platform_def.h>
 
 /*
  * Placeholder variables for copying the arguments that have been passed to
diff --git a/plat/arm/common/arm_cci.c b/plat/arm/common/arm_cci.c
index 7ee997e..3795fc5 100644
--- a/plat/arm/common/arm_cci.c
+++ b/plat/arm/common/arm_cci.c
@@ -9,8 +9,7 @@
 #include <arch.h>
 #include <drivers/arm/cci.h>
 #include <lib/utils.h>
-
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
 
 static const int cci_map[] = {
 	PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX,
diff --git a/plat/arm/common/arm_ccn.c b/plat/arm/common/arm_ccn.c
index 6aa56f2..2e681ca 100644
--- a/plat/arm/common/arm_ccn.c
+++ b/plat/arm/common/arm_ccn.c
@@ -8,8 +8,7 @@
 
 #include <arch.h>
 #include <drivers/arm/ccn.h>
-
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
 
 static const unsigned char master_to_rn_id_map[] = {
 	PLAT_ARM_CLUSTER_TO_CCN_ID_MAP
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index 4cd2ce3..5361d4a 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -14,11 +14,10 @@
 #include <common/romlib.h>
 #include <lib/mmio.h>
 #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 <plat_arm.h>
-
 /* Weak definitions may be overridden in specific ARM standard platform */
 #pragma weak plat_get_ns_image_entrypoint
 #pragma weak plat_arm_get_mmap
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index a8ac286..f18a9af 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -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
 #
@@ -141,9 +141,6 @@
     endif
 endif
 
-PLAT_INCLUDES		+=	-Iinclude/common/tbbr				\
-				-Iinclude/plat/arm/common
-
 ifeq (${ARCH}, aarch64)
 PLAT_INCLUDES		+=	-Iinclude/plat/arm/common/aarch64
 endif
@@ -240,7 +237,7 @@
 endif
 
 # SPM uses libfdt in Arm platforms
-ifeq (${SPM_DEPRECATED},0)
+ifeq (${SPM_MM},0)
 ifeq (${ENABLE_SPM},1)
 BL31_SOURCES		+=	common/fdt_wrappers.c			\
 				plat/common/plat_spm_rd.c		\
@@ -257,8 +254,6 @@
 				drivers/auth/img_parser_mod.c			\
 				drivers/auth/tbbr/tbbr_cot.c			\
 
-    PLAT_INCLUDES	+=	-Iinclude/bl1/tbbr
-
     BL1_SOURCES		+=	${AUTH_SOURCES}					\
 				bl1/tbbr/tbbr_img_desc.c			\
 				plat/arm/common/arm_bl1_fwu.c			\
diff --git a/plat/arm/common/arm_console.c b/plat/arm/common/arm_console.c
index 29cb378..0367085 100644
--- a/plat/arm/common/arm_console.c
+++ b/plat/arm/common/arm_console.c
@@ -11,8 +11,7 @@
 #include <common/debug.h>
 #include <drivers/arm/pl011.h>
 #include <drivers/console.h>
-
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
 
 /*******************************************************************************
  * Functions that set up the console
diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c
index 6c6dc56..1c58649 100644
--- a/plat/arm/common/arm_dyn_cfg.c
+++ b/plat/arm/common/arm_dyn_cfg.c
@@ -15,11 +15,10 @@
 #if TRUSTED_BOARD_BOOT
 #include <drivers/auth/mbedtls/mbedtls_config.h>
 #endif
+#include <plat/arm/common/arm_dyn_cfg_helpers.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <arm_dyn_cfg_helpers.h>
-#include <plat_arm.h>
-
 /* 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;
diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c
index bf2f156..36d37f8 100644
--- a/plat/arm/common/arm_dyn_cfg_helpers.c
+++ b/plat/arm/common/arm_dyn_cfg_helpers.c
@@ -10,9 +10,8 @@
 
 #include <common/desc_image_load.h>
 #include <common/fdt_wrappers.h>
-
-#include <arm_dyn_cfg_helpers.h>
-#include <plat_arm.h>
+#include <plat/arm/common/arm_dyn_cfg_helpers.h>
+#include <plat/arm/common/plat_arm.h>
 
 #define DTB_PROP_MBEDTLS_HEAP_ADDR "mbedtls_heap_addr"
 #define DTB_PROP_MBEDTLS_HEAP_SIZE "mbedtls_heap_size"
diff --git a/plat/arm/common/arm_err.c b/plat/arm/common/arm_err.c
index 8650d48..e77f5dc 100644
--- a/plat/arm/common/arm_err.c
+++ b/plat/arm/common/arm_err.c
@@ -13,10 +13,9 @@
 #include <common/debug.h>
 #include <drivers/cfi/v2m_flash.h>
 #include <drivers/console.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <plat_arm.h>
-
 #pragma weak plat_arm_error_handler
 
 /*
diff --git a/plat/arm/common/arm_gicv2.c b/plat/arm/common/arm_gicv2.c
index fc848c1..80a845f 100644
--- a/plat/arm/common/arm_gicv2.c
+++ b/plat/arm/common/arm_gicv2.c
@@ -7,10 +7,9 @@
 #include <platform_def.h>
 
 #include <drivers/arm/gicv2.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <plat_arm.h>
-
 /******************************************************************************
  * The following functions are defined as weak to allow a platform to override
  * the way the GICv2 driver is initialised and used.
diff --git a/plat/arm/common/arm_gicv3.c b/plat/arm/common/arm_gicv3.c
index 0f6690a..93bebf3 100644
--- a/plat/arm/common/arm_gicv3.c
+++ b/plat/arm/common/arm_gicv3.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
  */
@@ -9,11 +9,9 @@
 #include <common/interrupt_props.h>
 #include <drivers/arm/gicv3.h>
 #include <lib/utils.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <arm_def.h>
-#include <plat_arm.h>
-
 /******************************************************************************
  * The following functions are defined as weak to allow a platform to override
  * the way the GICv3 driver is initialised and used.
@@ -152,7 +150,7 @@
 	 * If an ITS is available, save its context before
 	 * the Redistributor using:
 	 * gicv3_its_save_disable(gits_base, &its_ctx[i])
-	 * Additionnaly, an implementation-defined sequence may
+	 * Additionally, an implementation-defined sequence may
 	 * be required to save the whole ITS state.
 	 */
 
diff --git a/plat/arm/common/arm_image_load.c b/plat/arm/common/arm_image_load.c
index 791f05e..2faaa76 100644
--- a/plat/arm/common/arm_image_load.c
+++ b/plat/arm/common/arm_image_load.c
@@ -4,17 +4,17 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <assert.h>
 #include <common/bl_common.h>
 #include <common/desc_image_load.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <arm_def.h>
-#include <plat_arm.h>
-
 #pragma weak plat_flush_next_bl_params
 #pragma weak plat_get_bl_image_load_info
 #pragma weak plat_get_next_bl_params
 
+static bl_params_t *next_bl_params_cpy_ptr;
 
 /*******************************************************************************
  * This function flushes the data structures so that they are visible
@@ -22,7 +22,11 @@
  ******************************************************************************/
 void plat_flush_next_bl_params(void)
 {
-	flush_bl_params_desc();
+	assert(next_bl_params_cpy_ptr != NULL);
+
+	flush_bl_params_desc_args(bl_mem_params_desc_ptr,
+		bl_mem_params_desc_num,
+		next_bl_params_cpy_ptr);
 }
 
 /*******************************************************************************
@@ -34,12 +38,53 @@
 }
 
 /*******************************************************************************
- * This function returns the list of executable images.
+ * ARM helper function to return the list of executable images.Since the default
+ * descriptors are allocated within BL2 RW memory, this prevents BL31/BL32
+ * overlay of BL2 memory. Hence this function also copies the descriptors to a
+ * pre-allocated memory indicated by ARM_BL2_MEM_DESC_BASE.
  ******************************************************************************/
-struct bl_params *plat_get_next_bl_params(void)
+struct bl_params *arm_get_next_bl_params(void)
 {
-	bl_params_t *next_bl_params = get_next_bl_params_from_mem_params_desc();
+	bl_mem_params_node_t *bl2_mem_params_descs_cpy
+			= (bl_mem_params_node_t *)ARM_BL2_MEM_DESC_BASE;
+	const bl_params_t *next_bl_params;
+
+	next_bl_params_cpy_ptr =
+		(bl_params_t *)(ARM_BL2_MEM_DESC_BASE +
+		(bl_mem_params_desc_num * sizeof(bl_mem_params_node_t)));
+
+	/*
+	 * Copy the memory descriptors to ARM_BL2_MEM_DESC_BASE area.
+	 */
+	(void) memcpy(bl2_mem_params_descs_cpy, bl_mem_params_desc_ptr,
+		(bl_mem_params_desc_num * sizeof(bl_mem_params_node_t)));
+
+	/*
+	 * Modify the global 'bl_mem_params_desc_ptr' to point to the
+	 * copied location.
+	 */
+	bl_mem_params_desc_ptr = bl2_mem_params_descs_cpy;
+
+	next_bl_params = get_next_bl_params_from_mem_params_desc();
+	assert(next_bl_params != NULL);
+
+	/*
+	 * Copy 'next_bl_params' to the reserved location after the copied
+	 * memory descriptors.
+	 */
+	(void) memcpy(next_bl_params_cpy_ptr, next_bl_params,
+						(sizeof(bl_params_t)));
 
-	populate_next_bl_params_config(next_bl_params);
-	return next_bl_params;
+	populate_next_bl_params_config(next_bl_params_cpy_ptr);
+
+	return next_bl_params_cpy_ptr;
+}
+
+/*******************************************************************************
+ * This function returns the list of executable images
+ ******************************************************************************/
+struct bl_params *plat_get_next_bl_params(void)
+{
+	return arm_get_next_bl_params();
 }
+
diff --git a/plat/arm/common/arm_io_storage.c b/plat/arm/common/arm_io_storage.c
index d7c5cac..fc1eb49 100644
--- a/plat/arm/common/arm_io_storage.c
+++ b/plat/arm/common/arm_io_storage.c
@@ -15,11 +15,10 @@
 #include <drivers/io/io_memmap.h>
 #include <drivers/io/io_storage.h>
 #include <lib/utils.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 #include <tools_share/firmware_image_package.h>
 
-#include <plat_arm.h>
-
 /* IO devices */
 static const io_dev_connector_t *fip_dev_con;
 static uintptr_t fip_dev_handle;
diff --git a/plat/arm/common/arm_nor_psci_mem_protect.c b/plat/arm/common/arm_nor_psci_mem_protect.c
index 4ae57e5..dfbd129 100644
--- a/plat/arm/common/arm_nor_psci_mem_protect.c
+++ b/plat/arm/common/arm_nor_psci_mem_protect.c
@@ -11,8 +11,7 @@
 #include <lib/psci/psci.h>
 #include <lib/mmio.h>
 #include <lib/utils.h>
-
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
 
 /*
  * DRAM1 is used also to load the NS boot loader. For this reason we
diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c
index acfd908..cb87baf 100644
--- a/plat/arm/common/arm_pm.c
+++ b/plat/arm/common/arm_pm.c
@@ -11,11 +11,9 @@
 
 #include <arch_helpers.h>
 #include <lib/psci/psci.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <arm_def.h>
-#include <plat_arm.h>
-
 /* Allow ARM Standard platforms to override these functions */
 #pragma weak plat_arm_program_trusted_mailbox
 
diff --git a/plat/arm/common/arm_sip_svc.c b/plat/arm/common/arm_sip_svc.c
index 6b0f7e7..3d308a3 100644
--- a/plat/arm/common/arm_sip_svc.c
+++ b/plat/arm/common/arm_sip_svc.c
@@ -9,11 +9,10 @@
 #include <common/debug.h>
 #include <common/runtime_svc.h>
 #include <lib/pmf/pmf.h>
+#include <plat/arm/common/arm_sip_svc.h>
+#include <plat/arm/common/plat_arm.h>
 #include <tools_share/uuid.h>
 
-#include <arm_sip_svc.h>
-#include <plat_arm.h>
-
 /* ARM SiP Service UUID */
 DEFINE_SVC_UUID2(arm_sip_svc_uid,
 	0x556d75e2, 0x6033, 0xb54b, 0xb5, 0x75,
diff --git a/plat/arm/common/arm_topology.c b/plat/arm/common/arm_topology.c
index 6986e52..37047bc 100644
--- a/plat/arm/common/arm_topology.c
+++ b/plat/arm/common/arm_topology.c
@@ -7,8 +7,7 @@
 #include <platform_def.h>
 
 #include <arch.h>
-
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
 
 /*******************************************************************************
  * This function validates an MPIDR by checking whether it falls within the
diff --git a/plat/arm/common/arm_tzc400.c b/plat/arm/common/arm_tzc400.c
index 0346fa1..34e650f 100644
--- a/plat/arm/common/arm_tzc400.c
+++ b/plat/arm/common/arm_tzc400.c
@@ -8,10 +8,7 @@
 
 #include <common/debug.h>
 #include <drivers/arm/tzc400.h>
-
-#include <arm_def.h>
-#include <arm_spm_def.h>
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
 
 /* Weak definitions may be overridden in specific ARM standard platform */
 #pragma weak plat_arm_security_setup
diff --git a/plat/arm/common/arm_tzc_dmc500.c b/plat/arm/common/arm_tzc_dmc500.c
index bea3867..e9f897f 100644
--- a/plat/arm/common/arm_tzc_dmc500.c
+++ b/plat/arm/common/arm_tzc_dmc500.c
@@ -10,9 +10,7 @@
 
 #include <common/debug.h>
 #include <drivers/arm/tzc_dmc500.h>
-
-#include <arm_def.h>
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
 
 /*******************************************************************************
  * Initialize the DMC500-TrustZone Controller for ARM standard platforms.
diff --git a/plat/arm/common/execution_state_switch.c b/plat/arm/common/execution_state_switch.c
index e313410..d471130 100644
--- a/plat/arm/common/execution_state_switch.c
+++ b/plat/arm/common/execution_state_switch.c
@@ -12,11 +12,10 @@
 #include <lib/el3_runtime/context_mgmt.h>
 #include <lib/psci/psci.h>
 #include <lib/utils.h>
+#include <plat/arm/common/arm_sip_svc.h>
+#include <plat/arm/common/plat_arm.h>
 #include <smccc_helpers.h>
 
-#include <arm_sip_svc.h>
-#include <plat_arm.h>
-
 /*
  * Handle SMC from a lower exception level to switch its execution state
  * (either from AArch64 to AArch32, or vice versa).
diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c
index 967b551..c0ea027 100644
--- a/plat/arm/common/sp_min/arm_sp_min_setup.c
+++ b/plat/arm/common/sp_min/arm_sp_min_setup.c
@@ -14,10 +14,9 @@
 #include <drivers/arm/pl011.h>
 #include <drivers/console.h>
 #include <lib/mmio.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <plat_arm.h>
-
 static entry_point_info_t bl33_image_ep_info;
 
 /* Weak definitions may be overridden in specific ARM standard platform */
diff --git a/plat/arm/common/tsp/arm_tsp_setup.c b/plat/arm/common/tsp/arm_tsp_setup.c
index a3d2f71..2965ccd 100644
--- a/plat/arm/common/tsp/arm_tsp_setup.c
+++ b/plat/arm/common/tsp/arm_tsp_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
  */
@@ -13,9 +13,7 @@
 #include <common/debug.h>
 #include <drivers/arm/pl011.h>
 #include <drivers/console.h>
-
-#include <arm_def.h>
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
 
 #define BL32_END (unsigned long)(&__BL32_END__)
 
@@ -78,7 +76,7 @@
 void tsp_plat_arch_setup(void)
 {
 #if USE_COHERENT_MEM
-	/* Ensure ARM platforms dont use coherent memory in TSP */
+	/* Ensure ARM platforms don't use coherent memory in TSP */
 	assert((BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE) == 0U);
 #endif
 
diff --git a/plat/arm/css/common/aarch32/css_helpers.S b/plat/arm/css/common/aarch32/css_helpers.S
index 80aa24c..d47e13d 100644
--- a/plat/arm/css/common/aarch32/css_helpers.S
+++ b/plat/arm/css/common/aarch32/css_helpers.S
@@ -3,10 +3,11 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
+
 #include <arch.h>
 #include <asm_macros.S>
 #include <cpu_macros.S>
-#include <css_def.h>
+#include <platform_def.h>
 
 	.weak	plat_secondary_cold_boot_setup
 	.weak	plat_get_my_entrypoint
diff --git a/plat/arm/css/common/aarch64/css_helpers.S b/plat/arm/css/common/aarch64/css_helpers.S
index 5096d8d..01669be 100644
--- a/plat/arm/css/common/aarch64/css_helpers.S
+++ b/plat/arm/css/common/aarch64/css_helpers.S
@@ -3,10 +3,11 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
+
 #include <arch.h>
 #include <asm_macros.S>
 #include <cpu_macros.S>
-#include <css_def.h>
+#include <platform_def.h>
 
 	.weak	plat_secondary_cold_boot_setup
 	.weak	plat_get_my_entrypoint
diff --git a/plat/arm/css/common/css_bl1_setup.c b/plat/arm/css/common/css_bl1_setup.c
index ae0f011..596cc3d 100644
--- a/plat/arm/css/common/css_bl1_setup.c
+++ b/plat/arm/css/common/css_bl1_setup.c
@@ -6,11 +6,10 @@
 
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/soc/common/soc_css.h>
 #include <plat/common/platform.h>
 
-#include <plat_arm.h>
-#include <soc_css.h>
-
 void bl1_platform_setup(void)
 {
 	arm_bl1_platform_setup();
diff --git a/plat/arm/css/common/css_bl2_setup.c b/plat/arm/css/common/css_bl2_setup.c
index c1c7868..002c6eb 100644
--- a/plat/arm/css/common/css_bl2_setup.c
+++ b/plat/arm/css/common/css_bl2_setup.c
@@ -8,13 +8,11 @@
 
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <drivers/arm/css/css_scp.h>
 #include <lib/mmio.h>
 #include <lib/utils.h>
-
-#include <css_def.h>
-#include <plat_arm.h>
-
-#include "../drivers/scp/css_scp.h"
+#include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
 
 /* Weak definition may be overridden in specific CSS based platform */
 #pragma weak plat_arm_bl2_handle_scp_bl2
diff --git a/plat/arm/css/common/css_bl2u_setup.c b/plat/arm/css/common/css_bl2u_setup.c
index 564e98f..15cf4f6 100644
--- a/plat/arm/css/common/css_bl2u_setup.c
+++ b/plat/arm/css/common/css_bl2u_setup.c
@@ -6,12 +6,10 @@
 
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <drivers/arm/css/css_scp.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <plat_arm.h>
-
-#include "../drivers/scp/css_scp.h"
-
 /* Weak definition may be overridden in specific CSS based platform */
 #pragma weak bl2u_plat_handle_scp_bl2u
 
diff --git a/plat/arm/css/common/css_common.mk b/plat/arm/css/common/css_common.mk
index ca1edab..2fbbe45 100644
--- a/plat/arm/css/common/css_common.mk
+++ b/plat/arm/css/common/css_common.mk
@@ -11,8 +11,7 @@
 # By default, SCMI driver is disabled for CSS platforms
 CSS_USE_SCMI_SDS_DRIVER	?=	0
 
-PLAT_INCLUDES		+=	-Iinclude/plat/arm/css/common			\
-				-Iinclude/plat/arm/css/common/aarch64
+PLAT_INCLUDES		+=	-Iinclude/plat/arm/css/common/aarch64
 
 
 PLAT_BL_COMMON_SOURCES	+=	plat/arm/css/common/${ARCH}/css_helpers.S
@@ -27,16 +26,16 @@
 				plat/arm/css/common/css_topology.c
 
 ifeq (${CSS_USE_SCMI_SDS_DRIVER},0)
-BL31_SOURCES		+=	plat/arm/css/drivers/scp/css_pm_scpi.c		\
-				plat/arm/css/drivers/mhu/css_mhu.c		\
-				plat/arm/css/drivers/scpi/css_scpi.c
+BL31_SOURCES		+=	drivers/arm/css/mhu/css_mhu.c			\
+				drivers/arm/css/scp/css_pm_scpi.c		\
+				drivers/arm/css/scpi/css_scpi.c
 else
-BL31_SOURCES		+=	plat/arm/css/drivers/scp/css_pm_scmi.c		\
-				plat/arm/css/drivers/scmi/scmi_ap_core_proto.c	\
-				plat/arm/css/drivers/scmi/scmi_common.c		\
-				plat/arm/css/drivers/scmi/scmi_pwr_dmn_proto.c	\
-				plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c	\
-				plat/arm/css/drivers/mhu/css_mhu_doorbell.c
+BL31_SOURCES		+=	drivers/arm/css/mhu/css_mhu_doorbell.c		\
+				drivers/arm/css/scmi/scmi_ap_core_proto.c	\
+				drivers/arm/css/scmi/scmi_common.c		\
+				drivers/arm/css/scmi/scmi_pwr_dmn_proto.c	\
+				drivers/arm/css/scmi/scmi_sys_pwr_proto.c	\
+				drivers/arm/css/scp/css_pm_scmi.c
 endif
 
 # Process CSS_LOAD_SCP_IMAGES flag
@@ -50,19 +49,19 @@
   endif
 
   ifeq (${CSS_USE_SCMI_SDS_DRIVER},1)
-    BL2U_SOURCES	+=	plat/arm/css/drivers/scp/css_sds.c	\
-				plat/arm/css/drivers/sds/sds.c
+    BL2U_SOURCES	+=	drivers/arm/css/scp/css_sds.c			\
+				drivers/arm/css/sds/sds.c
 
-    BL2_SOURCES		+=	plat/arm/css/drivers/scp/css_sds.c	\
-				plat/arm/css/drivers/sds/sds.c
+    BL2_SOURCES		+=	drivers/arm/css/scp/css_sds.c			\
+				drivers/arm/css/sds/sds.c
   else
-    BL2U_SOURCES	+=	plat/arm/css/drivers/scp/css_bom_bootloader.c	\
-				plat/arm/css/drivers/mhu/css_mhu.c		\
-				plat/arm/css/drivers/scpi/css_scpi.c
+    BL2U_SOURCES	+=	drivers/arm/css/mhu/css_mhu.c			\
+				drivers/arm/css/scp/css_bom_bootloader.c	\
+				drivers/arm/css/scpi/css_scpi.c
 
-    BL2_SOURCES		+=	plat/arm/css/drivers/scp/css_bom_bootloader.c	\
-				plat/arm/css/drivers/mhu/css_mhu.c		\
-				plat/arm/css/drivers/scpi/css_scpi.c
+    BL2_SOURCES		+=	drivers/arm/css/mhu/css_mhu.c			\
+				drivers/arm/css/scp/css_bom_bootloader.c	\
+				drivers/arm/css/scpi/css_scpi.c
     # Enable option to detect whether the SCP ROM firmware in use predates version
     # 1.7.0 and therefore, is incompatible.
     CSS_DETECT_PRE_1_7_0_SCP	:=	1
@@ -74,7 +73,7 @@
 endif
 
 ifeq (${CSS_USE_SCMI_SDS_DRIVER},1)
-  PLAT_BL_COMMON_SOURCES	+=	plat/arm/css/drivers/sds/${ARCH}/sds_helpers.S
+  PLAT_BL_COMMON_SOURCES	+=	drivers/arm/css/sds/${ARCH}/sds_helpers.S
 endif
 
 # Process CSS_USE_SCMI_SDS_DRIVER flag
diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c
index 8a156e6..f6fc6aa 100644
--- a/plat/arm/css/common/css_pm.c
+++ b/plat/arm/css/common/css_pm.c
@@ -11,14 +11,12 @@
 
 #include <arch_helpers.h>
 #include <common/debug.h>
+#include <drivers/arm/css/css_scp.h>
 #include <lib/cassert.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/css/common/css_pm.h>
 #include <plat/common/platform.h>
 
-#include <css_pm.h>
-#include <plat_arm.h>
-
-#include "../drivers/scp/css_scp.h"
-
 /* Allow CSS platforms to override `plat_arm_psci_pm_ops` */
 #pragma weak plat_arm_psci_pm_ops
 
diff --git a/plat/arm/css/common/css_topology.c b/plat/arm/css/common/css_topology.c
index 8ac2232..8aca744 100644
--- a/plat/arm/css/common/css_topology.c
+++ b/plat/arm/css/common/css_topology.c
@@ -6,10 +6,9 @@
 
 #include <assert.h>
 
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <plat_arm.h>
-
 #if ARM_PLAT_MT
 #pragma weak plat_arm_get_cpu_pe_count
 #endif
diff --git a/plat/arm/css/common/sp_min/css_sp_min.mk b/plat/arm/css/common/sp_min/css_sp_min.mk
index 9fb280c..6523a16 100644
--- a/plat/arm/css/common/sp_min/css_sp_min.mk
+++ b/plat/arm/css/common/sp_min/css_sp_min.mk
@@ -9,13 +9,13 @@
 				plat/arm/css/common/css_topology.c
 
 ifeq (${CSS_USE_SCMI_SDS_DRIVER},0)
-BL32_SOURCES		+=	plat/arm/css/drivers/scp/css_pm_scpi.c		\
-				plat/arm/css/drivers/mhu/css_mhu.c		\
-				plat/arm/css/drivers/scpi/css_scpi.c
+BL32_SOURCES		+=	drivers/arm/css/mhu/css_mhu.c			\
+				drivers/arm/css/scp/css_pm_scpi.c		\
+				drivers/arm/css/scpi/css_scpi.c
 else
-BL32_SOURCES		+=	plat/arm/css/drivers/scp/css_pm_scmi.c		\
-				plat/arm/css/drivers/scmi/scmi_common.c		\
-				plat/arm/css/drivers/scmi/scmi_pwr_dmn_proto.c	\
-				plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c	\
-				plat/arm/css/drivers/mhu/css_mhu_doorbell.c
+BL32_SOURCES		+=	drivers/arm/css/mhu/css_mhu_doorbell.c		\
+				drivers/arm/css/scp/css_pm_scmi.c		\
+				drivers/arm/css/scmi/scmi_common.c		\
+				drivers/arm/css/scmi/scmi_pwr_dmn_proto.c	\
+				drivers/arm/css/scmi/scmi_sys_pwr_proto.c
 endif
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 ad7ab81..c0e6555 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -9,15 +9,14 @@
 
 #include <lib/utils_def.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
+#include <plat/arm/board/common/board_css_def.h>
+#include <plat/arm/board/common/v2m_def.h>
+#include <plat/arm/common/arm_def.h>
+#include <plat/arm/common/arm_spm_def.h>
+#include <plat/arm/css/common/css_def.h>
+#include <plat/arm/soc/common/soc_css_def.h>
 #include <plat/common/common_def.h>
 
-#include <arm_def.h>
-#include <arm_spm_def.h>
-#include <board_css_def.h>
-#include <css_def.h>
-#include <soc_css_def.h>
-#include <v2m_def.h>
-
 #define PLATFORM_CORE_COUNT		(PLAT_ARM_CLUSTER_COUNT *	\
 					CSS_SGI_MAX_CPUS_PER_CLUSTER * \
 					CSS_SGI_MAX_PE_PER_CPU)
@@ -147,8 +146,8 @@
 /* Allocate 128KB for CPER buffers */
 #define PLAT_SP_BUF_BASE			ULL(0x20000)
 
-#define PLAT_ARM_SP_IMAGE_STACK_BASE		(ARM_SP_IMAGE_NS_BUF_BASE + \
-						ARM_SP_IMAGE_NS_BUF_SIZE + \
+#define PLAT_ARM_SP_IMAGE_STACK_BASE		(PLAT_SP_IMAGE_NS_BUF_BASE + \
+						PLAT_SP_IMAGE_NS_BUF_SIZE + \
 						PLAT_SP_BUF_BASE)
 
 /* Platform specific SMC FID's used for RAS */
@@ -171,8 +170,8 @@
 	SDEI_EXPLICIT_EVENT(SGI_SDEI_DS_EVENT_1, SDEI_MAPF_CRITICAL),
 #define PLAT_ARM_SHARED_SDEI_EVENTS
 
-#define ARM_SP_CPER_BUF_BASE			(ARM_SP_IMAGE_NS_BUF_BASE + \
-						ARM_SP_IMAGE_NS_BUF_SIZE)
+#define ARM_SP_CPER_BUF_BASE			(PLAT_SP_IMAGE_NS_BUF_BASE + \
+						PLAT_SP_IMAGE_NS_BUF_SIZE)
 #define ARM_SP_CPER_BUF_SIZE			ULL(0x20000)
 #define ARM_SP_CPER_BUF_MMAP			MAP_REGION2(		\
 						ARM_SP_CPER_BUF_BASE,	\
@@ -182,8 +181,8 @@
 						PAGE_SIZE)
 
 #else
-#define PLAT_ARM_SP_IMAGE_STACK_BASE	(ARM_SP_IMAGE_NS_BUF_BASE +	\
-					 ARM_SP_IMAGE_NS_BUF_SIZE)
+#define PLAT_ARM_SP_IMAGE_STACK_BASE	(PLAT_SP_IMAGE_NS_BUF_BASE +	\
+					 PLAT_SP_IMAGE_NS_BUF_SIZE)
 #endif /* RAS_EXTENSION */
 
 /* Platform ID address */
diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c
index 617a62b..bfcb521 100644
--- a/plat/arm/css/sgi/sgi_bl31_setup.c
+++ b/plat/arm/css/sgi/sgi_bl31_setup.c
@@ -10,14 +10,13 @@
 
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <drivers/arm/css/css_mhu_doorbell.h>
+#include <drivers/arm/css/scmi.h>
+#include <plat/arm/common/plat_arm.h>
 
-#include <plat_arm.h>
 #include <sgi_ras.h>
 #include <sgi_variant.h>
 
-#include "../../css/drivers/scmi/scmi.h"
-#include "../../css/drivers/mhu/css_mhu_doorbell.h"
-
 sgi_platform_info_t sgi_plat_info;
 
 static scmi_channel_plat_info_t sgi575_scmi_plat_info = {
diff --git a/plat/arm/css/sgi/sgi_image_load.c b/plat/arm/css/sgi/sgi_image_load.c
index 1ed219d..a2f10dc 100644
--- a/plat/arm/css/sgi/sgi_image_load.c
+++ b/plat/arm/css/sgi/sgi_image_load.c
@@ -9,6 +9,7 @@
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <common/desc_image_load.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
 #include <sgi_variant.h>
@@ -72,14 +73,11 @@
 bl_params_t *plat_get_next_bl_params(void)
 {
 	int ret;
-	bl_params_t *next_bl_params;
 
 	ret = plat_sgi_append_config_node();
 	if (ret != 0)
 		panic();
 
-	next_bl_params = get_next_bl_params_from_mem_params_desc();
-	populate_next_bl_params_config(next_bl_params);
-
-	return next_bl_params;
+	return arm_get_next_bl_params();
 }
+
diff --git a/plat/arm/css/sgi/sgi_plat.c b/plat/arm/css/sgi/sgi_plat.c
index 79f3e5b..83ca30c 100644
--- a/plat/arm/css/sgi/sgi_plat.c
+++ b/plat/arm/css/sgi/sgi_plat.c
@@ -11,14 +11,10 @@
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <drivers/arm/ccn.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 #include <services/secure_partition.h>
 
-#include <arm_def.h>
-#include <arm_spm_def.h>
-#include <plat_arm.h>
-#include "../../../../bl1/bl1_private.h"
-
 #if USE_COHERENT_MEM
 /*
  * The next 2 constants identify the extents of the coherent memory region.
@@ -127,12 +123,12 @@
 	.sp_image_base       = ARM_SP_IMAGE_BASE,
 	.sp_stack_base       = PLAT_SP_IMAGE_STACK_BASE,
 	.sp_heap_base        = ARM_SP_IMAGE_HEAP_BASE,
-	.sp_ns_comm_buf_base = ARM_SP_IMAGE_NS_BUF_BASE,
+	.sp_ns_comm_buf_base = PLAT_SP_IMAGE_NS_BUF_BASE,
 	.sp_shared_buf_base  = PLAT_SPM_BUF_BASE,
 	.sp_image_size       = ARM_SP_IMAGE_SIZE,
 	.sp_pcpu_stack_size  = PLAT_SP_IMAGE_STACK_PCPU_SIZE,
 	.sp_heap_size        = ARM_SP_IMAGE_HEAP_SIZE,
-	.sp_ns_comm_buf_size = ARM_SP_IMAGE_NS_BUF_SIZE,
+	.sp_ns_comm_buf_size = PLAT_SP_IMAGE_NS_BUF_SIZE,
 	.sp_shared_buf_size  = PLAT_SPM_BUF_SIZE,
 	.num_sp_mem_regions  = ARM_SP_IMAGE_NUM_MEM_REGIONS,
 	.num_cpus            = PLATFORM_CORE_COUNT,
diff --git a/plat/arm/css/sgi/sgi_ras.c b/plat/arm/css/sgi/sgi_ras.c
index a6a32d1..0001ffd 100644
--- a/plat/arm/css/sgi/sgi_ras.c
+++ b/plat/arm/css/sgi/sgi_ras.c
@@ -10,12 +10,12 @@
 #include <bl31/interrupt_mgmt.h>
 #include <lib/el3_runtime/context_mgmt.h>
 #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 <arm_spm_def.h>
 #include <sgi_ras.h>
 
 static int sgi_ras_intr_handler(const struct err_record_info *err_rec,
diff --git a/plat/arm/css/sgi/sgi_topology.c b/plat/arm/css/sgi/sgi_topology.c
index 2921c0c..dafaf40 100644
--- a/plat/arm/css/sgi/sgi_topology.c
+++ b/plat/arm/css/sgi/sgi_topology.c
@@ -4,7 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
+
 #include <sgi_variant.h>
 
 /* Topology */
diff --git a/plat/arm/css/sgm/include/platform_oid.h b/plat/arm/css/sgm/include/platform_oid.h
index 18d41e3..fd1854a 100644
--- a/plat/arm/css/sgm/include/platform_oid.h
+++ b/plat/arm/css/sgm/include/platform_oid.h
@@ -3,7 +3,8 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-#include "../../../../../include/plat/arm/board/common/board_arm_oid.h"
+
+#include <plat/arm/board/common/board_arm_oid.h>
 
 /*
  * Required platform OIDs
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 e3fa3f3..4647e74 100644
--- a/plat/arm/css/sgm/include/sgm_base_platform_def.h
+++ b/plat/arm/css/sgm/include/sgm_base_platform_def.h
@@ -9,14 +9,13 @@
 
 #include <drivers/arm/tzc400.h>
 #include <drivers/arm/tzc_common.h>
+#include <plat/arm/board/common/board_css_def.h>
+#include <plat/arm/board/common/v2m_def.h>
+#include <plat/arm/common/arm_def.h>
+#include <plat/arm/css/common/css_def.h>
+#include <plat/arm/soc/common/soc_css_def.h>
 #include <plat/common/common_def.h>
 
-#include <arm_def.h>
-#include <board_css_def.h>
-#include <css_def.h>
-#include <soc_css_def.h>
-#include <v2m_def.h>
-
 /* CPU topology */
 #define PLAT_ARM_CLUSTER_COUNT		1
 #define PLAT_ARM_CLUSTER_CORE_COUNT	8
diff --git a/plat/arm/css/sgm/sgm_bl1_setup.c b/plat/arm/css/sgm/sgm_bl1_setup.c
index 8b7c5da..2036515 100644
--- a/plat/arm/css/sgm/sgm_bl1_setup.c
+++ b/plat/arm/css/sgm/sgm_bl1_setup.c
@@ -6,10 +6,10 @@
 
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/soc/common/soc_css.h>
 
-#include <plat_arm.h>
 #include <sgm_plat_config.h>
-#include <soc_css.h>
 
 void bl1_early_platform_setup(void)
 {
diff --git a/plat/arm/css/sgm/sgm_bl31_setup.c b/plat/arm/css/sgm/sgm_bl31_setup.c
index 7967cb5..7e92ac8 100644
--- a/plat/arm/css/sgm/sgm_bl31_setup.c
+++ b/plat/arm/css/sgm/sgm_bl31_setup.c
@@ -6,13 +6,12 @@
 
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <drivers/arm/css/css_mhu_doorbell.h>
+#include <drivers/arm/css/scmi.h>
+#include <plat/arm/common/plat_arm.h>
 
-#include <plat_arm.h>
 #include <sgm_plat_config.h>
 
-#include "../../css/drivers/scmi/scmi.h"
-#include "../../css/drivers/mhu/css_mhu_doorbell.h"
-
 static scmi_channel_plat_info_t sgm775_scmi_plat_info = {
 		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
 		.db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
diff --git a/plat/arm/css/sgm/sgm_mmap_config.c b/plat/arm/css/sgm/sgm_mmap_config.c
index a4df9ab..e5b4b03 100644
--- a/plat/arm/css/sgm/sgm_mmap_config.c
+++ b/plat/arm/css/sgm/sgm_mmap_config.c
@@ -8,9 +8,8 @@
 
 #include <common/bl_common.h>
 #include <common/debug.h>
+#include <plat/arm/common/plat_arm.h>
 
-#include <arm_def.h>
-#include <plat_arm.h>
 #include <sgm_variant.h>
 
 /*
diff --git a/plat/arm/css/sgm/sgm_plat_config.c b/plat/arm/css/sgm/sgm_plat_config.c
index 2a43487..d9e65c5 100644
--- a/plat/arm/css/sgm/sgm_plat_config.c
+++ b/plat/arm/css/sgm/sgm_plat_config.c
@@ -10,8 +10,8 @@
 #include <platform_def.h>
 
 #include <common/debug.h>
+#include <plat/arm/common/plat_arm.h>
 
-#include <plat_arm.h>
 #include <sgm_plat_config.h>
 #include <sgm_variant.h>
 
diff --git a/plat/arm/css/sgm/sgm_security.c b/plat/arm/css/sgm/sgm_security.c
index 548ec7b..21d5306 100644
--- a/plat/arm/css/sgm/sgm_security.c
+++ b/plat/arm/css/sgm/sgm_security.c
@@ -6,10 +6,10 @@
 
 #include <common/debug.h>
 #include <drivers/arm/tzc_dmc500.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/soc/common/soc_css.h>
 
-#include <plat_arm.h>
 #include <sgm_variant.h>
-#include <soc_css.h>
 
 /* Is populated with the DMC-500 controllers base addresses */
 static tzc_dmc500_driver_data_t plat_driver_data;
diff --git a/plat/arm/css/sgm/sgm_topology.c b/plat/arm/css/sgm/sgm_topology.c
index ce72464..2d9552d 100644
--- a/plat/arm/css/sgm/sgm_topology.c
+++ b/plat/arm/css/sgm/sgm_topology.c
@@ -4,7 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
+
 #include <sgm_plat_config.h>
 
 /*******************************************************************************
diff --git a/plat/arm/css/sgm/tsp/sgm_tsp_setup.c b/plat/arm/css/sgm/tsp/sgm_tsp_setup.c
index 39bba94..5f40c4c 100644
--- a/plat/arm/css/sgm/tsp/sgm_tsp_setup.c
+++ b/plat/arm/css/sgm/tsp/sgm_tsp_setup.c
@@ -4,7 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
+
 #include <sgm_plat_config.h>
 
 void tsp_early_platform_setup(void)
diff --git a/plat/arm/soc/common/soc_css.mk b/plat/arm/soc/common/soc_css.mk
index e009467..8cad2a5 100644
--- a/plat/arm/soc/common/soc_css.mk
+++ b/plat/arm/soc/common/soc_css.mk
@@ -4,8 +4,6 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-PLAT_INCLUDES		+=	-Iinclude/plat/arm/soc/common/
-
 #PLAT_BL_COMMON_SOURCES	+=
 
 BL1_SOURCES		+=	plat/arm/soc/common/soc_css_security.c
diff --git a/plat/arm/soc/common/soc_css_security.c b/plat/arm/soc/common/soc_css_security.c
index bbc5dcd..4f6bf61 100644
--- a/plat/arm/soc/common/soc_css_security.c
+++ b/plat/arm/soc/common/soc_css_security.c
@@ -8,10 +8,7 @@
 
 #include <drivers/arm/nic_400.h>
 #include <lib/mmio.h>
-
-#include <board_css_def.h>
-#include <soc_css.h>
-#include <soc_css_def.h>
+#include <plat/arm/soc/common/soc_css.h>
 
 void soc_css_init_nic400(void)
 {
diff --git a/plat/hisilicon/hikey/hikey_bl1_setup.c b/plat/hisilicon/hikey/hikey_bl1_setup.c
index a08bdfa..a97d763 100644
--- a/plat/hisilicon/hikey/hikey_bl1_setup.c
+++ b/plat/hisilicon/hikey/hikey_bl1_setup.c
@@ -22,7 +22,6 @@
 #include <hikey_def.h>
 #include <hikey_layout.h>
 
-#include "../../../bl1/bl1_private.h"
 #include "hikey_private.h"
 
 /* Data structure which holds the extents of the trusted RAM for BL1 */
diff --git a/plat/hisilicon/hikey960/hikey960_bl1_setup.c b/plat/hisilicon/hikey960/hikey960_bl1_setup.c
index 38bdbe4..4a7036c 100644
--- a/plat/hisilicon/hikey960/hikey960_bl1_setup.c
+++ b/plat/hisilicon/hikey960/hikey960_bl1_setup.c
@@ -25,7 +25,6 @@
 #include <plat/common/platform.h>
 
 #include <hi3660.h>
-#include "../../../bl1/bl1_private.h"
 #include "hikey960_def.h"
 #include "hikey960_private.h"
 
diff --git a/plat/hisilicon/hikey960/hikey960_def.h b/plat/hisilicon/hikey960/hikey960_def.h
index d977c79..4ea3acd 100644
--- a/plat/hisilicon/hikey960/hikey960_def.h
+++ b/plat/hisilicon/hikey960/hikey960_def.h
@@ -11,7 +11,7 @@
 #include <plat/common/common_def.h>
 
 #define DDR_BASE			0x0
-#define DDR_SIZE			0xC0000000
+#define DDR_SIZE			0xE0000000
 
 #define DEVICE_BASE			0xE0000000
 #define DEVICE_SIZE			0x20000000
diff --git a/plat/hisilicon/hikey960/include/platform_def.h b/plat/hisilicon/hikey960/include/platform_def.h
index 3e2d79d..7c3c102 100644
--- a/plat/hisilicon/hikey960/include/platform_def.h
+++ b/plat/hisilicon/hikey960/include/platform_def.h
@@ -122,11 +122,7 @@
 #endif
 
 #ifdef IMAGE_BL2
-#ifdef SPD_opteed
 #define MAX_XLAT_TABLES			4
-#else
-#define MAX_XLAT_TABLES			3
-#endif
 #endif
 
 #define MAX_MMAP_REGIONS		16
diff --git a/plat/hisilicon/poplar/bl1_plat_setup.c b/plat/hisilicon/poplar/bl1_plat_setup.c
index eb8ffe4..08ad67c 100644
--- a/plat/hisilicon/poplar/bl1_plat_setup.c
+++ b/plat/hisilicon/poplar/bl1_plat_setup.c
@@ -22,7 +22,6 @@
 #include <lib/mmio.h>
 #include <plat/common/platform.h>
 
-#include "../../../bl1/bl1_private.h"
 #include "hi3798cv200.h"
 #include "plat_private.h"
 
diff --git a/plat/imx/common/imx8_psci.c b/plat/imx/common/imx8_psci.c
index 588d8b4..91d3370 100644
--- a/plat/imx/common/imx8_psci.c
+++ b/plat/imx/common/imx8_psci.c
@@ -32,8 +32,22 @@
 int imx_validate_power_state(unsigned int power_state,
 			 psci_power_state_t *req_state)
 {
-	/* TODO */
-	return PSCI_E_INVALID_PARAMS;
+	int pwr_lvl = psci_get_pstate_pwrlvl(power_state);
+	int pwr_type = psci_get_pstate_type(power_state);
+	int state_id = psci_get_pstate_id(power_state);
+
+	if (pwr_lvl > PLAT_MAX_PWR_LVL)
+		return PSCI_E_INVALID_PARAMS;
+
+	if (pwr_type == PSTATE_TYPE_POWERDOWN) {
+		req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_OFF_STATE;
+		if (!state_id)
+			req_state->pwr_domain_state[MPIDR_AFFLVL1] = PLAT_MAX_RET_STATE;
+		else
+			req_state->pwr_domain_state[MPIDR_AFFLVL1] = PLAT_MAX_OFF_STATE;
+	}
+
+	return PSCI_E_SUCCESS;
 }
 
 void imx_get_sys_suspend_power_state(psci_power_state_t *req_state)
diff --git a/plat/imx/common/imx_sip_handler.c b/plat/imx/common/imx_sip_handler.c
new file mode 100644
index 0000000..55639cd
--- /dev/null
+++ b/plat/imx/common/imx_sip_handler.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2019 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <std_svc.h>
+#include <string.h>
+#include <platform_def.h>
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <imx_sip_svc.h>
+#include <sci/sci.h>
+
+#ifdef PLAT_IMX8QM
+const static int ap_cluster_index[PLATFORM_CLUSTER_COUNT] = {
+	SC_R_A53, SC_R_A72,
+};
+#endif
+
+static int imx_srtc_set_time(uint32_t year_mon,
+			unsigned long day_hour,
+			unsigned long min_sec)
+{
+	return sc_timer_set_rtc_time(ipc_handle,
+		year_mon >> 16, year_mon & 0xffff,
+		day_hour >> 16, day_hour & 0xffff,
+		min_sec >> 16, min_sec & 0xffff);
+}
+
+int imx_srtc_handler(uint32_t smc_fid,
+		    void *handle,
+		    u_register_t x1,
+		    u_register_t x2,
+		    u_register_t x3,
+		    u_register_t x4)
+{
+	int ret;
+
+	switch (x1) {
+	case IMX_SIP_SRTC_SET_TIME:
+		ret = imx_srtc_set_time(x2, x3, x4);
+		break;
+	default:
+		ret = SMC_UNK;
+	}
+
+	SMC_RET1(handle, ret);
+}
+
+static void imx_cpufreq_set_target(uint32_t cluster_id, unsigned long freq)
+{
+	sc_pm_clock_rate_t rate = (sc_pm_clock_rate_t)freq;
+
+#ifdef PLAT_IMX8QM
+	sc_pm_set_clock_rate(ipc_handle, ap_cluster_index[cluster_id], SC_PM_CLK_CPU, &rate);
+#endif
+#ifdef PLAT_IMX8QX
+	sc_pm_set_clock_rate(ipc_handle, SC_R_A35, SC_PM_CLK_CPU, &rate);
+#endif
+}
+
+int imx_cpufreq_handler(uint32_t smc_fid,
+		    u_register_t x1,
+		    u_register_t x2,
+		    u_register_t x3)
+{
+	switch (x1) {
+	case IMX_SIP_SET_CPUFREQ:
+		imx_cpufreq_set_target(x2, x3);
+		break;
+	default:
+		return SMC_UNK;
+	}
+
+	return 0;
+}
+
+static bool wakeup_src_irqsteer;
+
+bool imx_is_wakeup_src_irqsteer(void)
+{
+	return wakeup_src_irqsteer;
+}
+
+int imx_wakeup_src_handler(uint32_t smc_fid,
+		    u_register_t x1,
+		    u_register_t x2,
+		    u_register_t x3)
+{
+	switch (x1) {
+	case IMX_SIP_WAKEUP_SRC_IRQSTEER:
+		wakeup_src_irqsteer = true;
+		break;
+	case IMX_SIP_WAKEUP_SRC_SCU:
+		wakeup_src_irqsteer = false;
+		break;
+	default:
+		return SMC_UNK;
+	}
+
+	return SMC_OK;
+}
+
+int imx_otp_handler(uint32_t smc_fid,
+		void *handle,
+		u_register_t x1,
+		u_register_t x2)
+{
+	int ret;
+	uint32_t fuse;
+
+	switch (smc_fid) {
+	case IMX_SIP_OTP_READ:
+		ret = sc_misc_otp_fuse_read(ipc_handle, x1, &fuse);
+		SMC_RET2(handle, ret, fuse);
+		break;
+	case IMX_SIP_OTP_WRITE:
+		ret = sc_misc_otp_fuse_write(ipc_handle, x1, x2);
+		SMC_RET1(handle, ret);
+		break;
+	default:
+		ret = SMC_UNK;
+		SMC_RET1(handle, ret);
+		break;
+	}
+
+	return ret;
+}
+
+int imx_misc_set_temp_handler(uint32_t smc_fid,
+		    u_register_t x1,
+		    u_register_t x2,
+		    u_register_t x3,
+		    u_register_t x4)
+{
+	return sc_misc_set_temp(ipc_handle, x1, x2, x3, x4);
+}
+
+static uint64_t imx_get_commit_hash(u_register_t x2,
+		    u_register_t x3,
+		    u_register_t x4)
+{
+	/* Parse the version_string */
+	char *parse = (char *)version_string;
+	uint64_t hash = 0;
+
+	do {
+		parse = strchr(parse, '-');
+		if (parse) {
+			parse += 1;
+			if (*(parse) == 'g') {
+				/* Default is 7 hexadecimal digits */
+				memcpy((void *)&hash, (void *)(parse + 1), 7);
+				break;
+			}
+		}
+
+	} while (parse != NULL);
+
+	return hash;
+}
+
+uint64_t imx_buildinfo_handler(uint32_t smc_fid,
+		    u_register_t x1,
+		    u_register_t x2,
+		    u_register_t x3,
+		    u_register_t x4)
+{
+	uint64_t ret;
+
+	switch (x1) {
+	case IMX_SIP_BUILDINFO_GET_COMMITHASH:
+		ret = imx_get_commit_hash(x2, x3, x4);
+		break;
+	default:
+		return SMC_UNK;
+	}
+
+	return ret;
+}
diff --git a/plat/imx/common/imx_sip_svc.c b/plat/imx/common/imx_sip_svc.c
new file mode 100644
index 0000000..c27fbf2
--- /dev/null
+++ b/plat/imx/common/imx_sip_svc.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/pmf/pmf.h>
+#include <tools_share/uuid.h>
+#include <imx_sip_svc.h>
+
+static int32_t imx_sip_setup(void)
+{
+	return 0;
+}
+
+static uintptr_t imx_sip_handler(unsigned int 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)
+{
+	switch (smc_fid) {
+#if (defined(PLAT_IMX8QM) || defined(PLAT_IMX8QX))
+	case  IMX_SIP_SRTC:
+		return imx_srtc_handler(smc_fid, handle, x1, x2, x3, x4);
+	case  IMX_SIP_CPUFREQ:
+		SMC_RET1(handle, imx_cpufreq_handler(smc_fid, x1, x2, x3));
+		break;
+	case  IMX_SIP_WAKEUP_SRC:
+		SMC_RET1(handle, imx_wakeup_src_handler(smc_fid, x1, x2, x3));
+	case IMX_SIP_OTP_READ:
+	case IMX_SIP_OTP_WRITE:
+		return imx_otp_handler(smc_fid, handle, x1, x2);
+	case IMX_SIP_MISC_SET_TEMP:
+		SMC_RET1(handle, imx_misc_set_temp_handler(smc_fid, x1, x2, x3, x4));
+#endif
+	case  IMX_SIP_BUILDINFO:
+		SMC_RET1(handle, imx_buildinfo_handler(smc_fid, x1, x2, x3, x4));
+	default:
+		WARN("Unimplemented i.MX SiP Service Call: 0x%x\n", smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+		break;
+	}
+}
+
+/* Define a runtime service descriptor for fast SMC calls */
+DECLARE_RT_SVC(
+		imx_sip_svc,
+		OEN_SIP_START,
+		OEN_SIP_END,
+		SMC_TYPE_FAST,
+		imx_sip_setup,
+		imx_sip_handler
+);
diff --git a/plat/imx/common/imx_uart_console.S b/plat/imx/common/imx_uart_console.S
index 7dbde79..03ec313 100644
--- a/plat/imx/common/imx_uart_console.S
+++ b/plat/imx/common/imx_uart_console.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,10 +16,11 @@
 #define UTS   0xb4 /* UART Test Register (mx31) */
 #define  URXD_RX_DATA    (0xFF)
 
-	.globl	console_uart_register
-	.globl	console_uart_init
-	.globl	console_uart_putc
-	.globl	console_uart_getc
+	.globl	console_imx_uart_register
+	.globl	console_imx_uart_init
+	.globl	console_imx_uart_putc
+	.globl	console_imx_uart_getc
+	.globl	console_imx_uart_flush
 
 func console_imx_uart_register
 	mov	x7, x30
@@ -32,7 +33,7 @@
 
 	mov	x0, x6
 	mov	x30, x7
-	finish_console_register imx_uart putc=1, getc=1
+	finish_console_register imx_uart putc=1, getc=1, flush=1
 
 register_fail:
 	ret	x7
@@ -82,3 +83,8 @@
 	mov	w0, #-1
 	ret
 endfunc console_imx_uart_getc
+
+func console_imx_uart_flush
+	mov	x0, #0
+	ret
+endfunc console_imx_uart_flush
diff --git a/plat/imx/common/include/imx_sip_svc.h b/plat/imx/common/include/imx_sip_svc.h
new file mode 100644
index 0000000..648be37
--- /dev/null
+++ b/plat/imx/common/include/imx_sip_svc.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __IMX_SIP_SVC_H__
+#define __IMX_SIP_SVC_H__
+
+/* SMC function IDs for SiP Service queries */
+#define IMX_SIP_CPUFREQ			0xC2000001
+#define IMX_SIP_SET_CPUFREQ		0x00
+
+#define IMX_SIP_SRTC			0xC2000002
+#define IMX_SIP_SRTC_SET_TIME		0x00
+
+#define IMX_SIP_BUILDINFO			0xC2000003
+#define IMX_SIP_BUILDINFO_GET_COMMITHASH	0x00
+
+#define IMX_SIP_WAKEUP_SRC		0xC2000009
+#define IMX_SIP_WAKEUP_SRC_SCU		0x1
+#define IMX_SIP_WAKEUP_SRC_IRQSTEER	0x2
+
+#define IMX_SIP_OTP_READ		0xC200000A
+#define IMX_SIP_OTP_WRITE		0xC200000B
+
+#define IMX_SIP_MISC_SET_TEMP		0xC200000C
+
+#if (defined(PLAT_IMX8QM) || defined(PLAT_IMX8QX))
+int imx_cpufreq_handler(uint32_t smc_fid, u_register_t x1,
+			u_register_t x2, u_register_t x3);
+int imx_srtc_handler(uint32_t smc_fid, void *handle, u_register_t x1,
+		     u_register_t x2, u_register_t x3, u_register_t x4);
+int imx_wakeup_src_handler(uint32_t smc_fid, u_register_t x1,
+			   u_register_t x2, u_register_t x3);
+int imx_otp_handler(uint32_t smc_fid, void *handle,
+		    u_register_t x1, u_register_t x2);
+int imx_misc_set_temp_handler(uint32_t smc_fid, u_register_t x1,
+			      u_register_t x2, u_register_t x3,
+			      u_register_t x4);
+uint64_t imx_buildinfo_handler(uint32_t smc_fid, u_register_t x1,
+			       u_register_t x2, u_register_t x3,
+			       u_register_t x4);
+#endif
+
+#endif /* __IMX_SIP_SVC_H__ */
diff --git a/plat/imx/common/include/imx_uart.h b/plat/imx/common/include/imx_uart.h
index a251024..1b52e2f 100644
--- a/plat/imx/common/include/imx_uart.h
+++ b/plat/imx/common/include/imx_uart.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
  */
@@ -16,7 +16,7 @@
 	uintptr_t base;
 } console_uart_t;
 
-int console_uart_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
+int console_imx_uart_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
 			   console_uart_t *console);
 #endif /*__ASSEMBLY__*/
 
diff --git a/plat/imx/common/include/plat_imx8.h b/plat/imx/common/include/plat_imx8.h
index 8d83173..be99b97 100644
--- a/plat/imx/common/include/plat_imx8.h
+++ b/plat/imx/common/include/plat_imx8.h
@@ -10,6 +10,11 @@
 #include <drivers/arm/gicv3.h>
 #include <lib/psci/psci.h>
 
+struct plat_gic_ctx {
+	gicv3_redist_ctx_t rdist_ctx[PLATFORM_CORE_COUNT];
+	gicv3_dist_ctx_t dist_ctx;
+};
+
 unsigned int plat_calc_core_pos(uint64_t mpidr);
 void imx_mailbox_init(uintptr_t base_addr);
 void plat_gic_driver_init(void);
@@ -23,5 +28,8 @@
 int imx_validate_power_state(unsigned int power_state,
 			psci_power_state_t *req_state);
 void imx_get_sys_suspend_power_state(psci_power_state_t *req_state);
+bool imx_is_wakeup_src_irqsteer(void);
+void plat_gic_save(unsigned int proc_num, struct plat_gic_ctx *ctx);
+void plat_gic_restore(unsigned int proc_num, struct plat_gic_ctx *ctx);
 
 #endif /* PLAT_IMX8_H */
diff --git a/plat/imx/common/include/sci/sci.h b/plat/imx/common/include/sci/sci.h
index f0a2502..2c45bb8 100644
--- a/plat/imx/common/include/sci/sci.h
+++ b/plat/imx/common/include/sci/sci.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
  */
@@ -15,5 +15,7 @@
 #include <sci/svc/pad/sci_pad_api.h>
 #include <sci/svc/pm/sci_pm_api.h>
 #include <sci/svc/rm/sci_rm_api.h>
+#include <sci/svc/timer/sci_timer_api.h>
+#include <sci/svc/misc/sci_misc_api.h>
 
 #endif /* SCI_H */
diff --git a/plat/imx/common/include/sci/svc/misc/sci_misc_api.h b/plat/imx/common/include/sci/svc/misc/sci_misc_api.h
new file mode 100644
index 0000000..d9dd49d
--- /dev/null
+++ b/plat/imx/common/include/sci/svc/misc/sci_misc_api.h
@@ -0,0 +1,539 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ * Header file containing the public API for the System Controller (SC)
+ * Miscellaneous (MISC) function.
+ *
+ * @addtogroup MISC_SVC (SVC) Miscellaneous Service
+ *
+ * Module for the Miscellaneous (MISC) service.
+ *
+ * @{
+ */
+
+#ifndef SC_MISC_API_H
+#define SC_MISC_API_H
+
+/* Includes */
+
+#include <sci/svc/rm/sci_rm_api.h>
+#include <sci/sci_types.h>
+
+/* Defines */
+
+/*!
+ * @name Defines for type widths
+ */
+/*@{*/
+#define SC_MISC_DMA_GRP_W       5U	/* Width of sc_misc_dma_group_t */
+/*@}*/
+
+/*! Max DMA channel priority group */
+#define SC_MISC_DMA_GRP_MAX     31U
+
+/*!
+ * @name Defines for sc_misc_boot_status_t
+ */
+/*@{*/
+#define SC_MISC_BOOT_STATUS_SUCCESS     0U	/* Success */
+#define SC_MISC_BOOT_STATUS_SECURITY    1U	/* Security violation */
+/*@}*/
+
+/*!
+ * @name Defines for sc_misc_seco_auth_cmd_t
+ */
+/*@{*/
+#define SC_MISC_SECO_AUTH_SECO_FW       0U	/* SECO Firmware */
+#define SC_MISC_SECO_AUTH_HDMI_TX_FW    1U	/* HDMI TX Firmware */
+#define SC_MISC_SECO_AUTH_HDMI_RX_FW    2U	/* HDMI RX Firmware */
+/*@}*/
+
+/*!
+ * @name Defines for sc_misc_temp_t
+ */
+/*@{*/
+#define SC_MISC_TEMP                    0U	/* Temp sensor */
+#define SC_MISC_TEMP_HIGH               1U	/* Temp high alarm */
+#define SC_MISC_TEMP_LOW                2U	/* Temp low alarm */
+/*@}*/
+
+/*!
+ * @name Defines for sc_misc_seco_auth_cmd_t
+ */
+/*@{*/
+#define SC_MISC_AUTH_CONTAINER          0U	/* Authenticate container */
+#define SC_MISC_VERIFY_IMAGE            1U	/* Verify image */
+#define SC_MISC_REL_CONTAINER           2U	/* Release container */
+/*@}*/
+
+/* Types */
+
+/*!
+ * This type is used to store a DMA channel priority group.
+ */
+typedef uint8_t sc_misc_dma_group_t;
+
+/*!
+ * This type is used report boot status.
+ */
+typedef uint8_t sc_misc_boot_status_t;
+
+/*!
+ * This type is used to issue SECO authenticate commands.
+ */
+typedef uint8_t sc_misc_seco_auth_cmd_t;
+
+/*!
+ * This type is used report boot status.
+ */
+typedef uint8_t sc_misc_temp_t;
+
+/* Functions */
+
+/*!
+ * @name Control Functions
+ * @{
+ */
+
+/*!
+ * This function sets a miscellaneous control value.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     resource    resource the control is associated with
+ * @param[in]     ctrl        control to change
+ * @param[in]     val         value to apply to the control
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the resource owner or parent
+ *   of the owner
+ *
+ * Refer to the [Control List](@ref CONTROLS) for valid control values.
+ */
+sc_err_t sc_misc_set_control(sc_ipc_t ipc, sc_rsrc_t resource,
+			     sc_ctrl_t ctrl, uint32_t val);
+
+/*!
+ * This function gets a miscellaneous control value.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     resource    resource the control is associated with
+ * @param[in]     ctrl        control to get
+ * @param[out]    val         pointer to return the control value
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the resource owner or parent
+ *   of the owner
+ *
+ * Refer to the [Control List](@ref CONTROLS) for valid control values.
+ */
+sc_err_t sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource,
+			     sc_ctrl_t ctrl, uint32_t *val);
+
+/* @} */
+
+/*!
+ * @name DMA Functions
+ * @{
+ */
+
+/*!
+ * This function configures the max DMA channel priority group for a
+ * partition.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     pt          handle of partition to assign \a max
+ * @param[in]     max         max priority group (0-31)
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the parent
+ *   of the affected partition
+ *
+ * Valid \a max range is 0-31 with 0 being the lowest and 31 the highest.
+ * Default is the max priority group for the parent partition of \a pt.
+ */
+sc_err_t sc_misc_set_max_dma_group(sc_ipc_t ipc, sc_rm_pt_t pt,
+				   sc_misc_dma_group_t max);
+
+/*!
+ * This function configures the priority group for a DMA channel.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     resource    DMA channel resource
+ * @param[in]     group       priority group (0-31)
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the owner or parent
+ *   of the owner of the DMA channel
+ *
+ * Valid \a group range is 0-31 with 0 being the lowest and 31 the highest.
+ * The max value of \a group is limited by the partition max set using
+ * sc_misc_set_max_dma_group().
+ */
+sc_err_t sc_misc_set_dma_group(sc_ipc_t ipc, sc_rsrc_t resource,
+			       sc_misc_dma_group_t group);
+
+/* @} */
+
+/*!
+ * @name Security Functions
+ * @{
+ */
+
+/*!
+ * This function loads a SECO image.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     addr_src    address of image source
+ * @param[in]     addr_dst    address of image destination
+ * @param[in]     len         length of image to load
+ * @param[in]     fw          SC_TRUE = firmware load
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * This is used to load images via the SECO. Examples include SECO
+ * Firmware and IVT/CSF data used for authentication. These are usually
+ * loaded into SECO TCM. \a addr_src is in secure memory.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_image_load(sc_ipc_t ipc, sc_faddr_t addr_src,
+				 sc_faddr_t addr_dst, uint32_t len,
+				 sc_bool_t fw);
+
+/*!
+ * This function is used to authenticate a SECO image or command.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     cmd         authenticate command
+ * @param[in]     addr        address of/or metadata
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * This is used to authenticate a SECO image or issue a security
+ * command. \a addr often points to an container. It is also
+ * just data (or even unused) for some commands.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_authenticate(sc_ipc_t ipc,
+				   sc_misc_seco_auth_cmd_t cmd,
+				   sc_faddr_t addr);
+
+/*!
+ * This function securely writes a group of fuse words.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     addr        address of message block
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * Note \a addr must be a pointer to a signed message block.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_fuse_write(sc_ipc_t ipc, sc_faddr_t addr);
+
+/*!
+ * This function securely enables debug.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     addr        address of message block
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * Note \a addr must be a pointer to a signed message block.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_enable_debug(sc_ipc_t ipc, sc_faddr_t addr);
+
+/*!
+ * This function updates the lifecycle of the device.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     lifecycle   new lifecycle
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * This message is used for going from Open to NXP Closed to OEM Closed.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_forward_lifecycle(sc_ipc_t ipc, uint32_t lifecycle);
+
+/*!
+ * This function updates the lifecycle to one of the return lifecycles.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     addr        address of message block
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * Note \a addr must be a pointer to a signed message block.
+ *
+ * To switch back to NXP states (Full Field Return), message must be signed
+ * by NXP SRK. For OEM States (Partial Field Return), must be signed by OEM
+ * SRK.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_return_lifecycle(sc_ipc_t ipc, sc_faddr_t addr);
+
+/*!
+ * This function is used to return the SECO FW build info.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[out]    version     pointer to return build number
+ * @param[out]    commit      pointer to return commit ID (git SHA-1)
+ */
+void sc_misc_seco_build_info(sc_ipc_t ipc, uint32_t *version, uint32_t *commit);
+
+/*!
+ * This function is used to return SECO chip info.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[out]    lc          pointer to return lifecycle
+ * @param[out]    monotonic   pointer to return monotonic counter
+ * @param[out]    uid_l       pointer to return UID (lower 32 bits)
+ * @param[out]    uid_h       pointer to return UID (upper 32 bits)
+ */
+sc_err_t sc_misc_seco_chip_info(sc_ipc_t ipc, uint16_t *lc,
+				uint16_t *monotonic, uint32_t *uid_l,
+				uint32_t *uid_h);
+
+/* @} */
+
+/*!
+ * @name Debug Functions
+ * @{
+ */
+
+/*!
+ * This function is used output a debug character from the SCU UART.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     ch          character to output
+ */
+void sc_misc_debug_out(sc_ipc_t ipc, uint8_t ch);
+
+/*!
+ * This function starts/stops emulation waveform capture.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     enable      flag to enable/disable capture
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_UNAVAILABLE if not running on emulation
+ */
+sc_err_t sc_misc_waveform_capture(sc_ipc_t ipc, sc_bool_t enable);
+
+/*!
+ * This function is used to return the SCFW build info.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[out]    build       pointer to return build number
+ * @param[out]    commit      pointer to return commit ID (git SHA-1)
+ */
+void sc_misc_build_info(sc_ipc_t ipc, uint32_t *build, uint32_t *commit);
+
+/*!
+ * This function is used to return the device's unique ID.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[out]    id_l        pointer to return lower 32-bit of ID [31:0]
+ * @param[out]    id_h        pointer to return upper 32-bits of ID [63:32]
+ */
+void sc_misc_unique_id(sc_ipc_t ipc, uint32_t *id_l, uint32_t *id_h);
+
+/* @} */
+
+/*!
+ * @name Other Functions
+ * @{
+ */
+
+/*!
+ * This function configures the ARI match value for PCIe/SATA resources.
+ *
+ * @param[in]     ipc          IPC handle
+ * @param[in]     resource     match resource
+ * @param[in]     resource_mst PCIe/SATA master to match
+ * @param[in]     ari          ARI to match
+ * @param[in]     enable       enable match or not
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the owner or parent
+ *   of the owner of the resource and translation
+ *
+ * For PCIe, the ARI is the 16-bit value that includes the bus number,
+ * device number, and function number. For SATA, this value includes the
+ * FISType and PM_Port.
+ */
+sc_err_t sc_misc_set_ari(sc_ipc_t ipc, sc_rsrc_t resource,
+			 sc_rsrc_t resource_mst, uint16_t ari,
+			 sc_bool_t enable);
+
+/*!
+ * This function reports boot status.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     status      boot status
+ *
+ * This is used by SW partitions to report status of boot. This is
+ * normally used to report a boot failure.
+ */
+void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status);
+
+/*!
+ * This function tells the SCFW that a CPU is done booting.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     cpu         CPU that is done booting
+ *
+ * This is called by early booting CPUs to report they are done with
+ * initialization. After starting early CPUs, the SCFW halts the
+ * booting process until they are done. During this time, early
+ * CPUs can call the SCFW with lower latency as the SCFW is idle.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the CPU owner
+ */
+sc_err_t sc_misc_boot_done(sc_ipc_t ipc, sc_rsrc_t cpu);
+
+/*!
+ * This function reads a given fuse word index.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     word        fuse word index
+ * @param[out]    val         fuse read value
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_NOACCESS if read operation failed
+ * - SC_ERR_LOCKED if read operation is locked
+ */
+sc_err_t sc_misc_otp_fuse_read(sc_ipc_t ipc, uint32_t word, uint32_t *val);
+
+/*!
+ * This function writes a given fuse word index.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     word        fuse word index
+ * @param[in]     val         fuse write value
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_NOACCESS if write operation failed
+ * - SC_ERR_LOCKED if write operation is locked
+ */
+sc_err_t sc_misc_otp_fuse_write(sc_ipc_t ipc, uint32_t word, uint32_t val);
+
+/*!
+ * This function sets a temp sensor alarm.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     resource    resource with sensor
+ * @param[in]     temp        alarm to set
+ * @param[in]     celsius     whole part of temp to set
+ * @param[in]     tenths      fractional part of temp to set
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * This function will enable the alarm interrupt if the temp requested is
+ * not the min/max temp. This enable automatically clears when the alarm
+ * occurs and this function has to be called again to re-enable.
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if parameters invalid
+ */
+sc_err_t sc_misc_set_temp(sc_ipc_t ipc, sc_rsrc_t resource,
+			  sc_misc_temp_t temp, int16_t celsius, int8_t tenths);
+
+/*!
+ * This function gets a temp sensor value.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     resource    resource with sensor
+ * @param[in]     temp        value to get (sensor or alarm)
+ * @param[out]    celsius     whole part of temp to get
+ * @param[out]    tenths      fractional part of temp to get
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if parameters invalid
+ */
+sc_err_t sc_misc_get_temp(sc_ipc_t ipc, sc_rsrc_t resource,
+			  sc_misc_temp_t temp, int16_t *celsius,
+			  int8_t *tenths);
+
+/*!
+ * This function returns the boot device.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[out]    dev         pointer to return boot device
+ */
+void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *dev);
+
+/*!
+ * This function returns the current status of the ON/OFF button.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[out]    status      pointer to return button status
+ */
+void sc_misc_get_button_status(sc_ipc_t ipc, sc_bool_t *status);
+
+/* @} */
+
+#endif				/* SC_MISC_API_H */
+
+/**@}*/
diff --git a/plat/imx/common/include/sci/svc/timer/sci_timer_api.h b/plat/imx/common/include/sci/svc/timer/sci_timer_api.h
new file mode 100644
index 0000000..f8423ab
--- /dev/null
+++ b/plat/imx/common/include/sci/svc/timer/sci_timer_api.h
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ * Header file containing the public API for the System Controller (SC)
+ * Timer function.
+ *
+ * @addtogroup TIMER_SVC (SVC) Timer Service
+ *
+ * Module for the Timer service. This includes support for the watchdog, RTC,
+ * and system counter. Note every resource partition has a watchdog it can
+ * use.
+ *
+ * @{
+ */
+
+#ifndef SC_TIMER_API_H
+#define SC_TIMER_API_H
+
+/* Includes */
+
+#include <sci/sci_types.h>
+
+/* Defines */
+
+/*!
+ * @name Defines for type widths
+ */
+/*@{*/
+#define SC_TIMER_ACTION_W   3U	/* Width of sc_timer_wdog_action_t */
+/*@}*/
+
+/*!
+ * @name Defines for sc_timer_wdog_action_t
+ */
+/*@{*/
+#define SC_TIMER_WDOG_ACTION_PARTITION      0U	/* Reset partition */
+#define SC_TIMER_WDOG_ACTION_WARM           1U	/* Warm reset system */
+#define SC_TIMER_WDOG_ACTION_COLD           2U	/* Cold reset system */
+#define SC_TIMER_WDOG_ACTION_BOARD          3U	/* Reset board */
+#define SC_TIMER_WDOG_ACTION_IRQ            4U	/* Only generate IRQs */
+/*@}*/
+
+/* Types */
+
+/*!
+ * This type is used to configure the watchdog action.
+ */
+typedef uint8_t sc_timer_wdog_action_t;
+
+/*!
+ * This type is used to declare a watchdog time value in milliseconds.
+ */
+typedef uint32_t sc_timer_wdog_time_t;
+
+/* Functions */
+
+/*!
+ * @name Watchdog Functions
+ * @{
+ */
+
+/*!
+ * This function sets the watchdog timeout in milliseconds. If not
+ * set then the timeout defaults to the max. Once locked this value
+ * cannot be changed.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     timeout     timeout period for the watchdog
+ *
+ * @return Returns an error code (SC_ERR_NONE = success, SC_ERR_LOCKED
+ *         = locked).
+ */
+sc_err_t sc_timer_set_wdog_timeout(sc_ipc_t ipc, sc_timer_wdog_time_t timeout);
+
+/*!
+ * This function sets the watchdog pre-timeout in milliseconds. If not
+ * set then the pre-timeout defaults to the max. Once locked this value
+ * cannot be changed.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     pre_timeout pre-timeout period for the watchdog
+ *
+ * When the pre-timeout expires an IRQ will be generated. Note this timeout
+ * clears when the IRQ is triggered. An IRQ is generated for the failing
+ * partition and all of its child partitions.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_timer_set_wdog_pre_timeout(sc_ipc_t ipc,
+				       sc_timer_wdog_time_t pre_timeout);
+
+/*!
+ * This function starts the watchdog.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     lock        boolean indicating the lock status
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * If \a lock is set then the watchdog cannot be stopped or the timeout
+ * period changed.
+ */
+sc_err_t sc_timer_start_wdog(sc_ipc_t ipc, sc_bool_t lock);
+
+/*!
+ * This function stops the watchdog if it is not locked.
+ *
+ * @param[in]     ipc         IPC handle
+ *
+ * @return Returns an error code (SC_ERR_NONE = success, SC_ERR_LOCKED
+ *         = locked).
+ */
+sc_err_t sc_timer_stop_wdog(sc_ipc_t ipc);
+
+/*!
+ * This function pings (services, kicks) the watchdog resetting the time
+ * before expiration back to the timeout.
+ *
+ * @param[in]     ipc         IPC handle
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_timer_ping_wdog(sc_ipc_t ipc);
+
+/*!
+ * This function gets the status of the watchdog. All arguments are
+ * in milliseconds.
+ *
+ * @param[in]     ipc             IPC handle
+ * @param[out]    timeout         pointer to return the timeout
+ * @param[out]    max_timeout     pointer to return the max timeout
+ * @param[out]    remaining_time  pointer to return the time remaining
+ *                                until trigger
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_timer_get_wdog_status(sc_ipc_t ipc,
+				  sc_timer_wdog_time_t *timeout,
+				  sc_timer_wdog_time_t *max_timeout,
+				  sc_timer_wdog_time_t *remaining_time);
+
+/*!
+ * This function gets the status of the watchdog of a partition. All
+ * arguments are in milliseconds.
+ *
+ * @param[in]     ipc             IPC handle
+ * @param[in]     pt              partition to query
+ * @param[out]    enb             pointer to return enable status
+ * @param[out]    timeout         pointer to return the timeout
+ * @param[out]    remaining_time  pointer to return the time remaining
+ *                                until trigger
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_timer_pt_get_wdog_status(sc_ipc_t ipc, sc_rm_pt_t pt,
+				     sc_bool_t *enb,
+				     sc_timer_wdog_time_t *timeout,
+				     sc_timer_wdog_time_t *remaining_time);
+
+/*!
+ * This function configures the action to be taken when a watchdog
+ * expires.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     pt          partition to affect
+ * @param[in]     action      action to take
+ *
+ * Default action is inherited from the parent.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid parameters,
+ * - SC_ERR_NOACCESS if caller's partition is not the SYSTEM owner,
+ * - SC_ERR_LOCKED if the watchdog is locked
+ */
+sc_err_t sc_timer_set_wdog_action(sc_ipc_t ipc,
+				  sc_rm_pt_t pt, sc_timer_wdog_action_t action);
+
+/* @} */
+
+/*!
+ * @name Real-Time Clock (RTC) Functions
+ * @{
+ */
+
+/*!
+ * This function sets the RTC time. Only the owner of the SC_R_SYSTEM
+ * resource can set the time.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     year        year (min 1970)
+ * @param[in]     mon         month (1-12)
+ * @param[in]     day         day of the month (1-31)
+ * @param[in]     hour        hour (0-23)
+ * @param[in]     min         minute (0-59)
+ * @param[in]     sec         second (0-59)
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid time/date parameters,
+ * - SC_ERR_NOACCESS if caller's partition is not the SYSTEM owner
+ */
+sc_err_t sc_timer_set_rtc_time(sc_ipc_t ipc, uint16_t year, uint8_t mon,
+			       uint8_t day, uint8_t hour, uint8_t min,
+			       uint8_t sec);
+
+/*!
+ * This function gets the RTC time.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[out]    year        pointer to return year (min 1970)
+ * @param[out]    mon         pointer to return month (1-12)
+ * @param[out]    day         pointer to return day of the month (1-31)
+ * @param[out]    hour        pointer to return hour (0-23)
+ * @param[out]    min         pointer to return minute (0-59)
+ * @param[out]    sec         pointer to return second (0-59)
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_timer_get_rtc_time(sc_ipc_t ipc, uint16_t *year, uint8_t *mon,
+			       uint8_t *day, uint8_t *hour, uint8_t *min,
+			       uint8_t *sec);
+
+/*!
+ * This function gets the RTC time in seconds since 1/1/1970.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[out]    sec         pointer to return second
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_timer_get_rtc_sec1970(sc_ipc_t ipc, uint32_t *sec);
+
+/*!
+ * This function sets the RTC alarm.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     year        year (min 1970)
+ * @param[in]     mon         month (1-12)
+ * @param[in]     day         day of the month (1-31)
+ * @param[in]     hour        hour (0-23)
+ * @param[in]     min         minute (0-59)
+ * @param[in]     sec         second (0-59)
+ *
+ * Note this alarm setting clears when the alarm is triggered.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid time/date parameters
+ */
+sc_err_t sc_timer_set_rtc_alarm(sc_ipc_t ipc, uint16_t year, uint8_t mon,
+				uint8_t day, uint8_t hour, uint8_t min,
+				uint8_t sec);
+
+/*!
+ * This function sets the RTC alarm (periodic mode).
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     sec         period in seconds
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid time/date parameters
+ */
+sc_err_t sc_timer_set_rtc_periodic_alarm(sc_ipc_t ipc, uint32_t sec);
+
+/*!
+ * This function cancels the RTC alarm.
+ *
+ * @param[in]     ipc         IPC handle
+ *
+ * Note this alarm setting clears when the alarm is triggered.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid time/date parameters
+ */
+sc_err_t sc_timer_cancel_rtc_alarm(sc_ipc_t ipc);
+
+/*!
+ * This function sets the RTC calibration value. Only the owner of the SC_R_SYSTEM
+ * resource can set the calibration.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     count       calbration count (-16 to 15)
+ *
+ * The calibration value is a 5-bit value including the sign bit, which is
+ * implemented in 2's complement. It is added or subtracted from the RTC on
+ * a perdiodic basis, once per 32768 cycles of the RTC clock.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ */
+sc_err_t sc_timer_set_rtc_calb(sc_ipc_t ipc, int8_t count);
+
+/* @} */
+
+/*!
+ * @name System Counter (SYSCTR) Functions
+ * @{
+ */
+
+/*!
+ * This function sets the SYSCTR alarm.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     ticks       number of 8MHz cycles
+ *
+ * Note this alarm setting clears when the alarm is triggered.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid time/date parameters
+ */
+sc_err_t sc_timer_set_sysctr_alarm(sc_ipc_t ipc, uint64_t ticks);
+
+/*!
+ * This function sets the SYSCTR alarm (periodic mode).
+ *
+ * @param[in]     ipc          IPC handle
+ * @param[in]     ticks        number of 8MHz cycles
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid time/date parameters
+ */
+sc_err_t sc_timer_set_sysctr_periodic_alarm(sc_ipc_t ipc, uint64_t ticks);
+
+/*!
+ * This function cancels the SYSCTR alarm.
+ *
+ * @param[in]     ipc         IPC handle
+ *
+ * Note this alarm setting clears when the alarm is triggered.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_PARM if invalid time/date parameters
+ */
+sc_err_t sc_timer_cancel_sysctr_alarm(sc_ipc_t ipc);
+
+/* @} */
+
+#endif				/* SC_TIMER_API_H */
+
+/**@}*/
diff --git a/plat/imx/common/lpuart_console.S b/plat/imx/common/lpuart_console.S
index 668fd62..0162868 100644
--- a/plat/imx/common/lpuart_console.S
+++ b/plat/imx/common/lpuart_console.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
  */
@@ -15,6 +15,7 @@
 	.globl	console_lpuart_init
 	.globl	console_lpuart_putc
 	.globl	console_lpuart_getc
+	.globl	console_lpuart_flush
 
 func console_lpuart_register
 	mov	x7, x30
@@ -27,7 +28,7 @@
 
 	mov	x0, x6
 	mov	x30, x7
-	finish_console_register lpuart putc=1, getc=1
+	finish_console_register lpuart putc=1, getc=1, flush=1
 
 register_fail:
 	ret	x7
@@ -70,3 +71,8 @@
 	mov	w0, #-1
 	ret
 endfunc console_lpuart_getc
+
+func console_lpuart_flush
+	mov	x0, #0
+	ret
+endfunc console_lpuart_flush
diff --git a/plat/imx/common/plat_imx8_gic.c b/plat/imx/common/plat_imx8_gic.c
index aec0b6c..27c525b 100644
--- a/plat/imx/common/plat_imx8_gic.c
+++ b/plat/imx/common/plat_imx8_gic.c
@@ -73,3 +73,19 @@
 {
 	gicv3_rdistif_init(plat_my_core_pos());
 }
+
+void plat_gic_save(unsigned int proc_num, struct plat_gic_ctx *ctx)
+{
+	/* save the gic rdist/dist context */
+	for (int i = 0; i < PLATFORM_CORE_COUNT; i++)
+		gicv3_rdistif_save(i, &ctx->rdist_ctx[i]);
+	gicv3_distif_save(&ctx->dist_ctx);
+}
+
+void plat_gic_restore(unsigned int proc_num, struct plat_gic_ctx *ctx)
+{
+	/* restore the gic rdist/dist context */
+	gicv3_distif_init_restore(&ctx->dist_ctx);
+	for (int i = 0; i < PLATFORM_CORE_COUNT; i++)
+		gicv3_rdistif_init_restore(i, &ctx->rdist_ctx[i]);
+}
diff --git a/plat/imx/common/sci/imx8_mu.c b/plat/imx/common/sci/imx8_mu.c
index 26d9bdf..66e956d 100644
--- a/plat/imx/common/sci/imx8_mu.c
+++ b/plat/imx/common/sci/imx8_mu.c
@@ -8,6 +8,21 @@
 
 #include "imx8_mu.h"
 
+void MU_Resume(uint32_t base)
+{
+	uint32_t reg, i;
+
+	reg = mmio_read_32(base + MU_ACR_OFFSET1);
+	/* Clear GIEn, RIEn, TIEn, GIRn and ABFn. */
+	reg &= ~(MU_CR_GIEn_MASK1 | MU_CR_RIEn_MASK1 | MU_CR_TIEn_MASK1
+			| MU_CR_GIRn_MASK1 | MU_CR_Fn_MASK1);
+	mmio_write_32(base + MU_ACR_OFFSET1, reg);
+
+	/* Enable all RX interrupts */
+	for (i = 0; i < MU_RR_COUNT; i++)
+		MU_EnableRxFullInt(base, i);
+}
+
 void MU_EnableRxFullInt(uint32_t base, uint32_t index)
 {
 	uint32_t reg = mmio_read_32(base + MU_ACR_OFFSET1);
diff --git a/plat/imx/common/sci/imx8_mu.h b/plat/imx/common/sci/imx8_mu.h
index 8c78877..edcac7b 100644
--- a/plat/imx/common/sci/imx8_mu.h
+++ b/plat/imx/common/sci/imx8_mu.h
@@ -33,3 +33,4 @@
 void MU_ReceiveMsg(uint32_t base, uint32_t regIndex, uint32_t *msg);
 void MU_EnableGeneralInt(uint32_t base, uint32_t index);
 void MU_EnableRxFullInt(uint32_t base, uint32_t index);
+void MU_Resume(uint32_t base);
diff --git a/plat/imx/common/sci/sci_api.mk b/plat/imx/common/sci/sci_api.mk
index b277877..92c7190 100644
--- a/plat/imx/common/sci/sci_api.mk
+++ b/plat/imx/common/sci/sci_api.mk
@@ -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
 #
@@ -8,4 +8,6 @@
 			plat/imx/common/sci/imx8_mu.c			\
 			plat/imx/common/sci/svc/pad/pad_rpc_clnt.c	\
 			plat/imx/common/sci/svc/pm/pm_rpc_clnt.c	\
-			plat/imx/common/sci/svc/rm/rm_rpc_clnt.c
+			plat/imx/common/sci/svc/rm/rm_rpc_clnt.c	\
+			plat/imx/common/sci/svc/timer/timer_rpc_clnt.c	\
+			plat/imx/common/sci/svc/misc/misc_rpc_clnt.c
diff --git a/plat/imx/common/sci/svc/misc/misc_rpc_clnt.c b/plat/imx/common/sci/svc/misc/misc_rpc_clnt.c
new file mode 100644
index 0000000..080de6a
--- /dev/null
+++ b/plat/imx/common/sci/svc/misc/misc_rpc_clnt.c
@@ -0,0 +1,506 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ * File containing client-side RPC functions for the MISC service. These
+ * functions are ported to clients that communicate to the SC.
+ *
+ * @addtogroup MISC_SVC
+ * @{
+ */
+
+/* Includes */
+
+#include <sci/sci_types.h>
+#include <sci/svc/rm/sci_rm_api.h>
+#include <sci/svc/misc/sci_misc_api.h>
+#include <sci/sci_rpc.h>
+#include <stdlib.h>
+#include "sci_misc_rpc.h"
+
+/* Local Defines */
+
+/* Local Types */
+
+/* Local Functions */
+
+sc_err_t sc_misc_set_control(sc_ipc_t ipc, sc_rsrc_t resource,
+			     sc_ctrl_t ctrl, uint32_t val)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SET_CONTROL;
+	RPC_U32(&msg, 0U) = (uint32_t)ctrl;
+	RPC_U32(&msg, 4U) = (uint32_t)val;
+	RPC_U16(&msg, 8U) = (uint16_t)resource;
+	RPC_SIZE(&msg) = 4U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource,
+			     sc_ctrl_t ctrl, uint32_t *val)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_GET_CONTROL;
+	RPC_U32(&msg, 0U) = (uint32_t)ctrl;
+	RPC_U16(&msg, 4U) = (uint16_t)resource;
+	RPC_SIZE(&msg) = 3U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	if (val != NULL)
+		*val = RPC_U32(&msg, 0U);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_set_max_dma_group(sc_ipc_t ipc, sc_rm_pt_t pt,
+				   sc_misc_dma_group_t max)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SET_MAX_DMA_GROUP;
+	RPC_U8(&msg, 0U) = (uint8_t)pt;
+	RPC_U8(&msg, 1U) = (uint8_t)max;
+	RPC_SIZE(&msg) = 2U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_set_dma_group(sc_ipc_t ipc, sc_rsrc_t resource,
+			       sc_misc_dma_group_t group)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SET_DMA_GROUP;
+	RPC_U16(&msg, 0U) = (uint16_t)resource;
+	RPC_U8(&msg, 2U) = (uint8_t)group;
+	RPC_SIZE(&msg) = 2U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_image_load(sc_ipc_t ipc, sc_faddr_t addr_src,
+				 sc_faddr_t addr_dst, uint32_t len,
+				 sc_bool_t fw)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_IMAGE_LOAD;
+	RPC_U32(&msg, 0U) = (uint32_t)(addr_src >> 32U);
+	RPC_U32(&msg, 4U) = (uint32_t)addr_src;
+	RPC_U32(&msg, 8U) = (uint32_t)(addr_dst >> 32U);
+	RPC_U32(&msg, 12U) = (uint32_t)addr_dst;
+	RPC_U32(&msg, 16U) = (uint32_t)len;
+	RPC_U8(&msg, 20U) = (uint8_t)fw;
+	RPC_SIZE(&msg) = 7U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_authenticate(sc_ipc_t ipc,
+				   sc_misc_seco_auth_cmd_t cmd, sc_faddr_t addr)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_AUTHENTICATE;
+	RPC_U32(&msg, 0U) = (uint32_t)(addr >> 32U);
+	RPC_U32(&msg, 4U) = (uint32_t)addr;
+	RPC_U8(&msg, 8U) = (uint8_t)cmd;
+	RPC_SIZE(&msg) = 4U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_fuse_write(sc_ipc_t ipc, sc_faddr_t addr)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_FUSE_WRITE;
+	RPC_U32(&msg, 0U) = (uint32_t)(addr >> 32U);
+	RPC_U32(&msg, 4U) = (uint32_t)addr;
+	RPC_SIZE(&msg) = 3U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_enable_debug(sc_ipc_t ipc, sc_faddr_t addr)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_ENABLE_DEBUG;
+	RPC_U32(&msg, 0U) = (uint32_t)(addr >> 32U);
+	RPC_U32(&msg, 4U) = (uint32_t)addr;
+	RPC_SIZE(&msg) = 3U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_forward_lifecycle(sc_ipc_t ipc, uint32_t lifecycle)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_FORWARD_LIFECYCLE;
+	RPC_U32(&msg, 0U) = (uint32_t)lifecycle;
+	RPC_SIZE(&msg) = 2U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_return_lifecycle(sc_ipc_t ipc, sc_faddr_t addr)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_RETURN_LIFECYCLE;
+	RPC_U32(&msg, 0U) = (uint32_t)(addr >> 32U);
+	RPC_U32(&msg, 4U) = (uint32_t)addr;
+	RPC_SIZE(&msg) = 3U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+void sc_misc_seco_build_info(sc_ipc_t ipc, uint32_t *version, uint32_t *commit)
+{
+	sc_rpc_msg_t msg;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_BUILD_INFO;
+	RPC_SIZE(&msg) = 1U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	if (version != NULL)
+		*version = RPC_U32(&msg, 0U);
+
+	if (commit != NULL)
+		*commit = RPC_U32(&msg, 4U);
+}
+
+sc_err_t sc_misc_seco_chip_info(sc_ipc_t ipc, uint16_t *lc,
+				uint16_t *monotonic, uint32_t *uid_l,
+				uint32_t *uid_h)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_CHIP_INFO;
+	RPC_SIZE(&msg) = 1U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	if (uid_l != NULL)
+		*uid_l = RPC_U32(&msg, 0U);
+
+	if (uid_h != NULL)
+		*uid_h = RPC_U32(&msg, 4U);
+
+	if (lc != NULL)
+		*lc = RPC_U16(&msg, 8U);
+
+	if (monotonic != NULL)
+		*monotonic = RPC_U16(&msg, 10U);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+void sc_misc_debug_out(sc_ipc_t ipc, uint8_t ch)
+{
+	sc_rpc_msg_t msg;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_DEBUG_OUT;
+	RPC_U8(&msg, 0U) = (uint8_t)ch;
+	RPC_SIZE(&msg) = 2U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+}
+
+sc_err_t sc_misc_waveform_capture(sc_ipc_t ipc, sc_bool_t enable)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_WAVEFORM_CAPTURE;
+	RPC_U8(&msg, 0U) = (uint8_t)enable;
+	RPC_SIZE(&msg) = 2U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+void sc_misc_build_info(sc_ipc_t ipc, uint32_t *build, uint32_t *commit)
+{
+	sc_rpc_msg_t msg;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_BUILD_INFO;
+	RPC_SIZE(&msg) = 1U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	if (build != NULL)
+		*build = RPC_U32(&msg, 0U);
+
+	if (commit != NULL)
+		*commit = RPC_U32(&msg, 4U);
+}
+
+void sc_misc_unique_id(sc_ipc_t ipc, uint32_t *id_l, uint32_t *id_h)
+{
+	sc_rpc_msg_t msg;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_UNIQUE_ID;
+	RPC_SIZE(&msg) = 1U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	if (id_l != NULL)
+		*id_l = RPC_U32(&msg, 0U);
+
+	if (id_h != NULL)
+		*id_h = RPC_U32(&msg, 4U);
+}
+
+sc_err_t sc_misc_set_ari(sc_ipc_t ipc, sc_rsrc_t resource,
+			 sc_rsrc_t resource_mst, uint16_t ari, sc_bool_t enable)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SET_ARI;
+	RPC_U16(&msg, 0U) = (uint16_t)resource;
+	RPC_U16(&msg, 2U) = (uint16_t)resource_mst;
+	RPC_U16(&msg, 4U) = (uint16_t)ari;
+	RPC_U8(&msg, 6U) = (uint8_t)enable;
+	RPC_SIZE(&msg) = 3U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status)
+{
+	sc_rpc_msg_t msg;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_BOOT_STATUS;
+	RPC_U8(&msg, 0U) = (uint8_t)status;
+	RPC_SIZE(&msg) = 2U;
+
+	sc_call_rpc(ipc, &msg, SC_TRUE);
+}
+
+sc_err_t sc_misc_boot_done(sc_ipc_t ipc, sc_rsrc_t cpu)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_BOOT_DONE;
+	RPC_U16(&msg, 0U) = (uint16_t)cpu;
+	RPC_SIZE(&msg) = 2U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_otp_fuse_read(sc_ipc_t ipc, uint32_t word, uint32_t *val)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_OTP_FUSE_READ;
+	RPC_U32(&msg, 0U) = (uint32_t)word;
+	RPC_SIZE(&msg) = 2U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	if (val != NULL)
+		*val = RPC_U32(&msg, 0U);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_otp_fuse_write(sc_ipc_t ipc, uint32_t word, uint32_t val)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_OTP_FUSE_WRITE;
+	RPC_U32(&msg, 0U) = (uint32_t)word;
+	RPC_U32(&msg, 4U) = (uint32_t)val;
+	RPC_SIZE(&msg) = 3U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_set_temp(sc_ipc_t ipc, sc_rsrc_t resource,
+			  sc_misc_temp_t temp, int16_t celsius, int8_t tenths)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SET_TEMP;
+	RPC_U16(&msg, 0U) = (uint16_t)resource;
+	RPC_I16(&msg, 2U) = (int16_t) celsius;
+	RPC_U8(&msg, 4U) = (uint8_t)temp;
+	RPC_I8(&msg, 5U) = (int8_t) tenths;
+	RPC_SIZE(&msg) = 3U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_get_temp(sc_ipc_t ipc, sc_rsrc_t resource,
+			  sc_misc_temp_t temp, int16_t *celsius,
+			  int8_t *tenths)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_GET_TEMP;
+	RPC_U16(&msg, 0U) = (uint16_t)resource;
+	RPC_U8(&msg, 2U) = (uint8_t)temp;
+	RPC_SIZE(&msg) = 2U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	if (celsius != NULL)
+		*celsius = RPC_I16(&msg, 0U);
+
+	result = RPC_R8(&msg);
+	if (tenths != NULL)
+		*tenths = RPC_I8(&msg, 2U);
+
+	return (sc_err_t)result;
+}
+
+void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *dev)
+{
+	sc_rpc_msg_t msg;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_GET_BOOT_DEV;
+	RPC_SIZE(&msg) = 1U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	if (dev != NULL)
+		*dev = RPC_U16(&msg, 0U);
+}
+
+void sc_misc_get_button_status(sc_ipc_t ipc, sc_bool_t *status)
+{
+	sc_rpc_msg_t msg;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_GET_BUTTON_STATUS;
+	RPC_SIZE(&msg) = 1U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	if (status != NULL)
+		*status = RPC_U8(&msg, 0U);
+}
+
+/**@}*/
diff --git a/plat/imx/common/sci/svc/misc/sci_misc_rpc.h b/plat/imx/common/sci/svc/misc/sci_misc_rpc.h
new file mode 100644
index 0000000..03b1a51
--- /dev/null
+++ b/plat/imx/common/sci/svc/misc/sci_misc_rpc.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ * Header file for the MISC RPC implementation.
+ *
+ * @addtogroup MISC_SVC
+ * @{
+ */
+
+#ifndef SC_MISC_RPC_H
+#define SC_MISC_RPC_H
+
+/* Includes */
+
+/* Defines */
+
+/*!
+ * @name Defines for RPC MISC function calls
+ */
+/*@{*/
+#define MISC_FUNC_UNKNOWN 0	/* Unknown function */
+#define MISC_FUNC_SET_CONTROL 1U	/* Index for misc_set_control() RPC call */
+#define MISC_FUNC_GET_CONTROL 2U	/* Index for misc_get_control() RPC call */
+#define MISC_FUNC_SET_MAX_DMA_GROUP 4U	/* Index for misc_set_max_dma_group() RPC call */
+#define MISC_FUNC_SET_DMA_GROUP 5U	/* Index for misc_set_dma_group() RPC call */
+#define MISC_FUNC_SECO_IMAGE_LOAD 8U	/* Index for misc_seco_image_load() RPC call */
+#define MISC_FUNC_SECO_AUTHENTICATE 9U	/* Index for misc_seco_authenticate() RPC call */
+#define MISC_FUNC_SECO_FUSE_WRITE 20U	/* Index for misc_seco_fuse_write() RPC call */
+#define MISC_FUNC_SECO_ENABLE_DEBUG 21U	/* Index for misc_seco_enable_debug() RPC call */
+#define MISC_FUNC_SECO_FORWARD_LIFECYCLE 22U	/* Index for misc_seco_forward_lifecycle() RPC call */
+#define MISC_FUNC_SECO_RETURN_LIFECYCLE 23U	/* Index for misc_seco_return_lifecycle() RPC call */
+#define MISC_FUNC_SECO_BUILD_INFO 24U	/* Index for misc_seco_build_info() RPC call */
+#define MISC_FUNC_SECO_CHIP_INFO 25U	/* Index for misc_seco_chip_info() RPC call */
+#define MISC_FUNC_DEBUG_OUT 10U	/* Index for misc_debug_out() RPC call */
+#define MISC_FUNC_WAVEFORM_CAPTURE 6U	/* Index for misc_waveform_capture() RPC call */
+#define MISC_FUNC_BUILD_INFO 15U	/* Index for misc_build_info() RPC call */
+#define MISC_FUNC_UNIQUE_ID 19U	/* Index for misc_unique_id() RPC call */
+#define MISC_FUNC_SET_ARI 3U	/* Index for misc_set_ari() RPC call */
+#define MISC_FUNC_BOOT_STATUS 7U	/* Index for misc_boot_status() RPC call */
+#define MISC_FUNC_BOOT_DONE 14U	/* Index for misc_boot_done() RPC call */
+#define MISC_FUNC_OTP_FUSE_READ 11U	/* Index for misc_otp_fuse_read() RPC call */
+#define MISC_FUNC_OTP_FUSE_WRITE 17U	/* Index for misc_otp_fuse_write() RPC call */
+#define MISC_FUNC_SET_TEMP 12U	/* Index for misc_set_temp() RPC call */
+#define MISC_FUNC_GET_TEMP 13U	/* Index for misc_get_temp() RPC call */
+#define MISC_FUNC_GET_BOOT_DEV 16U	/* Index for misc_get_boot_dev() RPC call */
+#define MISC_FUNC_GET_BUTTON_STATUS 18U	/* Index for misc_get_button_status() RPC call */
+/*@}*/
+
+/* Types */
+
+/* Functions */
+
+/*!
+ * This function dispatches an incoming MISC RPC request.
+ *
+ * @param[in]     caller_pt   caller partition
+ * @param[in]     msg         pointer to RPC message
+ */
+void misc_dispatch(sc_rm_pt_t caller_pt, sc_rpc_msg_t *msg);
+
+/*!
+ * This function translates and dispatches an MISC RPC request.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     msg         pointer to RPC message
+ */
+void misc_xlate(sc_ipc_t ipc, sc_rpc_msg_t *msg);
+
+#endif				/* SC_MISC_RPC_H */
+
+/**@}*/
diff --git a/plat/imx/common/sci/svc/timer/sci_timer_rpc.h b/plat/imx/common/sci/svc/timer/sci_timer_rpc.h
new file mode 100644
index 0000000..6716399
--- /dev/null
+++ b/plat/imx/common/sci/svc/timer/sci_timer_rpc.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ * Header file for the TIMER RPC implementation.
+ *
+ * @addtogroup TIMER_SVC
+ * @{
+ */
+
+#ifndef SC_TIMER_RPC_H
+#define SC_TIMER_RPC_H
+
+/* Includes */
+
+/* Defines */
+
+/*!
+ * @name Defines for RPC TIMER function calls
+ */
+/*@{*/
+#define TIMER_FUNC_UNKNOWN 0	/* Unknown function */
+#define TIMER_FUNC_SET_WDOG_TIMEOUT 1U	/* Index for timer_set_wdog_timeout() RPC call */
+#define TIMER_FUNC_SET_WDOG_PRE_TIMEOUT 12U	/* Index for timer_set_wdog_pre_timeout() RPC call */
+#define TIMER_FUNC_START_WDOG 2U	/* Index for timer_start_wdog() RPC call */
+#define TIMER_FUNC_STOP_WDOG 3U	/* Index for timer_stop_wdog() RPC call */
+#define TIMER_FUNC_PING_WDOG 4U	/* Index for timer_ping_wdog() RPC call */
+#define TIMER_FUNC_GET_WDOG_STATUS 5U	/* Index for timer_get_wdog_status() RPC call */
+#define TIMER_FUNC_PT_GET_WDOG_STATUS 13U	/* Index for timer_pt_get_wdog_status() RPC call */
+#define TIMER_FUNC_SET_WDOG_ACTION 10U	/* Index for timer_set_wdog_action() RPC call */
+#define TIMER_FUNC_SET_RTC_TIME 6U	/* Index for timer_set_rtc_time() RPC call */
+#define TIMER_FUNC_GET_RTC_TIME 7U	/* Index for timer_get_rtc_time() RPC call */
+#define TIMER_FUNC_GET_RTC_SEC1970 9U	/* Index for timer_get_rtc_sec1970() RPC call */
+#define TIMER_FUNC_SET_RTC_ALARM 8U	/* Index for timer_set_rtc_alarm() RPC call */
+#define TIMER_FUNC_SET_RTC_PERIODIC_ALARM 14U	/* Index for timer_set_rtc_periodic_alarm() RPC call */
+#define TIMER_FUNC_CANCEL_RTC_ALARM 15U	/* Index for timer_cancel_rtc_alarm() RPC call */
+#define TIMER_FUNC_SET_RTC_CALB 11U	/* Index for timer_set_rtc_calb() RPC call */
+#define TIMER_FUNC_SET_SYSCTR_ALARM 16U	/* Index for timer_set_sysctr_alarm() RPC call */
+#define TIMER_FUNC_SET_SYSCTR_PERIODIC_ALARM 17U	/* Index for timer_set_sysctr_periodic_alarm() RPC call */
+#define TIMER_FUNC_CANCEL_SYSCTR_ALARM 18U	/* Index for timer_cancel_sysctr_alarm() RPC call */
+/*@}*/
+
+/* Types */
+
+/* Functions */
+
+/*!
+ * This function dispatches an incoming TIMER RPC request.
+ *
+ * @param[in]     caller_pt   caller partition
+ * @param[in]     msg         pointer to RPC message
+ */
+void timer_dispatch(sc_rm_pt_t caller_pt, sc_rpc_msg_t *msg);
+
+/*!
+ * This function translates and dispatches an TIMER RPC request.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     msg         pointer to RPC message
+ */
+void timer_xlate(sc_ipc_t ipc, sc_rpc_msg_t *msg);
+
+#endif				/* SC_TIMER_RPC_H */
+
+/**@}*/
diff --git a/plat/imx/common/sci/svc/timer/timer_rpc_clnt.c b/plat/imx/common/sci/svc/timer/timer_rpc_clnt.c
new file mode 100644
index 0000000..a82be96
--- /dev/null
+++ b/plat/imx/common/sci/svc/timer/timer_rpc_clnt.c
@@ -0,0 +1,396 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ * File containing client-side RPC functions for the TIMER service. These
+ * functions are ported to clients that communicate to the SC.
+ *
+ * @addtogroup TIMER_SVC
+ * @{
+ */
+
+/* Includes */
+
+#include <sci/sci_types.h>
+#include <sci/svc/rm/sci_rm_api.h>
+#include <sci/svc/timer/sci_timer_api.h>
+#include <sci/sci_rpc.h>
+#include <stdlib.h>
+#include "sci_timer_rpc.h"
+
+/* Local Defines */
+
+/* Local Types */
+
+/* Local Functions */
+
+sc_err_t sc_timer_set_wdog_timeout(sc_ipc_t ipc, sc_timer_wdog_time_t timeout)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+	RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_SET_WDOG_TIMEOUT;
+	RPC_U32(&msg, 0U) = (uint32_t)timeout;
+	RPC_SIZE(&msg) = 2U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_set_wdog_pre_timeout(sc_ipc_t ipc,
+				       sc_timer_wdog_time_t pre_timeout)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+	RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_SET_WDOG_PRE_TIMEOUT;
+	RPC_U32(&msg, 0U) = (uint32_t)pre_timeout;
+	RPC_SIZE(&msg) = 2U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_start_wdog(sc_ipc_t ipc, sc_bool_t lock)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+	RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_START_WDOG;
+	RPC_U8(&msg, 0U) = (uint8_t)lock;
+	RPC_SIZE(&msg) = 2U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_stop_wdog(sc_ipc_t ipc)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+	RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_STOP_WDOG;
+	RPC_SIZE(&msg) = 1U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_ping_wdog(sc_ipc_t ipc)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+	RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_PING_WDOG;
+	RPC_SIZE(&msg) = 1U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_get_wdog_status(sc_ipc_t ipc,
+				  sc_timer_wdog_time_t *timeout,
+				  sc_timer_wdog_time_t *max_timeout,
+				  sc_timer_wdog_time_t *remaining_time)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+	RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_GET_WDOG_STATUS;
+	RPC_SIZE(&msg) = 1U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	if (timeout != NULL)
+		*timeout = RPC_U32(&msg, 0U);
+
+	if (max_timeout != NULL)
+		*max_timeout = RPC_U32(&msg, 4U);
+
+	if (remaining_time != NULL)
+		*remaining_time = RPC_U32(&msg, 8U);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_pt_get_wdog_status(sc_ipc_t ipc, sc_rm_pt_t pt,
+				     sc_bool_t *enb,
+				     sc_timer_wdog_time_t *timeout,
+				     sc_timer_wdog_time_t *remaining_time)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+	RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_PT_GET_WDOG_STATUS;
+	RPC_U8(&msg, 0U) = (uint8_t)pt;
+	RPC_SIZE(&msg) = 2U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	if (timeout != NULL)
+		*timeout = RPC_U32(&msg, 0U);
+
+	if (remaining_time != NULL)
+		*remaining_time = RPC_U32(&msg, 4U);
+
+	result = RPC_R8(&msg);
+	if (enb != NULL)
+		*enb = RPC_U8(&msg, 8U);
+
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_set_wdog_action(sc_ipc_t ipc,
+				  sc_rm_pt_t pt, sc_timer_wdog_action_t action)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+	RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_SET_WDOG_ACTION;
+	RPC_U8(&msg, 0U) = (uint8_t)pt;
+	RPC_U8(&msg, 1U) = (uint8_t)action;
+	RPC_SIZE(&msg) = 2U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_set_rtc_time(sc_ipc_t ipc, uint16_t year, uint8_t mon,
+			       uint8_t day, uint8_t hour, uint8_t min,
+			       uint8_t sec)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+	RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_SET_RTC_TIME;
+	RPC_U16(&msg, 0U) = (uint16_t)year;
+	RPC_U8(&msg, 2U) = (uint8_t)mon;
+	RPC_U8(&msg, 3U) = (uint8_t)day;
+	RPC_U8(&msg, 4U) = (uint8_t)hour;
+	RPC_U8(&msg, 5U) = (uint8_t)min;
+	RPC_U8(&msg, 6U) = (uint8_t)sec;
+	RPC_SIZE(&msg) = 3U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_get_rtc_time(sc_ipc_t ipc, uint16_t *year, uint8_t *mon,
+			       uint8_t *day, uint8_t *hour, uint8_t *min,
+			       uint8_t *sec)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+	RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_GET_RTC_TIME;
+	RPC_SIZE(&msg) = 1U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	if (year != NULL)
+		*year = RPC_U16(&msg, 0U);
+
+	result = RPC_R8(&msg);
+	if (mon != NULL)
+		*mon = RPC_U8(&msg, 2U);
+
+	if (day != NULL)
+		*day = RPC_U8(&msg, 3U);
+
+	if (hour != NULL)
+		*hour = RPC_U8(&msg, 4U);
+
+	if (min != NULL)
+		*min = RPC_U8(&msg, 5U);
+
+	if (sec != NULL)
+		*sec = RPC_U8(&msg, 6U);
+
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_get_rtc_sec1970(sc_ipc_t ipc, uint32_t *sec)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+	RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_GET_RTC_SEC1970;
+	RPC_SIZE(&msg) = 1U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	if (sec != NULL)
+		*sec = RPC_U32(&msg, 0U);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_set_rtc_alarm(sc_ipc_t ipc, uint16_t year, uint8_t mon,
+				uint8_t day, uint8_t hour, uint8_t min,
+				uint8_t sec)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+	RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_SET_RTC_ALARM;
+	RPC_U16(&msg, 0U) = (uint16_t)year;
+	RPC_U8(&msg, 2U) = (uint8_t)mon;
+	RPC_U8(&msg, 3U) = (uint8_t)day;
+	RPC_U8(&msg, 4U) = (uint8_t)hour;
+	RPC_U8(&msg, 5U) = (uint8_t)min;
+	RPC_U8(&msg, 6U) = (uint8_t)sec;
+	RPC_SIZE(&msg) = 3U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_set_rtc_periodic_alarm(sc_ipc_t ipc, uint32_t sec)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+	RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_SET_RTC_PERIODIC_ALARM;
+	RPC_U32(&msg, 0U) = (uint32_t)sec;
+	RPC_SIZE(&msg) = 2U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_cancel_rtc_alarm(sc_ipc_t ipc)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+	RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_CANCEL_RTC_ALARM;
+	RPC_SIZE(&msg) = 1U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_set_rtc_calb(sc_ipc_t ipc, int8_t count)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+	RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_SET_RTC_CALB;
+	RPC_I8(&msg, 0U) = (int8_t) count;
+	RPC_SIZE(&msg) = 2U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_set_sysctr_alarm(sc_ipc_t ipc, uint64_t ticks)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+	RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_SET_SYSCTR_ALARM;
+	RPC_U32(&msg, 0U) = (uint32_t)(ticks >> 32U);
+	RPC_U32(&msg, 4U) = (uint32_t)ticks;
+	RPC_SIZE(&msg) = 3U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_set_sysctr_periodic_alarm(sc_ipc_t ipc, uint64_t ticks)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+	RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_SET_SYSCTR_PERIODIC_ALARM;
+	RPC_U32(&msg, 0U) = (uint32_t)(ticks >> 32U);
+	RPC_U32(&msg, 4U) = (uint32_t)ticks;
+	RPC_SIZE(&msg) = 3U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_timer_cancel_sysctr_alarm(sc_ipc_t ipc)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_TIMER;
+	RPC_FUNC(&msg) = (uint8_t)TIMER_FUNC_CANCEL_SYSCTR_ALARM;
+	RPC_SIZE(&msg) = 1U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+/**@}*/
diff --git a/plat/imx/imx7/warp7/include/platform_def.h b/plat/imx/imx7/warp7/include/platform_def.h
index a931c80..d58382f 100644
--- a/plat/imx/imx7/warp7/include/platform_def.h
+++ b/plat/imx/imx7/warp7/include/platform_def.h
@@ -106,6 +106,12 @@
 #define WARP7_DTB_BASE			(DRAM_BASE + 0x03000000)
 #define WARP7_DTB_LIMIT			(WARP7_DTB_BASE + WARP7_DTB_SIZE)
 
+/* Define the absolute location of DTB Overlay 0x83100000 - 0x83101000 */
+#define WARP7_DTB_OVERLAY_SIZE		0x00001000
+#define WARP7_DTB_OVERLAY_BASE		WARP7_DTB_LIMIT
+#define WARP7_DTB_OVERLAY_LIMIT		(WARP7_DTB_OVERLAY_BASE + \
+					 WARP7_DTB_OVERLAY_SIZE)
+
 /*
  * BL2 specific defines.
  *
@@ -142,6 +148,8 @@
  *            |       DDR       | BL33/U-BOOT
  * 0x87800000 +-----------------+
  *            |       DDR       | Unallocated
+ * 0x83101000 +-----------------+
+ *            |       DDR       | DTB Overlay
  * 0x83100000 +-----------------+
  *            |       DDR       | DTB
  * 0x83000000 +-----------------+
diff --git a/plat/imx/imx7/warp7/platform.mk b/plat/imx/imx7/warp7/platform.mk
index a771865..f7bd4ae 100644
--- a/plat/imx/imx7/warp7/platform.mk
+++ b/plat/imx/imx7/warp7/platform.mk
@@ -62,6 +62,43 @@
 				plat/imx/imx7/warp7/warp7_image_load.c		\
 				${XLAT_TABLES_LIB_SRCS}
 
+ifneq (${TRUSTED_BOARD_BOOT},0)
+
+include drivers/auth/mbedtls/mbedtls_crypto.mk
+include drivers/auth/mbedtls/mbedtls_x509.mk
+
+AUTH_SOURCES	:=	drivers/auth/auth_mod.c			\
+			drivers/auth/crypto_mod.c		\
+			drivers/auth/img_parser_mod.c		\
+			drivers/auth/tbbr/tbbr_cot.c
+
+BL2_SOURCES		+=	${AUTH_SOURCES}					\
+				plat/common/tbbr/plat_tbbr.c			\
+				plat/imx/imx7/warp7/warp7_trusted_boot.c	\
+				plat/imx/imx7/warp7/warp7_rotpk.S
+
+ROT_KEY             = $(BUILD_PLAT)/rot_key.pem
+ROTPK_HASH          = $(BUILD_PLAT)/rotpk_sha256.bin
+
+$(eval $(call add_define_val,ROTPK_HASH,'"$(ROTPK_HASH)"'))
+$(eval $(call MAKE_LIB_DIRS))
+
+$(BUILD_PLAT)/bl2/warp7_rotpk.o: $(ROTPK_HASH)
+
+certificates: $(ROT_KEY)
+
+$(ROT_KEY): | $(BUILD_PLAT)
+	@echo "  OPENSSL $@"
+	@if [ ! -f $(ROT_KEY) ]; then \
+		openssl genrsa 2048 > $@ 2>/dev/null; \
+	fi
+
+$(ROTPK_HASH): $(ROT_KEY)
+	@echo "  OPENSSL $@"
+	$(Q)openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+	openssl dgst -sha256 -binary > $@ 2>/dev/null
+endif
+
 # Build config flags
 # ------------------
 
@@ -86,6 +123,21 @@
 PLAT_WARP7_UART			:=1
 $(eval $(call add_define,PLAT_WARP7_UART))
 
+# Add the build options to pack BLx images and kernel device tree
+# in the FIP if the platform requires.
+ifneq ($(BL2),)
+$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/tb_fw.crt,--tb-fw-cert))
+endif
+ifneq ($(BL32_EXTRA1),)
+$(eval $(call TOOL_ADD_IMG,BL32_EXTRA1,--tos-fw-extra1))
+endif
+ifneq ($(BL32_EXTRA2),)
+$(eval $(call TOOL_ADD_IMG,BL32_EXTRA2,--tos-fw-extra2))
+endif
+ifneq ($(HW_CONFIG),)
+$(eval $(call TOOL_ADD_IMG,HW_CONFIG,--hw-config))
+endif
+
 # Verify build config
 # -------------------
 
diff --git a/plat/imx/imx7/warp7/warp7_bl2_el3_setup.c b/plat/imx/imx7/warp7/warp7_bl2_el3_setup.c
index 032ed7b..08baf19 100644
--- a/plat/imx/imx7/warp7/warp7_bl2_el3_setup.c
+++ b/plat/imx/imx7/warp7/warp7_bl2_el3_setup.c
@@ -290,12 +290,13 @@
 	imx_wdog_init();
 
 	/* Print out the expected memory map */
-	VERBOSE("\tOPTEE      0x%08x-0x%08x\n", WARP7_OPTEE_BASE, WARP7_OPTEE_LIMIT);
-	VERBOSE("\tATF/BL2    0x%08x-0x%08x\n", BL2_RAM_BASE, BL2_RAM_LIMIT);
-	VERBOSE("\tSHRAM      0x%08x-0x%08x\n", SHARED_RAM_BASE, SHARED_RAM_LIMIT);
-	VERBOSE("\tFIP        0x%08x-0x%08x\n", WARP7_FIP_BASE, WARP7_FIP_LIMIT);
-	VERBOSE("\tDTB        0x%08x-0x%08x\n", WARP7_DTB_BASE, WARP7_DTB_LIMIT);
-	VERBOSE("\tUBOOT/BL33 0x%08x-0x%08x\n", WARP7_UBOOT_BASE, WARP7_UBOOT_LIMIT);
+	VERBOSE("\tOPTEE       0x%08x-0x%08x\n", WARP7_OPTEE_BASE, WARP7_OPTEE_LIMIT);
+	VERBOSE("\tATF/BL2     0x%08x-0x%08x\n", BL2_RAM_BASE, BL2_RAM_LIMIT);
+	VERBOSE("\tSHRAM       0x%08x-0x%08x\n", SHARED_RAM_BASE, SHARED_RAM_LIMIT);
+	VERBOSE("\tFIP         0x%08x-0x%08x\n", WARP7_FIP_BASE, WARP7_FIP_LIMIT);
+	VERBOSE("\tDTB-OVERLAY 0x%08x-0x%08x\n", WARP7_DTB_OVERLAY_BASE, WARP7_DTB_OVERLAY_LIMIT);
+	VERBOSE("\tDTB         0x%08x-0x%08x\n", WARP7_DTB_BASE, WARP7_DTB_LIMIT);
+	VERBOSE("\tUBOOT/BL33  0x%08x-0x%08x\n", WARP7_UBOOT_BASE, WARP7_UBOOT_LIMIT);
 }
 
 /*
diff --git a/plat/imx/imx7/warp7/warp7_bl2_mem_params_desc.c b/plat/imx/imx7/warp7/warp7_bl2_mem_params_desc.c
index a29e141..c670d42 100644
--- a/plat/imx/imx7/warp7/warp7_bl2_mem_params_desc.c
+++ b/plat/imx/imx7/warp7/warp7_bl2_mem_params_desc.c
@@ -28,16 +28,6 @@
 		.next_handoff_image_id = BL33_IMAGE_ID,
 	},
 	{
-		.image_id = HW_CONFIG_ID,
-		SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
-				      VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
-		SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
-				      VERSION_2, image_info_t, 0),
-		.image_info.image_base = WARP7_DTB_BASE,
-		.image_info.image_max_size = WARP7_DTB_SIZE,
-		.next_handoff_image_id = INVALID_IMAGE_ID,
-	},
-	{
 		.image_id = BL32_EXTRA1_IMAGE_ID,
 
 		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2,
diff --git a/plat/imx/imx7/warp7/warp7_io_storage.c b/plat/imx/imx7/warp7/warp7_io_storage.c
index b9cace0..fcfb503 100644
--- a/plat/imx/imx7/warp7/warp7_io_storage.c
+++ b/plat/imx/imx7/warp7/warp7_io_storage.c
@@ -60,10 +60,6 @@
 	.uuid = UUID_SECURE_PAYLOAD_BL32,
 };
 
-static const io_uuid_spec_t hw_config_uuid_spec = {
-	.uuid = UUID_HW_CONFIG,
-};
-
 static const io_uuid_spec_t bl32_extra1_uuid_spec = {
 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
 };
@@ -76,6 +72,32 @@
 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
 };
 
+#if TRUSTED_BOARD_BOOT
+static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
+	.uuid = UUID_TRUSTED_BOOT_FW_CERT,
+};
+
+static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
+	.uuid = UUID_TRUSTED_KEY_CERT,
+};
+
+static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
+	.uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
+	.uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
+};
+
+static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
+	.uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
+	.uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
+};
+#endif /* TRUSTED_BOARD_BOOT */
+
 /* TODO: this structure is replicated multiple times. rationalize it ! */
 struct plat_io_policy {
 	uintptr_t *dev_handle;
@@ -112,16 +134,43 @@
 		(uintptr_t)&bl32_extra2_uuid_spec,
 		open_fip
 	},
-	[HW_CONFIG_ID] = {
+	[BL33_IMAGE_ID] = {
 		&fip_dev_handle,
-		(uintptr_t)&hw_config_uuid_spec,
+		(uintptr_t)&bl33_uuid_spec,
 		open_fip
 	},
-	[BL33_IMAGE_ID] = {
+#if TRUSTED_BOARD_BOOT
+	[TRUSTED_BOOT_FW_CERT_ID] = {
 		&fip_dev_handle,
-		(uintptr_t)&bl33_uuid_spec,
+		(uintptr_t)&tb_fw_cert_uuid_spec,
 		open_fip
-	}
+	},
+	[TRUSTED_KEY_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&trusted_key_cert_uuid_spec,
+		open_fip
+	},
+	[TRUSTED_OS_FW_KEY_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&tos_fw_key_cert_uuid_spec,
+		open_fip
+	},
+	[NON_TRUSTED_FW_KEY_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&nt_fw_key_cert_uuid_spec,
+		open_fip
+	},
+	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&tos_fw_cert_uuid_spec,
+		open_fip
+	},
+	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&nt_fw_cert_uuid_spec,
+		open_fip
+	},
+#endif /* TRUSTED_BOARD_BOOT */
 };
 
 static int open_fip(const uintptr_t spec)
diff --git a/plat/imx/imx7/warp7/warp7_rotpk.S b/plat/imx/imx7/warp7/warp7_rotpk.S
new file mode 100644
index 0000000..f74b6d25b
--- /dev/null
+++ b/plat/imx/imx7/warp7/warp7_rotpk.S
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+	.global warp7_rotpk_hash
+	.global warp7_rotpk_hash_end
+warp7_rotpk_hash:
+	/* DER header */
+	.byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
+	.byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
+	/* SHA256 */
+	.incbin ROTPK_HASH
+warp7_rotpk_hash_end:
diff --git a/plat/imx/imx7/warp7/warp7_trusted_boot.c b/plat/imx/imx7/warp7/warp7_trusted_boot.c
new file mode 100644
index 0000000..8157cd5
--- /dev/null
+++ b/plat/imx/imx7/warp7/warp7_trusted_boot.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/common/platform.h>
+
+extern char warp7_rotpk_hash[], warp7_rotpk_hash_end[];
+
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+			unsigned int *flags)
+{
+	*key_ptr = warp7_rotpk_hash;
+	*key_len = warp7_rotpk_hash_end - warp7_rotpk_hash;
+	*flags = ROTPK_IS_HASH;
+
+	return 0;
+}
+
+int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
+{
+	*nv_ctr = 0;
+
+	return 0;
+}
+
+int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
+{
+	return 1;
+}
diff --git a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
index f4e6ee7..b18edd9 100644
--- a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c
+++ b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.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
  */
@@ -87,7 +87,7 @@
 #if DEBUG_CONSOLE
 	static console_uart_t console;
 
-	console_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
+	console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ,
 		IMX_CONSOLE_BAUDRATE, &console);
 #endif
 	/*
diff --git a/plat/imx/imx8m/imx8mq/platform.mk b/plat/imx/imx8m/imx8mq/platform.mk
index 0255268..2681e57 100644
--- a/plat/imx/imx8m/imx8mq/platform.mk
+++ b/plat/imx/imx8m/imx8mq/platform.mk
@@ -34,3 +34,7 @@
 RESET_TO_BL31		:=	1
 A53_DISABLE_NON_TEMPORAL_HINT := 0
 MULTI_CONSOLE_API	:=	1
+
+ERRATA_A53_835769	:=	1
+ERRATA_A53_843419	:=	1
+ERRATA_A53_855873	:=	1
diff --git a/plat/imx/imx8qm/imx8qm_bl31_setup.c b/plat/imx/imx8qm/imx8qm_bl31_setup.c
index a00695c..c76de64 100644
--- a/plat/imx/imx8qm/imx8qm_bl31_setup.c
+++ b/plat/imx/imx8qm/imx8qm_bl31_setup.c
@@ -49,11 +49,7 @@
 };
 
 static const mmap_region_t imx_mmap[] = {
-	MAP_REGION_FLAT(IMX_BOOT_UART_BASE, IMX_BOOT_UART_SIZE, MT_DEVICE | MT_RW),
-	MAP_REGION_FLAT(SC_IPC_BASE, SC_IPC_SIZE, MT_DEVICE | MT_RW),
-	MAP_REGION_FLAT(PLAT_GICD_BASE, PLAT_GICD_SIZE, MT_DEVICE | MT_RW),
-	MAP_REGION_FLAT(PLAT_GICR_BASE, PLAT_GICR_SIZE, MT_DEVICE | MT_RW),
-	MAP_REGION_FLAT(PLAT_CCI_BASE, PLAT_CCI_SIZE, MT_DEVICE | MT_RW),
+	MAP_REGION_FLAT(IMX_REG_BASE, IMX_REG_SIZE, MT_DEVICE | MT_RW),
 	{0}
 };
 
@@ -324,6 +320,10 @@
 
 	/* turn on MU1 for non-secure OS/Hypervisor */
 	sc_pm_set_resource_power_mode(ipc_handle, SC_R_MU_1A, SC_PM_PW_MODE_ON);
+	/* Turn on GPT_0's power & clock for non-secure OS/Hypervisor */
+	sc_pm_set_resource_power_mode(ipc_handle, SC_R_GPT_0, SC_PM_PW_MODE_ON);
+	sc_pm_clock_enable(ipc_handle, SC_R_GPT_0, SC_PM_CLK_PER, true, 0);
+	mmio_write_32(IMX_GPT_LPCG_BASE, mmio_read_32(IMX_GPT_LPCG_BASE) | (1 << 25));
 
 	/*
 	 * create new partition for non-secure OS/Hypervisor
diff --git a/plat/imx/imx8qm/imx8qm_psci.c b/plat/imx/imx8qm/imx8qm_psci.c
index 833048d..bdba37c 100644
--- a/plat/imx/imx8qm/imx8qm_psci.c
+++ b/plat/imx/imx8qm/imx8qm_psci.c
@@ -17,6 +17,8 @@
 #include <plat_imx8.h>
 #include <sci/sci.h>
 
+#include "../../common/sci/imx8_mu.h"
+
 #define CORE_PWR_STATE(state) \
 	((state)->pwr_domain_state[MPIDR_AFFLVL0])
 #define CLUSTER_PWR_STATE(state) \
@@ -29,44 +31,70 @@
 	SC_R_A53_3, SC_R_A72_0, SC_R_A72_1,
 };
 
+/* save gic dist/redist context when GIC is poewr down */
+static struct plat_gic_ctx imx_gicv3_ctx;
+static unsigned int gpt_lpcg, gpt_reg[2];
+
+static void imx_enable_irqstr_wakeup(void)
+{
+	uint32_t irq_mask;
+	gicv3_dist_ctx_t *dist_ctx = &imx_gicv3_ctx.dist_ctx;
+
+	/* put IRQSTR into ON mode */
+	sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_ON);
+
+	/* enable the irqsteer to handle wakeup irq */
+	mmio_write_32(IMX_WUP_IRQSTR_BASE, 0x1);
+	for (int i = 0; i < 15; i++) {
+		irq_mask = dist_ctx->gicd_isenabler[i];
+		mmio_write_32(IMX_WUP_IRQSTR_BASE + 0x3c - 0x4 * i, irq_mask);
+	}
+
+	/* set IRQSTR low power mode */
+	if (imx_is_wakeup_src_irqsteer())
+		sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_STBY);
+	else
+		sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_OFF);
+}
+
+static void imx_disable_irqstr_wakeup(void)
+{
+	/* put IRQSTR into ON from STBY mode */
+	sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_ON);
+
+	/* disable the irqsteer */
+	mmio_write_32(IMX_WUP_IRQSTR_BASE, 0x0);
+	for (int i = 0; i < 16; i++)
+		mmio_write_32(IMX_WUP_IRQSTR_BASE + 0x4 + 0x4 * i, 0x0);
+
+	/* put IRQSTR into OFF mode */
+	sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_OFF);
+}
+
 int imx_pwr_domain_on(u_register_t mpidr)
 {
 	int ret = PSCI_E_SUCCESS;
-	unsigned int cluster_id, cpu_id;
-
-	cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
-	cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
+	unsigned int cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
+	unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
 
-	printf("imx_pwr_domain_on cluster_id %d, cpu_id %d\n", cluster_id, cpu_id);
+	sc_pm_set_resource_power_mode(ipc_handle, cluster_id == 0 ?
+		SC_R_A53 : SC_R_A72, SC_PM_PW_MODE_ON);
 
-	if (cluster_id == 0) {
-		sc_pm_set_resource_power_mode(ipc_handle, SC_R_A53,
-			SC_PM_PW_MODE_ON);
-		if (sc_pm_set_resource_power_mode(ipc_handle, ap_core_index[cpu_id],
-			SC_PM_PW_MODE_ON) != SC_ERR_NONE) {
-			ERROR("cluster0 core %d power on failed!\n", cpu_id);
-			ret = PSCI_E_INTERN_FAIL;
-		}
+	if (cluster_id == 1)
+		sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_ON);
 
-		if (sc_pm_cpu_start(ipc_handle, ap_core_index[cpu_id],
-			true, BL31_BASE) != SC_ERR_NONE) {
-			ERROR("boot cluster0 core %d failed!\n", cpu_id);
-			ret = PSCI_E_INTERN_FAIL;
-		}
-	} else {
-		sc_pm_set_resource_power_mode(ipc_handle, SC_R_A72,
-			SC_PM_PW_MODE_ON);
-		if (sc_pm_set_resource_power_mode(ipc_handle, ap_core_index[cpu_id + 4],
-			SC_PM_PW_MODE_ON) != SC_ERR_NONE) {
-			ERROR(" cluster1 core %d power on failed!\n", cpu_id);
-			ret = PSCI_E_INTERN_FAIL;
-		}
+	if (sc_pm_set_resource_power_mode(ipc_handle,
+		ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+		SC_PM_PW_MODE_ON) != SC_ERR_NONE) {
+		ERROR("core %d power on failed!\n", cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id);
+		ret = PSCI_E_INTERN_FAIL;
+	}
 
-		if (sc_pm_cpu_start(ipc_handle, ap_core_index[cpu_id + 4],
-			true, BL31_BASE) != SC_ERR_NONE) {
-			ERROR("boot cluster1 core %d failed!\n", cpu_id);
-			ret = PSCI_E_INTERN_FAIL;
-		}
+	if (sc_pm_cpu_start(ipc_handle,
+		ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+		true, BL31_BASE) != SC_ERR_NONE) {
+		ERROR("boot core %d failed!\n", cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id);
+		ret = PSCI_E_INTERN_FAIL;
 	}
 
 	return ret;
@@ -91,11 +119,14 @@
 
 	plat_gic_cpuif_disable();
 	sc_pm_req_cpu_low_power_mode(ipc_handle,
-		ap_core_index[cpu_id + cluster_id * 4],
-		SC_PM_PW_MODE_OFF,
-		SC_PM_WAKE_SRC_NONE);
-	if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
-		cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
+		ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+		SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_NONE);
+
+	if (is_local_state_off(CLUSTER_PWR_STATE(target_state))) {
+		cci_disable_snoop_dvm_reqs(cluster_id);
+		if (cluster_id == 1)
+			sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_OFF);
+	}
 	printf("turn off cluster:%d core:%d\n", cluster_id, cpu_id);
 }
 
@@ -105,24 +136,148 @@
 	unsigned int cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
 	unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
 
-	plat_gic_cpuif_disable();
+	if (is_local_state_off(CORE_PWR_STATE(target_state))) {
+		plat_gic_cpuif_disable();
+		sc_pm_set_cpu_resume(ipc_handle,
+			ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+			true, BL31_BASE);
+		sc_pm_req_cpu_low_power_mode(ipc_handle,
+			ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+			SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_GIC);
+	} else {
+		dsb();
+		write_scr_el3(read_scr_el3() | SCR_FIQ_BIT);
+		isb();
+	}
 
-	cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
+	if (is_local_state_off(CLUSTER_PWR_STATE(target_state))) {
+		cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
+		if (cluster_id == 1)
+			sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_OFF);
+	}
 
-	sc_pm_set_cpu_resume_addr(ipc_handle,
-		ap_core_index[cpu_id + cluster_id * 4], BL31_BASE);
-	sc_pm_req_cpu_low_power_mode(ipc_handle,
-		ap_core_index[cpu_id + cluster_id * 4],
-		SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_GIC);
+	if (is_local_state_retn(SYSTEM_PWR_STATE(target_state))) {
+		plat_gic_cpuif_disable();
+
+		/* save gic context */
+		plat_gic_save(cpu_id, &imx_gicv3_ctx);
+		/* enable the irqsteer for wakeup */
+		imx_enable_irqstr_wakeup();
+
+		cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
+
+		/* Put GIC in LP mode. */
+		sc_pm_set_resource_power_mode(ipc_handle, SC_R_GIC, SC_PM_PW_MODE_OFF);
+		/* Save GPT clock and registers, then turn off its power */
+		gpt_lpcg = mmio_read_32(IMX_GPT_LPCG_BASE);
+		gpt_reg[0] = mmio_read_32(IMX_GPT_BASE);
+		gpt_reg[1] = mmio_read_32(IMX_GPT_BASE + 0x4);
+		sc_pm_set_resource_power_mode(ipc_handle, SC_R_GPT_0, SC_PM_PW_MODE_OFF);
+
+		sc_pm_req_low_power_mode(ipc_handle, SC_R_A53, SC_PM_PW_MODE_OFF);
+		sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_OFF);
+		sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_OFF);
+
+		sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_DDR,
+			SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+		sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_DDR,
+			SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+		sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_MU,
+			SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+		sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_MU,
+			SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+		sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_INTERCONNECT,
+			SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+		sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_INTERCONNECT,
+			SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+		sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_OFF);
+
+		sc_pm_set_cpu_resume(ipc_handle,
+			ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+			true, BL31_BASE);
+		if (imx_is_wakeup_src_irqsteer())
+			sc_pm_req_cpu_low_power_mode(ipc_handle,
+				ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+				SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_IRQSTEER);
+		else
+			sc_pm_req_cpu_low_power_mode(ipc_handle,
+				ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+				SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_SCU);
+	}
 }
 
 void imx_domain_suspend_finish(const psci_power_state_t *target_state)
 {
 	u_register_t mpidr = read_mpidr_el1();
+	unsigned int cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
+	unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
 
-	cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
+	/* check the system level status */
+	if (is_local_state_retn(SYSTEM_PWR_STATE(target_state))) {
+		MU_Resume(SC_IPC_BASE);
 
-	plat_gic_cpuif_enable();
+		sc_pm_req_cpu_low_power_mode(ipc_handle,
+			ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+			SC_PM_PW_MODE_ON, SC_PM_WAKE_SRC_GIC);
+
+		/* Put GIC/IRQSTR back to high power mode. */
+		sc_pm_set_resource_power_mode(ipc_handle, SC_R_GIC, SC_PM_PW_MODE_ON);
+
+		/* Turn GPT power and restore its clock and registers */
+		sc_pm_set_resource_power_mode(ipc_handle, SC_R_GPT_0, SC_PM_PW_MODE_ON);
+		sc_pm_clock_enable(ipc_handle, SC_R_GPT_0, SC_PM_CLK_PER, true, 0);
+		mmio_write_32(IMX_GPT_BASE, gpt_reg[0]);
+		mmio_write_32(IMX_GPT_BASE + 0x4, gpt_reg[1]);
+		mmio_write_32(IMX_GPT_LPCG_BASE, gpt_lpcg);
+
+		sc_pm_req_low_power_mode(ipc_handle, SC_R_A53, SC_PM_PW_MODE_ON);
+		sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_ON);
+		sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_ON);
+
+		sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_DDR,
+			SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+		sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_DDR,
+			SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+		sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_MU,
+			SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+		sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_MU,
+			SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+		sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_INTERCONNECT,
+			SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+		sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_INTERCONNECT,
+			SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+		sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_ON);
+
+		cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
+
+		/* restore gic context */
+		plat_gic_restore(cpu_id, &imx_gicv3_ctx);
+		/* disable the irqsteer wakeup */
+		imx_disable_irqstr_wakeup();
+
+		plat_gic_cpuif_enable();
+	}
+
+	/* check the cluster level power status */
+	if (is_local_state_off(CLUSTER_PWR_STATE(target_state))) {
+		cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
+		if (cluster_id == 1)
+			sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_ON);
+	}
+
+	/* check the core level power status */
+	if (is_local_state_off(CORE_PWR_STATE(target_state))) {
+		sc_pm_set_cpu_resume(ipc_handle,
+			ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+			false, BL31_BASE);
+		sc_pm_req_cpu_low_power_mode(ipc_handle,
+			ap_core_index[cpu_id + PLATFORM_CLUSTER0_CORE_COUNT * cluster_id],
+			SC_PM_PW_MODE_ON, SC_PM_WAKE_SRC_GIC);
+		plat_gic_cpuif_enable();
+	} else {
+		write_scr_el3(read_scr_el3() & (~SCR_FIQ_BIT));
+		isb();
+	}
 }
 
 int imx_validate_ns_entrypoint(uintptr_t ns_entrypoint)
@@ -149,26 +304,23 @@
 	imx_mailbox_init(sec_entrypoint);
 	*psci_ops = &imx_plat_psci_ops;
 
-	/* Request low power mode for cluster/cci, only need to do once */
-	sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_OFF);
-	sc_pm_req_low_power_mode(ipc_handle, SC_R_A53, SC_PM_PW_MODE_OFF);
-	sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_OFF);
+	/* make sure system sources power ON in low power mode by default */
+	sc_pm_req_low_power_mode(ipc_handle, SC_R_A53, SC_PM_PW_MODE_ON);
+	sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_ON);
+	sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_ON);
 
-	/* Request RUN and LP modes for DDR, system interconnect etc. */
-	sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53,
-		SC_PM_SYS_IF_DDR, SC_PM_PW_MODE_ON, SC_PM_PW_MODE_STBY);
-	sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72,
-		SC_PM_SYS_IF_DDR, SC_PM_PW_MODE_ON, SC_PM_PW_MODE_STBY);
-	sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53,
-		SC_PM_SYS_IF_MU, SC_PM_PW_MODE_ON, SC_PM_PW_MODE_STBY);
-	sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72,
-		SC_PM_SYS_IF_MU, SC_PM_PW_MODE_ON, SC_PM_PW_MODE_STBY);
-	sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53,
-		SC_PM_SYS_IF_INTERCONNECT, SC_PM_PW_MODE_ON,
-		SC_PM_PW_MODE_STBY);
-	sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72,
-		SC_PM_SYS_IF_INTERCONNECT, SC_PM_PW_MODE_ON,
-		SC_PM_PW_MODE_STBY);
+	sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_DDR,
+		SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+	sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_DDR,
+		SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+	sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_MU,
+		SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+	sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_MU,
+		SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+	sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53, SC_PM_SYS_IF_INTERCONNECT,
+		SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+	sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72, SC_PM_SYS_IF_INTERCONNECT,
+		SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
 
 	return 0;
 }
diff --git a/plat/imx/imx8qm/include/platform_def.h b/plat/imx/imx8qm/include/platform_def.h
index 1d0bdf9..946be76 100644
--- a/plat/imx/imx8qm/include/platform_def.h
+++ b/plat/imx/imx8qm/include/platform_def.h
@@ -36,22 +36,22 @@
 #define BL31_LIMIT			0x80020000
 
 #define PLAT_GICD_BASE			0x51a00000
-#define PLAT_GICD_SIZE			0x10000
 #define PLAT_GICR_BASE			0x51b00000
-#define PLAT_GICR_SIZE			0xc0000
 #define PLAT_CCI_BASE			0x52090000
-#define PLAT_CCI_SIZE			0x10000
 #define CLUSTER0_CCI_SLVAE_IFACE	3
 #define CLUSTER1_CCI_SLVAE_IFACE	4
 #define IMX_BOOT_UART_BASE		0x5a060000
-#define IMX_BOOT_UART_SIZE		0x1000
 #define IMX_BOOT_UART_BAUDRATE		115200
 #define IMX_BOOT_UART_CLK_IN_HZ		24000000
 #define PLAT_CRASH_UART_BASE		IMX_BOOT_UART_BASE
 #define PLAT__CRASH_UART_CLK_IN_HZ	24000000
 #define IMX_CONSOLE_BAUDRATE		115200
 #define SC_IPC_BASE			0x5d1b0000
-#define SC_IPC_SIZE			0x10000
+#define IMX_GPT_LPCG_BASE		0x5d540000
+#define IMX_GPT_BASE			0x5d140000
+#define IMX_WUP_IRQSTR_BASE		0x51090000
+#define IMX_REG_BASE			0x50000000
+#define IMX_REG_SIZE			0x10000000
 
 #define COUNTER_FREQUENCY		8000000 /* 8MHz */
 
diff --git a/plat/imx/imx8qm/include/sec_rsrc.h b/plat/imx/imx8qm/include/sec_rsrc.h
index a623cd3..d16d051 100644
--- a/plat/imx/imx8qm/include/sec_rsrc.h
+++ b/plat/imx/imx8qm/include/sec_rsrc.h
@@ -19,12 +19,14 @@
 	SC_R_GIC_SMMU,
 	SC_R_CCI,
 	SC_R_SYSTEM,
-	SC_R_IRQSTR_SCU2
+	SC_R_IRQSTR_SCU2,
+	SC_R_GPT_0
 };
 
 /* resources that have register access for non-secure domain */
 sc_rsrc_t ns_access_allowed[] = {
 	SC_R_GIC,
 	SC_R_GIC_SMMU,
-	SC_R_CCI
+	SC_R_CCI,
+	SC_R_GPT_0
 };
diff --git a/plat/imx/imx8qm/platform.mk b/plat/imx/imx8qm/platform.mk
index dc45e90..ed6108d 100644
--- a/plat/imx/imx8qm/platform.mk
+++ b/plat/imx/imx8qm/platform.mk
@@ -22,6 +22,8 @@
 				plat/imx/imx8qm/imx8qm_psci.c		\
 				plat/imx/common/imx8_topology.c		\
 				plat/imx/common/imx8_psci.c		\
+				plat/imx/common/imx_sip_svc.c		\
+				plat/imx/common/imx_sip_handler.c	\
 				lib/xlat_tables/aarch64/xlat_tables.c		\
 				lib/xlat_tables/xlat_tables_common.c		\
 				lib/cpus/aarch64/cortex_a53.S			\
@@ -36,3 +38,7 @@
 A53_DISABLE_NON_TEMPORAL_HINT := 0
 MULTI_CONSOLE_API	:=	1
 ERRATA_A72_859971	:=	1
+
+ERRATA_A53_835769	:=	1
+ERRATA_A53_843419	:=	1
+ERRATA_A53_855873	:=	1
diff --git a/plat/imx/imx8qx/imx8qx_bl31_setup.c b/plat/imx/imx8qx/imx8qx_bl31_setup.c
index c90794a..bfe4052 100644
--- a/plat/imx/imx8qx/imx8qx_bl31_setup.c
+++ b/plat/imx/imx8qx/imx8qx_bl31_setup.c
@@ -44,10 +44,7 @@
 			(SC_PAD_28FDSOI_PS_PD << PADRING_PULL_SHIFT))
 
 static const mmap_region_t imx_mmap[] = {
-	MAP_REGION_FLAT(IMX_BOOT_UART_BASE, IMX_BOOT_UART_SIZE, MT_DEVICE | MT_RW),
-	MAP_REGION_FLAT(SC_IPC_BASE, SC_IPC_SIZE, MT_DEVICE | MT_RW),
-	MAP_REGION_FLAT(PLAT_GICD_BASE, PLAT_GICD_SIZE, MT_DEVICE | MT_RW),
-	MAP_REGION_FLAT(PLAT_GICR_BASE, PLAT_GICR_SIZE, MT_DEVICE | MT_RW),
+	MAP_REGION_FLAT(IMX_REG_BASE, IMX_REG_SIZE, MT_DEVICE | MT_RW),
 	{0}
 };
 
@@ -281,6 +278,11 @@
 	/* Turn on MU1 for non-secure OS/Hypervisor */
 	sc_pm_set_resource_power_mode(ipc_handle, SC_R_MU_1A, SC_PM_PW_MODE_ON);
 
+	/* Turn on GPT_0's power & clock for non-secure OS/Hypervisor */
+	sc_pm_set_resource_power_mode(ipc_handle, SC_R_GPT_0, SC_PM_PW_MODE_ON);
+	sc_pm_clock_enable(ipc_handle, SC_R_GPT_0, SC_PM_CLK_PER, true, 0);
+	mmio_write_32(IMX_GPT0_LPCG_BASE, mmio_read_32(IMX_GPT0_LPCG_BASE) | (1 << 25));
+
 	/*
 	 * create new partition for non-secure OS/Hypervisor
 	 * uses global structs defined in sec_rsrc.h
diff --git a/plat/imx/imx8qx/imx8qx_psci.c b/plat/imx/imx8qx/imx8qx_psci.c
index 94c2e2b..aab3a2d 100644
--- a/plat/imx/imx8qx/imx8qx_psci.c
+++ b/plat/imx/imx8qx/imx8qx_psci.c
@@ -16,10 +16,52 @@
 #include <plat_imx8.h>
 #include <sci/sci.h>
 
+#include "../../common/sci/imx8_mu.h"
+
 const static int ap_core_index[PLATFORM_CORE_COUNT] = {
 	SC_R_A35_0, SC_R_A35_1, SC_R_A35_2, SC_R_A35_3
 };
 
+/* save gic dist/redist context when GIC is power down */
+static struct plat_gic_ctx imx_gicv3_ctx;
+static unsigned int gpt_lpcg, gpt_reg[2];
+
+static void imx_enable_irqstr_wakeup(void)
+{
+	uint32_t irq_mask;
+	gicv3_dist_ctx_t *dist_ctx = &imx_gicv3_ctx.dist_ctx;
+
+	/* put IRQSTR into ON mode */
+	sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_ON);
+
+	/* enable the irqsteer to handle wakeup irq */
+	mmio_write_32(IMX_WUP_IRQSTR_BASE, 0x1);
+	for (int i = 0; i < 15; i++) {
+		irq_mask = dist_ctx->gicd_isenabler[i];
+		mmio_write_32(IMX_WUP_IRQSTR_BASE + 0x3c - 0x4 * i, irq_mask);
+	}
+
+	/* set IRQSTR low power mode */
+	if (imx_is_wakeup_src_irqsteer())
+		sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_STBY);
+	else
+		sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_OFF);
+}
+
+static void imx_disable_irqstr_wakeup(void)
+{
+	/* Put IRQSTEER back to ON mode */
+	sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_ON);
+
+	/* disable the irqsteer */
+	mmio_write_32(IMX_WUP_IRQSTR_BASE, 0x0);
+	for (int i = 0; i < 16; i++)
+		mmio_write_32(IMX_WUP_IRQSTR_BASE + 0x4 + 0x4 * i, 0x0);
+
+	/* Put IRQSTEER into OFF mode */
+	sc_pm_set_resource_power_mode(ipc_handle, SC_R_IRQSTR_SCU2, SC_PM_PW_MODE_OFF);
+}
+
 int imx_pwr_domain_on(u_register_t mpidr)
 {
 	int ret = PSCI_E_SUCCESS;
@@ -71,11 +113,52 @@
 	u_register_t mpidr = read_mpidr_el1();
 	unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
 
-	plat_gic_cpuif_disable();
+	if (is_local_state_off(target_state->pwr_domain_state[MPIDR_AFFLVL0])) {
+		plat_gic_cpuif_disable();
+		sc_pm_set_cpu_resume(ipc_handle, ap_core_index[cpu_id], true, BL31_BASE);
+		sc_pm_req_cpu_low_power_mode(ipc_handle, ap_core_index[cpu_id],
+			SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_GIC);
+	} else {
+		dsb();
+		write_scr_el3(read_scr_el3() | SCR_FIQ_BIT);
+		isb();
+	}
 
-	sc_pm_set_cpu_resume_addr(ipc_handle, ap_core_index[cpu_id], BL31_BASE);
-	sc_pm_req_cpu_low_power_mode(ipc_handle, ap_core_index[cpu_id],
-		SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_GIC);
+	if (is_local_state_off(target_state->pwr_domain_state[MPIDR_AFFLVL1]))
+		sc_pm_req_low_power_mode(ipc_handle, SC_R_A35, SC_PM_PW_MODE_OFF);
+
+	if (is_local_state_retn(target_state->pwr_domain_state[PLAT_MAX_PWR_LVL])) {
+		plat_gic_cpuif_disable();
+
+		/* save gic context */
+		plat_gic_save(cpu_id, &imx_gicv3_ctx);
+		/* enable the irqsteer for wakeup */
+		imx_enable_irqstr_wakeup();
+
+		/* Save GPT clock and registers, then turn off its power */
+		gpt_lpcg = mmio_read_32(IMX_GPT0_LPCG_BASE);
+		gpt_reg[0] = mmio_read_32(IMX_GPT0_BASE);
+		gpt_reg[1] = mmio_read_32(IMX_GPT0_BASE + 0x4);
+		sc_pm_set_resource_power_mode(ipc_handle, SC_R_GPT_0, SC_PM_PW_MODE_OFF);
+
+		sc_pm_req_low_power_mode(ipc_handle, SC_R_A35, SC_PM_PW_MODE_OFF);
+		sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_DDR,
+			SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+		sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_MU,
+			SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+		sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_INTERCONNECT,
+			SC_PM_PW_MODE_ON, SC_PM_PW_MODE_OFF);
+
+		/* Put GIC in OFF mode. */
+		sc_pm_set_resource_power_mode(ipc_handle, SC_R_GIC, SC_PM_PW_MODE_OFF);
+		sc_pm_set_cpu_resume(ipc_handle, ap_core_index[cpu_id], true, BL31_BASE);
+		if (imx_is_wakeup_src_irqsteer())
+			sc_pm_req_cpu_low_power_mode(ipc_handle, ap_core_index[cpu_id],
+				SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_IRQSTEER);
+		else
+			sc_pm_req_cpu_low_power_mode(ipc_handle, ap_core_index[cpu_id],
+				SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_SCU);
+	}
 }
 
 void imx_domain_suspend_finish(const psci_power_state_t *target_state)
@@ -83,10 +166,51 @@
 	u_register_t mpidr = read_mpidr_el1();
 	unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
 
-	sc_pm_req_low_power_mode(ipc_handle, ap_core_index[cpu_id],
-		SC_PM_PW_MODE_ON);
+	if (is_local_state_retn(target_state->pwr_domain_state[PLAT_MAX_PWR_LVL])) {
+		MU_Resume(SC_IPC_BASE);
 
-	plat_gic_cpuif_enable();
+		sc_pm_req_low_power_mode(ipc_handle, ap_core_index[cpu_id], SC_PM_PW_MODE_ON);
+		sc_pm_req_cpu_low_power_mode(ipc_handle, ap_core_index[cpu_id],
+			SC_PM_PW_MODE_ON, SC_PM_WAKE_SRC_GIC);
+
+		/* Put GIC back to high power mode. */
+		sc_pm_set_resource_power_mode(ipc_handle, SC_R_GIC, SC_PM_PW_MODE_ON);
+
+		/* restore gic context */
+		plat_gic_restore(cpu_id, &imx_gicv3_ctx);
+
+		/* Turn on GPT power and restore its clock and registers */
+		sc_pm_set_resource_power_mode(ipc_handle, SC_R_GPT_0, SC_PM_PW_MODE_ON);
+		sc_pm_clock_enable(ipc_handle, SC_R_GPT_0, SC_PM_CLK_PER, true, 0);
+		mmio_write_32(IMX_GPT0_BASE, gpt_reg[0]);
+		mmio_write_32(IMX_GPT0_BASE + 0x4, gpt_reg[1]);
+		mmio_write_32(IMX_GPT0_LPCG_BASE, gpt_lpcg);
+
+		sc_pm_req_low_power_mode(ipc_handle, SC_R_A35, SC_PM_PW_MODE_ON);
+		sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_DDR,
+			SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+		sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_MU,
+			SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+		sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_INTERCONNECT,
+			SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+
+		/* disable the irqsteer wakeup */
+		imx_disable_irqstr_wakeup();
+
+		plat_gic_cpuif_enable();
+	}
+
+	if (is_local_state_off(target_state->pwr_domain_state[MPIDR_AFFLVL1]))
+		sc_pm_req_low_power_mode(ipc_handle, SC_R_A35, SC_PM_PW_MODE_ON);
+
+	if (is_local_state_off(target_state->pwr_domain_state[MPIDR_AFFLVL0])) {
+		sc_pm_req_cpu_low_power_mode(ipc_handle, ap_core_index[cpu_id],
+			SC_PM_PW_MODE_ON, SC_PM_WAKE_SRC_GIC);
+		plat_gic_cpuif_enable();
+	} else {
+		write_scr_el3(read_scr_el3() & (~SCR_FIQ_BIT));
+		isb();
+	}
 }
 
 static const plat_psci_ops_t imx_plat_psci_ops = {
@@ -108,17 +232,15 @@
 	imx_mailbox_init(sec_entrypoint);
 	*psci_ops = &imx_plat_psci_ops;
 
-	/* Request low power mode for A35 cluster, only need to do once */
-	sc_pm_req_low_power_mode(ipc_handle, SC_R_A35, SC_PM_PW_MODE_OFF);
+	/* make sure system sources power ON in low power mode by default */
+	sc_pm_req_low_power_mode(ipc_handle, SC_R_A35, SC_PM_PW_MODE_ON);
 
-	/* Request RUN and LP modes for DDR, system interconnect etc. */
-	sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35,
-		SC_PM_SYS_IF_DDR, SC_PM_PW_MODE_ON, SC_PM_PW_MODE_STBY);
-	sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35,
-		SC_PM_SYS_IF_MU, SC_PM_PW_MODE_ON, SC_PM_PW_MODE_STBY);
-	sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35,
-		SC_PM_SYS_IF_INTERCONNECT, SC_PM_PW_MODE_ON,
-		SC_PM_PW_MODE_STBY);
+	sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_DDR,
+		SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+	sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_MU,
+		SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
+	sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35, SC_PM_SYS_IF_INTERCONNECT,
+		SC_PM_PW_MODE_ON, SC_PM_PW_MODE_ON);
 
 	return 0;
 }
diff --git a/plat/imx/imx8qx/include/platform_def.h b/plat/imx/imx8qx/include/platform_def.h
index 1239340..3a3fac8 100644
--- a/plat/imx/imx8qx/include/platform_def.h
+++ b/plat/imx/imx8qx/include/platform_def.h
@@ -37,18 +37,19 @@
 #define MAX_MMAP_REGIONS		8
 
 #define PLAT_GICD_BASE			0x51a00000
-#define PLAT_GICD_SIZE			0x10000
 #define PLAT_GICR_BASE			0x51b00000
-#define PLAT_GICR_SIZE			0xc0000
 #define IMX_BOOT_UART_BASE		0x5a060000
-#define IMX_BOOT_UART_SIZE		0x1000
 #define IMX_BOOT_UART_BAUDRATE		115200
 #define IMX_BOOT_UART_CLK_IN_HZ		24000000
 #define PLAT_CRASH_UART_BASE		IMX_BOOT_UART_BASE
 #define PLAT__CRASH_UART_CLK_IN_HZ	24000000
 #define IMX_CONSOLE_BAUDRATE		115200
 #define SC_IPC_BASE			0x5d1b0000
-#define SC_IPC_SIZE			0x10000
+#define IMX_GPT0_LPCG_BASE		0x5d540000
+#define IMX_GPT0_BASE			0x5d140000
+#define IMX_WUP_IRQSTR_BASE		0x51090000
+#define IMX_REG_BASE			0x50000000
+#define IMX_REG_SIZE			0x10000000
 
 #define COUNTER_FREQUENCY		8000000
 
diff --git a/plat/imx/imx8qx/include/sec_rsrc.h b/plat/imx/imx8qx/include/sec_rsrc.h
index 37c9f66..b7fe0e8 100644
--- a/plat/imx/imx8qx/include/sec_rsrc.h
+++ b/plat/imx/imx8qx/include/sec_rsrc.h
@@ -14,10 +14,12 @@
 	SC_R_A35_3,
 	SC_R_GIC,
 	SC_R_SYSTEM,
-	SC_R_IRQSTR_SCU2
+	SC_R_IRQSTR_SCU2,
+	SC_R_GPT_0
 };
 
 /* resources that have register access for non-secure domain */
 sc_rsrc_t ns_access_allowed[] = {
 	SC_R_GIC,
+	SC_R_GPT_0
 };
diff --git a/plat/imx/imx8qx/platform.mk b/plat/imx/imx8qx/platform.mk
index a831bf2..eeb1f34 100644
--- a/plat/imx/imx8qx/platform.mk
+++ b/plat/imx/imx8qx/platform.mk
@@ -21,6 +21,8 @@
 				plat/imx/imx8qx/imx8qx_psci.c		\
 				plat/imx/common/imx8_topology.c		\
 				plat/imx/common/imx8_psci.c		\
+				plat/imx/common/imx_sip_svc.c		\
+				plat/imx/common/imx_sip_handler.c	\
 				plat/common/plat_psci_common.c		\
 				lib/xlat_tables/xlat_tables_common.c	\
 				lib/xlat_tables/aarch64/xlat_tables.c	\
diff --git a/plat/layerscape/common/ls_bl1_setup.c b/plat/layerscape/common/ls_bl1_setup.c
index fb929fe..163b35c 100644
--- a/plat/layerscape/common/ls_bl1_setup.c
+++ b/plat/layerscape/common/ls_bl1_setup.c
@@ -4,11 +4,11 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <common/bl_common.h>
 #include <common/debug.h>
 
 #include "ls_16550.h"
 #include "plat_ls.h"
-#include "../../../bl1/bl1_private.h"
 
 /* Data structure which holds the extents of the trusted SRAM for BL1*/
 static meminfo_t bl1_tzram_layout;
diff --git a/plat/marvell/common/marvell_bl1_setup.c b/plat/marvell/common/marvell_bl1_setup.c
index 8f72210..7b7cef3 100644
--- a/plat/marvell/common/marvell_bl1_setup.c
+++ b/plat/marvell/common/marvell_bl1_setup.c
@@ -8,7 +8,6 @@
 #include <platform_def.h>
 
 #include <bl1/bl1.h>
-#include <bl1/bl1_private.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <drivers/arm/sp805.h>
diff --git a/plat/mediatek/mt8173/bl31_plat_setup.c b/plat/mediatek/mt8173/bl31_plat_setup.c
index bd384a1..dd23e63 100644
--- a/plat/mediatek/mt8173/bl31_plat_setup.c
+++ b/plat/mediatek/mt8173/bl31_plat_setup.c
@@ -11,13 +11,13 @@
 #include <drivers/console.h>
 #include <drivers/generic_delay_timer.h>
 #include <lib/mmio.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/common_def.h>
 #include <plat/common/platform.h>
 
 #include <mcucfg.h>
 #include <mtcmos.h>
 #include <mtk_plat_common.h>
-#include <plat_arm.h>
 #include <plat_private.h>
 #include <spm.h>
 
diff --git a/plat/mediatek/mt8173/plat_pm.c b/plat/mediatek/mt8173/plat_pm.c
index 9673d2c..1b52470 100644
--- a/plat/mediatek/mt8173/plat_pm.c
+++ b/plat/mediatek/mt8173/plat_pm.c
@@ -15,11 +15,11 @@
 #include <lib/bakery_lock.h>
 #include <lib/mmio.h>
 #include <lib/psci/psci.h>
+#include <plat/arm/common/plat_arm.h>
 
 #include <mcucfg.h>
 #include <mt8173_def.h>
 #include <mt_cpuxgpt.h> /* generic_timer_backup() */
-#include <plat_arm.h>
 #include <plat_private.h>
 #include <power_tracer.h>
 #include <rtc.h>
diff --git a/plat/mediatek/mt8173/platform.mk b/plat/mediatek/mt8173/platform.mk
index 294aea4..0726efe 100644
--- a/plat/mediatek/mt8173/platform.mk
+++ b/plat/mediatek/mt8173/platform.mk
@@ -9,7 +9,6 @@
 
 PLAT_INCLUDES		:=	-I${MTK_PLAT}/common/				\
 				-I${MTK_PLAT}/common/drivers/uart/		\
-				-Iinclude/plat/arm/common			\
 				-Iinclude/plat/arm/common/aarch64		\
 				-I${MTK_PLAT_SOC}/drivers/crypt/		\
 				-I${MTK_PLAT_SOC}/drivers/mtcmos/		\
diff --git a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
index 0476ba8..b47be6d 100644
--- a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
+++ b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
@@ -11,22 +11,28 @@
 #include <cortex_a57.h>
 #include <platform_def.h>
 #include <tegra_def.h>
+#include <tegra_platform.h>
 
 #define MIDR_PN_CORTEX_A57		0xD07
 
 /*******************************************************************************
  * Implementation defined ACTLR_EL3 bit definitions
  ******************************************************************************/
-#define ACTLR_EL3_L2ACTLR_BIT		(1 << 6)
-#define ACTLR_EL3_L2ECTLR_BIT		(1 << 5)
-#define ACTLR_EL3_L2CTLR_BIT		(1 << 4)
-#define ACTLR_EL3_CPUECTLR_BIT		(1 << 1)
-#define ACTLR_EL3_CPUACTLR_BIT		(1 << 0)
+#define ACTLR_EL3_L2ACTLR_BIT		(U(1) << 6)
+#define ACTLR_EL3_L2ECTLR_BIT		(U(1) << 5)
+#define ACTLR_EL3_L2CTLR_BIT		(U(1) << 4)
+#define ACTLR_EL3_CPUECTLR_BIT		(U(1) << 1)
+#define ACTLR_EL3_CPUACTLR_BIT		(U(1) << 0)
+#define ACTLR_EL3_ENABLE_ALL_MASK	(ACTLR_EL3_L2ACTLR_BIT | \
+								ACTLR_EL3_L2ECTLR_BIT | \
+					 			ACTLR_EL3_L2CTLR_BIT | \
+					 			ACTLR_EL3_CPUECTLR_BIT | \
+					 			ACTLR_EL3_CPUACTLR_BIT)
 #define ACTLR_EL3_ENABLE_ALL_ACCESS	(ACTLR_EL3_L2ACTLR_BIT | \
-					 ACTLR_EL3_L2ECTLR_BIT | \
-					 ACTLR_EL3_L2CTLR_BIT | \
-					 ACTLR_EL3_CPUECTLR_BIT | \
-					 ACTLR_EL3_CPUACTLR_BIT)
+					 			ACTLR_EL3_L2ECTLR_BIT | \
+					 			ACTLR_EL3_L2CTLR_BIT | \
+					 			ACTLR_EL3_CPUECTLR_BIT | \
+					 			ACTLR_EL3_CPUACTLR_BIT)
 
 	/* Global functions */
 	.globl	plat_is_my_cpu_primary
@@ -45,7 +51,6 @@
 	.globl	ns_image_entrypoint
 	.globl	tegra_bl31_phys_base
 	.globl	tegra_console_base
-	.globl	tegra_enable_l2_ecc_parity_prot
 
 	/* ---------------------
 	 * Common CPU init code
@@ -87,25 +92,20 @@
 	 * Enable L2 and CPU ECTLR RW access from non-secure world
 	 * -------------------------------------------------------
 	 */
-	mov	x0, #ACTLR_EL3_ENABLE_ALL_ACCESS
+	mrs	x0, actlr_el3
+	mov	x1, #ACTLR_EL3_ENABLE_ALL_MASK
+	bic	x0, x0, x1
+	mov	x1, #ACTLR_EL3_ENABLE_ALL_ACCESS
+	orr	x0, x0, x1
 	msr	actlr_el3, x0
+	mrs	x0, actlr_el2
+	mov	x1, #ACTLR_EL3_ENABLE_ALL_MASK
+	bic	x0, x0, x1
+	mov	x1, #ACTLR_EL3_ENABLE_ALL_ACCESS
+	orr	x0, x0, x1
 	msr	actlr_el2, x0
 	isb
 
-	/* -------------------------------------------------------
-	 * Enable L2 ECC and Parity Protection
-	 * -------------------------------------------------------
-	 */
-	adr	x0, tegra_enable_l2_ecc_parity_prot
-	ldr	x0, [x0]
-	cbz	x0, 1f
-	mrs	x0, CORTEX_A57_L2CTLR_EL1
-	and	x1, x0, #CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT
-	cbnz	x1, 1f
-	orr	x0, x0, #CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT
-	msr	CORTEX_A57_L2CTLR_EL1, x0
-	isb
-
 	/* --------------------------------
 	 * Enable the cycle count register
 	 * --------------------------------
@@ -144,17 +144,20 @@
 	ret
 endfunc plat_is_my_cpu_primary
 
-	/* -----------------------------------------------------
+	/* ----------------------------------------------------------
 	 * unsigned int plat_my_core_pos(void);
 	 *
-	 * result: CorePos = CoreId + (ClusterId << 2)
-	 * -----------------------------------------------------
+	 * result: CorePos = CoreId + (ClusterId * cpus per cluster)
+	 * ----------------------------------------------------------
 	 */
 func plat_my_core_pos
 	mrs	x0, mpidr_el1
 	and	x1, x0, #MPIDR_CPU_MASK
 	and	x0, x0, #MPIDR_CLUSTER_MASK
-	add	x0, x1, x0, LSR #6
+	lsr	x0, x0, #MPIDR_AFFINITY_BITS
+	mov	x2, #PLATFORM_MAX_CPUS_PER_CLUSTER
+	mul	x0, x0, x2
+	add	x0, x1, x0
 	ret
 endfunc plat_my_core_pos
 
@@ -176,14 +179,17 @@
 	/* -----------------------------------------------------
 	 * int platform_get_core_pos(int mpidr);
 	 *
-	 * With this function: CorePos = (ClusterId * 4) +
-	 *                                CoreId
+	 * result: CorePos = (ClusterId * cpus per cluster) +
+	 *                   CoreId
 	 * -----------------------------------------------------
 	 */
 func platform_get_core_pos
 	and	x1, x0, #MPIDR_CPU_MASK
 	and	x0, x0, #MPIDR_CLUSTER_MASK
-	add	x0, x1, x0, LSR #6
+	lsr	x0, x0, #MPIDR_AFFINITY_BITS
+	mov	x2, #PLATFORM_MAX_CPUS_PER_CLUSTER
+	mul	x0, x0, x2
+	add	x0, x1, x0
 	ret
 endfunc platform_get_core_pos
 
@@ -326,6 +332,23 @@
 
 #if ERRATA_TEGRA_INVALIDATE_BTB_AT_BOOT
 
+	/* --------------------------------------------------------
+	 * Skip the invalidate BTB workaround for Tegra210B01 SKUs.
+	 * --------------------------------------------------------
+	 */
+	mov	x0, #TEGRA_MISC_BASE
+	add	x0, x0, #HARDWARE_REVISION_OFFSET
+	ldr	w1, [x0]
+	lsr	w1, w1, #CHIP_ID_SHIFT
+	and	w1, w1, #CHIP_ID_MASK
+	cmp	w1, #TEGRA_CHIPID_TEGRA21	/* T210? */
+	b.ne	2f
+	ldr	w1, [x0]
+	lsr	w1, w1, #MAJOR_VERSION_SHIFT
+	and	w1, w1, #MAJOR_VERSION_MASK
+	cmp	w1, #0x02			/* T210 B01? */
+	b.eq	2f
+
 	/* -------------------------------------------------------
 	 * Invalidate BTB along with I$ to remove any stale
 	 * entries from the branch predictor array.
@@ -382,7 +405,7 @@
 	.rept	65
 	nop
 	.endr
-
+2:
 	/* --------------------------------------------------
 	 * Do not insert instructions here
 	 * --------------------------------------------------
@@ -397,31 +420,6 @@
 	mov	x0, #1
 	msr	oslar_el1, x0
 
-	cpu_init_common
-
-	/* ---------------------------------------------------------------------
-	 * The initial state of the Architectural feature trap register
-	 * (CPTR_EL3) is unknown and it must be set to a known state. All
-	 * feature traps are disabled. Some bits in this register are marked as
-	 * Reserved and should not be modified.
-	 *
-	 * CPTR_EL3.TCPAC: This causes a direct access to the CPACR_EL1 from EL1
-	 *  or the CPTR_EL2 from EL2 to trap to EL3 unless it is trapped at EL2.
-	 * CPTR_EL3.TTA: This causes access to the Trace functionality to trap
-	 *  to EL3 when executed from EL0, EL1, EL2, or EL3. If system register
-	 *  access to trace functionality is not supported, this bit is RES0.
-	 * CPTR_EL3.TFP: This causes instructions that access the registers
-	 *  associated with Floating Point and Advanced SIMD execution to trap
-	 *  to EL3 when executed from any exception level, unless trapped to EL1
-	 *  or EL2.
-	 * ---------------------------------------------------------------------
-	 */
-	mrs	x1, cptr_el3
-	bic	w1, w1, #TCPAC_BIT
-	bic	w1, w1, #TTA_BIT
-	bic	w1, w1, #TFP_BIT
-	msr	cptr_el3, x1
-
 	/* --------------------------------------------------
 	 * Get secure world's entry point and jump to it
 	 * --------------------------------------------------
@@ -460,10 +458,3 @@
 	 */
 tegra_console_base:
 	.quad	0
-
-	/* --------------------------------------------------
-	 * Enable L2 ECC and Parity Protection
-	 * --------------------------------------------------
-	 */
-tegra_enable_l2_ecc_parity_prot:
-	.quad	0
diff --git a/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c b/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c
new file mode 100644
index 0000000..1c5d2e1
--- /dev/null
+++ b/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bpmp.h>
+#include <common/debug.h>
+#include <delay_timer.h>
+#include <errno.h>
+#include <mmio.h>
+#include <platform.h>
+#include <stdbool.h>
+#include <string.h>
+#include <tegra_def.h>
+
+#define BPMP_TIMEOUT	2
+
+static uint32_t channel_base[NR_CHANNELS];
+static uint32_t bpmp_init_state = BPMP_INIT_PENDING;
+
+static uint32_t channel_field(unsigned int ch)
+{
+	return mmio_read_32(TEGRA_RES_SEMA_BASE + STA_OFFSET) & CH_MASK(ch);
+}
+
+static bool master_free(unsigned int ch)
+{
+	return channel_field(ch) == MA_FREE(ch);
+}
+
+static bool master_acked(unsigned int ch)
+{
+	return channel_field(ch) == MA_ACKD(ch);
+}
+
+static void signal_slave(unsigned int ch)
+{
+	mmio_write_32(TEGRA_RES_SEMA_BASE + CLR_OFFSET, CH_MASK(ch));
+}
+
+static void free_master(unsigned int ch)
+{
+	mmio_write_32(TEGRA_RES_SEMA_BASE + CLR_OFFSET,
+		      MA_ACKD(ch) ^ MA_FREE(ch));
+}
+
+/* should be called with local irqs disabled */
+int32_t tegra_bpmp_send_receive_atomic(int mrq, const void *ob_data, int ob_sz,
+		void *ib_data, int ib_sz)
+{
+	unsigned int ch = (unsigned int)plat_my_core_pos();
+	mb_data_t *p = (mb_data_t *)(uintptr_t)channel_base[ch];
+	int32_t ret = -ETIMEDOUT, timeout = 0;
+
+	if (bpmp_init_state == BPMP_INIT_COMPLETE) {
+
+		/* loop until BPMP is free */
+		for (timeout = 0; timeout < BPMP_TIMEOUT; timeout++) {
+			if (master_free(ch) == true) {
+				break;
+			}
+
+			mdelay(1);
+		}
+
+		if (timeout != BPMP_TIMEOUT) {
+
+			/* generate the command struct */
+			p->code = mrq;
+			p->flags = DO_ACK;
+			(void)memcpy((void *)p->data, ob_data, (size_t)ob_sz);
+
+			/* signal command ready to the BPMP */
+			signal_slave(ch);
+			mmio_write_32(TEGRA_PRI_ICTLR_BASE + CPU_IEP_FIR_SET,
+				      (1U << INT_SHR_SEM_OUTBOX_FULL));
+
+			/* loop until the command is executed */
+			for (timeout = 0; timeout < BPMP_TIMEOUT; timeout++) {
+				if (master_acked(ch) == true) {
+					break;
+				}
+
+				mdelay(1);
+			}
+
+			if (timeout != BPMP_TIMEOUT) {
+
+				/* get the command response */
+				(void)memcpy(ib_data, (const void *)p->data,
+					     (size_t)ib_sz);
+
+				/* return error code */
+				ret = p->code;
+
+				/* free this channel */
+				free_master(ch);
+			}
+		}
+
+	} else {
+		/* return error code */
+		ret = -EINVAL;
+	}
+
+	if (timeout == BPMP_TIMEOUT) {
+		ERROR("Timed out waiting for bpmp's response\n");
+	}
+
+	return ret;
+}
+
+int tegra_bpmp_init(void)
+{
+	uint32_t val, base;
+	unsigned int ch;
+	int ret = 0;
+
+	if (bpmp_init_state != BPMP_INIT_COMPLETE) {
+
+		/* check if the bpmp processor is alive. */
+		val = mmio_read_32(TEGRA_RES_SEMA_BASE + STA_OFFSET);
+		if (val != SIGN_OF_LIFE) {
+			ERROR("BPMP precessor not available\n");
+			return -ENOTSUP;
+		}
+
+		/* check if clock for the atomics block is enabled */
+		val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_ENB_V);
+		if ((val & CAR_ENABLE_ATOMICS) == 0) {
+			ERROR("Clock to the atomics block is disabled\n");
+		}
+
+		/* check if the atomics block is out of reset */
+		val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_CLR_V);
+		if ((val & CAR_ENABLE_ATOMICS) == CAR_ENABLE_ATOMICS) {
+			ERROR("Reset to the atomics block is asserted\n");
+		}
+
+		/* base address to get the result from Atomics */
+		base = TEGRA_ATOMICS_BASE + RESULT0_REG_OFFSET;
+
+		/* channel area is setup by BPMP before signaling handshake */
+		for (ch = 0; ch < NR_CHANNELS; ch++) {
+
+			/* issue command to get the channel base address */
+			mmio_write_32(base, (ch << TRIGGER_ID_SHIFT) |
+				      ATOMIC_CMD_GET);
+
+			/* get the base address for the channel */
+			channel_base[ch] = mmio_read_32(base);
+
+			/* increment result register offset */
+			base += 4U;
+		}
+
+		/* mark state as "initialized" */
+		bpmp_init_state = BPMP_INIT_COMPLETE;
+
+		/* the channel values have to be visible across all cpus */
+		flush_dcache_range((uint64_t)channel_base, sizeof(channel_base));
+		flush_dcache_range((uint64_t)&bpmp_init_state,
+				   sizeof(bpmp_init_state));
+
+		INFO("%s: done\n", __func__);
+	}
+
+	return ret;
+}
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c
new file mode 100644
index 0000000..7faa2f0
--- /dev/null
+++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <bpmp_ipc.h>
+#include <debug.h>
+#include <delay_timer.h>
+#include <errno.h>
+#include <mmio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <tegra_def.h>
+#include <utils_def.h>
+
+#include "intf.h"
+#include "ivc.h"
+
+/**
+ * Holds IVC channel data
+ */
+struct ccplex_bpmp_channel_data {
+	/* Buffer for incoming data */
+	struct frame_data *ib;
+
+	/* Buffer for outgoing data */
+	struct frame_data *ob;
+};
+
+static struct ccplex_bpmp_channel_data s_channel;
+static struct ivc ivc_ccplex_bpmp_channel;
+
+/*
+ * Helper functions to access the HSP doorbell registers
+ */
+static inline uint32_t hsp_db_read(uint32_t reg)
+{
+	return mmio_read_32((uint32_t)(TEGRA_HSP_DBELL_BASE + reg));
+}
+
+static inline void hsp_db_write(uint32_t reg, uint32_t val)
+{
+	mmio_write_32((uint32_t)(TEGRA_HSP_DBELL_BASE + reg), val);
+}
+
+/*******************************************************************************
+ *      IVC wrappers for CCPLEX <-> BPMP communication.
+ ******************************************************************************/
+
+static void tegra_bpmp_ring_bpmp_doorbell(void);
+
+/*
+ * Get the next frame where data can be written.
+ */
+static struct frame_data *tegra_bpmp_get_next_out_frame(void)
+{
+	struct frame_data *frame;
+	const struct ivc *ch = &ivc_ccplex_bpmp_channel;
+
+	frame = (struct frame_data *)tegra_ivc_write_get_next_frame(ch);
+	if (frame == NULL) {
+		ERROR("%s: Error in getting next frame, exiting\n", __func__);
+	} else {
+		s_channel.ob = frame;
+	}
+
+	return frame;
+}
+
+static void tegra_bpmp_signal_slave(void)
+{
+	(void)tegra_ivc_write_advance(&ivc_ccplex_bpmp_channel);
+	tegra_bpmp_ring_bpmp_doorbell();
+}
+
+static int32_t tegra_bpmp_free_master(void)
+{
+	return tegra_ivc_read_advance(&ivc_ccplex_bpmp_channel);
+}
+
+static bool tegra_bpmp_slave_acked(void)
+{
+	struct frame_data *frame;
+	bool ret = true;
+
+	frame = (struct frame_data *)tegra_ivc_read_get_next_frame(&ivc_ccplex_bpmp_channel);
+	if (frame == NULL) {
+		ret = false;
+	} else {
+		s_channel.ib = frame;
+	}
+
+	return ret;
+}
+
+static struct frame_data *tegra_bpmp_get_cur_in_frame(void)
+{
+	return s_channel.ib;
+}
+
+/*
+ * Enables BPMP to ring CCPlex doorbell
+ */
+static void tegra_bpmp_enable_ccplex_doorbell(void)
+{
+	uint32_t reg;
+
+	reg = hsp_db_read(HSP_DBELL_1_ENABLE);
+	reg |= HSP_MASTER_BPMP_BIT;
+	hsp_db_write(HSP_DBELL_1_ENABLE, reg);
+}
+
+/*
+ * CCPlex rings the BPMP doorbell
+ */
+static void tegra_bpmp_ring_bpmp_doorbell(void)
+{
+	/*
+	 * Any writes to this register has the same effect,
+	 * uses master ID of the write transaction and set
+	 * corresponding flag.
+	 */
+	hsp_db_write(HSP_DBELL_3_TRIGGER, HSP_MASTER_CCPLEX_BIT);
+}
+
+/*
+ * Returns true if CCPLex can ring BPMP doorbell, otherwise false.
+ * This also signals that BPMP is up and ready.
+ */
+static bool tegra_bpmp_can_ccplex_ring_doorbell(void)
+{
+	uint32_t reg;
+
+	/* check if ccplex can communicate with bpmp */
+	reg = hsp_db_read(HSP_DBELL_3_ENABLE);
+
+	return ((reg & HSP_MASTER_CCPLEX_BIT) != 0U);
+}
+
+static int32_t tegra_bpmp_wait_for_slave_ack(void)
+{
+	uint32_t timeout = TIMEOUT_RESPONSE_FROM_BPMP_US;
+
+	while (!tegra_bpmp_slave_acked() && (timeout != 0U)) {
+		udelay(1);
+		timeout--;
+	};
+
+	return ((timeout == 0U) ? -ETIMEDOUT : 0);
+}
+
+/*
+ * Notification from the ivc layer
+ */
+static void tegra_bpmp_ivc_notify(const struct ivc *ivc)
+{
+	(void)(ivc);
+
+	tegra_bpmp_ring_bpmp_doorbell();
+}
+
+/*
+ * Atomic send/receive API, which means it waits until slave acks
+ */
+static int32_t tegra_bpmp_ipc_send_req_atomic(uint32_t mrq, void *p_out,
+			uint32_t size_out, void *p_in, uint32_t size_in)
+{
+	struct frame_data *frame = tegra_bpmp_get_next_out_frame();
+	const struct frame_data *f_in = NULL;
+	int32_t ret = 0;
+	void *p_fdata;
+
+	if ((p_out == NULL) || (size_out > IVC_DATA_SZ_BYTES) ||
+	    (frame == NULL)) {
+		ERROR("%s: invalid parameters, exiting\n", __func__);
+		ret = -EINVAL;
+	}
+
+	if (ret == 0) {
+
+		/* prepare the command frame */
+		frame->mrq = mrq;
+		frame->flags = FLAG_DO_ACK;
+		p_fdata = frame->data;
+		(void)memcpy(p_fdata, p_out, (size_t)size_out);
+
+		/* signal the slave */
+		tegra_bpmp_signal_slave();
+
+		/* wait for slave to ack */
+		ret = tegra_bpmp_wait_for_slave_ack();
+		if (ret != 0) {
+			ERROR("failed waiting for the slave to ack\n");
+		}
+
+		/* retrieve the response frame */
+		if ((size_in <= IVC_DATA_SZ_BYTES) && (p_in != NULL) &&
+		    (ret == 0)) {
+
+			f_in = tegra_bpmp_get_cur_in_frame();
+			if (f_in != NULL) {
+				ERROR("Failed to get next input frame!\n");
+			} else {
+				(void)memcpy(p_in, p_fdata, (size_t)size_in);
+			}
+		}
+
+		if (ret == 0) {
+			ret = tegra_bpmp_free_master();
+			if (ret != 0) {
+				ERROR("Failed to free master\n");
+			}
+		}
+	}
+
+	return ret;
+}
+
+/*
+ * Initializes the BPMP<--->CCPlex communication path.
+ */
+int32_t tegra_bpmp_ipc_init(void)
+{
+	size_t msg_size;
+	uint32_t frame_size, timeout;
+	int32_t error = 0;
+
+	/* allow bpmp to ring CCPLEX's doorbell */
+	tegra_bpmp_enable_ccplex_doorbell();
+
+	/* wait for BPMP to actually ring the doorbell */
+	timeout = TIMEOUT_RESPONSE_FROM_BPMP_US;
+	while ((timeout != 0U) && !tegra_bpmp_can_ccplex_ring_doorbell()) {
+		udelay(1); /* bpmp turn-around time */
+		timeout--;
+	}
+
+	if (timeout == 0U) {
+		ERROR("%s: BPMP firmware is not ready\n", __func__);
+		return -ENOTSUP;
+	}
+
+	INFO("%s: BPMP handshake completed\n", __func__);
+
+	msg_size = tegra_ivc_align(IVC_CMD_SZ_BYTES);
+	frame_size = (uint32_t)tegra_ivc_total_queue_size(msg_size);
+	if (frame_size > TEGRA_BPMP_IPC_CH_MAP_SIZE) {
+		ERROR("%s: carveout size is not sufficient\n", __func__);
+		return -EINVAL;
+	}
+
+	error = tegra_ivc_init(&ivc_ccplex_bpmp_channel,
+				(uint32_t)TEGRA_BPMP_IPC_RX_PHYS_BASE,
+				(uint32_t)TEGRA_BPMP_IPC_TX_PHYS_BASE,
+				1U, frame_size, tegra_bpmp_ivc_notify);
+	if (error != 0) {
+
+		ERROR("%s: IVC init failed (%d)\n", __func__, error);
+
+	} else {
+
+		/* reset channel */
+		tegra_ivc_channel_reset(&ivc_ccplex_bpmp_channel);
+
+		/* wait for notification from BPMP */
+		while (tegra_ivc_channel_notified(&ivc_ccplex_bpmp_channel) != 0) {
+			/*
+			 * Interrupt BPMP with doorbell each time after
+			 * tegra_ivc_channel_notified() returns non zero
+			 * value.
+			 */
+			tegra_bpmp_ring_bpmp_doorbell();
+		}
+
+		INFO("%s: All communication channels initialized\n", __func__);
+	}
+
+	return error;
+}
+
+/* Handler to reset a hardware module */
+int32_t tegra_bpmp_ipc_reset_module(uint32_t rst_id)
+{
+	int32_t ret;
+	struct mrq_reset_request req = {
+		.cmd = (uint32_t)CMD_RESET_MODULE,
+		.reset_id = rst_id
+	};
+
+	/* only GPCDMA/XUSB_PADCTL resets are supported */
+	assert((rst_id == TEGRA_RESET_ID_XUSB_PADCTL) ||
+	       (rst_id == TEGRA_RESET_ID_GPCDMA));
+
+	ret = tegra_bpmp_ipc_send_req_atomic(MRQ_RESET, &req,
+			(uint32_t)sizeof(req), NULL, 0);
+	if (ret != 0) {
+		ERROR("%s: failed for module %d with error %d\n", __func__,
+		      rst_id, ret);
+	}
+
+	return ret;
+}
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h
new file mode 100644
index 0000000..689f8bb
--- /dev/null
+++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef INTF_H
+#define INTF_H
+
+/**
+ * Flags used in IPC req
+ */
+#define FLAG_DO_ACK			(U(1) << 0)
+#define FLAG_RING_DOORBELL		(U(1) << 1)
+
+/* Bit 1 is designated for CCPlex in secure world */
+#define HSP_MASTER_CCPLEX_BIT		(U(1) << 1)
+/* Bit 19 is designated for BPMP in non-secure world */
+#define HSP_MASTER_BPMP_BIT		(U(1) << 19)
+/* Timeout to receive response from BPMP is 1 sec */
+#define TIMEOUT_RESPONSE_FROM_BPMP_US	U(1000000) /* in microseconds */
+
+/**
+ * IVC protocol defines and command/response frame
+ */
+
+/**
+ * IVC specific defines
+ */
+#define IVC_CMD_SZ_BYTES		U(128)
+#define IVC_DATA_SZ_BYTES		U(120)
+
+/**
+ * Holds frame data for an IPC request
+ */
+struct frame_data {
+	/* Identification as to what kind of data is being transmitted */
+	uint32_t mrq;
+
+	/* Flags for slave as to how to respond back */
+	uint32_t flags;
+
+	/* Actual data being sent */
+	uint8_t data[IVC_DATA_SZ_BYTES];
+};
+
+/**
+ * Commands send to the BPMP firmware
+ */
+
+/**
+ * MRQ code to issue a module reset command to BPMP
+ */
+#define MRQ_RESET			U(20)
+
+/**
+ * Reset sub-commands
+ */
+#define CMD_RESET_ASSERT		U(1)
+#define CMD_RESET_DEASSERT		U(2)
+#define CMD_RESET_MODULE		U(3)
+
+/**
+ * Used by the sender of an #MRQ_RESET message to request BPMP to
+ * assert or deassert a given reset line.
+ */
+struct __attribute__((packed)) mrq_reset_request {
+	/* reset action to perform (mrq_reset_commands) */
+	uint32_t cmd;
+	/* id of the reset to affected */
+	uint32_t reset_id;
+};
+
+#endif /* INTF_H */
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c
new file mode 100644
index 0000000..4212eca
--- /dev/null
+++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c
@@ -0,0 +1,653 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "ivc.h"
+
+/*
+ * IVC channel reset protocol.
+ *
+ * Each end uses its tx_channel.state to indicate its synchronization state.
+ */
+enum {
+	/*
+	 * This value is zero for backwards compatibility with services that
+	 * assume channels to be initially zeroed. Such channels are in an
+	 * initially valid state, but cannot be asynchronously reset, and must
+	 * maintain a valid state at all times.
+	 *
+	 * The transmitting end can enter the established state from the sync or
+	 * ack state when it observes the receiving endpoint in the ack or
+	 * established state, indicating that has cleared the counters in our
+	 * rx_channel.
+	 */
+	ivc_state_established = U(0),
+
+	/*
+	 * If an endpoint is observed in the sync state, the remote endpoint is
+	 * allowed to clear the counters it owns asynchronously with respect to
+	 * the current endpoint. Therefore, the current endpoint is no longer
+	 * allowed to communicate.
+	 */
+	ivc_state_sync = U(1),
+
+	/*
+	 * When the transmitting end observes the receiving end in the sync
+	 * state, it can clear the w_count and r_count and transition to the ack
+	 * state. If the remote endpoint observes us in the ack state, it can
+	 * return to the established state once it has cleared its counters.
+	 */
+	ivc_state_ack = U(2)
+};
+
+/*
+ * This structure is divided into two-cache aligned parts, the first is only
+ * written through the tx_channel pointer, while the second is only written
+ * through the rx_channel pointer. This delineates ownership of the cache lines,
+ * which is critical to performance and necessary in non-cache coherent
+ * implementations.
+ */
+struct ivc_channel_header {
+	struct {
+		/* fields owned by the transmitting end */
+		uint32_t w_count;
+		uint32_t state;
+		uint32_t w_rsvd[IVC_CHHDR_TX_FIELDS - 2];
+	};
+	struct {
+		/* fields owned by the receiving end */
+		uint32_t r_count;
+		uint32_t r_rsvd[IVC_CHHDR_RX_FIELDS - 1];
+	};
+};
+
+static inline bool ivc_channel_empty(const struct ivc *ivc,
+		volatile const struct ivc_channel_header *ch)
+{
+	/*
+	 * This function performs multiple checks on the same values with
+	 * security implications, so sample the counters' current values in
+	 * shared memory to ensure that these checks use the same values.
+	 */
+	uint32_t wr_count = ch->w_count;
+	uint32_t rd_count = ch->r_count;
+	bool ret = false;
+
+	(void)ivc;
+
+	/*
+	 * Perform an over-full check to prevent denial of service attacks where
+	 * a server could be easily fooled into believing that there's an
+	 * extremely large number of frames ready, since receivers are not
+	 * expected to check for full or over-full conditions.
+	 *
+	 * Although the channel isn't empty, this is an invalid case caused by
+	 * a potentially malicious peer, so returning empty is safer, because it
+	 * gives the impression that the channel has gone silent.
+	 */
+	if (((wr_count - rd_count) > ivc->nframes) || (wr_count == rd_count)) {
+		ret = true;
+	}
+
+	return ret;
+}
+
+static inline bool ivc_channel_full(const struct ivc *ivc,
+		volatile const struct ivc_channel_header *ch)
+{
+	uint32_t wr_count = ch->w_count;
+	uint32_t rd_count = ch->r_count;
+
+	(void)ivc;
+
+	/*
+	 * Invalid cases where the counters indicate that the queue is over
+	 * capacity also appear full.
+	 */
+	return ((wr_count - rd_count) >= ivc->nframes);
+}
+
+static inline uint32_t ivc_channel_avail_count(const struct ivc *ivc,
+		volatile const struct ivc_channel_header *ch)
+{
+	uint32_t wr_count = ch->w_count;
+	uint32_t rd_count = ch->r_count;
+
+	(void)ivc;
+
+	/*
+	 * This function isn't expected to be used in scenarios where an
+	 * over-full situation can lead to denial of service attacks. See the
+	 * comment in ivc_channel_empty() for an explanation about special
+	 * over-full considerations.
+	 */
+	return (wr_count - rd_count);
+}
+
+static inline void ivc_advance_tx(struct ivc *ivc)
+{
+	ivc->tx_channel->w_count++;
+
+	if (ivc->w_pos == (ivc->nframes - (uint32_t)1U)) {
+		ivc->w_pos = 0U;
+	} else {
+		ivc->w_pos++;
+	}
+}
+
+static inline void ivc_advance_rx(struct ivc *ivc)
+{
+	ivc->rx_channel->r_count++;
+
+	if (ivc->r_pos == (ivc->nframes - (uint32_t)1U)) {
+		ivc->r_pos = 0U;
+	} else {
+		ivc->r_pos++;
+	}
+}
+
+static inline int32_t ivc_check_read(const struct ivc *ivc)
+{
+	/*
+	 * tx_channel->state is set locally, so it is not synchronized with
+	 * state from the remote peer. The remote peer cannot reset its
+	 * transmit counters until we've acknowledged its synchronization
+	 * request, so no additional synchronization is required because an
+	 * asynchronous transition of rx_channel->state to ivc_state_ack is not
+	 * allowed.
+	 */
+	if (ivc->tx_channel->state != ivc_state_established) {
+		return -ECONNRESET;
+	}
+
+	/*
+	* Avoid unnecessary invalidations when performing repeated accesses to
+	* an IVC channel by checking the old queue pointers first.
+	* Synchronization is only necessary when these pointers indicate empty
+	* or full.
+	*/
+	if (!ivc_channel_empty(ivc, ivc->rx_channel)) {
+		return 0;
+	}
+
+	return ivc_channel_empty(ivc, ivc->rx_channel) ? -ENOMEM : 0;
+}
+
+static inline int32_t ivc_check_write(const struct ivc *ivc)
+{
+	if (ivc->tx_channel->state != ivc_state_established) {
+		return -ECONNRESET;
+	}
+
+	if (!ivc_channel_full(ivc, ivc->tx_channel)) {
+		return 0;
+	}
+
+	return ivc_channel_full(ivc, ivc->tx_channel) ? -ENOMEM : 0;
+}
+
+bool tegra_ivc_can_read(const struct ivc *ivc)
+{
+	return ivc_check_read(ivc) == 0;
+}
+
+bool tegra_ivc_can_write(const struct ivc *ivc)
+{
+	return ivc_check_write(ivc) == 0;
+}
+
+bool tegra_ivc_tx_empty(const struct ivc *ivc)
+{
+	return ivc_channel_empty(ivc, ivc->tx_channel);
+}
+
+static inline uintptr_t calc_frame_offset(uint32_t frame_index,
+	uint32_t frame_size, uint32_t frame_offset)
+{
+    return ((uintptr_t)frame_index * (uintptr_t)frame_size) +
+	    (uintptr_t)frame_offset;
+}
+
+static void *ivc_frame_pointer(const struct ivc *ivc,
+				volatile const struct ivc_channel_header *ch,
+				uint32_t frame)
+{
+	assert(frame < ivc->nframes);
+	return (void *)((uintptr_t)(&ch[1]) +
+		calc_frame_offset(frame, ivc->frame_size, 0));
+}
+
+int32_t tegra_ivc_read(struct ivc *ivc, void *buf, size_t max_read)
+{
+	const void *src;
+	int32_t result;
+
+	if (buf == NULL) {
+		return -EINVAL;
+	}
+
+	if (max_read > ivc->frame_size) {
+		return -E2BIG;
+	}
+
+	result = ivc_check_read(ivc);
+	if (result != 0) {
+		return result;
+	}
+
+	/*
+	 * Order observation of w_pos potentially indicating new data before
+	 * data read.
+	 */
+	dmbish();
+
+	src = ivc_frame_pointer(ivc, ivc->rx_channel, ivc->r_pos);
+
+	(void)memcpy(buf, src, max_read);
+
+	ivc_advance_rx(ivc);
+
+	/*
+	 * Ensure our write to r_pos occurs before our read from w_pos.
+	 */
+	dmbish();
+
+	/*
+	 * Notify only upon transition from full to non-full.
+	 * The available count can only asynchronously increase, so the
+	 * worst possible side-effect will be a spurious notification.
+	 */
+	if (ivc_channel_avail_count(ivc, ivc->rx_channel) == (ivc->nframes - (uint32_t)1U)) {
+		ivc->notify(ivc);
+	}
+
+	return (int32_t)max_read;
+}
+
+/* directly peek at the next frame rx'ed */
+void *tegra_ivc_read_get_next_frame(const struct ivc *ivc)
+{
+	if (ivc_check_read(ivc) != 0) {
+		return NULL;
+	}
+
+	/*
+	 * Order observation of w_pos potentially indicating new data before
+	 * data read.
+	 */
+	dmbld();
+
+	return ivc_frame_pointer(ivc, ivc->rx_channel, ivc->r_pos);
+}
+
+int32_t tegra_ivc_read_advance(struct ivc *ivc)
+{
+	/*
+	 * No read barriers or synchronization here: the caller is expected to
+	 * have already observed the channel non-empty. This check is just to
+	 * catch programming errors.
+	 */
+	int32_t result = ivc_check_read(ivc);
+	if (result != 0) {
+		return result;
+	}
+
+	ivc_advance_rx(ivc);
+
+	/*
+	 * Ensure our write to r_pos occurs before our read from w_pos.
+	 */
+	dmbish();
+
+	/*
+	 * Notify only upon transition from full to non-full.
+	 * The available count can only asynchronously increase, so the
+	 * worst possible side-effect will be a spurious notification.
+	 */
+	if (ivc_channel_avail_count(ivc, ivc->rx_channel) == (ivc->nframes - (uint32_t)1U)) {
+		ivc->notify(ivc);
+	}
+
+	return 0;
+}
+
+int32_t tegra_ivc_write(struct ivc *ivc, const void *buf, size_t size)
+{
+	void *p;
+	int32_t result;
+
+	if ((buf == NULL) || (ivc == NULL)) {
+		return -EINVAL;
+	}
+
+	if (size > ivc->frame_size) {
+		return -E2BIG;
+	}
+
+	result = ivc_check_write(ivc);
+	if (result != 0) {
+		return result;
+	}
+
+	p = ivc_frame_pointer(ivc, ivc->tx_channel, ivc->w_pos);
+
+	(void)memset(p, 0, ivc->frame_size);
+	(void)memcpy(p, buf, size);
+
+	/*
+	 * Ensure that updated data is visible before the w_pos counter
+	 * indicates that it is ready.
+	 */
+	dmbst();
+
+	ivc_advance_tx(ivc);
+
+	/*
+	 * Ensure our write to w_pos occurs before our read from r_pos.
+	 */
+	dmbish();
+
+	/*
+	 * Notify only upon transition from empty to non-empty.
+	 * The available count can only asynchronously decrease, so the
+	 * worst possible side-effect will be a spurious notification.
+	 */
+	if (ivc_channel_avail_count(ivc, ivc->tx_channel) == 1U) {
+		ivc->notify(ivc);
+	}
+
+	return (int32_t)size;
+}
+
+/* directly poke at the next frame to be tx'ed */
+void *tegra_ivc_write_get_next_frame(const struct ivc *ivc)
+{
+	if (ivc_check_write(ivc) != 0) {
+		return NULL;
+	}
+
+	return ivc_frame_pointer(ivc, ivc->tx_channel, ivc->w_pos);
+}
+
+/* advance the tx buffer */
+int32_t tegra_ivc_write_advance(struct ivc *ivc)
+{
+	int32_t result = ivc_check_write(ivc);
+
+	if (result != 0) {
+		return result;
+	}
+
+	/*
+	 * Order any possible stores to the frame before update of w_pos.
+	 */
+	dmbst();
+
+	ivc_advance_tx(ivc);
+
+	/*
+	 * Ensure our write to w_pos occurs before our read from r_pos.
+	 */
+	dmbish();
+
+	/*
+	 * Notify only upon transition from empty to non-empty.
+	 * The available count can only asynchronously decrease, so the
+	 * worst possible side-effect will be a spurious notification.
+	 */
+	if (ivc_channel_avail_count(ivc, ivc->tx_channel) == (uint32_t)1U) {
+		ivc->notify(ivc);
+	}
+
+	return 0;
+}
+
+void tegra_ivc_channel_reset(const struct ivc *ivc)
+{
+	ivc->tx_channel->state = ivc_state_sync;
+	ivc->notify(ivc);
+}
+
+/*
+ * ===============================================================
+ *  IVC State Transition Table - see tegra_ivc_channel_notified()
+ * ===============================================================
+ *
+ *	local	remote	action
+ *	-----	------	-----------------------------------
+ *	SYNC	EST	<none>
+ *	SYNC	ACK	reset counters; move to EST; notify
+ *	SYNC	SYNC	reset counters; move to ACK; notify
+ *	ACK	EST	move to EST; notify
+ *	ACK	ACK	move to EST; notify
+ *	ACK	SYNC	reset counters; move to ACK; notify
+ *	EST	EST	<none>
+ *	EST	ACK	<none>
+ *	EST	SYNC	reset counters; move to ACK; notify
+ *
+ * ===============================================================
+ */
+int32_t tegra_ivc_channel_notified(struct ivc *ivc)
+{
+	uint32_t peer_state;
+
+	/* Copy the receiver's state out of shared memory. */
+	peer_state = ivc->rx_channel->state;
+
+	if (peer_state == (uint32_t)ivc_state_sync) {
+		/*
+		 * Order observation of ivc_state_sync before stores clearing
+		 * tx_channel.
+		 */
+		dmbld();
+
+		/*
+		 * Reset tx_channel counters. The remote end is in the SYNC
+		 * state and won't make progress until we change our state,
+		 * so the counters are not in use at this time.
+		 */
+		ivc->tx_channel->w_count = 0U;
+		ivc->rx_channel->r_count = 0U;
+
+		ivc->w_pos = 0U;
+		ivc->r_pos = 0U;
+
+		/*
+		 * Ensure that counters appear cleared before new state can be
+		 * observed.
+		 */
+		dmbst();
+
+		/*
+		 * Move to ACK state. We have just cleared our counters, so it
+		 * is now safe for the remote end to start using these values.
+		 */
+		ivc->tx_channel->state = ivc_state_ack;
+
+		/*
+		 * Notify remote end to observe state transition.
+		 */
+		ivc->notify(ivc);
+
+	} else if ((ivc->tx_channel->state == (uint32_t)ivc_state_sync) &&
+			(peer_state == (uint32_t)ivc_state_ack)) {
+		/*
+		 * Order observation of ivc_state_sync before stores clearing
+		 * tx_channel.
+		 */
+		dmbld();
+
+		/*
+		 * Reset tx_channel counters. The remote end is in the ACK
+		 * state and won't make progress until we change our state,
+		 * so the counters are not in use at this time.
+		 */
+		ivc->tx_channel->w_count = 0U;
+		ivc->rx_channel->r_count = 0U;
+
+		ivc->w_pos = 0U;
+		ivc->r_pos = 0U;
+
+		/*
+		 * Ensure that counters appear cleared before new state can be
+		 * observed.
+		 */
+		dmbst();
+
+		/*
+		 * Move to ESTABLISHED state. We know that the remote end has
+		 * already cleared its counters, so it is safe to start
+		 * writing/reading on this channel.
+		 */
+		ivc->tx_channel->state = ivc_state_established;
+
+		/*
+		 * Notify remote end to observe state transition.
+		 */
+		ivc->notify(ivc);
+
+	} else if (ivc->tx_channel->state == (uint32_t)ivc_state_ack) {
+		/*
+		 * At this point, we have observed the peer to be in either
+		 * the ACK or ESTABLISHED state. Next, order observation of
+		 * peer state before storing to tx_channel.
+		 */
+		dmbld();
+
+		/*
+		 * Move to ESTABLISHED state. We know that we have previously
+		 * cleared our counters, and we know that the remote end has
+		 * cleared its counters, so it is safe to start writing/reading
+		 * on this channel.
+		 */
+		ivc->tx_channel->state = ivc_state_established;
+
+		/*
+		 * Notify remote end to observe state transition.
+		 */
+		ivc->notify(ivc);
+
+	} else {
+		/*
+		 * There is no need to handle any further action. Either the
+		 * channel is already fully established, or we are waiting for
+		 * the remote end to catch up with our current state. Refer
+		 * to the diagram in "IVC State Transition Table" above.
+		 */
+	}
+
+	return ((ivc->tx_channel->state == (uint32_t)ivc_state_established) ? 0 : -EAGAIN);
+}
+
+size_t tegra_ivc_align(size_t size)
+{
+	return (size + (IVC_ALIGN - 1U)) & ~(IVC_ALIGN - 1U);
+}
+
+size_t tegra_ivc_total_queue_size(size_t queue_size)
+{
+	if ((queue_size & (IVC_ALIGN - 1U)) != 0U) {
+		ERROR("queue_size (%d) must be %d-byte aligned\n",
+				(int32_t)queue_size, IVC_ALIGN);
+		return 0;
+	}
+	return queue_size + sizeof(struct ivc_channel_header);
+}
+
+static int32_t check_ivc_params(uintptr_t queue_base1, uintptr_t queue_base2,
+		uint32_t nframes, uint32_t frame_size)
+{
+	assert((offsetof(struct ivc_channel_header, w_count)
+				& (IVC_ALIGN - 1U)) == 0U);
+	assert((offsetof(struct ivc_channel_header, r_count)
+				& (IVC_ALIGN - 1U)) == 0U);
+	assert((sizeof(struct ivc_channel_header) & (IVC_ALIGN - 1U)) == 0U);
+
+	if (((uint64_t)nframes * (uint64_t)frame_size) >= 0x100000000ULL) {
+		ERROR("nframes * frame_size overflows\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * The headers must at least be aligned enough for counters
+	 * to be accessed atomically.
+	 */
+	if ((queue_base1 & (IVC_ALIGN - 1U)) != 0U) {
+		ERROR("ivc channel start not aligned: %lx\n", queue_base1);
+		return -EINVAL;
+	}
+	if ((queue_base2 & (IVC_ALIGN - 1U)) != 0U) {
+		ERROR("ivc channel start not aligned: %lx\n", queue_base2);
+		return -EINVAL;
+	}
+
+	if ((frame_size & (IVC_ALIGN - 1U)) != 0U) {
+		ERROR("frame size not adequately aligned: %u\n",
+				frame_size);
+		return -EINVAL;
+	}
+
+	if (queue_base1 < queue_base2) {
+		if ((queue_base1 + ((uint64_t)frame_size * nframes)) > queue_base2) {
+			ERROR("queue regions overlap: %lx + %x, %x\n",
+					queue_base1, frame_size,
+					frame_size * nframes);
+			return -EINVAL;
+		}
+	} else {
+		if ((queue_base2 + ((uint64_t)frame_size * nframes)) > queue_base1) {
+			ERROR("queue regions overlap: %lx + %x, %x\n",
+					queue_base2, frame_size,
+					frame_size * nframes);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+int32_t tegra_ivc_init(struct ivc *ivc, uintptr_t rx_base, uintptr_t tx_base,
+		uint32_t nframes, uint32_t frame_size,
+		ivc_notify_function notify)
+{
+	int32_t result;
+
+	/* sanity check input params */
+	if ((ivc == NULL) || (notify == NULL)) {
+		return -EINVAL;
+	}
+
+	result = check_ivc_params(rx_base, tx_base, nframes, frame_size);
+	if (result != 0) {
+		return result;
+	}
+
+	/*
+	 * All sizes that can be returned by communication functions should
+	 * fit in a 32-bit integer.
+	 */
+	if (frame_size > (1u << 31)) {
+		return -E2BIG;
+	}
+
+	ivc->rx_channel = (struct ivc_channel_header *)rx_base;
+	ivc->tx_channel = (struct ivc_channel_header *)tx_base;
+	ivc->notify = notify;
+	ivc->frame_size = frame_size;
+	ivc->nframes = nframes;
+	ivc->w_pos = 0U;
+	ivc->r_pos = 0U;
+
+	INFO("%s: done\n", __func__);
+
+	return 0;
+}
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h
new file mode 100644
index 0000000..f34d6cf
--- /dev/null
+++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IVC_H
+#define IVC_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <utils_def.h>
+
+#define IVC_ALIGN		U(64)
+#define IVC_CHHDR_TX_FIELDS	U(16)
+#define IVC_CHHDR_RX_FIELDS	U(16)
+
+struct ivc;
+struct ivc_channel_header;
+
+/* callback handler for notify on receiving a response */
+typedef void (* ivc_notify_function)(const struct ivc *);
+
+struct ivc {
+	struct ivc_channel_header *rx_channel;
+	struct ivc_channel_header *tx_channel;
+	uint32_t w_pos;
+	uint32_t r_pos;
+	ivc_notify_function notify;
+	uint32_t nframes;
+	uint32_t frame_size;
+};
+
+int32_t tegra_ivc_init(struct ivc *ivc, uintptr_t rx_base, uintptr_t tx_base,
+		uint32_t nframes, uint32_t frame_size,
+		ivc_notify_function notify);
+size_t tegra_ivc_total_queue_size(size_t queue_size);
+size_t tegra_ivc_align(size_t size);
+int32_t tegra_ivc_channel_notified(struct ivc *ivc);
+void tegra_ivc_channel_reset(const struct ivc *ivc);
+int32_t tegra_ivc_write_advance(struct ivc *ivc);
+void *tegra_ivc_write_get_next_frame(const struct ivc *ivc);
+int32_t tegra_ivc_write(struct ivc *ivc, const void *buf, size_t size);
+int32_t tegra_ivc_read_advance(struct ivc *ivc);
+void *tegra_ivc_read_get_next_frame(const struct ivc *ivc);
+int32_t tegra_ivc_read(struct ivc *ivc, void *buf, size_t max_read);
+bool tegra_ivc_tx_empty(const struct ivc *ivc);
+bool tegra_ivc_can_write(const struct ivc *ivc);
+bool tegra_ivc_can_read(const struct ivc *ivc);
+
+#endif /* IVC_H */
diff --git a/plat/nvidia/tegra/common/drivers/gpcdma/gpcdma.c b/plat/nvidia/tegra/common/drivers/gpcdma/gpcdma.c
new file mode 100644
index 0000000..64e84ac
--- /dev/null
+++ b/plat/nvidia/tegra/common/drivers/gpcdma/gpcdma.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <delay_timer.h>
+#include <errno.h>
+#include <gpcdma.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <stdbool.h>
+#include <tegra_def.h>
+#include <utils_def.h>
+
+/* DMA channel registers */
+#define DMA_CH_CSR				U(0x0)
+#define DMA_CH_CSR_WEIGHT_SHIFT			U(10)
+#define DMA_CH_CSR_XFER_MODE_SHIFT		U(21)
+#define DMA_CH_CSR_DMA_MODE_MEM2MEM		U(4)
+#define DMA_CH_CSR_DMA_MODE_FIXEDPATTERN	U(6)
+#define DMA_CH_CSR_IRQ_MASK_ENABLE		(U(1) << 15)
+#define DMA_CH_CSR_RUN_ONCE			(U(1) << 27)
+#define DMA_CH_CSR_ENABLE			(U(1) << 31)
+
+#define DMA_CH_STAT				U(0x4)
+#define DMA_CH_STAT_BUSY			(U(1) << 31)
+
+#define DMA_CH_SRC_PTR				U(0xC)
+
+#define DMA_CH_DST_PTR				U(0x10)
+
+#define DMA_CH_HI_ADR_PTR			U(0x14)
+#define DMA_CH_HI_ADR_PTR_SRC_MASK		U(0xFF)
+#define DMA_CH_HI_ADR_PTR_DST_SHIFT		U(16)
+#define DMA_CH_HI_ADR_PTR_DST_MASK		U(0xFF)
+
+#define DMA_CH_MC_SEQ				U(0x18)
+#define DMA_CH_MC_SEQ_REQ_CNT_SHIFT		U(25)
+#define DMA_CH_MC_SEQ_REQ_CNT_VAL		U(0x10)
+#define DMA_CH_MC_SEQ_BURST_SHIFT		U(23)
+#define DMA_CH_MC_SEQ_BURST_16_WORDS		U(0x3)
+
+#define DMA_CH_WORD_COUNT			U(0x20)
+#define DMA_CH_FIXED_PATTERN			U(0x34)
+#define DMA_CH_TZ				U(0x38)
+#define DMA_CH_TZ_ACCESS_ENABLE			U(0)
+#define DMA_CH_TZ_ACCESS_DISABLE		U(3)
+
+#define MAX_TRANSFER_SIZE			(1U*1024U*1024U*1024U)	/* 1GB */
+#define GPCDMA_TIMEOUT_MS			U(100)
+#define GPCDMA_RESET_BIT			(U(1) << 1)
+
+static bool init_done;
+
+static void tegra_gpcdma_write32(uint32_t offset, uint32_t val)
+{
+	mmio_write_32(TEGRA_GPCDMA_BASE + offset, val);
+}
+
+static uint32_t tegra_gpcdma_read32(uint32_t offset)
+{
+	return mmio_read_32(TEGRA_GPCDMA_BASE + offset);
+}
+
+static void tegra_gpcdma_init(void)
+{
+	/* assert reset for DMA engine */
+	mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_GPCDMA_RST_SET_REG_OFFSET,
+		      GPCDMA_RESET_BIT);
+
+	udelay(2);
+
+	/* de-assert reset for DMA engine */
+	mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_GPCDMA_RST_CLR_REG_OFFSET,
+		      GPCDMA_RESET_BIT);
+}
+
+static void tegra_gpcdma_memcpy_priv(uint64_t dst_addr, uint64_t src_addr,
+				     uint32_t num_bytes, uint32_t mode)
+{
+	uint32_t val, timeout = 0;
+	int32_t ret = 0;
+
+	/* sanity check byte count */
+	if ((num_bytes > MAX_TRANSFER_SIZE) || ((num_bytes & 0x3U) != U(0))) {
+		ret = -EINVAL;
+	}
+
+	/* initialise GPCDMA block */
+	if (!init_done) {
+		tegra_gpcdma_init();
+		init_done = true;
+	}
+
+	/* make sure channel isn't busy */
+	val = tegra_gpcdma_read32(DMA_CH_STAT);
+	if ((val & DMA_CH_STAT_BUSY) == DMA_CH_STAT_BUSY) {
+		ERROR("DMA channel is busy\n");
+		ret = -EBUSY;
+	}
+
+	if (ret == 0) {
+
+		/* disable any DMA transfers */
+		tegra_gpcdma_write32(DMA_CH_CSR, 0);
+
+		/* enable DMA access to TZDRAM */
+		tegra_gpcdma_write32(DMA_CH_TZ, DMA_CH_TZ_ACCESS_ENABLE);
+
+		/* configure MC sequencer */
+		val = (DMA_CH_MC_SEQ_REQ_CNT_VAL << DMA_CH_MC_SEQ_REQ_CNT_SHIFT) |
+		      (DMA_CH_MC_SEQ_BURST_16_WORDS << DMA_CH_MC_SEQ_BURST_SHIFT);
+		tegra_gpcdma_write32(DMA_CH_MC_SEQ, val);
+
+		/* reset fixed pattern */
+		tegra_gpcdma_write32(DMA_CH_FIXED_PATTERN, 0);
+
+		/* populate src and dst address registers */
+		tegra_gpcdma_write32(DMA_CH_SRC_PTR, (uint32_t)src_addr);
+		tegra_gpcdma_write32(DMA_CH_DST_PTR, (uint32_t)dst_addr);
+
+		val = (uint32_t)((src_addr >> 32) & DMA_CH_HI_ADR_PTR_SRC_MASK);
+		val |= (uint32_t)(((dst_addr >> 32) & DMA_CH_HI_ADR_PTR_DST_MASK) <<
+			DMA_CH_HI_ADR_PTR_DST_SHIFT);
+		tegra_gpcdma_write32(DMA_CH_HI_ADR_PTR, val);
+
+		/* transfer size (in words) */
+		tegra_gpcdma_write32(DMA_CH_WORD_COUNT, ((num_bytes >> 2) - 1U));
+
+		/* populate value for CSR */
+		val = (mode << DMA_CH_CSR_XFER_MODE_SHIFT) |
+		      DMA_CH_CSR_RUN_ONCE | (U(1) << DMA_CH_CSR_WEIGHT_SHIFT) |
+		      DMA_CH_CSR_IRQ_MASK_ENABLE;
+		tegra_gpcdma_write32(DMA_CH_CSR, val);
+
+		/* enable transfer */
+		val = tegra_gpcdma_read32(DMA_CH_CSR);
+		val |= DMA_CH_CSR_ENABLE;
+		tegra_gpcdma_write32(DMA_CH_CSR, val);
+
+		/* wait till transfer completes */
+		do {
+
+			/* read the status */
+			val = tegra_gpcdma_read32(DMA_CH_STAT);
+			if ((val & DMA_CH_STAT_BUSY) != DMA_CH_STAT_BUSY) {
+				break;
+			}
+
+			mdelay(1);
+			timeout++;
+
+		} while (timeout < GPCDMA_TIMEOUT_MS);
+
+		/* flag timeout error */
+		if (timeout == GPCDMA_TIMEOUT_MS) {
+			ERROR("DMA transfer timed out\n");
+		}
+
+		dsbsy();
+
+		/* disable DMA access to TZDRAM */
+		tegra_gpcdma_write32(DMA_CH_TZ, DMA_CH_TZ_ACCESS_DISABLE);
+		isb();
+	}
+}
+
+/*******************************************************************************
+ * Memcpy using GPCDMA block (Mem2Mem copy)
+ ******************************************************************************/
+void tegra_gpcdma_memcpy(uint64_t dst_addr, uint64_t src_addr,
+			 uint32_t num_bytes)
+{
+	tegra_gpcdma_memcpy_priv(dst_addr, src_addr, num_bytes,
+				 DMA_CH_CSR_DMA_MODE_MEM2MEM);
+}
+
+/*******************************************************************************
+ * Memset using GPCDMA block (Fixed pattern write)
+ ******************************************************************************/
+void tegra_gpcdma_zeromem(uint64_t dst_addr, uint32_t num_bytes)
+{
+	tegra_gpcdma_memcpy_priv(dst_addr, 0, num_bytes,
+				 DMA_CH_CSR_DMA_MODE_FIXEDPATTERN);
+}
diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c
index 58f49d0..92fa273 100644
--- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c
+++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v1.c
@@ -109,13 +109,16 @@
 static void tegra_clear_videomem(uintptr_t non_overlap_area_start,
 				 unsigned long long non_overlap_area_size)
 {
+	int ret;
+
 	/*
 	 * Map the NS memory first, clean it and then unmap it.
 	 */
-	mmap_add_dynamic_region(non_overlap_area_start, /* PA */
+	ret = mmap_add_dynamic_region(non_overlap_area_start, /* PA */
 				non_overlap_area_start, /* VA */
 				non_overlap_area_size, /* size */
 				MT_NS | MT_RW | MT_EXECUTE_NEVER); /* attrs */
+	assert(ret == 0);
 
 	zeromem((void *)non_overlap_area_start, non_overlap_area_size);
 	flush_dcache_range(non_overlap_area_start, non_overlap_area_size);
@@ -206,3 +209,16 @@
 	/* lock the aperture registers */
 	tegra_mc_write_32(MC_IRAM_REG_CTRL, MC_DISABLE_IRAM_CFG_WRITES);
 }
+
+void tegra_memctrl_clear_pending_interrupts(void)
+{
+	uint32_t mcerr;
+
+	/* check if there are any pending interrupts */
+	mcerr = mmio_read_32(TEGRA_MC_BASE + MC_INTSTATUS);
+
+	if (mcerr != (uint32_t)0U) { /* should not see error here */
+		WARN("MC_INTSTATUS = 0x%x (should be zero)\n", mcerr);
+		mmio_write_32((TEGRA_MC_BASE + MC_INTSTATUS),  mcerr);
+	}
+}
diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
index 55b9152..a3ef5e1 100644
--- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
+++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
@@ -25,293 +25,15 @@
 static uint64_t video_mem_base;
 static uint64_t video_mem_size_mb;
 
-static void tegra_memctrl_reconfig_mss_clients(void)
-{
-#if ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS
-	uint32_t val, wdata_0, wdata_1;
-
-	/*
-	 * Assert Memory Controller's HOTRESET_FLUSH_ENABLE signal for
-	 * boot and strongly ordered MSS clients to flush existing memory
-	 * traffic and stall future requests.
-	 */
-	val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL0);
-	assert(val == MC_CLIENT_HOTRESET_CTRL0_RESET_VAL);
-
-	wdata_0 = MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB |
-#if ENABLE_AFI_DEVICE
-		  MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB |
-#endif
-		  MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB |
-		  MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB |
-		  MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB;
-	tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0);
-
-	/* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
-	do {
-		val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0);
-	} while ((val & wdata_0) != wdata_0);
-
-	/* Wait one more time due to SW WAR for known legacy issue */
-	do {
-		val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0);
-	} while ((val & wdata_0) != wdata_0);
-
-	val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL1);
-	assert(val == MC_CLIENT_HOTRESET_CTRL1_RESET_VAL);
-
-	wdata_1 = MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB |
-		  MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB |
-		  MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB |
-		  MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB |
-		  MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB |
-		  MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB |
-		  MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB |
-		  MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB |
-		  MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB |
-		  MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB;
-	tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1);
-
-	/* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
-	do {
-		val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1);
-	} while ((val & wdata_1) != wdata_1);
-
-	/* Wait one more time due to SW WAR for known legacy issue */
-	do {
-		val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1);
-	} while ((val & wdata_1) != wdata_1);
-
-	/*
-	 * Change MEMTYPE_OVERRIDE from SO_DEV -> PASSTHRU for boot and
-	 * strongly ordered MSS clients. ROC needs to be single point
-	 * of control on overriding the memory type. So, remove TSA's
-	 * memtype override.
-	 */
-#if ENABLE_AFI_DEVICE
-	mc_set_tsa_passthrough(AFIW);
-#endif
-	mc_set_tsa_passthrough(HDAW);
-	mc_set_tsa_passthrough(SATAW);
-	mc_set_tsa_passthrough(XUSB_HOSTW);
-	mc_set_tsa_passthrough(XUSB_DEVW);
-	mc_set_tsa_passthrough(SDMMCWAB);
-	mc_set_tsa_passthrough(APEDMAW);
-	mc_set_tsa_passthrough(SESWR);
-	mc_set_tsa_passthrough(ETRW);
-	mc_set_tsa_passthrough(AXISW);
-	mc_set_tsa_passthrough(EQOSW);
-	mc_set_tsa_passthrough(UFSHCW);
-	mc_set_tsa_passthrough(BPMPDMAW);
-	mc_set_tsa_passthrough(AONDMAW);
-	mc_set_tsa_passthrough(SCEDMAW);
-
-	/*
-	 * Change COH_PATH_OVERRIDE_SO_DEV from NO_OVERRIDE -> FORCE_COHERENT
-	 * for boot and strongly ordered MSS clients. This steers all sodev
-	 * transactions to ROC.
-	 *
-	 * Change AXID_OVERRIDE/AXID_OVERRIDE_SO_DEV only for some clients
-	 * whose AXI IDs we know and trust.
-	 */
-
-#if ENABLE_AFI_DEVICE
-	/* Match AFIW */
-	mc_set_forced_coherent_so_dev_cfg(AFIR);
-#endif
-
-	/*
-	 * See bug 200131110 comment #35 - there are no normal requests
-	 * and AWID for SO/DEV requests is hardcoded in RTL for a
-	 * particular PCIE controller
-	 */
-#if ENABLE_AFI_DEVICE
-	mc_set_forced_coherent_so_dev_cfg(AFIW);
-#endif
-	mc_set_forced_coherent_cfg(HDAR);
-	mc_set_forced_coherent_cfg(HDAW);
-	mc_set_forced_coherent_cfg(SATAR);
-	mc_set_forced_coherent_cfg(SATAW);
-	mc_set_forced_coherent_cfg(XUSB_HOSTR);
-	mc_set_forced_coherent_cfg(XUSB_HOSTW);
-	mc_set_forced_coherent_cfg(XUSB_DEVR);
-	mc_set_forced_coherent_cfg(XUSB_DEVW);
-	mc_set_forced_coherent_cfg(SDMMCRAB);
-	mc_set_forced_coherent_cfg(SDMMCWAB);
-
-	/* Match APEDMAW */
-	mc_set_forced_coherent_axid_so_dev_cfg(APEDMAR);
-
-	/*
-	 * See bug 200131110 comment #35 - AWID for normal requests
-	 * is 0x80 and AWID for SO/DEV requests is 0x01
-	 */
-	mc_set_forced_coherent_axid_so_dev_cfg(APEDMAW);
-	mc_set_forced_coherent_cfg(SESRD);
-	mc_set_forced_coherent_cfg(SESWR);
-	mc_set_forced_coherent_cfg(ETRR);
-	mc_set_forced_coherent_cfg(ETRW);
-	mc_set_forced_coherent_cfg(AXISR);
-	mc_set_forced_coherent_cfg(AXISW);
-	mc_set_forced_coherent_cfg(EQOSR);
-	mc_set_forced_coherent_cfg(EQOSW);
-	mc_set_forced_coherent_cfg(UFSHCR);
-	mc_set_forced_coherent_cfg(UFSHCW);
-	mc_set_forced_coherent_cfg(BPMPDMAR);
-	mc_set_forced_coherent_cfg(BPMPDMAW);
-	mc_set_forced_coherent_cfg(AONDMAR);
-	mc_set_forced_coherent_cfg(AONDMAW);
-	mc_set_forced_coherent_cfg(SCEDMAR);
-	mc_set_forced_coherent_cfg(SCEDMAW);
-
-	/*
-	 * At this point, ordering can occur at ROC. So, remove PCFIFO's
-	 * control over ordering requests.
-	 *
-	 * Change PCFIFO_*_ORDERED_CLIENT from ORDERED -> UNORDERED for
-	 * boot and strongly ordered MSS clients
-	 */
-	val = MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL &
-#if ENABLE_AFI_DEVICE
-		mc_set_pcfifo_unordered_boot_so_mss(1, AFIW) &
-#endif
-		mc_set_pcfifo_unordered_boot_so_mss(1, HDAW) &
-		mc_set_pcfifo_unordered_boot_so_mss(1, SATAW);
-	tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG1, val);
-
-	val = MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL &
-		mc_set_pcfifo_unordered_boot_so_mss(2, XUSB_HOSTW) &
-		mc_set_pcfifo_unordered_boot_so_mss(2, XUSB_DEVW);
-	tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG2, val);
-
-	val = MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL &
-		mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCWAB);
-	tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG3, val);
-
-	val = MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL &
-		mc_set_pcfifo_unordered_boot_so_mss(4, SESWR) &
-		mc_set_pcfifo_unordered_boot_so_mss(4, ETRW) &
-		mc_set_pcfifo_unordered_boot_so_mss(4, AXISW) &
-		mc_set_pcfifo_unordered_boot_so_mss(4, EQOSW) &
-		mc_set_pcfifo_unordered_boot_so_mss(4, UFSHCW) &
-		mc_set_pcfifo_unordered_boot_so_mss(4, BPMPDMAW) &
-		mc_set_pcfifo_unordered_boot_so_mss(4, AONDMAW) &
-		mc_set_pcfifo_unordered_boot_so_mss(4, SCEDMAW);
-	tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG4, val);
-
-	val = MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL &
-		mc_set_pcfifo_unordered_boot_so_mss(5, APEDMAW);
-	tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG5, val);
-
-	/*
-	 * At this point, ordering can occur at ROC. SMMU need not
-	 * reorder any requests.
-	 *
-	 * Change SMMU_*_ORDERED_CLIENT from ORDERED -> UNORDERED
-	 * for boot and strongly ordered MSS clients
-	 */
-	val = MC_SMMU_CLIENT_CONFIG1_RESET_VAL &
-#if ENABLE_AFI_DEVICE
-		mc_set_smmu_unordered_boot_so_mss(1, AFIW) &
-#endif
-		mc_set_smmu_unordered_boot_so_mss(1, HDAW) &
-		mc_set_smmu_unordered_boot_so_mss(1, SATAW);
-	tegra_mc_write_32(MC_SMMU_CLIENT_CONFIG1, val);
-
-	val = MC_SMMU_CLIENT_CONFIG2_RESET_VAL &
-		mc_set_smmu_unordered_boot_so_mss(2, XUSB_HOSTW) &
-		mc_set_smmu_unordered_boot_so_mss(2, XUSB_DEVW);
-	tegra_mc_write_32(MC_SMMU_CLIENT_CONFIG2, val);
-
-	val = MC_SMMU_CLIENT_CONFIG3_RESET_VAL &
-		mc_set_smmu_unordered_boot_so_mss(3, SDMMCWAB);
-	tegra_mc_write_32(MC_SMMU_CLIENT_CONFIG3, val);
-
-	val = MC_SMMU_CLIENT_CONFIG4_RESET_VAL &
-		mc_set_smmu_unordered_boot_so_mss(4, SESWR) &
-		mc_set_smmu_unordered_boot_so_mss(4, ETRW) &
-		mc_set_smmu_unordered_boot_so_mss(4, AXISW) &
-		mc_set_smmu_unordered_boot_so_mss(4, EQOSW) &
-		mc_set_smmu_unordered_boot_so_mss(4, UFSHCW) &
-		mc_set_smmu_unordered_boot_so_mss(4, BPMPDMAW) &
-		mc_set_smmu_unordered_boot_so_mss(4, AONDMAW) &
-		mc_set_smmu_unordered_boot_so_mss(4, SCEDMAW);
-	tegra_mc_write_32(MC_SMMU_CLIENT_CONFIG4, val);
-
-	val = MC_SMMU_CLIENT_CONFIG5_RESET_VAL &
-		mc_set_smmu_unordered_boot_so_mss(5, APEDMAW);
-	tegra_mc_write_32(MC_SMMU_CLIENT_CONFIG5, val);
-
-	/*
-	 * Deassert HOTRESET FLUSH_ENABLE for boot and strongly ordered MSS
-	 * clients to allow memory traffic from all clients to start passing
-	 * through ROC
-	 */
-	val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL0);
-	assert(val == wdata_0);
-
-	wdata_0 = MC_CLIENT_HOTRESET_CTRL0_RESET_VAL;
-	tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0);
-
-	val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL1);
-	assert(val == wdata_1);
-
-	wdata_1 = MC_CLIENT_HOTRESET_CTRL1_RESET_VAL;
-	tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1);
-
-#endif
-}
+/*
+ * The following platform setup functions are weakly defined. They
+ * provide typical implementations that will be overridden by a SoC.
+ */
+#pragma weak plat_memctrl_tzdram_setup
 
-static void tegra_memctrl_set_overrides(void)
+void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes)
 {
-	tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings();
-	const mc_txn_override_cfg_t *mc_txn_override_cfgs;
-	uint32_t num_txn_override_cfgs;
-	uint32_t i, val;
-
-	/* Get the settings from the platform */
-	assert(plat_mc_settings);
-	mc_txn_override_cfgs = plat_mc_settings->txn_override_cfg;
-	num_txn_override_cfgs = plat_mc_settings->num_txn_override_cfgs;
-
-	/*
-	 * Set the MC_TXN_OVERRIDE registers for write clients.
-	 */
-	if ((tegra_chipid_is_t186()) &&
-	    (!tegra_platform_is_silicon() ||
-	    (tegra_platform_is_silicon() && (tegra_get_chipid_minor() == 1)))) {
-
-		/*
-		 * GPU and NVENC settings for Tegra186 simulation and
-		 * Silicon rev. A01
-		 */
-		val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR);
-		val &= ~MC_TXN_OVERRIDE_CGID_TAG_MASK;
-		tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR,
-			val | MC_TXN_OVERRIDE_CGID_TAG_ZERO);
-
-		val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR2);
-		val &= ~MC_TXN_OVERRIDE_CGID_TAG_MASK;
-		tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR2,
-			val | MC_TXN_OVERRIDE_CGID_TAG_ZERO);
-
-		val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_NVENCSWR);
-		val &= ~MC_TXN_OVERRIDE_CGID_TAG_MASK;
-		tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_NVENCSWR,
-			val | MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID);
-
-	} else {
-
-		/*
-		 * Settings for Tegra186 silicon rev. A02 and onwards.
-		 */
-		for (i = 0; i < num_txn_override_cfgs; i++) {
-			val = tegra_mc_read_32(mc_txn_override_cfgs[i].offset);
-			val &= ~MC_TXN_OVERRIDE_CGID_TAG_MASK;
-			tegra_mc_write_32(mc_txn_override_cfgs[i].offset,
-				val | mc_txn_override_cfgs[i].cgid_tag);
-		}
-	}
+	; /* do nothing */
 }
 
 /*
@@ -324,17 +46,16 @@
 	uint32_t num_streamid_override_regs;
 	const mc_streamid_security_cfg_t *mc_streamid_sec_cfgs;
 	uint32_t num_streamid_sec_cfgs;
-	tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings();
+	const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings();
 	uint32_t i;
 
 	INFO("Tegra Memory Controller (v2)\n");
 
-#if ENABLE_SMMU_DEVICE
 	/* Program the SMMU pagesize */
 	tegra_smmu_init();
-#endif
+
 	/* Get the settings from the platform */
-	assert(plat_mc_settings);
+	assert(plat_mc_settings != NULL);
 	mc_streamid_override_regs = plat_mc_settings->streamid_override_cfg;
 	num_streamid_override_regs = plat_mc_settings->num_streamid_override_cfgs;
 	mc_streamid_sec_cfgs = plat_mc_settings->streamid_security_cfg;
@@ -375,10 +96,14 @@
 	 * boots with MSS having all control, but ROC provides a performance
 	 * boost as compared to MSS.
 	 */
-	tegra_memctrl_reconfig_mss_clients();
+	if (plat_mc_settings->reconfig_mss_clients != NULL) {
+		plat_mc_settings->reconfig_mss_clients();
+	}
 
 	/* Program overrides for MC transactions */
-	tegra_memctrl_set_overrides();
+	if (plat_mc_settings->set_txn_overrides != NULL) {
+		plat_mc_settings->set_txn_overrides();
+	}
 }
 
 /*
@@ -386,19 +111,27 @@
  */
 void tegra_memctrl_restore_settings(void)
 {
+	const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings();
+
+	assert(plat_mc_settings != NULL);
+
 	/*
 	 * Re-configure MSS to allow ROC to deal with ordering of the
 	 * Memory Controller traffic. This is needed as the Memory Controller
 	 * resets during System Suspend with MSS having all control, but ROC
 	 * provides a performance boost as compared to MSS.
 	 */
-	tegra_memctrl_reconfig_mss_clients();
+	if (plat_mc_settings->reconfig_mss_clients != NULL) {
+		plat_mc_settings->reconfig_mss_clients();
+	}
 
 	/* Program overrides for MC transactions */
-	tegra_memctrl_set_overrides();
+	if (plat_mc_settings->set_txn_overrides != NULL) {
+		plat_mc_settings->set_txn_overrides();
+	}
 
 	/* video memory carveout region */
-	if (video_mem_base) {
+	if (video_mem_base != 0ULL) {
 		tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO,
 				  (uint32_t)video_mem_base);
 		tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI,
@@ -422,34 +155,9 @@
 void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes)
 {
 	/*
-	 * Setup the Memory controller to allow only secure accesses to
-	 * the TZDRAM carveout
-	 */
-	INFO("Configuring TrustZone DRAM Memory Carveout\n");
-
-	tegra_mc_write_32(MC_SECURITY_CFG0_0, (uint32_t)phys_base);
-	tegra_mc_write_32(MC_SECURITY_CFG3_0, (uint32_t)(phys_base >> 32));
-	tegra_mc_write_32(MC_SECURITY_CFG1_0, size_in_bytes >> 20);
-
-	/*
-	 * When TZ encryption enabled,
-	 * We need setup TZDRAM before CPU to access TZ Carveout,
-	 * otherwise CPU will fetch non-decrypted data.
-	 * So save TZDRAM setting for retore by SC7 resume FW.
+	 * Perform platform specific steps.
 	 */
-
-	mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV55_LO,
-					tegra_mc_read_32(MC_SECURITY_CFG0_0));
-	mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV55_HI,
-					tegra_mc_read_32(MC_SECURITY_CFG3_0));
-	mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV54_HI,
-					tegra_mc_read_32(MC_SECURITY_CFG1_0));
-
-	/*
-	 * MCE propagates the security configuration values across the
-	 * CCPLEX.
-	 */
-	mce_update_gsc_tzdram();
+	plat_memctrl_tzdram_setup(phys_base, size_in_bytes);
 }
 
 /*
@@ -471,13 +179,22 @@
 	 * Reset the access configuration registers to restrict access
 	 * to the TZRAM aperture
 	 */
-	for (index = MC_TZRAM_CLIENT_ACCESS_CFG0;
+	for (index = MC_TZRAM_CLIENT_ACCESS0_CFG0;
 	     index < ((uint32_t)MC_TZRAM_CARVEOUT_CFG + (uint32_t)MC_GSC_CONFIG_REGS_SIZE);
 	     index += 4U) {
 		tegra_mc_write_32(index, 0);
 	}
 
 	/*
+	 * Enable CPU access configuration registers to access the TZRAM aperture
+	 */
+	if (!tegra_chipid_is_t186()) {
+		val = tegra_mc_read_32(MC_TZRAM_CLIENT_ACCESS1_CFG0);
+		val |= TZRAM_ALLOW_MPCORER | TZRAM_ALLOW_MPCOREW;
+		tegra_mc_write_32(MC_TZRAM_CLIENT_ACCESS1_CFG0, val);
+	}
+
+	/*
 	 * Set the TZRAM base. TZRAM base must be 4k aligned, at least.
 	 */
 	assert((phys_base & (uint64_t)0xFFF) == 0U);
@@ -502,8 +219,11 @@
 	 * at all.
 	 */
 	val = tegra_mc_read_32(MC_TZRAM_CARVEOUT_CFG);
-	val &= ~MC_GSC_ENABLE_TZ_LOCK_BIT;
+	val &= (uint32_t)~MC_GSC_ENABLE_TZ_LOCK_BIT;
 	val |= MC_GSC_LOCK_CFG_SETTINGS_BIT;
+	if (!tegra_chipid_is_t186()) {
+		val |= MC_GSC_ENABLE_CPU_SECURE_BIT;
+	}
 	tegra_mc_write_32(MC_TZRAM_CARVEOUT_CFG, val);
 
 	/*
@@ -577,18 +297,21 @@
 static void tegra_clear_videomem(uintptr_t non_overlap_area_start,
 				 unsigned long long non_overlap_area_size)
 {
+	int ret;
+
 	/*
 	 * Map the NS memory first, clean it and then unmap it.
 	 */
-	mmap_add_dynamic_region(non_overlap_area_start, /* PA */
+	ret = mmap_add_dynamic_region(non_overlap_area_start, /* PA */
 				non_overlap_area_start, /* VA */
 				non_overlap_area_size, /* size */
 				MT_NS | MT_RW | MT_EXECUTE_NEVER); /* attrs */
+	assert(ret == 0);
 
 	zero_normalmem((void *)non_overlap_area_start, non_overlap_area_size);
 	flush_dcache_range(non_overlap_area_start, non_overlap_area_size);
 
-	mmap_remove_dynamic_region(non_overlap_area_start,
+	(void)mmap_remove_dynamic_region(non_overlap_area_start,
 		non_overlap_area_size);
 }
 
@@ -635,17 +358,19 @@
 	 */
 	INFO("Cleaning previous Video Memory Carveout\n");
 
-	if (phys_base > vmem_end_old || video_mem_base > vmem_end_new) {
+	if ((phys_base > vmem_end_old) || (video_mem_base > vmem_end_new)) {
 		tegra_clear_videomem(video_mem_base,
-				     (uint64_t)video_mem_size_mb << 20);
+				     (uint32_t)video_mem_size_mb << 20U);
 	} else {
 		if (video_mem_base < phys_base) {
 			non_overlap_area_size = phys_base - video_mem_base;
-			tegra_clear_videomem(video_mem_base, non_overlap_area_size);
+			tegra_clear_videomem(video_mem_base,
+					(uint32_t)non_overlap_area_size);
 		}
 		if (vmem_end_old > vmem_end_new) {
 			non_overlap_area_size = vmem_end_old - vmem_end_new;
-			tegra_clear_videomem(vmem_end_new, non_overlap_area_size);
+			tegra_clear_videomem(vmem_end_new,
+					(uint32_t)non_overlap_area_size);
 		}
 	}
 
@@ -677,3 +402,8 @@
 {
 	; /* do nothing */
 }
+
+void tegra_memctrl_clear_pending_interrupts(void)
+{
+	; /* do nothing */
+}
diff --git a/plat/nvidia/tegra/common/drivers/smmu/smmu.c b/plat/nvidia/tegra/common/drivers/smmu/smmu.c
index 610f32f..8c1b899 100644
--- a/plat/nvidia/tegra/common/drivers/smmu/smmu.c
+++ b/plat/nvidia/tegra/common/drivers/smmu/smmu.c
@@ -19,47 +19,55 @@
 
 /* SMMU IDs currently supported by the driver */
 enum {
-	TEGRA_SMMU0,
+	TEGRA_SMMU0 = 0U,
 	TEGRA_SMMU1,
 	TEGRA_SMMU2
 };
 
 static uint32_t tegra_smmu_read_32(uint32_t smmu_id, uint32_t off)
 {
+	uint32_t ret = 0U;
+
 #if defined(TEGRA_SMMU0_BASE)
-	if (smmu_id == TEGRA_SMMU0)
-		return mmio_read_32(TEGRA_SMMU0_BASE + off);
+	if (smmu_id == TEGRA_SMMU0) {
+		ret = mmio_read_32(TEGRA_SMMU0_BASE + (uint64_t)off);
+	}
 #endif
 
 #if defined(TEGRA_SMMU1_BASE)
-	if (smmu_id == TEGRA_SMMU1)
-		return mmio_read_32(TEGRA_SMMU1_BASE + off);
+	if (smmu_id == TEGRA_SMMU1) {
+		ret = mmio_read_32(TEGRA_SMMU1_BASE + (uint64_t)off);
+	}
 #endif
 
 #if defined(TEGRA_SMMU2_BASE)
-	if (smmu_id == TEGRA_SMMU2)
-		return mmio_read_32(TEGRA_SMMU2_BASE + off);
+	if (smmu_id == TEGRA_SMMU2) {
+		ret = mmio_read_32(TEGRA_SMMU2_BASE + (uint64_t)off);
+	}
 #endif
 
-	return 0;
+	return ret;
 }
 
 static void tegra_smmu_write_32(uint32_t smmu_id,
 			uint32_t off, uint32_t val)
 {
 #if defined(TEGRA_SMMU0_BASE)
-	if (smmu_id == TEGRA_SMMU0)
-		mmio_write_32(TEGRA_SMMU0_BASE + off, val);
+	if (smmu_id == TEGRA_SMMU0) {
+		mmio_write_32(TEGRA_SMMU0_BASE + (uint64_t)off, val);
+	}
 #endif
 
 #if defined(TEGRA_SMMU1_BASE)
-	if (smmu_id == TEGRA_SMMU1)
-		mmio_write_32(TEGRA_SMMU1_BASE + off, val);
+	if (smmu_id == TEGRA_SMMU1) {
+		mmio_write_32(TEGRA_SMMU1_BASE + (uint64_t)off, val);
+	}
 #endif
 
 #if defined(TEGRA_SMMU2_BASE)
-	if (smmu_id == TEGRA_SMMU2)
-		mmio_write_32(TEGRA_SMMU2_BASE + off, val);
+	if (smmu_id == TEGRA_SMMU2) {
+		mmio_write_32(TEGRA_SMMU2_BASE + (uint64_t)off, val);
+	}
 #endif
 }
 
@@ -70,52 +78,55 @@
 {
 	uint32_t i, num_entries = 0;
 	smmu_regs_t *smmu_ctx_regs;
-	plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+	const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
 	uint64_t tzdram_base = params_from_bl2->tzdram_base;
 	uint64_t tzdram_end = tzdram_base + params_from_bl2->tzdram_size;
 	uint32_t reg_id1, pgshift, cb_size;
 
 	/* sanity check SMMU settings c*/
 	reg_id1 = mmio_read_32((TEGRA_SMMU0_BASE + SMMU_GNSR0_IDR1));
-	pgshift = (reg_id1 & ID1_PAGESIZE) ? 16 : 12;
-	cb_size = (2 << pgshift) * \
-	(1 << (((reg_id1 >> ID1_NUMPAGENDXB_SHIFT) & ID1_NUMPAGENDXB_MASK) + 1));
+	pgshift = ((reg_id1 & ID1_PAGESIZE) != 0U) ? 16U : 12U;
+	cb_size = ((uint32_t)2 << pgshift) * \
+	((uint32_t)1 << (((reg_id1 >> ID1_NUMPAGENDXB_SHIFT) & ID1_NUMPAGENDXB_MASK) + 1U));
 
 	assert(!((pgshift != PGSHIFT) || (cb_size != CB_SIZE)));
 	assert((smmu_ctx_addr >= tzdram_base) && (smmu_ctx_addr <= tzdram_end));
 
 	/* get SMMU context table */
 	smmu_ctx_regs = plat_get_smmu_ctx();
-	assert(smmu_ctx_regs);
+	assert(smmu_ctx_regs != NULL);
 
 	/*
 	 * smmu_ctx_regs[0].val contains the size of the context table minus
 	 * the last entry. Sanity check the table size before we start with
 	 * the context save operation.
 	 */
-	while (smmu_ctx_regs[num_entries].val != 0xFFFFFFFFU) {
+	while ((smmu_ctx_regs[num_entries].reg != 0xFFFFFFFFU)) {
 		num_entries++;
 	}
 
 	/* panic if the sizes do not match */
-	if (num_entries != smmu_ctx_regs[0].val)
+	if (num_entries != smmu_ctx_regs[0].val) {
+		ERROR("SMMU context size mismatch!");
 		panic();
+	}
 
 	/* save SMMU register values */
-	for (i = 1; i < num_entries; i++)
+	for (i = 1U; i < num_entries; i++) {
 		smmu_ctx_regs[i].val = mmio_read_32(smmu_ctx_regs[i].reg);
+	}
 
 	/* increment by 1 to take care of the last entry */
 	num_entries++;
 
 	/* Save SMMU config settings */
-	memcpy16((void *)(uintptr_t)smmu_ctx_addr, (void *)smmu_ctx_regs,
-		 (sizeof(smmu_regs_t) * num_entries));
+	(void)memcpy16((uint8_t *)smmu_ctx_addr, (uint8_t *)smmu_ctx_regs,
+			(sizeof(smmu_regs_t) * num_entries));
 
 	/* save the SMMU table address */
-	mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV11_LO,
+	mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SMMU_TABLE_ADDR_LO,
 		(uint32_t)smmu_ctx_addr);
-	mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV11_HI,
+	mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SMMU_TABLE_ADDR_HI,
 		(uint32_t)(smmu_ctx_addr >> 32));
 }
 
@@ -128,17 +139,18 @@
 void tegra_smmu_init(void)
 {
 	uint32_t val, cb_idx, smmu_id, ctx_base;
+	uint32_t smmu_counter = plat_get_num_smmu_devices();
 
-	for (smmu_id = 0; smmu_id < NUM_SMMU_DEVICES; smmu_id++) {
+	for (smmu_id = 0U; smmu_id < smmu_counter; smmu_id++) {
 		/* Program the SMMU pagesize and reset CACHE_LOCK bit */
 		val = tegra_smmu_read_32(smmu_id, SMMU_GSR0_SECURE_ACR);
 		val |= SMMU_GSR0_PGSIZE_64K;
-		val &= ~SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
+		val &= (uint32_t)~SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
 		tegra_smmu_write_32(smmu_id, SMMU_GSR0_SECURE_ACR, val);
 
 		/* reset CACHE LOCK bit for NS Aux. Config. Register */
 		val = tegra_smmu_read_32(smmu_id, SMMU_GNSR_ACR);
-		val &= ~SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
+		val &= (uint32_t)~SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
 		tegra_smmu_write_32(smmu_id, SMMU_GNSR_ACR, val);
 
 		/* disable TCU prefetch for all contexts */
@@ -147,19 +159,19 @@
 		for (cb_idx = 0; cb_idx < SMMU_CONTEXT_BANK_MAX_IDX; cb_idx++) {
 			val = tegra_smmu_read_32(smmu_id,
 				ctx_base + (SMMU_GSR0_PGSIZE_64K * cb_idx));
-			val &= ~SMMU_CBn_ACTLR_CPRE_BIT;
+			val &= (uint32_t)~SMMU_CBn_ACTLR_CPRE_BIT;
 			tegra_smmu_write_32(smmu_id, ctx_base +
 				(SMMU_GSR0_PGSIZE_64K * cb_idx), val);
 		}
 
 		/* set CACHE LOCK bit for NS Aux. Config. Register */
 		val = tegra_smmu_read_32(smmu_id, SMMU_GNSR_ACR);
-		val |= SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
+		val |= (uint32_t)SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
 		tegra_smmu_write_32(smmu_id, SMMU_GNSR_ACR, val);
 
 		/* set CACHE LOCK bit for S Aux. Config. Register */
 		val = tegra_smmu_read_32(smmu_id, SMMU_GSR0_SECURE_ACR);
-		val |= SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
+		val |= (uint32_t)SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
 		tegra_smmu_write_32(smmu_id, SMMU_GSR0_SECURE_ACR, val);
 	}
 }
diff --git a/plat/nvidia/tegra/common/drivers/spe/shared_console.S b/plat/nvidia/tegra/common/drivers/spe/shared_console.S
new file mode 100644
index 0000000..a9f0334
--- /dev/null
+++ b/plat/nvidia/tegra/common/drivers/spe/shared_console.S
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <asm_macros.S>
+
+#define CONSOLE_NUM_BYTES_SHIFT		24
+#define CONSOLE_FLUSH_DATA_TO_PORT	(1 << 26)
+#define CONSOLE_RING_DOORBELL		(1 << 31)
+#define CONSOLE_IS_BUSY			(1 << 31)
+#define CONSOLE_WRITE			(CONSOLE_RING_DOORBELL | CONSOLE_FLUSH_DATA_TO_PORT)
+
+	/*
+	 * This file contains a driver implementation to make use of the
+	 * real console implementation provided by the SPE firmware running
+	 * SoCs after Tegra186.
+	 *
+	 * This console is shared by multiple components and the SPE firmware
+	 * finally displays everything on the UART port.
+	 */
+
+	.globl	console_core_init
+	.globl	console_core_putc
+	.globl	console_core_getc
+	.globl	console_core_flush
+
+	/* -----------------------------------------------
+	 * int console_core_init(uintptr_t base_addr,
+	 * unsigned int uart_clk, unsigned int baud_rate)
+	 * Function to initialize the console without a
+	 * C Runtime to print debug information. This
+	 * function will be accessed by console_init and
+	 * crash reporting.
+	 * In: x0 - console base address
+	 *     w1 - Uart clock in Hz
+	 *     w2 - Baud rate
+	 * Out: return 1 on success else 0 on error
+	 * Clobber list : x1, x2
+	 * -----------------------------------------------
+	 */
+func console_core_init
+	/* Check the input base address */
+	cbz	x0, core_init_fail
+	mov	w0, #1
+	ret
+core_init_fail:
+	mov	w0, wzr
+	ret
+endfunc console_core_init
+
+	/* --------------------------------------------------------
+	 * int console_core_putc(int c, uintptr_t base_addr)
+	 * Function to output a character over the console. It
+	 * returns the character printed on success or -1 on error.
+	 * In : w0 - character to be printed
+	 *      x1 - console base address
+	 * Out : return -1 on error else return character.
+	 * Clobber list : x2
+	 * --------------------------------------------------------
+	 */
+func console_core_putc
+	/* Check the input parameter */
+	cbz	x1, putc_error
+
+	/* wait until spe is ready */
+1:	ldr	w2, [x1]
+	and	w2, w2, #CONSOLE_IS_BUSY
+	cbnz	w2, 1b
+
+	/* spe is ready */
+	mov	w2, w0
+	and	w2, w2, #0xFF
+	mov	w3, #(CONSOLE_WRITE | (1 << CONSOLE_NUM_BYTES_SHIFT))
+	orr	w2, w2, w3
+	str	w2, [x1]
+
+	ret
+putc_error:
+	mov	w0, #-1
+	ret
+endfunc console_core_putc
+
+	/* ---------------------------------------------
+	 * int console_core_getc(uintptr_t base_addr)
+	 * Function to get a character from the console.
+	 * It returns the character grabbed on success
+	 * or -1 on error.
+	 * In : x0 - console base address
+	 * Clobber list : x0, x1
+	 * ---------------------------------------------
+	 */
+func console_core_getc
+	mov	w0, #-1
+	ret
+endfunc console_core_getc
+
+	/* ---------------------------------------------
+	 * int console_core_flush(uintptr_t base_addr)
+	 * Function to force a write of all buffered
+	 * data that hasn't been output.
+	 * In : x0 - console base address
+	 * Out : return -1 on error else return 0.
+	 * Clobber list : x0, x1
+	 * ---------------------------------------------
+	 */
+func console_core_flush
+	cbz	x0, flush_error
+
+	/* flush console */
+	mov	w1, #CONSOLE_WRITE
+	str	w1, [x0]
+	mov	w0, #0
+	ret
+flush_error:
+	mov	w0, #-1
+	ret
+endfunc console_core_flush
diff --git a/plat/nvidia/tegra/common/lib/debug/profiler.c b/plat/nvidia/tegra/common/lib/debug/profiler.c
new file mode 100644
index 0000000..d4c3f95
--- /dev/null
+++ b/plat/nvidia/tegra/common/lib/debug/profiler.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*******************************************************************************
+ * The profiler stores the timestamps captured during cold boot to the shared
+ * memory for the non-secure world. The non-secure world driver parses the
+ * shared memory block and writes the contents to a file on the device, which
+ * can be later extracted for analysis.
+ *
+ * Profiler memory map
+ *
+ * TOP     ---------------------------      ---
+ *            Trusted OS timestamps         3KB
+ *         ---------------------------      ---
+ *         Trusted Firmware timestamps      1KB
+ * BASE    ---------------------------      ---
+ *
+ ******************************************************************************/
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <mmio.h>
+#include <profiler.h>
+#include <stdbool.h>
+#include <string.h>
+#include <utils_def.h>
+#include <xlat_tables_v2.h>
+
+static uint64_t shmem_base_addr;
+
+#define MAX_PROFILER_RECORDS	U(16)
+#define TAG_LEN_BYTES		U(56)
+
+/*******************************************************************************
+ * Profiler entry format
+ ******************************************************************************/
+typedef struct {
+	/* text explaining the timestamp location in code */
+	uint8_t tag[TAG_LEN_BYTES];
+	/* timestamp value */
+	uint64_t timestamp;
+} profiler_rec_t;
+
+static profiler_rec_t *head, *cur, *tail;
+static uint32_t tmr;
+static bool is_shmem_buf_mapped;
+
+/*******************************************************************************
+ * Initialise the profiling library
+ ******************************************************************************/
+void boot_profiler_init(uint64_t shmem_base, uint32_t tmr_base)
+{
+	uint64_t shmem_end_base;
+
+	assert(shmem_base != ULL(0));
+	assert(tmr_base != U(0));
+
+	/* store the buffer address */
+	shmem_base_addr = shmem_base;
+
+	/* calculate the base address of the last record */
+	shmem_end_base = shmem_base + (sizeof(profiler_rec_t) *
+			 (MAX_PROFILER_RECORDS - U(1)));
+
+	/* calculate the head, tail and cur values */
+	head = (profiler_rec_t *)shmem_base;
+	tail = (profiler_rec_t *)shmem_end_base;
+	cur = head;
+
+	/* timer used to get the current timestamp */
+	tmr = tmr_base;
+}
+
+/*******************************************************************************
+ * Add tag and timestamp to profiler
+ ******************************************************************************/
+void boot_profiler_add_record(const char *str)
+{
+	unsigned int len;
+
+	/* calculate the length of the tag */
+	if (((unsigned int)strlen(str) + U(1)) > TAG_LEN_BYTES) {
+		len = TAG_LEN_BYTES;
+	} else {
+		len = (unsigned int)strlen(str) + U(1);
+	}
+
+	if (head != NULL) {
+
+		/*
+		 * The profiler runs with/without MMU enabled. Check
+		 * if MMU is enabled and memmap the shmem buffer, in
+		 * case it is.
+		 */
+		if ((!is_shmem_buf_mapped) &&
+		    ((read_sctlr_el3() & SCTLR_M_BIT) != U(0))) {
+
+			(void)mmap_add_dynamic_region(shmem_base_addr,
+					shmem_base_addr,
+					PROFILER_SIZE_BYTES,
+					(MT_NS | MT_RW | MT_EXECUTE_NEVER));
+
+			is_shmem_buf_mapped = true;
+		}
+
+		/* write the tag and timestamp to buffer */
+		(void)snprintf((char *)cur->tag, len, "%s", str);
+		cur->timestamp = mmio_read_32(tmr);
+
+		/* start from head if we reached the end */
+		if (cur == tail) {
+			cur = head;
+		} else {
+			cur++;
+		}
+	}
+}
+
+/*******************************************************************************
+ * Deinint the profiler
+ ******************************************************************************/
+void boot_profiler_deinit(void)
+{
+	if (shmem_base_addr != ULL(0)) {
+
+		/* clean up resources */
+		cur = NULL;
+		head = NULL;
+		tail = NULL;
+
+		/* flush the shmem for it to be visible to the NS world */
+		flush_dcache_range(shmem_base_addr, PROFILER_SIZE_BYTES);
+
+		/* unmap the shmem buffer */
+		if (is_shmem_buf_mapped) {
+			(void)mmap_remove_dynamic_region(shmem_base_addr,
+					PROFILER_SIZE_BYTES);
+		}
+	}
+}
diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c
index b496650..908e4f2 100644
--- a/plat/nvidia/tegra/common/tegra_bl31_setup.c
+++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c
@@ -26,7 +26,9 @@
 #include <plat/common/platform.h>
 
 #include <memctrl.h>
+#include <profiler.h>
 #include <tegra_def.h>
+#include <tegra_platform.h>
 #include <tegra_private.h>
 
 /* length of Trusty's input parameters (in bytes) */
@@ -39,20 +41,19 @@
  * of trusted SRAM
  ******************************************************************************/
 
-IMPORT_SYM(unsigned long, __RW_START__,		BL31_RW_START);
-IMPORT_SYM(unsigned long, __RW_END__,		BL31_RW_END);
-IMPORT_SYM(unsigned long, __RODATA_START__,	BL31_RODATA_BASE);
-IMPORT_SYM(unsigned long, __RODATA_END__,	BL31_RODATA_END);
-IMPORT_SYM(unsigned long, __TEXT_START__,	TEXT_START);
-IMPORT_SYM(unsigned long, __TEXT_END__,		TEXT_END);
+IMPORT_SYM(uint64_t, __RW_START__,	BL31_RW_START);
+IMPORT_SYM(uint64_t, __RW_END__,	BL31_RW_END);
+IMPORT_SYM(uint64_t, __RODATA_START__,	BL31_RODATA_BASE);
+IMPORT_SYM(uint64_t, __RODATA_END__,	BL31_RODATA_END);
+IMPORT_SYM(uint64_t, __TEXT_START__,	TEXT_START);
+IMPORT_SYM(uint64_t, __TEXT_END__,	TEXT_END);
 
 extern uint64_t tegra_bl31_phys_base;
 extern uint64_t tegra_console_base;
 
-
 static entry_point_info_t bl33_image_ep_info, bl32_image_ep_info;
 static plat_params_from_bl2_t plat_bl31_params_from_bl2 = {
-	.tzdram_size = (uint64_t)TZDRAM_SIZE
+	.tzdram_size = TZDRAM_SIZE
 };
 static unsigned long bl32_mem_size;
 static unsigned long bl32_boot_params;
@@ -69,6 +70,7 @@
 #pragma weak plat_early_platform_setup
 #pragma weak plat_get_bl31_params
 #pragma weak plat_get_bl31_plat_params
+#pragma weak plat_late_platform_setup
 
 void plat_early_platform_setup(void)
 {
@@ -85,6 +87,11 @@
 	return NULL;
 }
 
+void plat_late_platform_setup(void)
+{
+	; /* do nothing */
+}
+
 /*******************************************************************************
  * Return a pointer to the 'entry_point_info' structure of the next image for
  * security state specified. BL33 corresponds to the non-secure image type
@@ -92,14 +99,16 @@
  ******************************************************************************/
 entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
 {
-	if (type == NON_SECURE)
-		return &bl33_image_ep_info;
+	entry_point_info_t *ep =  NULL;
 
 	/* return BL32 entry point info if it is valid */
-	if (type == SECURE && bl32_image_ep_info.pc)
-		return &bl32_image_ep_info;
+	if (type == NON_SECURE) {
+		ep = &bl33_image_ep_info;
+	} else if ((type == SECURE) && (bl32_image_ep_info.pc != 0U)) {
+		ep = &bl32_image_ep_info;
+	}
 
-	return NULL;
+	return ep;
 }
 
 /*******************************************************************************
@@ -122,6 +131,8 @@
 	plat_params_from_bl2_t *plat_params = (plat_params_from_bl2_t *)arg1;
 	image_info_t bl32_img_info = { {0} };
 	uint64_t tzdram_start, tzdram_end, bl32_start, bl32_end;
+	uint32_t console_clock;
+	int32_t ret;
 
 	/*
 	 * For RESET_TO_BL31 systems, BL31 is the first bootloader to run so
@@ -129,20 +140,22 @@
 	 * might use custom ways to get arguments, so provide handlers which
 	 * they can override.
 	 */
-	if (arg_from_bl2 == NULL)
+	if (arg_from_bl2 == NULL) {
 		arg_from_bl2 = plat_get_bl31_params();
-	if (plat_params == NULL)
+	}
+	if (plat_params == NULL) {
 		plat_params = plat_get_bl31_plat_params();
+	}
 
 	/*
 	 * Copy BL3-3, BL3-2 entry point information.
 	 * They are stored in Secure RAM, in BL2's address space.
 	 */
-	assert(arg_from_bl2);
-	assert(arg_from_bl2->bl33_ep_info);
+	assert(arg_from_bl2 != NULL);
+	assert(arg_from_bl2->bl33_ep_info != NULL);
 	bl33_image_ep_info = *arg_from_bl2->bl33_ep_info;
 
-	if (arg_from_bl2->bl32_ep_info) {
+	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;
@@ -151,18 +164,29 @@
 	/*
 	 * Parse platform specific parameters - TZDRAM aperture base and size
 	 */
-	assert(plat_params);
+	assert(plat_params != NULL);
 	plat_bl31_params_from_bl2.tzdram_base = plat_params->tzdram_base;
 	plat_bl31_params_from_bl2.tzdram_size = plat_params->tzdram_size;
 	plat_bl31_params_from_bl2.uart_id = plat_params->uart_id;
+	plat_bl31_params_from_bl2.l2_ecc_parity_prot_dis = plat_params->l2_ecc_parity_prot_dis;
 
 	/*
 	 * It is very important that we run either from TZDRAM or TZSRAM base.
 	 * Add an explicit check here.
 	 */
-	if ((plat_bl31_params_from_bl2.tzdram_base != BL31_BASE) &&
-	    (TEGRA_TZRAM_BASE != BL31_BASE))
+	if ((plat_bl31_params_from_bl2.tzdram_base != (uint64_t)BL31_BASE) &&
+	    (TEGRA_TZRAM_BASE != BL31_BASE)) {
 		panic();
+	}
+
+	/*
+	 * Reference clock used by the FPGAs is a lot slower.
+	 */
+	if (tegra_platform_is_fpga()) {
+		console_clock = TEGRA_BOOT_UART_CLK_13_MHZ;
+	} else {
+		console_clock = TEGRA_BOOT_UART_CLK_408_MHZ;
+	}
 
 	/*
 	 * Get the base address of the UART controller to be used for the
@@ -170,31 +194,60 @@
 	 */
 	tegra_console_base = plat_get_console_from_id(plat_params->uart_id);
 
-	if (tegra_console_base != (uint64_t)0) {
+	if (tegra_console_base != 0U) {
 		/*
 		 * Configure the UART port to be used as the console
 		 */
-		console_init(tegra_console_base, TEGRA_BOOT_UART_CLK_IN_HZ,
-			TEGRA_CONSOLE_BAUDRATE);
+		(void)console_init(tegra_console_base, console_clock,
+			     TEGRA_CONSOLE_BAUDRATE);
 	}
 
 	/*
+	 * The previous bootloader passes the base address of the shared memory
+	 * location to store the boot profiler logs. Sanity check the
+	 * address and initilise the profiler library, if it looks ok.
+	 */
+	if (plat_params->boot_profiler_shmem_base != 0ULL) {
+
+		ret = bl31_check_ns_address(plat_params->boot_profiler_shmem_base,
+				PROFILER_SIZE_BYTES);
+		if (ret == (int32_t)0) {
+
+			/* store the membase for the profiler lib */
+			plat_bl31_params_from_bl2.boot_profiler_shmem_base =
+				plat_params->boot_profiler_shmem_base;
+
+			/* initialise the profiler library */
+			boot_profiler_init(plat_params->boot_profiler_shmem_base,
+					   TEGRA_TMRUS_BASE);
+		}
+	}
+
+	/*
+	 * Add timestamp for platform early setup entry.
+	 */
+	boot_profiler_add_record("[TF] early setup entry");
+
+	/*
 	 * Initialize delay timer
 	 */
 	tegra_delay_timer_init();
 
+	/* Early platform setup for Tegra SoCs */
+	plat_early_platform_setup();
+
 	/*
 	 * Do initial security configuration to allow DRAM/device access.
 	 */
 	tegra_memctrl_tzdram_setup(plat_bl31_params_from_bl2.tzdram_base,
-			plat_bl31_params_from_bl2.tzdram_size);
+			(uint32_t)plat_bl31_params_from_bl2.tzdram_size);
 
 	/*
 	 * The previous bootloader might not have placed the BL32 image
 	 * inside the TZDRAM. We check the BL32 image info to find out
 	 * the base/PC values and relocate the image if necessary.
 	 */
-	if (arg_from_bl2->bl32_image_info) {
+	if (arg_from_bl2->bl32_image_info != NULL) {
 
 		bl32_img_info = *arg_from_bl2->bl32_image_info;
 
@@ -211,11 +264,11 @@
 		assert(bl32_image_ep_info.pc < tzdram_end);
 
 		/* relocate BL32 */
-		if (bl32_start >= tzdram_end || bl32_end <= tzdram_start) {
+		if ((bl32_start >= tzdram_end) || (bl32_end <= tzdram_start)) {
 
 			INFO("Relocate BL32 to TZDRAM\n");
 
-			memcpy16((void *)(uintptr_t)bl32_image_ep_info.pc,
+			(void)memcpy16((void *)(uintptr_t)bl32_image_ep_info.pc,
 				 (void *)(uintptr_t)bl32_start,
 				 bl32_img_info.image_size);
 
@@ -225,8 +278,10 @@
 		}
 	}
 
-	/* Early platform setup for Tegra SoCs */
-	plat_early_platform_setup();
+	/*
+	 * Add timestamp for platform early setup exit.
+	 */
+	boot_profiler_add_record("[TF] early setup exit");
 
 	INFO("BL3-1: Boot CPU: %s Processor [%lx]\n",
 	     (((read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK)
@@ -239,6 +294,14 @@
 	args->arg0 = bl32_mem_size;
 	args->arg1 = bl32_boot_params;
 	args->arg2 = TRUSTY_PARAMS_LEN_BYTES;
+
+	/* update EKS size */
+	if (args->arg4 != 0U) {
+		args->arg2 = args->arg4;
+	}
+
+	/* Profiler Carveout Base */
+	args->arg3 = args->arg5;
 }
 #endif
 
@@ -247,7 +310,10 @@
  ******************************************************************************/
 void bl31_platform_setup(void)
 {
-	uint32_t tmp_reg;
+	/*
+	 * Add timestamp for platform setup entry.
+	 */
+	boot_profiler_add_record("[TF] plat setup entry");
 
 	/* Initialize the gic cpu and distributor interfaces */
 	plat_gic_setup();
@@ -268,9 +334,17 @@
 	 */
 	tegra_memctrl_tzram_setup(TEGRA_TZRAM_BASE, TEGRA_TZRAM_SIZE);
 
-	/* Set the next EL to be AArch64 */
-	tmp_reg = SCR_RES1_BITS | SCR_RW_BIT;
-	write_scr(tmp_reg);
+	/*
+	 * Late setup handler to allow platforms to performs additional
+	 * functionality.
+	 * This handler gets called with MMU enabled.
+	 */
+	plat_late_platform_setup();
+
+	/*
+	 * Add timestamp for platform setup exit.
+	 */
+	boot_profiler_add_record("[TF] plat setup exit");
 
 	INFO("BL3-1: Tegra platform setup complete\n");
 }
@@ -281,6 +355,15 @@
 void bl31_plat_runtime_setup(void)
 {
 	/*
+	 * During cold boot, it is observed that the arbitration
+	 * bit is set in the Memory controller leading to false
+	 * error interrupts in the non-secure world. To avoid
+	 * this, clean the interrupt status register before
+	 * booting into the non-secure world
+	 */
+	tegra_memctrl_clear_pending_interrupts();
+
+	/*
 	 * During boot, USB3 and flash media (SDMMC/SATA) devices need
 	 * access to IRAM. Because these clients connect to the MC and
 	 * do not have a direct path to the IRAM, the MC implements AHB
@@ -290,6 +373,12 @@
 	 * disabled before we jump to the non-secure world.
 	 */
 	tegra_memctrl_disable_ahb_redirection();
+
+	/*
+	 * Add final timestamp before exiting BL31.
+	 */
+	boot_profiler_add_record("[TF] bl31 exit");
+	boot_profiler_deinit();
 }
 
 /*******************************************************************************
@@ -298,17 +387,22 @@
  ******************************************************************************/
 void bl31_plat_arch_setup(void)
 {
-	unsigned long rw_start = BL31_RW_START;
-	unsigned long rw_size = BL31_RW_END - BL31_RW_START;
-	unsigned long rodata_start = BL31_RODATA_BASE;
-	unsigned long rodata_size = BL31_RODATA_END - BL31_RODATA_BASE;
-	unsigned long code_base = TEXT_START;
-	unsigned long code_size = TEXT_END - TEXT_START;
+	uint64_t rw_start = BL31_RW_START;
+	uint64_t rw_size = BL31_RW_END - BL31_RW_START;
+	uint64_t rodata_start = BL31_RODATA_BASE;
+	uint64_t rodata_size = BL31_RODATA_END - BL31_RODATA_BASE;
+	uint64_t code_base = TEXT_START;
+	uint64_t code_size = TEXT_END - TEXT_START;
 	const mmap_region_t *plat_mmio_map = NULL;
 #if USE_COHERENT_MEM
-	unsigned long coh_start, coh_size;
+	uint32_t coh_start, coh_size;
 #endif
-	plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+	const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+
+	/*
+	 * Add timestamp for arch setup entry.
+	 */
+	boot_profiler_add_record("[TF] arch setup entry");
 
 	/* add memory regions */
 	mmap_add_region(rw_start, rw_start,
@@ -335,21 +429,22 @@
 
 	mmap_add_region(coh_start, coh_start,
 			coh_size,
-			MT_DEVICE | MT_RW | MT_SECURE);
+			(uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE);
 #endif
 
 	/* map on-chip free running uS timer */
-	mmap_add_region(page_align((uint64_t)TEGRA_TMRUS_BASE, 0),
-			page_align((uint64_t)TEGRA_TMRUS_BASE, 0),
-			(uint64_t)TEGRA_TMRUS_SIZE,
-			MT_DEVICE | MT_RO | MT_SECURE);
+	mmap_add_region(page_align(TEGRA_TMRUS_BASE, 0),
+			page_align(TEGRA_TMRUS_BASE, 0),
+			TEGRA_TMRUS_SIZE,
+			(uint8_t)MT_DEVICE | (uint8_t)MT_RO | (uint8_t)MT_SECURE);
 
 	/* add MMIO space */
 	plat_mmio_map = plat_get_mmio_map();
-	if (plat_mmio_map)
+	if (plat_mmio_map != NULL) {
 		mmap_add(plat_mmio_map);
-	else
+	} else {
 		WARN("MMIO map not available\n");
+	}
 
 	/* set up translation tables */
 	init_xlat_tables();
@@ -357,33 +452,41 @@
 	/* enable the MMU */
 	enable_mmu_el3(0);
 
+	/*
+	 * Add timestamp for arch setup exit.
+	 */
+	boot_profiler_add_record("[TF] arch setup exit");
+
 	INFO("BL3-1: Tegra: MMU enabled\n");
 }
 
 /*******************************************************************************
  * Check if the given NS DRAM range is valid
  ******************************************************************************/
-int bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes)
+int32_t bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes)
 {
-	uint64_t end = base + size_in_bytes;
+	uint64_t end = base + size_in_bytes - U(1);
+	int32_t ret = 0;
 
 	/*
 	 * Check if the NS DRAM address is valid
 	 */
-	if ((base < TEGRA_DRAM_BASE) || (end > TEGRA_DRAM_END)) {
+	if ((base < TEGRA_DRAM_BASE) || (base >= TEGRA_DRAM_END) ||
+	    (end > TEGRA_DRAM_END)) {
+
 		ERROR("NS address is out-of-bounds!\n");
-		return -EFAULT;
+		ret = -EFAULT;
 	}
 
 	/*
 	 * TZDRAM aperture contains the BL31 and BL32 images, so we need
 	 * to check if the NS DRAM range overlaps the TZDRAM aperture.
 	 */
-	if ((base < TZDRAM_END) && (end > tegra_bl31_phys_base)) {
+	if ((base < (uint64_t)TZDRAM_END) && (end > tegra_bl31_phys_base)) {
 		ERROR("NS address overlaps TZDRAM!\n");
-		return -ENOTSUP;
+		ret = -ENOTSUP;
 	}
 
 	/* valid NS address */
-	return 0;
+	return ret;
 }
diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk
index 6a0854e..d9eec4d 100644
--- a/plat/nvidia/tegra/common/tegra_common.mk
+++ b/plat/nvidia/tegra/common/tegra_common.mk
@@ -5,6 +5,7 @@
 #
 
 PLAT_INCLUDES		:=	-Iplat/nvidia/tegra/include/drivers \
+				-Iplat/nvidia/tegra/include/lib \
 				-Iplat/nvidia/tegra/include \
 				-Iplat/nvidia/tegra/include/${TARGET_SOC}
 
@@ -21,10 +22,10 @@
 
 BL31_SOURCES		+=	drivers/console/aarch64/console.S		\
 				drivers/delay_timer/delay_timer.c		\
-				drivers/ti/uart/aarch64/16550_console.S		\
 				${TEGRA_GICv2_SOURCES}				\
 				${COMMON_DIR}/aarch64/tegra_helpers.S		\
 				${COMMON_DIR}/drivers/pmc/pmc.c			\
+				${COMMON_DIR}/lib/debug/profiler.c		\
 				${COMMON_DIR}/tegra_bl31_setup.c		\
 				${COMMON_DIR}/tegra_delay_timer.c		\
 				${COMMON_DIR}/tegra_fiq_glue.c			\
diff --git a/plat/nvidia/tegra/common/tegra_fiq_glue.c b/plat/nvidia/tegra/common/tegra_fiq_glue.c
index 0b663ce..cab2e5e 100644
--- a/plat/nvidia/tegra/common/tegra_fiq_glue.c
+++ b/plat/nvidia/tegra/common/tegra_fiq_glue.c
@@ -41,6 +41,11 @@
 	uint32_t cpu = plat_my_core_pos();
 	uint32_t irq;
 
+	(void)id;
+	(void)flags;
+	(void)handle;
+	(void)cookie;
+
 	bakery_lock_get(&tegra_fiq_lock);
 
 	/*
@@ -60,7 +65,7 @@
 	 * Set the new ELR to continue execution in the NS world using the
 	 * FIQ handler registered earlier.
 	 */
-	assert(ns_fiq_handler_addr);
+	assert(ns_fiq_handler_addr != 0ULL);
 	write_ctx_reg((el3state_ctx), (uint32_t)(CTX_ELR_EL3), (ns_fiq_handler_addr));
 
 	/*
diff --git a/plat/nvidia/tegra/common/tegra_platform.c b/plat/nvidia/tegra/common/tegra_platform.c
index 10edf92..c1e4209 100644
--- a/plat/nvidia/tegra/common/tegra_platform.c
+++ b/plat/nvidia/tegra/common/tegra_platform.c
@@ -1,12 +1,12 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <arch_helpers.h>
+#include <assert.h>
 #include <lib/mmio.h>
-
 #include <tegra_def.h>
 #include <tegra_platform.h>
 #include <tegra_private.h>
@@ -15,39 +15,37 @@
  * Tegra platforms
  ******************************************************************************/
 typedef enum tegra_platform {
-	TEGRA_PLATFORM_SILICON = 0,
+	TEGRA_PLATFORM_SILICON = 0U,
 	TEGRA_PLATFORM_QT,
 	TEGRA_PLATFORM_FPGA,
 	TEGRA_PLATFORM_EMULATION,
+	TEGRA_PLATFORM_LINSIM,
+	TEGRA_PLATFORM_UNIT_FPGA,
+	TEGRA_PLATFORM_VIRT_DEV_KIT,
 	TEGRA_PLATFORM_MAX,
 } tegra_platform_t;
 
 /*******************************************************************************
  * Tegra macros defining all the SoC minor versions
  ******************************************************************************/
-#define TEGRA_MINOR_QT			0
-#define TEGRA_MINOR_FPGA		1
-#define TEGRA_MINOR_EMULATION_MIN	2
-#define TEGRA_MINOR_EMULATION_MAX	10
+#define TEGRA_MINOR_QT			U(0)
+#define TEGRA_MINOR_FPGA		U(1)
+#define TEGRA_MINOR_ASIM_QT		U(2)
+#define TEGRA_MINOR_ASIM_LINSIM		U(3)
+#define TEGRA_MINOR_DSIM_ASIM_LINSIM	U(4)
+#define TEGRA_MINOR_UNIT_FPGA		U(5)
+#define TEGRA_MINOR_VIRT_DEV_KIT	U(6)
 
 /*******************************************************************************
- * Tegra major, minor version helper macros
+ * Tegra macros defining all the SoC pre_si_platform
  ******************************************************************************/
-#define MAJOR_VERSION_SHIFT		0x4
-#define MAJOR_VERSION_MASK		0xF
-#define MINOR_VERSION_SHIFT		0x10
-#define MINOR_VERSION_MASK		0xF
-#define CHIP_ID_SHIFT			8
-#define CHIP_ID_MASK			0xFF
-
-/*******************************************************************************
- * Tegra chip ID values
- ******************************************************************************/
-typedef enum tegra_chipid {
-	TEGRA_CHIPID_TEGRA13 = 0x13,
-	TEGRA_CHIPID_TEGRA21 = 0x21,
-	TEGRA_CHIPID_TEGRA18 = 0x18,
-} tegra_chipid_t;
+#define TEGRA_PRE_SI_QT			U(1)
+#define TEGRA_PRE_SI_FPGA		U(2)
+#define TEGRA_PRE_SI_UNIT_FPGA		U(3)
+#define TEGRA_PRE_SI_ASIM_QT		U(4)
+#define TEGRA_PRE_SI_ASIM_LINSIM	U(5)
+#define TEGRA_PRE_SI_DSIM_ASIM_LINSIM	U(6)
+#define TEGRA_PRE_SI_VDK		U(8)
 
 /*
  * Read the chip ID value
@@ -73,25 +71,38 @@
 	return (tegra_get_chipid() >> MINOR_VERSION_SHIFT) & MINOR_VERSION_MASK;
 }
 
-uint8_t tegra_chipid_is_t132(void)
+/*
+ * Read the chip's pre_si_platform valus from the chip ID value
+ */
+static uint32_t tegra_get_chipid_pre_si_platform(void)
 {
-	uint32_t chip_id = (tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK;
+	return (tegra_get_chipid() >> PRE_SI_PLATFORM_SHIFT) & PRE_SI_PLATFORM_MASK;
+}
+
+bool tegra_chipid_is_t132(void)
+{
+	uint32_t chip_id = ((tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK);
 
 	return (chip_id == TEGRA_CHIPID_TEGRA13);
 }
 
-uint8_t tegra_chipid_is_t210(void)
+bool tegra_chipid_is_t186(void)
 {
 	uint32_t chip_id = (tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK;
 
-	return (chip_id == TEGRA_CHIPID_TEGRA21);
+	return (chip_id == TEGRA_CHIPID_TEGRA18);
 }
 
-uint8_t tegra_chipid_is_t186(void)
+bool tegra_chipid_is_t210(void)
 {
 	uint32_t chip_id = (tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK;
 
-	return (chip_id == TEGRA_CHIPID_TEGRA18);
+	return (chip_id == TEGRA_CHIPID_TEGRA21);
+}
+
+bool tegra_chipid_is_t210_b01(void)
+{
+	return (tegra_chipid_is_t210() && (tegra_get_chipid_major() == 0x2U));
 }
 
 /*
@@ -99,54 +110,152 @@
  */
 static tegra_platform_t tegra_get_platform(void)
 {
-	uint32_t major = tegra_get_chipid_major();
-	uint32_t minor = tegra_get_chipid_minor();
+	uint32_t major, minor, pre_si_platform;
+	tegra_platform_t ret;
 
-	/* Actual silicon platforms have a non-zero major version */
-	if (major > 0)
-		return TEGRA_PLATFORM_SILICON;
+	/* get the major/minor chip ID values */
+	major = tegra_get_chipid_major();
+	minor = tegra_get_chipid_minor();
+	pre_si_platform = tegra_get_chipid_pre_si_platform();
 
-	/*
-	 * The minor version number is used by simulation platforms
-	 */
+	if (major == 0U) {
+		/*
+		 * The minor version number is used by simulation platforms
+		 */
+		switch (minor) {
+		/*
+		 * Cadence's QuickTurn emulation system is a Solaris-based
+		 * chip emulation system
+		 */
+		case TEGRA_MINOR_QT:
+		case TEGRA_MINOR_ASIM_QT:
+			ret = TEGRA_PLATFORM_QT;
+			break;
 
-	/*
-	 * Cadence's QuickTurn emulation system is a Solaris-based
-	 * chip emulation system
-	 */
-	if (minor == TEGRA_MINOR_QT)
-		return TEGRA_PLATFORM_QT;
+		/*
+		 * FPGAs are used during early software/hardware development
+		 */
+		case TEGRA_MINOR_FPGA:
+			ret = TEGRA_PLATFORM_FPGA;
+			break;
+		/*
+		 * Linsim is a reconfigurable, clock-driven, mixed RTL/cmodel
+		 * simulation framework.
+		 */
+		case TEGRA_MINOR_ASIM_LINSIM:
+		case TEGRA_MINOR_DSIM_ASIM_LINSIM:
+			ret = TEGRA_PLATFORM_LINSIM;
+			break;
 
-	/*
-	 * FPGAs are used during early software/hardware development
-	 */
-	if (minor == TEGRA_MINOR_FPGA)
-		return TEGRA_PLATFORM_FPGA;
+		/*
+		 * Unit FPGAs run the actual hardware block IP on the FPGA with
+		 * the other parts of the system using Linsim.
+		 */
+		case TEGRA_MINOR_UNIT_FPGA:
+			ret = TEGRA_PLATFORM_UNIT_FPGA;
+			break;
+		/*
+		 * The Virtualizer Development Kit (VDK) is the standard chip
+		 * development from Synopsis.
+		 */
+		case TEGRA_MINOR_VIRT_DEV_KIT:
+			ret = TEGRA_PLATFORM_VIRT_DEV_KIT;
+			break;
 
-	/* Minor version reserved for other emulation platforms */
-	if ((minor > TEGRA_MINOR_FPGA) && (minor <= TEGRA_MINOR_EMULATION_MAX))
-		return TEGRA_PLATFORM_EMULATION;
+		default:
+			ret = TEGRA_PLATFORM_MAX;
+			break;
+		}
 
-	/* unsupported platform */
-	return TEGRA_PLATFORM_MAX;
+	} else if (pre_si_platform > 0U) {
+
+		switch (pre_si_platform) {
+		/*
+		 * Cadence's QuickTurn emulation system is a Solaris-based
+		 * chip emulation system
+		 */
+		case TEGRA_PRE_SI_QT:
+		case TEGRA_PRE_SI_ASIM_QT:
+			ret = TEGRA_PLATFORM_QT;
+			break;
+
+		/*
+		 * FPGAs are used during early software/hardware development
+		 */
+		case TEGRA_PRE_SI_FPGA:
+			ret = TEGRA_PLATFORM_FPGA;
+			break;
+		/*
+		 * Linsim is a reconfigurable, clock-driven, mixed RTL/cmodel
+		 * simulation framework.
+		 */
+		case TEGRA_PRE_SI_ASIM_LINSIM:
+		case TEGRA_PRE_SI_DSIM_ASIM_LINSIM:
+			ret = TEGRA_PLATFORM_LINSIM;
+			break;
+
+		/*
+		 * Unit FPGAs run the actual hardware block IP on the FPGA with
+		 * the other parts of the system using Linsim.
+		 */
+		case TEGRA_PRE_SI_UNIT_FPGA:
+			ret = TEGRA_PLATFORM_UNIT_FPGA;
+			break;
+		/*
+		 * The Virtualizer Development Kit (VDK) is the standard chip
+		 * development from Synopsis.
+		 */
+		case TEGRA_PRE_SI_VDK:
+			ret = TEGRA_PLATFORM_VIRT_DEV_KIT;
+			break;
+
+		default:
+			ret = TEGRA_PLATFORM_MAX;
+			break;
+		}
+
+	} else {
+		/* Actual silicon platforms have a non-zero major version */
+		ret = TEGRA_PLATFORM_SILICON;
+	}
+
+	return ret;
+}
+
+bool tegra_platform_is_silicon(void)
+{
+	return ((tegra_get_platform() == TEGRA_PLATFORM_SILICON) ? true : false);
 }
 
-uint8_t tegra_platform_is_silicon(void)
+bool tegra_platform_is_qt(void)
 {
-	return (tegra_get_platform() == TEGRA_PLATFORM_SILICON);
+	return ((tegra_get_platform() == TEGRA_PLATFORM_QT) ? true : false);
 }
 
-uint8_t tegra_platform_is_qt(void)
+bool tegra_platform_is_linsim(void)
 {
-	return (tegra_get_platform() == TEGRA_PLATFORM_QT);
+	tegra_platform_t plat = tegra_get_platform();
+
+	return (((plat == TEGRA_PLATFORM_LINSIM) ||
+	       (plat == TEGRA_PLATFORM_UNIT_FPGA)) ? true : false);
 }
 
-uint8_t tegra_platform_is_fpga(void)
+bool tegra_platform_is_fpga(void)
 {
-	return (tegra_get_platform() == TEGRA_PLATFORM_FPGA);
+	return ((tegra_get_platform() == TEGRA_PLATFORM_FPGA) ? true : false);
 }
 
-uint8_t tegra_platform_is_emulation(void)
+bool tegra_platform_is_emulation(void)
 {
 	return (tegra_get_platform() == TEGRA_PLATFORM_EMULATION);
 }
+
+bool tegra_platform_is_unit_fpga(void)
+{
+	return ((tegra_get_platform() == TEGRA_PLATFORM_UNIT_FPGA) ? true : false);
+}
+
+bool tegra_platform_is_virt_dev_kit(void)
+{
+	return ((tegra_get_platform() == TEGRA_PLATFORM_VIRT_DEV_KIT) ? true : false);
+}
diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c
index 8361ddd..2805272 100644
--- a/plat/nvidia/tegra/common/tegra_pm.c
+++ b/plat/nvidia/tegra/common/tegra_pm.c
@@ -21,6 +21,7 @@
 #include <memctrl.h>
 #include <pmc.h>
 #include <tegra_def.h>
+#include <tegra_platform.h>
 #include <tegra_private.h>
 
 extern uint64_t tegra_bl31_phys_base;
@@ -49,37 +50,42 @@
 #pragma weak tegra_soc_prepare_system_off
 #pragma weak tegra_soc_get_target_pwr_state
 
-int tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
+int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
 {
 	return PSCI_E_NOT_SUPPORTED;
 }
 
-int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
+int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
 {
+	(void)target_state;
 	return PSCI_E_NOT_SUPPORTED;
 }
 
-int tegra_soc_pwr_domain_on(u_register_t mpidr)
+int32_t tegra_soc_pwr_domain_on(u_register_t mpidr)
 {
+	(void)mpidr;
 	return PSCI_E_SUCCESS;
 }
 
-int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
+int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
 {
+	(void)target_state;
 	return PSCI_E_SUCCESS;
 }
 
-int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
+int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
 {
+	(void)target_state;
 	return PSCI_E_SUCCESS;
 }
 
-int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
+int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
 {
+	(void)target_state;
 	return PSCI_E_SUCCESS;
 }
 
-int tegra_soc_prepare_system_reset(void)
+int32_t tegra_soc_prepare_system_reset(void)
 {
 	return PSCI_E_SUCCESS;
 }
@@ -90,19 +96,26 @@
 	panic();
 }
 
-plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl,
+plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl,
 					     const plat_local_state_t *states,
-					     unsigned int ncpu)
+					     uint32_t ncpu)
 {
 	plat_local_state_t target = PLAT_MAX_OFF_STATE, temp;
+	uint32_t num_cpu = ncpu;
+	const plat_local_state_t *local_state = states;
 
-	assert(ncpu);
+	(void)lvl;
+
+	assert(ncpu != 0U);
 
 	do {
-		temp = *states++;
-		if ((temp < target))
+		temp = *local_state;
+		if ((temp < target)) {
 			target = temp;
-	} while (--ncpu);
+		}
+		--num_cpu;
+		local_state++;
+	} while (num_cpu != 0U);
 
 	return target;
 }
@@ -116,8 +129,9 @@
 void tegra_get_sys_suspend_power_state(psci_power_state_t *req_state)
 {
 	/* all affinities use system suspend state id */
-	for (uint32_t i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++)
+	for (uint32_t i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) {
 		req_state->pwr_domain_state[i] = PSTATE_ID_SOC_POWERDN;
+	}
 }
 
 /*******************************************************************************
@@ -125,6 +139,8 @@
  ******************************************************************************/
 void tegra_cpu_standby(plat_local_state_t cpu_state)
 {
+	(void)cpu_state;
+
 	/*
 	 * Enter standby state
 	 * dsb is good practice before using wfi to enter low power states
@@ -137,7 +153,7 @@
  * Handler called when an affinity instance is about to be turned on. The
  * level and mpidr determine the affinity instance.
  ******************************************************************************/
-int tegra_pwr_domain_on(u_register_t mpidr)
+int32_t tegra_pwr_domain_on(u_register_t mpidr)
 {
 	return tegra_soc_pwr_domain_on(mpidr);
 }
@@ -148,7 +164,7 @@
  ******************************************************************************/
 void tegra_pwr_domain_off(const psci_power_state_t *target_state)
 {
-	tegra_soc_pwr_domain_off(target_state);
+	(void)tegra_soc_pwr_domain_off(target_state);
 }
 
 /*******************************************************************************
@@ -168,12 +184,13 @@
  ******************************************************************************/
 void tegra_pwr_domain_suspend(const psci_power_state_t *target_state)
 {
-	tegra_soc_pwr_domain_suspend(target_state);
+	(void)tegra_soc_pwr_domain_suspend(target_state);
 
 	/* Disable console if we are entering deep sleep. */
 	if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] ==
-			PSTATE_ID_SOC_POWERDN)
-		console_uninit();
+			PSTATE_ID_SOC_POWERDN) {
+		(void)console_uninit();
+	}
 
 	/* disable GICC */
 	tegra_gic_cpuif_deactivate();
@@ -190,7 +207,7 @@
 	uint64_t rmr_el3 = 0;
 
 	/* call the chip's power down handler */
-	tegra_soc_pwr_domain_power_down_wfi(target_state);
+	(void)tegra_soc_pwr_domain_power_down_wfi(target_state);
 
 	/*
 	 * If we are in fake system suspend mode, ensure we start doing
@@ -221,7 +238,8 @@
  ******************************************************************************/
 void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state)
 {
-	plat_params_from_bl2_t *plat_params;
+	const plat_params_from_bl2_t *plat_params;
+	uint32_t console_clock;
 
 	/*
 	 * Initialize the GIC cpu and distributor interfaces
@@ -234,10 +252,19 @@
 	if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] ==
 			PSTATE_ID_SOC_POWERDN) {
 
+		/*
+		 * Reference clock used by the FPGAs is a lot slower.
+		 */
+		if (tegra_platform_is_fpga()) {
+			console_clock = TEGRA_BOOT_UART_CLK_13_MHZ;
+		} else {
+			console_clock = TEGRA_BOOT_UART_CLK_408_MHZ;
+		}
+
 		/* Initialize the runtime console */
-		if (tegra_console_base != (uint64_t)0) {
-			console_init(tegra_console_base, TEGRA_BOOT_UART_CLK_IN_HZ,
-				TEGRA_CONSOLE_BAUDRATE);
+		if (tegra_console_base != 0ULL) {
+			(void)console_init(tegra_console_base, console_clock,
+				     TEGRA_CONSOLE_BAUDRATE);
 		}
 
 		/*
@@ -251,7 +278,7 @@
 		 */
 		plat_params = bl31_get_plat_params();
 		tegra_memctrl_tzdram_setup(plat_params->tzdram_base,
-			plat_params->tzdram_size);
+			(uint32_t)plat_params->tzdram_size);
 
 		/*
 		 * Set up the TZRAM memory aperture to allow only secure world
@@ -263,7 +290,7 @@
 	/*
 	 * Reset hardware settings.
 	 */
-	tegra_soc_pwr_domain_on_finish(target_state);
+	(void)tegra_soc_pwr_domain_on_finish(target_state);
 }
 
 /*******************************************************************************
@@ -294,7 +321,7 @@
 	INFO("Restarting system...\n");
 
 	/* per-SoC system reset handler */
-	tegra_soc_prepare_system_reset();
+	(void)tegra_soc_prepare_system_reset();
 
 	/*
 	 * Program the PMC in order to restart the system.
@@ -305,10 +332,10 @@
 /*******************************************************************************
  * Handler called to check the validity of the power state parameter.
  ******************************************************************************/
-int32_t tegra_validate_power_state(unsigned int power_state,
+int32_t tegra_validate_power_state(uint32_t power_state,
 				   psci_power_state_t *req_state)
 {
-	assert(req_state);
+	assert(req_state != NULL);
 
 	return tegra_soc_validate_power_state(power_state, req_state);
 }
@@ -316,16 +343,19 @@
 /*******************************************************************************
  * Platform handler called to check the validity of the non secure entrypoint.
  ******************************************************************************/
-int tegra_validate_ns_entrypoint(uintptr_t entrypoint)
+int32_t tegra_validate_ns_entrypoint(uintptr_t entrypoint)
 {
+	int32_t ret = PSCI_E_INVALID_ADDRESS;
+
 	/*
 	 * Check if the non secure entrypoint lies within the non
 	 * secure DRAM.
 	 */
-	if ((entrypoint >= TEGRA_DRAM_BASE) && (entrypoint <= TEGRA_DRAM_END))
-		return PSCI_E_SUCCESS;
+	if ((entrypoint >= TEGRA_DRAM_BASE) && (entrypoint <= TEGRA_DRAM_END)) {
+		ret = PSCI_E_SUCCESS;
+	}
 
-	return PSCI_E_INVALID_ADDRESS;
+	return ret;
 }
 
 /*******************************************************************************
@@ -365,7 +395,7 @@
 	/*
 	 * Reset hardware settings.
 	 */
-	tegra_soc_pwr_domain_on_finish(&target_state);
+	(void)tegra_soc_pwr_domain_on_finish(&target_state);
 
 	/*
 	 * Initialize PSCI ops struct
diff --git a/plat/nvidia/tegra/common/tegra_sip_calls.c b/plat/nvidia/tegra/common/tegra_sip_calls.c
index e50d12f..4955b2f 100644
--- a/plat/nvidia/tegra/common/tegra_sip_calls.c
+++ b/plat/nvidia/tegra/common/tegra_sip_calls.c
@@ -31,20 +31,29 @@
  ******************************************************************************/
 extern uint8_t tegra_fake_system_suspend;
 
-
 /*******************************************************************************
  * SoC specific SiP handler
  ******************************************************************************/
 #pragma weak plat_sip_handler
-int plat_sip_handler(uint32_t smc_fid,
+int32_t plat_sip_handler(uint32_t smc_fid,
 		     uint64_t x1,
 		     uint64_t x2,
 		     uint64_t x3,
 		     uint64_t x4,
-		     void *cookie,
+		     const void *cookie,
 		     void *handle,
 		     uint64_t flags)
 {
+	/* unused parameters */
+	(void)smc_fid;
+	(void)x1;
+	(void)x2;
+	(void)x3;
+	(void)x4;
+	(void)cookie;
+	(void)handle;
+	(void)flags;
+
 	return -ENOTSUP;
 }
 
@@ -60,113 +69,113 @@
 			    void *handle,
 			    u_register_t flags)
 {
-	uint32_t regval;
-	int err;
+	uint32_t regval, local_x2_32 = (uint32_t)x2;
+	int32_t err;
 
 	/* Check if this is a SoC specific SiP */
 	err = plat_sip_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags);
-	if (err == 0)
+	if (err == 0) {
+
 		SMC_RET1(handle, (uint64_t)err);
 
-	switch (smc_fid) {
+	} else {
 
-	case TEGRA_SIP_NEW_VIDEOMEM_REGION:
+		switch (smc_fid) {
 
-		/* clean up the high bits */
-		x2 = (uint32_t)x2;
+		case TEGRA_SIP_NEW_VIDEOMEM_REGION:
 
-		/*
-		 * Check if Video Memory overlaps TZDRAM (contains bl31/bl32)
-		 * or falls outside of the valid DRAM range
-		 */
-		err = bl31_check_ns_address(x1, x2);
-		if (err)
-			SMC_RET1(handle, err);
+			/*
+			 * Check if Video Memory overlaps TZDRAM (contains bl31/bl32)
+			 * or falls outside of the valid DRAM range
+			*/
+			err = bl31_check_ns_address(x1, local_x2_32);
+			if (err != 0) {
+				SMC_RET1(handle, (uint64_t)err);
+			}
 
-		/*
-		 * Check if Video Memory is aligned to 1MB.
-		 */
-		if ((x1 & 0xFFFFF) || (x2 & 0xFFFFF)) {
-			ERROR("Unaligned Video Memory base address!\n");
-			SMC_RET1(handle, -ENOTSUP);
-		}
+			/*
+			 * Check if Video Memory is aligned to 1MB.
+			 */
+			if (((x1 & 0xFFFFFU) != 0U) || ((local_x2_32 & 0xFFFFFU) != 0U)) {
+				ERROR("Unaligned Video Memory base address!\n");
+				SMC_RET1(handle, (uint64_t)-ENOTSUP);
+			}
+
+			/*
+			 * The GPU is the user of the Video Memory region. In order to
+			 * transition to the new memory region smoothly, we program the
+			 * new base/size ONLY if the GPU is in reset mode.
+			 */
+			regval = mmio_read_32(TEGRA_CAR_RESET_BASE +
+					      TEGRA_GPU_RESET_REG_OFFSET);
+			if ((regval & GPU_RESET_BIT) == 0U) {
+				ERROR("GPU not in reset! Video Memory setup failed\n");
+				SMC_RET1(handle, (uint64_t)-ENOTSUP);
+			}
+
+			/* new video memory carveout settings */
+			tegra_memctrl_videomem_setup(x1, local_x2_32);
+
+			SMC_RET1(handle, 0);
 
 		/*
-		 * The GPU is the user of the Video Memory region. In order to
-		 * transition to the new memory region smoothly, we program the
-		 * new base/size ONLY if the GPU is in reset mode.
+		 * The NS world registers the address of its handler to be
+		 * used for processing the FIQ. This is normally used by the
+		 * NS FIQ debugger driver to detect system hangs by programming
+		 * a watchdog timer to fire a FIQ interrupt.
 		 */
-		regval = mmio_read_32(TEGRA_CAR_RESET_BASE +
-				      TEGRA_GPU_RESET_REG_OFFSET);
-		if ((regval & GPU_RESET_BIT) == 0U) {
-			ERROR("GPU not in reset! Video Memory setup failed\n");
-			SMC_RET1(handle, -ENOTSUP);
-		}
+		case TEGRA_SIP_FIQ_NS_ENTRYPOINT:
 
-		/* new video memory carveout settings */
-		tegra_memctrl_videomem_setup(x1, x2);
+			if (x1 == 0U) {
+				SMC_RET1(handle, SMC_UNK);
+			}
 
-		SMC_RET1(handle, 0);
-		break;
+			/*
+			 * TODO: Check if x1 contains a valid DRAM address
+			 */
 
-	/*
-	 * The NS world registers the address of its handler to be
-	 * used for processing the FIQ. This is normally used by the
-	 * NS FIQ debugger driver to detect system hangs by programming
-	 * a watchdog timer to fire a FIQ interrupt.
-	 */
-	case TEGRA_SIP_FIQ_NS_ENTRYPOINT:
+			/* store the NS world's entrypoint */
+			tegra_fiq_set_ns_entrypoint(x1);
 
-		if (!x1)
-			SMC_RET1(handle, SMC_UNK);
+			SMC_RET1(handle, 0);
 
 		/*
-		 * TODO: Check if x1 contains a valid DRAM address
+		 * The NS world's FIQ handler issues this SMC to get the NS EL1/EL0
+		 * CPU context when the FIQ interrupt was triggered. This allows the
+		 * NS world to understand the CPU state when the watchdog interrupt
+		 * triggered.
 		 */
+		case TEGRA_SIP_FIQ_NS_GET_CONTEXT:
 
-		/* store the NS world's entrypoint */
-		tegra_fiq_set_ns_entrypoint(x1);
+			/* retrieve context registers when FIQ triggered */
+			(void)tegra_fiq_get_intr_context();
 
-		SMC_RET1(handle, 0);
-		break;
+			SMC_RET0(handle);
 
-	/*
-	 * The NS world's FIQ handler issues this SMC to get the NS EL1/EL0
-	 * CPU context when the FIQ interrupt was triggered. This allows the
-	 * NS world to understand the CPU state when the watchdog interrupt
-	 * triggered.
-	 */
-	case TEGRA_SIP_FIQ_NS_GET_CONTEXT:
+		case TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND:
+			/*
+			 * System suspend fake mode is set if we are on VDK and we make
+			 * a debug SIP call. This mode ensures that we excercise debug
+			 * path instead of the regular code path to suit the pre-silicon
+			 * platform needs. These include replacing the call to WFI by
+			 * a warm reset request.
+			 */
+			if (tegra_platform_is_virt_dev_kit() != false) {
 
-		/* retrieve context registers when FIQ triggered */
-		tegra_fiq_get_intr_context();
+				tegra_fake_system_suspend = 1;
+				SMC_RET1(handle, 0);
+			}
 
-		SMC_RET0(handle);
-		break;
+			/*
+			 * We return to the external world as if this SIP is not
+			 * implemented in case, we are not running on VDK.
+			 */
+			break;
 
-	case TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND:
-		/*
-		 * System suspend fake mode is set if we are on VDK and we make
-		 * a debug SIP call. This mode ensures that we excercise debug
-		 * path instead of the regular code path to suit the pre-silicon
-		 * platform needs. These include replacing the call to WFI by
-		 * a warm reset request.
-		 */
-		if (tegra_platform_is_emulation() != 0U) {
-
-			tegra_fake_system_suspend = 1;
-			SMC_RET1(handle, 0);
+		default:
+			ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
+			break;
 		}
-
-		/*
-		 * We return to the external world as if this SIP is not
-		 * implemented in case, we are not running on VDK.
-		 */
-		break;
-
-	default:
-		ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
-		break;
 	}
 
 	SMC_RET1(handle, SMC_UNK);
@@ -176,9 +185,9 @@
 DECLARE_RT_SVC(
 	tegra_sip_fast,
 
-	OEN_SIP_START,
-	OEN_SIP_END,
-	SMC_TYPE_FAST,
-	NULL,
-	tegra_sip_handler
+	(OEN_SIP_START),
+	(OEN_SIP_END),
+	(SMC_TYPE_FAST),
+	(NULL),
+	(tegra_sip_handler)
 );
diff --git a/plat/nvidia/tegra/common/tegra_topology.c b/plat/nvidia/tegra/common/tegra_topology.c
index 893f28f..14631a7 100644
--- a/plat/nvidia/tegra/common/tegra_topology.c
+++ b/plat/nvidia/tegra/common/tegra_topology.c
@@ -7,41 +7,42 @@
 #include <platform_def.h>
 
 #include <arch.h>
+#include <platform.h>
 #include <lib/psci/psci.h>
 
-extern const unsigned char tegra_power_domain_tree_desc[];
 #pragma weak plat_core_pos_by_mpidr
 
 /*******************************************************************************
- * This function returns the Tegra default topology tree information.
- ******************************************************************************/
-const unsigned char *plat_get_power_domain_tree_desc(void)
-{
-	return tegra_power_domain_tree_desc;
-}
-
-/*******************************************************************************
  * This function implements a part of the critical interface between the psci
  * generic layer and the platform that allows the former to query the platform
  * to convert an MPIDR to a unique linear index. An error code (-1) is returned
  * in case the MPIDR is invalid.
  ******************************************************************************/
-int plat_core_pos_by_mpidr(u_register_t mpidr)
+int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
 {
-	unsigned int cluster_id, cpu_id;
+	u_register_t cluster_id, cpu_id;
+	int32_t result;
 
-	cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
-	cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+	cluster_id = (mpidr >> (u_register_t)MPIDR_AFF1_SHIFT) &
+		     (u_register_t)MPIDR_AFFLVL_MASK;
+	cpu_id = (mpidr >> (u_register_t)MPIDR_AFF0_SHIFT) &
+		 (u_register_t)MPIDR_AFFLVL_MASK;
 
-	if (cluster_id >= PLATFORM_CLUSTER_COUNT)
-		return PSCI_E_NOT_PRESENT;
+	/* CorePos = CoreId + (ClusterId * cpus per cluster) */
+	result = (int32_t)cpu_id + ((int32_t)cluster_id *
+		 PLATFORM_MAX_CPUS_PER_CLUSTER);
+
+	if (cluster_id >= (u_register_t)PLATFORM_CLUSTER_COUNT) {
+		result = PSCI_E_NOT_PRESENT;
+	}
 
 	/*
 	 * Validate cpu_id by checking whether it represents a CPU in
 	 * one of the two clusters present on the platform.
 	 */
-	if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER)
-		return PSCI_E_NOT_PRESENT;
+	if (cpu_id >= (u_register_t)PLATFORM_MAX_CPUS_PER_CLUSTER) {
+		result = PSCI_E_NOT_PRESENT;
+	}
 
-	return (cpu_id + (cluster_id * 4));
+	return result;
 }
diff --git a/plat/nvidia/tegra/include/drivers/bpmp.h b/plat/nvidia/tegra/include/drivers/bpmp.h
new file mode 100644
index 0000000..03da6f6
--- /dev/null
+++ b/plat/nvidia/tegra/include/drivers/bpmp.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BPMP_H
+#define BPMP_H
+
+#include <stdint.h>
+
+/* macro to enable clock to the Atomics block */
+#define CAR_ENABLE_ATOMICS	(1U << 16)
+
+/* command to get the channel base addresses from bpmp */
+#define ATOMIC_CMD_GET		4U
+
+/* Hardware IRQ # used to signal bpmp of an incoming command */
+#define INT_SHR_SEM_OUTBOX_FULL	6U
+
+/* macros to decode the bpmp's state */
+#define CH_MASK(ch)		((uint32_t)0x3 << ((ch) * 2U))
+#define MA_FREE(ch)		((uint32_t)0x2 << ((ch) * 2U))
+#define MA_ACKD(ch)		((uint32_t)0x3 << ((ch) * 2U))
+
+/* response from bpmp to indicate it has powered up */
+#define SIGN_OF_LIFE		0xAAAAAAAAU
+
+/* flags to indicate bpmp driver's state */
+#define BPMP_INIT_COMPLETE	0xBEEFF00DU
+#define BPMP_INIT_PENDING	0xDEADBEEFU
+
+/* requests serviced by the bpmp */
+#define MRQ_PING		0
+#define MRQ_QUERY_TAG		1
+#define MRQ_DO_IDLE		2
+#define MRQ_TOLERATE_IDLE	3
+#define MRQ_MODULE_LOAD		4
+#define MRQ_MODULE_UNLOAD	5
+#define MRQ_SWITCH_CLUSTER	6
+#define MRQ_TRACE_MODIFY	7
+#define MRQ_WRITE_TRACE		8
+#define MRQ_THREADED_PING	9
+#define MRQ_CPUIDLE_USAGE	10
+#define MRQ_MODULE_MAIL		11
+#define MRQ_SCX_ENABLE		12
+#define MRQ_BPMPIDLE_USAGE	14
+#define MRQ_HEAP_USAGE		15
+#define MRQ_SCLK_SKIP_SET_RATE	16
+#define MRQ_ENABLE_SUSPEND	17
+#define MRQ_PASR_MASK		18
+#define MRQ_DEBUGFS		19
+#define MRQ_THERMAL		27
+
+/* Tegra PM states as known to BPMP */
+#define TEGRA_PM_CC1		9
+#define TEGRA_PM_CC4		12
+#define TEGRA_PM_CC6		14
+#define TEGRA_PM_CC7		15
+#define TEGRA_PM_SC1		17
+#define TEGRA_PM_SC2		18
+#define TEGRA_PM_SC3		19
+#define TEGRA_PM_SC4		20
+#define TEGRA_PM_SC7		23
+
+/* flag to indicate if entry into a CCx power state is allowed */
+#define BPMP_CCx_ALLOWED	0U
+
+/* number of communication channels to interact with the bpmp */
+#define NR_CHANNELS		4U
+
+/* flag to ask bpmp to acknowledge command packet */
+#define NO_ACK			(0U << 0U)
+#define DO_ACK			(1U << 0U)
+
+/* size of the command/response data */
+#define MSG_DATA_MAX_SZ		120U
+
+/**
+ * command/response packet to/from the bpmp
+ *
+ * command
+ * -------
+ * code: MRQ_* command
+ * flags: DO_ACK or NO_ACK
+ * data:
+ * 	[0] = cpu #
+ * 	[1] = cluster power state (TEGRA_PM_CCx)
+ * 	[2] = system power state (TEGRA_PM_SCx)
+ *
+ * response
+ * ---------
+ * code: error code
+ * flags: not used
+ * data:
+ * 	[0-3] = response value
+ */
+typedef struct mb_data {
+	int32_t code;
+	uint32_t flags;
+	uint8_t data[MSG_DATA_MAX_SZ];
+} mb_data_t;
+
+/**
+ * Function to initialise the interface with the bpmp
+ */
+int tegra_bpmp_init(void);
+
+/**
+ * Handler to send a MRQ_* command to the bpmp
+ */
+int32_t tegra_bpmp_send_receive_atomic(int mrq, const void *ob_data, int ob_sz,
+		void *ib_data, int ib_sz);
+
+#endif /* BPMP_H */
diff --git a/plat/nvidia/tegra/include/drivers/bpmp_ipc.h b/plat/nvidia/tegra/include/drivers/bpmp_ipc.h
new file mode 100644
index 0000000..9304150
--- /dev/null
+++ b/plat/nvidia/tegra/include/drivers/bpmp_ipc.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __BPMP_IPC_H__
+#define __BPMP_IPC_H__
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <utils_def.h>
+
+/**
+ * Currently supported reset identifiers
+ */
+#define TEGRA_RESET_ID_XUSB_PADCTL	U(114)
+#define TEGRA_RESET_ID_GPCDMA		U(70)
+
+/**
+ * Function to initialise the IPC with the bpmp
+ */
+int32_t tegra_bpmp_ipc_init(void);
+
+/**
+ * Handler to reset a module
+ */
+int32_t tegra_bpmp_ipc_reset_module(uint32_t rst_id);
+
+#endif /* __BPMP_IPC_H__ */
diff --git a/plat/nvidia/tegra/include/drivers/gpcdma.h b/plat/nvidia/tegra/include/drivers/gpcdma.h
new file mode 100644
index 0000000..fb5486a
--- /dev/null
+++ b/plat/nvidia/tegra/include/drivers/gpcdma.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __GPCDMA_H__
+#define __GPCDMA_H__
+
+#include <stdint.h>
+
+void tegra_gpcdma_memcpy(uint64_t dst_addr, uint64_t src_addr,
+			    uint32_t num_bytes);
+void tegra_gpcdma_zeromem(uint64_t dst_addr, uint32_t num_bytes);
+
+#endif /* __GPCDMA_H__ */
diff --git a/plat/nvidia/tegra/include/drivers/memctrl.h b/plat/nvidia/tegra/include/drivers/memctrl.h
index 17427cb..d5ef60d 100644
--- a/plat/nvidia/tegra/include/drivers/memctrl.h
+++ b/plat/nvidia/tegra/include/drivers/memctrl.h
@@ -13,5 +13,6 @@
 void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes);
 void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes);
 void tegra_memctrl_disable_ahb_redirection(void);
+void tegra_memctrl_clear_pending_interrupts(void);
 
 #endif /* MEMCTRL_H */
diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v2.h b/plat/nvidia/tegra/include/drivers/memctrl_v2.h
index 957ff54..f5b0ed4 100644
--- a/plat/nvidia/tegra/include/drivers/memctrl_v2.h
+++ b/plat/nvidia/tegra/include/drivers/memctrl_v2.h
@@ -11,172 +11,10 @@
 
 #ifndef __ASSEMBLY__
 
+#include <mmio.h>
 #include <stdint.h>
 
 /*******************************************************************************
- * StreamID to indicate no SMMU translations (requests to be steered on the
- * SMMU bypass path)
- ******************************************************************************/
-#define MC_STREAM_ID_MAX			0x7F
-
-/*******************************************************************************
- * Stream ID Override Config registers
- ******************************************************************************/
-#define MC_STREAMID_OVERRIDE_CFG_PTCR		0x000
-#define MC_STREAMID_OVERRIDE_CFG_AFIR		0x070
-#define MC_STREAMID_OVERRIDE_CFG_HDAR		0x0A8
-#define MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR	0x0B0
-#define MC_STREAMID_OVERRIDE_CFG_NVENCSRD	0x0E0
-#define MC_STREAMID_OVERRIDE_CFG_SATAR		0x0F8
-#define MC_STREAMID_OVERRIDE_CFG_MPCORER	0x138
-#define MC_STREAMID_OVERRIDE_CFG_NVENCSWR	0x158
-#define MC_STREAMID_OVERRIDE_CFG_AFIW		0x188
-#define MC_STREAMID_OVERRIDE_CFG_HDAW		0x1A8
-#define MC_STREAMID_OVERRIDE_CFG_MPCOREW	0x1C8
-#define MC_STREAMID_OVERRIDE_CFG_SATAW		0x1E8
-#define MC_STREAMID_OVERRIDE_CFG_ISPRA		0x220
-#define MC_STREAMID_OVERRIDE_CFG_ISPWA		0x230
-#define MC_STREAMID_OVERRIDE_CFG_ISPWB		0x238
-#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR	0x250
-#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW	0x258
-#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR	0x260
-#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW	0x268
-#define MC_STREAMID_OVERRIDE_CFG_TSECSRD	0x2A0
-#define MC_STREAMID_OVERRIDE_CFG_TSECSWR	0x2A8
-#define MC_STREAMID_OVERRIDE_CFG_GPUSRD		0x2C0
-#define MC_STREAMID_OVERRIDE_CFG_GPUSWR		0x2C8
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCRA	0x300
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAA	0x308
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCR		0x310
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAB	0x318
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCWA	0x320
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAA	0x328
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCW		0x330
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAB	0x338
-#define MC_STREAMID_OVERRIDE_CFG_VICSRD		0x360
-#define MC_STREAMID_OVERRIDE_CFG_VICSWR		0x368
-#define MC_STREAMID_OVERRIDE_CFG_VIW		0x390
-#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD	0x3C0
-#define MC_STREAMID_OVERRIDE_CFG_NVDECSWR	0x3C8
-#define MC_STREAMID_OVERRIDE_CFG_APER		0x3D0
-#define MC_STREAMID_OVERRIDE_CFG_APEW		0x3D8
-#define MC_STREAMID_OVERRIDE_CFG_NVJPGSRD	0x3F0
-#define MC_STREAMID_OVERRIDE_CFG_NVJPGSWR	0x3F8
-#define MC_STREAMID_OVERRIDE_CFG_SESRD		0x400
-#define MC_STREAMID_OVERRIDE_CFG_SESWR		0x408
-#define MC_STREAMID_OVERRIDE_CFG_ETRR		0x420
-#define MC_STREAMID_OVERRIDE_CFG_ETRW		0x428
-#define MC_STREAMID_OVERRIDE_CFG_TSECSRDB	0x430
-#define MC_STREAMID_OVERRIDE_CFG_TSECSWRB	0x438
-#define MC_STREAMID_OVERRIDE_CFG_GPUSRD2	0x440
-#define MC_STREAMID_OVERRIDE_CFG_GPUSWR2	0x448
-#define MC_STREAMID_OVERRIDE_CFG_AXISR		0x460
-#define MC_STREAMID_OVERRIDE_CFG_AXISW		0x468
-#define MC_STREAMID_OVERRIDE_CFG_EQOSR		0x470
-#define MC_STREAMID_OVERRIDE_CFG_EQOSW		0x478
-#define MC_STREAMID_OVERRIDE_CFG_UFSHCR		0x480
-#define MC_STREAMID_OVERRIDE_CFG_UFSHCW		0x488
-#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR	0x490
-#define MC_STREAMID_OVERRIDE_CFG_BPMPR		0x498
-#define MC_STREAMID_OVERRIDE_CFG_BPMPW		0x4A0
-#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAR	0x4A8
-#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAW	0x4B0
-#define MC_STREAMID_OVERRIDE_CFG_AONR		0x4B8
-#define MC_STREAMID_OVERRIDE_CFG_AONW		0x4C0
-#define MC_STREAMID_OVERRIDE_CFG_AONDMAR	0x4C8
-#define MC_STREAMID_OVERRIDE_CFG_AONDMAW	0x4D0
-#define MC_STREAMID_OVERRIDE_CFG_SCER		0x4D8
-#define MC_STREAMID_OVERRIDE_CFG_SCEW		0x4E0
-#define MC_STREAMID_OVERRIDE_CFG_SCEDMAR	0x4E8
-#define MC_STREAMID_OVERRIDE_CFG_SCEDMAW	0x4F0
-#define MC_STREAMID_OVERRIDE_CFG_APEDMAR	0x4F8
-#define MC_STREAMID_OVERRIDE_CFG_APEDMAW	0x500
-#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1	0x508
-#define MC_STREAMID_OVERRIDE_CFG_VICSRD1	0x510
-#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD1	0x518
-
-/*******************************************************************************
- * Macro to calculate Security cfg register addr from StreamID Override register
- ******************************************************************************/
-#define MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(addr) (addr + sizeof(uint32_t))
-
-/*******************************************************************************
- * Memory Controller transaction override config registers
- ******************************************************************************/
-#define MC_TXN_OVERRIDE_CONFIG_HDAR		0x10a8
-#define MC_TXN_OVERRIDE_CONFIG_BPMPW		0x14a0
-#define MC_TXN_OVERRIDE_CONFIG_PTCR		0x1000
-#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR	0x1490
-#define MC_TXN_OVERRIDE_CONFIG_EQOSW		0x1478
-#define MC_TXN_OVERRIDE_CONFIG_NVJPGSWR		0x13f8
-#define MC_TXN_OVERRIDE_CONFIG_ISPRA		0x1220
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAA		0x1328
-#define MC_TXN_OVERRIDE_CONFIG_VICSRD		0x1360
-#define MC_TXN_OVERRIDE_CONFIG_MPCOREW		0x11c8
-#define MC_TXN_OVERRIDE_CONFIG_GPUSRD		0x12c0
-#define MC_TXN_OVERRIDE_CONFIG_AXISR		0x1460
-#define MC_TXN_OVERRIDE_CONFIG_SCEDMAW		0x14f0
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCW		0x1330
-#define MC_TXN_OVERRIDE_CONFIG_EQOSR		0x1470
-#define MC_TXN_OVERRIDE_CONFIG_APEDMAR		0x14f8
-#define MC_TXN_OVERRIDE_CONFIG_NVENCSRD		0x10e0
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAB		0x1318
-#define MC_TXN_OVERRIDE_CONFIG_VICSRD1		0x1510
-#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAR		0x14a8
-#define MC_TXN_OVERRIDE_CONFIG_VIW		0x1390
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAA		0x1308
-#define MC_TXN_OVERRIDE_CONFIG_AXISW		0x1468
-#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVR	0x1260
-#define MC_TXN_OVERRIDE_CONFIG_UFSHCR		0x1480
-#define MC_TXN_OVERRIDE_CONFIG_TSECSWR		0x12a8
-#define MC_TXN_OVERRIDE_CONFIG_GPUSWR		0x12c8
-#define MC_TXN_OVERRIDE_CONFIG_SATAR		0x10f8
-#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTW	0x1258
-#define MC_TXN_OVERRIDE_CONFIG_TSECSWRB		0x1438
-#define MC_TXN_OVERRIDE_CONFIG_GPUSRD2		0x1440
-#define MC_TXN_OVERRIDE_CONFIG_SCEDMAR		0x14e8
-#define MC_TXN_OVERRIDE_CONFIG_GPUSWR2		0x1448
-#define MC_TXN_OVERRIDE_CONFIG_AONDMAW		0x14d0
-#define MC_TXN_OVERRIDE_CONFIG_APEDMAW		0x1500
-#define MC_TXN_OVERRIDE_CONFIG_AONW		0x14c0
-#define MC_TXN_OVERRIDE_CONFIG_HOST1XDMAR	0x10b0
-#define MC_TXN_OVERRIDE_CONFIG_ETRR		0x1420
-#define MC_TXN_OVERRIDE_CONFIG_SESWR		0x1408
-#define MC_TXN_OVERRIDE_CONFIG_NVJPGSRD		0x13f0
-#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD		0x13c0
-#define MC_TXN_OVERRIDE_CONFIG_TSECSRDB		0x1430
-#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAW		0x14b0
-#define MC_TXN_OVERRIDE_CONFIG_APER		0x13d0
-#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD1	0x1518
-#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTR	0x1250
-#define MC_TXN_OVERRIDE_CONFIG_ISPWA		0x1230
-#define MC_TXN_OVERRIDE_CONFIG_SESRD		0x1400
-#define MC_TXN_OVERRIDE_CONFIG_SCER		0x14d8
-#define MC_TXN_OVERRIDE_CONFIG_AONR		0x14b8
-#define MC_TXN_OVERRIDE_CONFIG_MPCORER		0x1138
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCWA		0x1320
-#define MC_TXN_OVERRIDE_CONFIG_HDAW		0x11a8
-#define MC_TXN_OVERRIDE_CONFIG_NVDECSWR		0x13c8
-#define MC_TXN_OVERRIDE_CONFIG_UFSHCW		0x1488
-#define MC_TXN_OVERRIDE_CONFIG_AONDMAR		0x14c8
-#define MC_TXN_OVERRIDE_CONFIG_SATAW		0x11e8
-#define MC_TXN_OVERRIDE_CONFIG_ETRW		0x1428
-#define MC_TXN_OVERRIDE_CONFIG_VICSWR		0x1368
-#define MC_TXN_OVERRIDE_CONFIG_NVENCSWR		0x1158
-#define MC_TXN_OVERRIDE_CONFIG_AFIR		0x1070
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAB		0x1338
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCRA		0x1300
-#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR1	0x1508
-#define MC_TXN_OVERRIDE_CONFIG_ISPWB		0x1238
-#define MC_TXN_OVERRIDE_CONFIG_BPMPR		0x1498
-#define MC_TXN_OVERRIDE_CONFIG_APEW		0x13d8
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCR		0x1310
-#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVW	0x1268
-#define MC_TXN_OVERRIDE_CONFIG_TSECSRD		0x12a0
-#define MC_TXN_OVERRIDE_CONFIG_AFIW		0x1188
-#define MC_TXN_OVERRIDE_CONFIG_SCEW		0x14e0
-
-/*******************************************************************************
  * Structure to hold the transaction override settings to use to override
  * client inputs
  ******************************************************************************/
@@ -210,12 +48,31 @@
 	int override_client_ns_flag;
 } mc_streamid_security_cfg_t;
 
-#define OVERRIDE_DISABLE				1
-#define OVERRIDE_ENABLE					0
-#define CLIENT_FLAG_SECURE				0
-#define CLIENT_FLAG_NON_SECURE				1
-#define CLIENT_INPUTS_OVERRIDE				1
-#define CLIENT_INPUTS_NO_OVERRIDE			0
+#define OVERRIDE_DISABLE				1U
+#define OVERRIDE_ENABLE					0U
+#define CLIENT_FLAG_SECURE				0U
+#define CLIENT_FLAG_NON_SECURE				1U
+#define CLIENT_INPUTS_OVERRIDE				1U
+#define CLIENT_INPUTS_NO_OVERRIDE			0U
+/*******************************************************************************
+ * StreamID to indicate no SMMU translations (requests to be steered on the
+ * SMMU bypass path)
+ ******************************************************************************/
+#define MC_STREAM_ID_MAX			0x7FU
+
+/*******************************************************************************
+ * Memory Controller SMMU Bypass config register
+ ******************************************************************************/
+#define MC_SMMU_BYPASS_CONFIG			0x1820U
+#define MC_SMMU_BYPASS_CTRL_MASK		0x3U
+#define MC_SMMU_BYPASS_CTRL_SHIFT		0U
+#define MC_SMMU_CTRL_TBU_BYPASS_ALL		(0U << MC_SMMU_BYPASS_CTRL_SHIFT)
+#define MC_SMMU_CTRL_TBU_RSVD			(1U << MC_SMMU_BYPASS_CTRL_SHIFT)
+#define MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID	(2U << MC_SMMU_BYPASS_CTRL_SHIFT)
+#define MC_SMMU_CTRL_TBU_BYPASS_NONE		(3U << MC_SMMU_BYPASS_CTRL_SHIFT)
+#define MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT	(1U << 31)
+#define MC_SMMU_BYPASS_CONFIG_SETTINGS		(MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT | \
+						 MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID)
 
 #define mc_make_sec_cfg(off, ns, ovrrd, access) \
 	{ \
@@ -237,178 +94,10 @@
 	uint32_t num_streamid_security_cfgs;
 	const mc_txn_override_cfg_t *txn_override_cfg;
 	uint32_t num_txn_override_cfgs;
+	void (*reconfig_mss_clients)(void);
+	void (*set_txn_overrides)(void);
 } tegra_mc_settings_t;
 
-#endif /* __ASSEMBLY__ */
-
-/*******************************************************************************
- * Memory Controller SMMU Bypass config register
- ******************************************************************************/
-#define MC_SMMU_BYPASS_CONFIG			0x1820
-#define MC_SMMU_BYPASS_CTRL_MASK		0x3
-#define MC_SMMU_BYPASS_CTRL_SHIFT		0
-#define MC_SMMU_CTRL_TBU_BYPASS_ALL		(0 << MC_SMMU_BYPASS_CTRL_SHIFT)
-#define MC_SMMU_CTRL_TBU_RSVD			(1 << MC_SMMU_BYPASS_CTRL_SHIFT)
-#define MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID	(2 << MC_SMMU_BYPASS_CTRL_SHIFT)
-#define MC_SMMU_CTRL_TBU_BYPASS_NONE		(3 << MC_SMMU_BYPASS_CTRL_SHIFT)
-#define MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT	(1 << 31)
-#define MC_SMMU_BYPASS_CONFIG_SETTINGS		(MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT | \
-						 MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID)
-
-#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_CGID	(1 << 0)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV	(2 << 4)
-#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_CLIENT	(1 << 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	0
-#define MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID	1
-#define MC_TXN_OVERRIDE_CGID_TAG_ZERO		2
-#define MC_TXN_OVERRIDE_CGID_TAG_ADR		3
-#define MC_TXN_OVERRIDE_CGID_TAG_MASK		3
-
-/*******************************************************************************
- * Memory Controller Reset Control registers
- ******************************************************************************/
-#define MC_CLIENT_HOTRESET_CTRL0			0x200
-#define  MC_CLIENT_HOTRESET_CTRL0_RESET_VAL		0
-#define  MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB		(1 << 0)
-#define  MC_CLIENT_HOTRESET_CTRL0_HC_FLUSH_ENB		(1 << 6)
-#define  MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB		(1 << 7)
-#define  MC_CLIENT_HOTRESET_CTRL0_ISP2_FLUSH_ENB	(1 << 8)
-#define  MC_CLIENT_HOTRESET_CTRL0_MPCORE_FLUSH_ENB	(1 << 9)
-#define  MC_CLIENT_HOTRESET_CTRL0_NVENC_FLUSH_ENB	(1 << 11)
-#define  MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB	(1 << 15)
-#define  MC_CLIENT_HOTRESET_CTRL0_VI_FLUSH_ENB		(1 << 17)
-#define  MC_CLIENT_HOTRESET_CTRL0_VIC_FLUSH_ENB		(1 << 18)
-#define  MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB	(1 << 19)
-#define  MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB	(1 << 20)
-#define  MC_CLIENT_HOTRESET_CTRL0_TSEC_FLUSH_ENB	(1 << 22)
-#define  MC_CLIENT_HOTRESET_CTRL0_SDMMC1A_FLUSH_ENB	(1 << 29)
-#define  MC_CLIENT_HOTRESET_CTRL0_SDMMC2A_FLUSH_ENB	(1 << 30)
-#define  MC_CLIENT_HOTRESET_CTRL0_SDMMC3A_FLUSH_ENB	(1 << 31)
-#define MC_CLIENT_HOTRESET_STATUS0			0x204
-#define MC_CLIENT_HOTRESET_CTRL1			0x970
-#define  MC_CLIENT_HOTRESET_CTRL1_RESET_VAL		0
-#define  MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB	(1 << 0)
-#define  MC_CLIENT_HOTRESET_CTRL1_GPU_FLUSH_ENB		(1 << 2)
-#define  MC_CLIENT_HOTRESET_CTRL1_NVDEC_FLUSH_ENB	(1 << 5)
-#define  MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB		(1 << 6)
-#define  MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB		(1 << 7)
-#define  MC_CLIENT_HOTRESET_CTRL1_NVJPG_FLUSH_ENB	(1 << 8)
-#define  MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB		(1 << 12)
-#define  MC_CLIENT_HOTRESET_CTRL1_TSECB_FLUSH_ENB	(1 << 13)
-#define  MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB	(1 << 18)
-#define  MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB	(1 << 19)
-#define  MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB	(1 << 20)
-#define  MC_CLIENT_HOTRESET_CTRL1_NVDISPLAY_FLUSH_ENB	(1 << 21)
-#define  MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB	(1 << 22)
-#define  MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB		(1 << 23)
-#define  MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB		(1 << 24)
-#define MC_CLIENT_HOTRESET_STATUS1			0x974
-
-/*******************************************************************************
- * Memory Controller's PCFIFO client configuration registers
- ******************************************************************************/
-#define MC_PCFIFO_CLIENT_CONFIG1			0xdd4
-#define  MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL		0x20000
-#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_UNORDERED	(0 << 17)
-#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_MASK	(1 << 17)
-#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_UNORDERED	(0 << 21)
-#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_MASK	(1 << 21)
-#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_UNORDERED (0 << 29)
-#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_MASK	(1 << 29)
-
-#define MC_PCFIFO_CLIENT_CONFIG2			0xdd8
-#define  MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL		0x20000
-#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_UNORDERED	(0 << 11)
-#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_MASK	(1 << 11)
-#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_UNORDERED	(0 << 13)
-#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_MASK	(1 << 13)
-
-#define MC_PCFIFO_CLIENT_CONFIG3			0xddc
-#define  MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL		0
-#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_UNORDERED	(0 << 7)
-#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_MASK	(1 << 7)
-
-#define MC_PCFIFO_CLIENT_CONFIG4		0xde0
-#define  MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL	0
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_UNORDERED (0 << 1)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_MASK	(1 << 1)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_UNORDERED	(0 << 5)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_MASK	(1 << 5)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_UNORDERED (0 << 13)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_MASK	(1 << 13)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_UNORDERED (0 << 15)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_MASK	(1 << 15)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_UNORDERED	(0 << 17)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_MASK	(1 << 17)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_UNORDERED	(0 << 22)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_MASK	(1 << 22)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_UNORDERED	(0 << 26)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_MASK	(1 << 26)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_UNORDERED	(0 << 30)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_MASK	(1 << 30)
-
-#define MC_PCFIFO_CLIENT_CONFIG5		0xbf4
-#define  MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL	0
-#define  MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_UNORDERED	(0 << 0)
-#define  MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_MASK	(1 << 0)
-
-/*******************************************************************************
- * Memory Controller's SMMU client configuration registers
- ******************************************************************************/
-#define MC_SMMU_CLIENT_CONFIG1				0x44
-#define  MC_SMMU_CLIENT_CONFIG1_RESET_VAL		0x20000
-#define  MC_SMMU_CLIENT_CONFIG1_AFIW_UNORDERED		(0 << 17)
-#define  MC_SMMU_CLIENT_CONFIG1_AFIW_MASK		(1 << 17)
-#define  MC_SMMU_CLIENT_CONFIG1_HDAW_UNORDERED		(0 << 21)
-#define  MC_SMMU_CLIENT_CONFIG1_HDAW_MASK		(1 << 21)
-#define  MC_SMMU_CLIENT_CONFIG1_SATAW_UNORDERED		(0 << 29)
-#define  MC_SMMU_CLIENT_CONFIG1_SATAW_MASK		(1 << 29)
-
-#define MC_SMMU_CLIENT_CONFIG2				0x48
-#define  MC_SMMU_CLIENT_CONFIG2_RESET_VAL		0x20000
-#define  MC_SMMU_CLIENT_CONFIG2_XUSB_HOSTW_UNORDERED	(0 << 11)
-#define  MC_SMMU_CLIENT_CONFIG2_XUSB_HOSTW_MASK		(1 << 11)
-#define  MC_SMMU_CLIENT_CONFIG2_XUSB_DEVW_UNORDERED	(0 << 13)
-#define  MC_SMMU_CLIENT_CONFIG2_XUSB_DEVW_MASK		(1 << 13)
-
-#define MC_SMMU_CLIENT_CONFIG3				0x4c
-#define  MC_SMMU_CLIENT_CONFIG3_RESET_VAL		0
-#define  MC_SMMU_CLIENT_CONFIG3_SDMMCWAB_UNORDERED	(0 << 7)
-#define  MC_SMMU_CLIENT_CONFIG3_SDMMCWAB_MASK		(1 << 7)
-
-#define MC_SMMU_CLIENT_CONFIG4				0xb9c
-#define  MC_SMMU_CLIENT_CONFIG4_RESET_VAL		0
-#define  MC_SMMU_CLIENT_CONFIG4_SESWR_UNORDERED		(0 << 1)
-#define  MC_SMMU_CLIENT_CONFIG4_SESWR_MASK		(1 << 1)
-#define  MC_SMMU_CLIENT_CONFIG4_ETRW_UNORDERED		(0 << 5)
-#define  MC_SMMU_CLIENT_CONFIG4_ETRW_MASK		(1 << 5)
-#define  MC_SMMU_CLIENT_CONFIG4_AXISW_UNORDERED		(0 << 13)
-#define  MC_SMMU_CLIENT_CONFIG4_AXISW_MASK		(1 << 13)
-#define  MC_SMMU_CLIENT_CONFIG4_EQOSW_UNORDERED		(0 << 15)
-#define  MC_SMMU_CLIENT_CONFIG4_EQOSW_MASK		(1 << 15)
-#define  MC_SMMU_CLIENT_CONFIG4_UFSHCW_UNORDERED	(0 << 17)
-#define  MC_SMMU_CLIENT_CONFIG4_UFSHCW_MASK		(1 << 17)
-#define  MC_SMMU_CLIENT_CONFIG4_BPMPDMAW_UNORDERED	(0 << 22)
-#define  MC_SMMU_CLIENT_CONFIG4_BPMPDMAW_MASK		(1 << 22)
-#define  MC_SMMU_CLIENT_CONFIG4_AONDMAW_UNORDERED	(0 << 26)
-#define  MC_SMMU_CLIENT_CONFIG4_AONDMAW_MASK		(1 << 26)
-#define  MC_SMMU_CLIENT_CONFIG4_SCEDMAW_UNORDERED	(0 << 30)
-#define  MC_SMMU_CLIENT_CONFIG4_SCEDMAW_MASK		(1 << 30)
-
-#define MC_SMMU_CLIENT_CONFIG5				0xbac
-#define  MC_SMMU_CLIENT_CONFIG5_RESET_VAL		0
-#define  MC_SMMU_CLIENT_CONFIG5_APEDMAW_UNORDERED	(0 << 0)
-#define  MC_SMMU_CLIENT_CONFIG5_APEDMAW_MASK	(1 << 0)
-
-#ifndef __ASSEMBLY__
-
-#include <lib/mmio.h>
-
 static inline uint32_t tegra_mc_read_32(uint32_t off)
 {
 	return mmio_read_32(TEGRA_MC_BASE + off);
@@ -430,40 +119,43 @@
 }
 
 #define mc_set_pcfifo_unordered_boot_so_mss(id, client) \
-	(~MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_MASK | \
+	((uint32_t)~MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_MASK | \
 	 MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_UNORDERED)
 
-#define mc_set_smmu_unordered_boot_so_mss(id, client) \
-	(~MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_MASK | \
-	 MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_UNORDERED)
+#define mc_set_pcfifo_ordered_boot_so_mss(id, client) \
+	 MC_PCFIFO_CLIENT_CONFIG##id##_PCFIFO_##client##_ORDERED
 
 #define mc_set_tsa_passthrough(client) \
 	{ \
 		mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \
 			(TSA_CONFIG_STATIC0_CSW_##client##_RESET & \
-			 ~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \
-			TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
+			 (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \
+			(uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
 	}
 
-#define mc_set_forced_coherent_cfg(client) \
+#define mc_set_tsa_w_passthrough(client) \
 	{ \
-		tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_##client, \
-			MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV); \
+		mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \
+			(TSA_CONFIG_STATIC0_CSW_RESET_W & \
+			 (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \
+			(uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
 	}
 
-#define mc_set_forced_coherent_so_dev_cfg(client) \
+#define mc_set_tsa_r_passthrough(client) \
 	{ \
-		tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_##client, \
-			MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV | \
-			MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_CLIENT); \
+		mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSR_##client, \
+			(TSA_CONFIG_STATIC0_CSR_RESET_R & \
+			 (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \
+			(uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
 	}
 
-#define mc_set_forced_coherent_axid_so_dev_cfg(client) \
+#define mc_set_txn_override(client, normal_axi_id, so_dev_axi_id, normal_override, so_dev_override) \
 	{ \
 		tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_##client, \
-			MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV | \
-			MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_CGID | \
-			MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_CLIENT); \
+				  MC_TXN_OVERRIDE_##normal_axi_id | \
+				  MC_TXN_OVERRIDE_CONFIG_COH_PATH_##so_dev_override##_SO_DEV | \
+				  MC_TXN_OVERRIDE_CONFIG_COH_PATH_##normal_override##_NORMAL | \
+				  MC_TXN_OVERRIDE_CONFIG_CGID_##so_dev_axi_id); \
 	}
 
 /*******************************************************************************
@@ -473,6 +165,14 @@
  ******************************************************************************/
 tegra_mc_settings_t *tegra_get_mc_settings(void);
 
+/*******************************************************************************
+ * Handler to program the scratch registers with TZDRAM settings for the
+ * resume firmware.
+ *
+ * Implemented by SoCs under tegra/soc/txxx
+ ******************************************************************************/
+void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes);
+
-#endif /* __ASSMEBLY__ */
+#endif /* __ASSEMBLY__ */
 
 #endif /* MEMCTRL_V2_H */
diff --git a/plat/nvidia/tegra/include/drivers/security_engine.h b/plat/nvidia/tegra/include/drivers/security_engine.h
new file mode 100644
index 0000000..4ab2f9a
--- /dev/null
+++ b/plat/nvidia/tegra/include/drivers/security_engine.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SECURITY_ENGINE_H
+#define SECURITY_ENGINE_H
+
+/*******************************************************************************
+ * Structure definition
+ ******************************************************************************/
+
+/* Security Engine Linked List */
+struct tegra_se_ll {
+	/* DMA buffer address */
+	uint32_t addr;
+	/* Data length in DMA buffer */
+	uint32_t data_len;
+};
+
+#define SE_LL_MAX_BUFFER_NUM			4
+typedef struct tegra_se_io_lst {
+	volatile uint32_t last_buff_num;
+	volatile struct tegra_se_ll buffer[SE_LL_MAX_BUFFER_NUM];
+} tegra_se_io_lst_t __attribute__((aligned(4)));
+
+/* SE device structure */
+typedef struct tegra_se_dev {
+	/* Security Engine ID */
+	const int se_num;
+	/* SE base address */
+	const uint64_t se_base;
+	/* SE context size in AES blocks */
+	const uint32_t ctx_size_blks;
+	/* pointer to source linked list buffer */
+	tegra_se_io_lst_t *src_ll_buf;
+	/* pointer to destination linked list buffer */
+	tegra_se_io_lst_t *dst_ll_buf;
+	/* LP context buffer pointer */
+	uint32_t *ctx_save_buf;
+} tegra_se_dev_t;
+
+/* PKA1 device structure */
+typedef struct tegra_pka_dev {
+	/* PKA1 base address */
+	uint64_t pka_base;
+} tegra_pka_dev_t;
+
+/*******************************************************************************
+ * Public interface
+ ******************************************************************************/
+void tegra_se_init(void);
+int tegra_se_suspend(void);
+void tegra_se_resume(void);
+int tegra_se_save_tzram(void);
+
+#endif /* SECURITY_ENGINE_H */
diff --git a/plat/nvidia/tegra/include/drivers/smmu.h b/plat/nvidia/tegra/include/drivers/smmu.h
index 9582a67..41b0c51 100644
--- a/plat/nvidia/tegra/include/drivers/smmu.h
+++ b/plat/nvidia/tegra/include/drivers/smmu.h
@@ -586,12 +586,12 @@
 /*******************************************************************************
  * SMMU Global Aux. Control Register
  ******************************************************************************/
-#define SMMU_CBn_ACTLR_CPRE_BIT			(1U << 1)
+#define SMMU_CBn_ACTLR_CPRE_BIT			(1ULL << 1U)
 
 /*******************************************************************************
  * SMMU configuration constants
  ******************************************************************************/
-#define ID1_PAGESIZE				(1U << 31)
+#define ID1_PAGESIZE				(1U << 31U)
 #define ID1_NUMPAGENDXB_SHIFT			28U
 #define ID1_NUMPAGENDXB_MASK			7U
 #define ID1_NUMS2CB_SHIFT			16U
@@ -705,5 +705,6 @@
 void tegra_smmu_init(void);
 void tegra_smmu_save_context(uint64_t smmu_ctx_addr);
 smmu_regs_t *plat_get_smmu_ctx(void);
+uint32_t plat_get_num_smmu_devices(void);
 
 #endif /* SMMU_H */
diff --git a/plat/nvidia/tegra/include/lib/profiler.h b/plat/nvidia/tegra/include/lib/profiler.h
new file mode 100644
index 0000000..60f8d80
--- /dev/null
+++ b/plat/nvidia/tegra/include/lib/profiler.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PROFILER_H__
+#define __PROFILER_H__
+
+/*******************************************************************************
+ * Number of bytes of memory used by the profiler on Tegra
+ ******************************************************************************/
+#define PROFILER_SIZE_BYTES	U(0x1000)
+
+void boot_profiler_init(uint64_t shmem_base, uint32_t tmr_base);
+void boot_profiler_add_record(const char *str);
+void boot_profiler_deinit(void);
+
+#endif /* __PROFILER_H__ */
diff --git a/plat/nvidia/tegra/include/platform_def.h b/plat/nvidia/tegra/include/platform_def.h
index d10dc26..0a0126b 100644
--- a/plat/nvidia/tegra/include/platform_def.h
+++ b/plat/nvidia/tegra/include/platform_def.h
@@ -34,7 +34,8 @@
  * Platform console related constants
  ******************************************************************************/
 #define TEGRA_CONSOLE_BAUDRATE		U(115200)
-#define TEGRA_BOOT_UART_CLK_IN_HZ	U(408000000)
+#define TEGRA_BOOT_UART_CLK_13_MHZ	U(13000000)
+#define TEGRA_BOOT_UART_CLK_408_MHZ	U(408000000)
 
 /*******************************************************************************
  * Platform memory map related constants
diff --git a/plat/nvidia/tegra/include/t132/tegra_def.h b/plat/nvidia/tegra/include/t132/tegra_def.h
index 1f58caa..fd75fbc 100644
--- a/plat/nvidia/tegra/include/t132/tegra_def.h
+++ b/plat/nvidia/tegra/include/t132/tegra_def.h
@@ -83,6 +83,9 @@
  ******************************************************************************/
 #define TEGRA_MC_BASE			U(0x70019000)
 
+/* Memory Controller Interrupt Status */
+#define MC_INTSTATUS			0x00U
+
 /* TZDRAM carveout configuration registers */
 #define MC_SECURITY_CFG0_0		U(0x70)
 #define MC_SECURITY_CFG1_0		U(0x74)
diff --git a/plat/nvidia/tegra/include/t186/tegra186_private.h b/plat/nvidia/tegra/include/t186/tegra186_private.h
new file mode 100644
index 0000000..9e2c02b
--- /dev/null
+++ b/plat/nvidia/tegra/include/t186/tegra186_private.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TEGRA186_PRIVATE_H
+#define TEGRA186_PRIVATE_H
+
+void tegra186_cpu_reset_handler(void);
+uint64_t tegra186_get_cpu_reset_handler_base(void);
+uint64_t tegra186_get_cpu_reset_handler_size(void);
+uint64_t tegra186_get_smmu_ctx_offset(void);
+void tegra186_set_system_suspend_entry(void);
+
+#endif /* TEGRA186_PRIVATE_H */
diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h
index 3abba55..231f93a 100644
--- a/plat/nvidia/tegra/include/t186/tegra_def.h
+++ b/plat/nvidia/tegra/include/t186/tegra_def.h
@@ -112,10 +112,15 @@
 #define TSA_CONFIG_STATIC0_CSW_XUSB_HOSTW		U(0x15018)
 #define  TSA_CONFIG_STATIC0_CSW_XUSB_HOSTW_RESET	U(0x1100)
 
-#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK		(U(0x3) << 11)
-#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU		(U(0) << 11)
+#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK		(ULL(0x3) << 11)
+#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU		(ULL(0) << 11)
 
 /*******************************************************************************
+ * Tegra General Purpose Centralised DMA constants
+ ******************************************************************************/
+#define TEGRA_GPCDMA_BASE		ULL(0x2610000)
+
+/*******************************************************************************
  * Tegra Memory Controller constants
  ******************************************************************************/
 #define TEGRA_MC_STREAMID_BASE		U(0x02C00000)
@@ -124,18 +129,23 @@
 /* General Security Carveout register macros */
 #define MC_GSC_CONFIG_REGS_SIZE		U(0x40)
 #define MC_GSC_LOCK_CFG_SETTINGS_BIT	(U(1) << 1)
-#define MC_GSC_ENABLE_TZ_LOCK_BIT	(U(1) << 0)
+#define MC_GSC_ENABLE_TZ_LOCK_BIT	(ULL(1) << 0)
 #define MC_GSC_SIZE_RANGE_4KB_SHIFT	U(27)
 #define MC_GSC_BASE_LO_SHIFT		U(12)
 #define MC_GSC_BASE_LO_MASK		U(0xFFFFF)
 #define MC_GSC_BASE_HI_SHIFT		U(0)
 #define MC_GSC_BASE_HI_MASK		U(3)
+#define MC_GSC_ENABLE_CPU_SECURE_BIT    (U(1) << 31)
 
 /* TZDRAM carveout configuration registers */
 #define MC_SECURITY_CFG0_0		U(0x70)
 #define MC_SECURITY_CFG1_0		U(0x74)
 #define MC_SECURITY_CFG3_0		U(0x9BC)
 
+#define MC_SECURITY_BOM_MASK		(U(0xFFF) << 20)
+#define MC_SECURITY_SIZE_MB_MASK	(U(0x1FFF) << 0)
+#define MC_SECURITY_BOM_HI_MASK		(U(0x3) << 0)
+
 /* Video Memory carveout configuration registers */
 #define MC_VIDEO_PROTECT_BASE_HI	U(0x978)
 #define MC_VIDEO_PROTECT_BASE_LO	U(0x648)
@@ -156,7 +166,10 @@
 #define MC_TZRAM_BASE_LO		U(0x2194)
 #define MC_TZRAM_BASE_HI		U(0x2198)
 #define MC_TZRAM_SIZE			U(0x219C)
-#define MC_TZRAM_CLIENT_ACCESS_CFG0	U(0x21A0)
+#define MC_TZRAM_CLIENT_ACCESS0_CFG0	U(0x21A0)
+#define MC_TZRAM_CLIENT_ACCESS1_CFG0	U(0x21A4)
+#define  TZRAM_ALLOW_MPCORER		(U(1) << 7)
+#define  TZRAM_ALLOW_MPCOREW		(U(1) << 25)
 
 /*******************************************************************************
  * Tegra UART Controller constants
@@ -198,6 +211,8 @@
 #define TEGRA_CAR_RESET_BASE		U(0x05000000)
 #define TEGRA_GPU_RESET_REG_OFFSET	U(0x30)
 #define  GPU_RESET_BIT			(U(1) << 0)
+#define TEGRA_GPCDMA_RST_SET_REG_OFFSET	U(0x6A0004)
+#define TEGRA_GPCDMA_RST_CLR_REG_OFFSET	U(0x6A0008)
 
 /*******************************************************************************
  * Tegra micro-seconds timer constants
@@ -221,10 +236,19 @@
 #define  SECURE_SCRATCH_RSV11_HI	U(0x6AC)
 #define  SECURE_SCRATCH_RSV53_LO	U(0x7F8)
 #define  SECURE_SCRATCH_RSV53_HI	U(0x7FC)
-#define  SECURE_SCRATCH_RSV54_HI	U(0x804)
 #define  SECURE_SCRATCH_RSV55_LO	U(0x808)
 #define  SECURE_SCRATCH_RSV55_HI	U(0x80C)
 
+#define SCRATCH_RESET_VECTOR_LO		SECURE_SCRATCH_RSV1_LO
+#define SCRATCH_RESET_VECTOR_HI		SECURE_SCRATCH_RSV1_HI
+#define SCRATCH_SECURE_BOOTP_FCFG	SECURE_SCRATCH_RSV6
+#define SCRATCH_SMMU_TABLE_ADDR_LO	SECURE_SCRATCH_RSV11_LO
+#define SCRATCH_SMMU_TABLE_ADDR_HI	SECURE_SCRATCH_RSV11_HI
+#define SCRATCH_BL31_PARAMS_ADDR	SECURE_SCRATCH_RSV53_LO
+#define SCRATCH_BL31_PLAT_PARAMS_ADDR	SECURE_SCRATCH_RSV53_HI
+#define SCRATCH_TZDRAM_ADDR_LO		SECURE_SCRATCH_RSV55_LO
+#define SCRATCH_TZDRAM_ADDR_HI		SECURE_SCRATCH_RSV55_HI
+
 /*******************************************************************************
  * Tegra Memory Mapped Control Register Access constants
  ******************************************************************************/
diff --git a/plat/nvidia/tegra/include/t186/tegra_mc_def.h b/plat/nvidia/tegra/include/t186/tegra_mc_def.h
new file mode 100644
index 0000000..d051a15
--- /dev/null
+++ b/plat/nvidia/tegra/include/t186/tegra_mc_def.h
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TEGRA_MC_DEF_H
+#define TEGRA_MC_DEF_H
+
+/*******************************************************************************
+ * 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			0x20000U
+#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_MASK		(1U << 29)
+
+#define MC_PCFIFO_CLIENT_CONFIG2				0xdd8U
+#define  MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL			0x20000U
+#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_MASK		(1U << 13)
+
+#define MC_PCFIFO_CLIENT_CONFIG3				0xddcU
+#define  MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL			0U
+#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_UNORDERED	(0U << 7)
+#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_MASK		(1U << 7)
+
+#define MC_PCFIFO_CLIENT_CONFIG4				0xde0U
+#define  MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL			0U
+#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_AXISW_UNORDERED 	(0U << 13)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_MASK		(1U << 13)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_UNORDERED 	(0U << 15)
+#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_BPMPDMAW_UNORDERED	(0U << 22)
+#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_MASK		(1U << 22)
+#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_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			0U
+#define  MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_UNORDERED	(0U << 0)
+#define  MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_MASK		(1U << 0)
+
+/*******************************************************************************
+ * Stream ID Override Config registers
+ ******************************************************************************/
+#define MC_STREAMID_OVERRIDE_CFG_PTCR				0x000U
+#define MC_STREAMID_OVERRIDE_CFG_AFIR				0x070U
+#define MC_STREAMID_OVERRIDE_CFG_HDAR				0x0A8U
+#define MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR			0x0B0U
+#define MC_STREAMID_OVERRIDE_CFG_NVENCSRD			0x0E0U
+#define MC_STREAMID_OVERRIDE_CFG_SATAR				0x0F8U
+#define MC_STREAMID_OVERRIDE_CFG_MPCORER			0x138U
+#define MC_STREAMID_OVERRIDE_CFG_NVENCSWR			0x158U
+#define MC_STREAMID_OVERRIDE_CFG_AFIW				0x188U
+#define MC_STREAMID_OVERRIDE_CFG_HDAW				0x1A8U
+#define MC_STREAMID_OVERRIDE_CFG_MPCOREW			0x1C8U
+#define MC_STREAMID_OVERRIDE_CFG_SATAW				0x1E8U
+#define MC_STREAMID_OVERRIDE_CFG_ISPRA				0x220U
+#define MC_STREAMID_OVERRIDE_CFG_ISPWA				0x230U
+#define MC_STREAMID_OVERRIDE_CFG_ISPWB				0x238U
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR			0x250U
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW			0x258U
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR			0x260U
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW			0x268U
+#define MC_STREAMID_OVERRIDE_CFG_TSECSRD			0x2A0U
+#define MC_STREAMID_OVERRIDE_CFG_TSECSWR			0x2A8U
+#define MC_STREAMID_OVERRIDE_CFG_GPUSRD				0x2C0U
+#define MC_STREAMID_OVERRIDE_CFG_GPUSWR				0x2C8U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCRA			0x300U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAA			0x308U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCR				0x310U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAB			0x318U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCWA			0x320U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAA			0x328U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCW				0x330U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAB			0x338U
+#define MC_STREAMID_OVERRIDE_CFG_VICSRD				0x360U
+#define MC_STREAMID_OVERRIDE_CFG_VICSWR				0x368U
+#define MC_STREAMID_OVERRIDE_CFG_VIW				0x390U
+#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD			0x3C0U
+#define MC_STREAMID_OVERRIDE_CFG_NVDECSWR			0x3C8U
+#define MC_STREAMID_OVERRIDE_CFG_APER				0x3D0U
+#define MC_STREAMID_OVERRIDE_CFG_APEW				0x3D8U
+#define MC_STREAMID_OVERRIDE_CFG_NVJPGSRD			0x3F0U
+#define MC_STREAMID_OVERRIDE_CFG_NVJPGSWR			0x3F8U
+#define MC_STREAMID_OVERRIDE_CFG_SESRD				0x400U
+#define MC_STREAMID_OVERRIDE_CFG_SESWR				0x408U
+#define MC_STREAMID_OVERRIDE_CFG_ETRR				0x420U
+#define MC_STREAMID_OVERRIDE_CFG_ETRW				0x428U
+#define MC_STREAMID_OVERRIDE_CFG_TSECSRDB			0x430U
+#define MC_STREAMID_OVERRIDE_CFG_TSECSWRB			0x438U
+#define MC_STREAMID_OVERRIDE_CFG_GPUSRD2			0x440U
+#define MC_STREAMID_OVERRIDE_CFG_GPUSWR2			0x448U
+#define MC_STREAMID_OVERRIDE_CFG_AXISR				0x460U
+#define MC_STREAMID_OVERRIDE_CFG_AXISW				0x468U
+#define MC_STREAMID_OVERRIDE_CFG_EQOSR				0x470U
+#define MC_STREAMID_OVERRIDE_CFG_EQOSW				0x478U
+#define MC_STREAMID_OVERRIDE_CFG_UFSHCR				0x480U
+#define MC_STREAMID_OVERRIDE_CFG_UFSHCW				0x488U
+#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR			0x490U
+#define MC_STREAMID_OVERRIDE_CFG_BPMPR				0x498U
+#define MC_STREAMID_OVERRIDE_CFG_BPMPW				0x4A0U
+#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAR			0x4A8U
+#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAW			0x4B0U
+#define MC_STREAMID_OVERRIDE_CFG_AONR				0x4B8U
+#define MC_STREAMID_OVERRIDE_CFG_AONW				0x4C0U
+#define MC_STREAMID_OVERRIDE_CFG_AONDMAR			0x4C8U
+#define MC_STREAMID_OVERRIDE_CFG_AONDMAW			0x4D0U
+#define MC_STREAMID_OVERRIDE_CFG_SCER				0x4D8U
+#define MC_STREAMID_OVERRIDE_CFG_SCEW				0x4E0U
+#define MC_STREAMID_OVERRIDE_CFG_SCEDMAR			0x4E8U
+#define MC_STREAMID_OVERRIDE_CFG_SCEDMAW			0x4F0U
+#define MC_STREAMID_OVERRIDE_CFG_APEDMAR			0x4F8U
+#define MC_STREAMID_OVERRIDE_CFG_APEDMAW			0x500U
+#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1			0x508U
+#define MC_STREAMID_OVERRIDE_CFG_VICSRD1			0x510U
+#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD1			0x518U
+
+/*******************************************************************************
+ * 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_BPMPW				0x14a0U
+#define MC_TXN_OVERRIDE_CONFIG_PTCR				0x1000U
+#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR			0x1490U
+#define MC_TXN_OVERRIDE_CONFIG_EQOSW				0x1478U
+#define MC_TXN_OVERRIDE_CONFIG_NVJPGSWR				0x13f8U
+#define MC_TXN_OVERRIDE_CONFIG_ISPRA				0x1220U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAA				0x1328U
+#define MC_TXN_OVERRIDE_CONFIG_VICSRD				0x1360U
+#define MC_TXN_OVERRIDE_CONFIG_MPCOREW				0x11c8U
+#define MC_TXN_OVERRIDE_CONFIG_GPUSRD				0x12c0U
+#define MC_TXN_OVERRIDE_CONFIG_AXISR				0x1460U
+#define MC_TXN_OVERRIDE_CONFIG_SCEDMAW				0x14f0U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCW				0x1330U
+#define MC_TXN_OVERRIDE_CONFIG_EQOSR				0x1470U
+#define MC_TXN_OVERRIDE_CONFIG_APEDMAR				0x14f8U
+#define MC_TXN_OVERRIDE_CONFIG_NVENCSRD				0x10e0U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAB				0x1318U
+#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_SDMMCRAA				0x1308U
+#define MC_TXN_OVERRIDE_CONFIG_AXISW				0x1468U
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVR			0x1260U
+#define MC_TXN_OVERRIDE_CONFIG_UFSHCR				0x1480U
+#define MC_TXN_OVERRIDE_CONFIG_TSECSWR				0x12a8U
+#define MC_TXN_OVERRIDE_CONFIG_GPUSWR				0x12c8U
+#define MC_TXN_OVERRIDE_CONFIG_SATAR				0x10f8U
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTW			0x1258U
+#define MC_TXN_OVERRIDE_CONFIG_TSECSWRB				0x1438U
+#define MC_TXN_OVERRIDE_CONFIG_GPUSRD2				0x1440U
+#define MC_TXN_OVERRIDE_CONFIG_SCEDMAR				0x14e8U
+#define MC_TXN_OVERRIDE_CONFIG_GPUSWR2				0x1448U
+#define MC_TXN_OVERRIDE_CONFIG_AONDMAW				0x14d0U
+#define MC_TXN_OVERRIDE_CONFIG_APEDMAW				0x1500U
+#define MC_TXN_OVERRIDE_CONFIG_AONW				0x14c0U
+#define MC_TXN_OVERRIDE_CONFIG_HOST1XDMAR			0x10b0U
+#define MC_TXN_OVERRIDE_CONFIG_ETRR				0x1420U
+#define MC_TXN_OVERRIDE_CONFIG_SESWR				0x1408U
+#define MC_TXN_OVERRIDE_CONFIG_NVJPGSRD				0x13f0U
+#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD				0x13c0U
+#define MC_TXN_OVERRIDE_CONFIG_TSECSRDB				0x1430U
+#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAW				0x14b0U
+#define MC_TXN_OVERRIDE_CONFIG_APER				0x13d0U
+#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD1			0x1518U
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTR			0x1250U
+#define MC_TXN_OVERRIDE_CONFIG_ISPWA				0x1230U
+#define MC_TXN_OVERRIDE_CONFIG_SESRD				0x1400U
+#define MC_TXN_OVERRIDE_CONFIG_SCER				0x14d8U
+#define MC_TXN_OVERRIDE_CONFIG_AONR				0x14b8U
+#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_UFSHCW				0x1488U
+#define MC_TXN_OVERRIDE_CONFIG_AONDMAR				0x14c8U
+#define MC_TXN_OVERRIDE_CONFIG_SATAW				0x11e8U
+#define MC_TXN_OVERRIDE_CONFIG_ETRW				0x1428U
+#define MC_TXN_OVERRIDE_CONFIG_VICSWR				0x1368U
+#define MC_TXN_OVERRIDE_CONFIG_NVENCSWR				0x1158U
+#define MC_TXN_OVERRIDE_CONFIG_AFIR				0x1070U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAB				0x1338U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCRA				0x1300U
+#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR1			0x1508U
+#define MC_TXN_OVERRIDE_CONFIG_ISPWB				0x1238U
+#define MC_TXN_OVERRIDE_CONFIG_BPMPR				0x1498U
+#define MC_TXN_OVERRIDE_CONFIG_APEW				0x13d8U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCR				0x1310U
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVW			0x1268U
+#define MC_TXN_OVERRIDE_CONFIG_TSECSRD				0x12a0U
+#define MC_TXN_OVERRIDE_CONFIG_AFIW				0x1188U
+#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 << 18)
+#define  MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB		(1U << 19)
+#define  MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB		(1U << 20)
+#define  MC_CLIENT_HOTRESET_CTRL1_NVDISPLAY_FLUSH_ENB		(1U << 21)
+#define  MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB		(1U << 22)
+#define  MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB			(1U << 23)
+#define  MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB			(1U << 24)
+#define MC_CLIENT_HOTRESET_STATUS1				0x974U
+
+#endif /* TEGRA_MC_DEF_H */
diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h
index 14cdfd5..75919e1 100644
--- a/plat/nvidia/tegra/include/t210/tegra_def.h
+++ b/plat/nvidia/tegra/include/t210/tegra_def.h
@@ -33,6 +33,11 @@
 #define PLAT_MAX_OFF_STATE		(PSTATE_ID_SOC_POWERDN + U(1))
 
 /*******************************************************************************
+ * iRAM memory constants
+ ******************************************************************************/
+#define TEGRA_IRAM_BASE			0x40000000
+
+/*******************************************************************************
  * GIC memory map
  ******************************************************************************/
 #define TEGRA_GICD_BASE			U(0x50041000)
@@ -56,6 +61,20 @@
 					 ENABLE_WRAP_INCR_MASTER0_BIT)
 
 /*******************************************************************************
+ * Tegra Resource Semaphore constants
+ ******************************************************************************/
+#define TEGRA_RES_SEMA_BASE		0x60001000UL
+#define  STA_OFFSET			0UL
+#define  SET_OFFSET			4UL
+#define  CLR_OFFSET			8UL
+
+/*******************************************************************************
+ * Tegra Primary Interrupt Controller constants
+ ******************************************************************************/
+#define TEGRA_PRI_ICTLR_BASE		0x60004000UL
+#define  CPU_IEP_FIR_SET		0x18UL
+
+/*******************************************************************************
  * Tegra micro-seconds timer constants
  ******************************************************************************/
 #define TEGRA_TMRUS_BASE		U(0x60005010)
@@ -67,6 +86,18 @@
 #define TEGRA_CAR_RESET_BASE		U(0x60006000)
 #define TEGRA_GPU_RESET_REG_OFFSET	U(0x28C)
 #define  GPU_RESET_BIT			(U(1) << 24)
+#define TEGRA_RST_DEV_CLR_V		U(0x434)
+#define TEGRA_CLK_ENB_V			U(0x440)
+
+/* SE Clock Offsets */
+#define TEGRA_RST_DEVICES_V		0x358UL
+#define  SE_RESET_BIT 			(0x1UL << 31)
+#define TEGRA_RST_DEVICES_W		 0x35CUL
+#define  ENTROPY_CLK_ENB_BIT		(0x1UL << 21)
+#define TEGRA_CLK_OUT_ENB_V		0x360UL
+#define  SE_CLK_ENB_BIT			(0x1UL << 31)
+#define TEGRA_CLK_OUT_ENB_W		0x364UL
+#define  ENTROPY_RESET_BIT 		(0x1UL << 21)
 
 /*******************************************************************************
  * Tegra Flow Controller constants
@@ -74,6 +105,11 @@
 #define TEGRA_FLOWCTRL_BASE		U(0x60007000)
 
 /*******************************************************************************
+ * Tegra AHB arbitration controller
+ ******************************************************************************/
+#define TEGRA_AHB_ARB_BASE		0x6000C000UL
+
+/*******************************************************************************
  * Tegra Secure Boot Controller constants
  ******************************************************************************/
 #define TEGRA_SB_BASE			U(0x6000C200)
@@ -99,15 +135,37 @@
 #define TEGRA_UARTE_BASE		U(0x70006400)
 
 /*******************************************************************************
+ * Tegra Fuse Controller related constants
+ ******************************************************************************/
+#define TEGRA_FUSE_BASE			0x7000F800UL
+#define FUSE_BOOT_SECURITY_INFO		0x268UL
+#define FUSE_ATOMIC_SAVE_CARVEOUT_EN	(0x1U << 7)
+#define FUSE_JTAG_SECUREID_VALID	(0x104UL)
+#define ECID_VALID			(0x1UL)
+
+
+/*******************************************************************************
  * Tegra Power Mgmt Controller constants
  ******************************************************************************/
 #define TEGRA_PMC_BASE			U(0x7000E400)
 
 /*******************************************************************************
+ * Tegra Atomics constants
+ ******************************************************************************/
+#define TEGRA_ATOMICS_BASE		0x70016000UL
+#define  TRIGGER0_REG_OFFSET		0UL
+#define  TRIGGER_WIDTH_SHIFT		4UL
+#define  TRIGGER_ID_SHIFT		16UL
+#define  RESULT0_REG_OFFSET		0xC00UL
+
+/*******************************************************************************
  * Tegra Memory Controller constants
  ******************************************************************************/
 #define TEGRA_MC_BASE			U(0x70019000)
 
+/* Memory Controller Interrupt Status */
+#define MC_INTSTATUS			0x00U
+
 /* TZDRAM carveout configuration registers */
 #define MC_SECURITY_CFG0_0		U(0x70)
 #define MC_SECURITY_CFG1_0		U(0x74)
@@ -118,10 +176,29 @@
 #define MC_VIDEO_PROTECT_BASE_LO	U(0x648)
 #define MC_VIDEO_PROTECT_SIZE_MB	U(0x64c)
 
+/* SMMU configuration registers*/
+#define MC_SMMU_PPCS_ASID_0		0x270U
+#define  PPCS_SMMU_ENABLE		(0x1U << 31)
+
+/*******************************************************************************
+ * Tegra SE constants
+ ******************************************************************************/
+#define TEGRA_SE1_BASE			U(0x70012000)
+#define TEGRA_SE2_BASE			U(0x70412000)
+#define TEGRA_PKA1_BASE			U(0x70420000)
+#define TEGRA_SE2_RANGE_SIZE		U(0x2000)
+#define SE_TZRAM_SECURITY		U(0x4)
+
 /*******************************************************************************
  * Tegra TZRAM constants
  ******************************************************************************/
 #define TEGRA_TZRAM_BASE		U(0x7C010000)
 #define TEGRA_TZRAM_SIZE		U(0x10000)
 
+/*******************************************************************************
+ * Tegra TZRAM carveout constants
+ ******************************************************************************/
+#define TEGRA_TZRAM_CARVEOUT_BASE	U(0x7C04C000)
+#define TEGRA_TZRAM_CARVEOUT_SIZE	U(0x4000)
+
 #endif /* TEGRA_DEF_H */
diff --git a/plat/nvidia/tegra/include/tegra_platform.h b/plat/nvidia/tegra/include/tegra_platform.h
index 63a0e01..13c92e0 100644
--- a/plat/nvidia/tegra/include/tegra_platform.h
+++ b/plat/nvidia/tegra/include/tegra_platform.h
@@ -8,27 +8,55 @@
 #define TEGRA_PLATFORM_H
 
 #include <cdefs.h>
+#include <stdbool.h>
+#include <utils_def.h>
+
+/*******************************************************************************
+ * Tegra major, minor version helper macros
+ ******************************************************************************/
+#define MAJOR_VERSION_SHIFT		U(0x4)
+#define MAJOR_VERSION_MASK		U(0xF)
+#define MINOR_VERSION_SHIFT		U(0x10)
+#define MINOR_VERSION_MASK		U(0xF)
+#define CHIP_ID_SHIFT			U(8)
+#define CHIP_ID_MASK			U(0xFF)
+#define PRE_SI_PLATFORM_SHIFT		U(0x14)
+#define PRE_SI_PLATFORM_MASK		U(0xF)
+
+/*******************************************************************************
+ * Tegra chip ID values
+ ******************************************************************************/
+#define TEGRA_CHIPID_TEGRA13		U(0x13)
+#define TEGRA_CHIPID_TEGRA21		U(0x21)
+#define TEGRA_CHIPID_TEGRA18		U(0x18)
+
+#ifndef __ASSEMBLY__
 
 /*
- * Tegra chip major/minor version
+ * Tegra chip ID major/minor identifiers
  */
 uint32_t tegra_get_chipid_major(void);
 uint32_t tegra_get_chipid_minor(void);
 
 /*
- * Tegra chip identifiers
+ * Tegra chip ID identifiers
  */
-uint8_t tegra_chipid_is_t132(void);
-uint8_t tegra_chipid_is_t210(void);
-uint8_t tegra_chipid_is_t186(void);
-
+bool tegra_chipid_is_t132(void);
+bool tegra_chipid_is_t186(void);
+bool tegra_chipid_is_t210(void);
+bool tegra_chipid_is_t210_b01(void);
 
 /*
  * Tegra platform identifiers
  */
-uint8_t tegra_platform_is_silicon(void);
-uint8_t tegra_platform_is_qt(void);
-uint8_t tegra_platform_is_emulation(void);
-uint8_t tegra_platform_is_fpga(void);
+bool tegra_platform_is_silicon(void);
+bool tegra_platform_is_qt(void);
+bool tegra_platform_is_emulation(void);
+bool tegra_platform_is_linsim(void);
+bool tegra_platform_is_fpga(void);
+bool tegra_platform_is_unit_fpga(void);
+bool tegra_platform_is_virt_dev_kit(void);
+
+#endif /* __ASSEMBLY__ */
 
 #endif /* TEGRA_PLATFORM_H */
diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h
index 93223cc..68b4624 100644
--- a/plat/nvidia/tegra/include/tegra_private.h
+++ b/plat/nvidia/tegra/include/tegra_private.h
@@ -23,6 +23,16 @@
 #define TEGRA_DRAM_END		ULL(0x27FFFFFFF)
 
 /*******************************************************************************
+ * Implementation defined ACTLR_EL1 bit definitions
+ ******************************************************************************/
+#define ACTLR_EL1_PMSTATE_MASK		(ULL(0xF) << 0)
+
+/*******************************************************************************
+ * Implementation defined ACTLR_EL2 bit definitions
+ ******************************************************************************/
+#define ACTLR_EL2_PMSTATE_MASK		(ULL(0xF) << 0)
+
+/*******************************************************************************
  * Struct for parameters received from BL2
  ******************************************************************************/
 typedef struct plat_params_from_bl2 {
@@ -31,10 +41,19 @@
 	/* TZ memory base */
 	uint64_t tzdram_base;
 	/* UART port ID */
-	int uart_id;
+	int32_t uart_id;
+	/* L2 ECC parity protection disable flag */
+	int32_t l2_ecc_parity_prot_dis;
+	/* SHMEM base address for storing the boot logs */
+	uint64_t boot_profiler_shmem_base;
 } plat_params_from_bl2_t;
 
 /*******************************************************************************
+ * Helper function to access l2ctlr_el1 register on Cortex-A57 CPUs
+ ******************************************************************************/
+DEFINE_RENAME_SYSREG_RW_FUNCS(l2ctlr_el1, CORTEX_A57_L2CTLR_EL1)
+
+/*******************************************************************************
  * Struct describing parameters passed to bl31
  ******************************************************************************/
 struct tegra_bl31_params {
@@ -47,19 +66,21 @@
 };
 
 /* Declarations for plat_psci_handlers.c */
-int32_t tegra_soc_validate_power_state(unsigned int power_state,
+int32_t tegra_soc_validate_power_state(uint32_t power_state,
 		psci_power_state_t *req_state);
 
 /* Declarations for plat_setup.c */
 const mmap_region_t *plat_get_mmio_map(void);
-uint32_t plat_get_console_from_id(int id);
+uint32_t plat_get_console_from_id(int32_t id);
 void plat_gic_setup(void);
 struct tegra_bl31_params *plat_get_bl31_params(void);
 plat_params_from_bl2_t *plat_get_bl31_plat_params(void);
+void plat_early_platform_setup(void);
+void plat_late_platform_setup(void);
 
 /* Declarations for plat_secondary.c */
 void plat_secondary_setup(void);
-int plat_lock_cpu_vectors(void);
+int32_t plat_lock_cpu_vectors(void);
 
 /* Declarations for tegra_fiq_glue.c */
 void tegra_fiq_handler_setup(void);
@@ -75,7 +96,30 @@
 
 void tegra_pm_system_suspend_entry(void);
 void tegra_pm_system_suspend_exit(void);
-int tegra_system_suspended(void);
+int32_t tegra_system_suspended(void);
+int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state);
+int32_t tegra_soc_pwr_domain_on(u_register_t mpidr);
+int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state);
+int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state);
+int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state);
+int32_t tegra_soc_prepare_system_reset(void);
+__dead2 void tegra_soc_prepare_system_off(void);
+plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl,
+					     const plat_local_state_t *states,
+					     uint32_t ncpu);
+void tegra_get_sys_suspend_power_state(psci_power_state_t *req_state);
+void tegra_cpu_standby(plat_local_state_t cpu_state);
+int32_t tegra_pwr_domain_on(u_register_t mpidr);
+void tegra_pwr_domain_off(const psci_power_state_t *target_state);
+void tegra_pwr_domain_suspend(const psci_power_state_t *target_state);
+void __dead2 tegra_pwr_domain_power_down_wfi(const psci_power_state_t *target_state);
+void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state);
+void tegra_pwr_domain_suspend_finish(const psci_power_state_t *target_state);
+__dead2 void tegra_system_off(void);
+__dead2 void tegra_system_reset(void);
+int32_t tegra_validate_power_state(uint32_t power_state,
+				   psci_power_state_t *req_state);
+int32_t tegra_validate_ns_entrypoint(uintptr_t entrypoint);
 
 /* Declarations for tegraXXX_pm.c */
 int tegra_prepare_cpu_suspend(unsigned int id, unsigned int afflvl);
@@ -83,8 +127,7 @@
 
 /* Declarations for tegra_bl31_setup.c */
 plat_params_from_bl2_t *bl31_get_plat_params(void);
-int bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes);
-void plat_early_platform_setup(void);
+int32_t bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes);
 
 /* Declarations for tegra_delay_timer.c */
 void tegra_delay_timer_init(void);
@@ -92,4 +135,22 @@
 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,
+			    u_register_t x1,
+			    u_register_t x2,
+			    u_register_t x3,
+			    u_register_t x4,
+			    void *cookie,
+			    void *handle,
+			    u_register_t flags);
+int plat_sip_handler(uint32_t smc_fid,
+		     uint64_t x1,
+		     uint64_t x2,
+		     uint64_t x3,
+		     uint64_t x4,
+		     const void *cookie,
+		     void *handle,
+		     uint64_t flags);
+
 #endif /* TEGRA_PRIVATE_H */
diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk
index 33548b7..614d2a2 100644
--- a/plat/nvidia/tegra/platform.mk
+++ b/plat/nvidia/tegra/platform.mk
@@ -12,6 +12,8 @@
 
 # enable assert() for release/debug builds
 ENABLE_ASSERTIONS	:=	1
+PLAT_LOG_LEVEL_ASSERT	:=	40
+$(eval $(call add_define,PLAT_LOG_LEVEL_ASSERT))
 
 # enable dynamic memory mapping
 PLAT_XLAT_TABLES_DYNAMIC :=	1
@@ -29,11 +31,14 @@
 # do not enable SVE
 ENABLE_SVE_FOR_NS	:=	0
 
+# enable D-cache early during CPU warmboot
+WARMBOOT_ENABLE_DCACHE_EARLY := 1
+
 include plat/nvidia/tegra/common/tegra_common.mk
 include ${SOC_DIR}/platform_${TARGET_SOC}.mk
 
 # modify BUILD_PLAT to point to SoC specific build directory
 BUILD_PLAT	:=	${BUILD_BASE}/${PLAT}/${TARGET_SOC}/${BUILD_TYPE}
 
-# enable signed comparison checks
-TF_CFLAGS	+= -Wsign-compare
+# platform cflags (enable signed comparisons, disable stdlib)
+TF_CFLAGS	+= -Wsign-compare -nostdlib
diff --git a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
index 7226120..bd3f46f 100644
--- a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
@@ -98,19 +98,24 @@
 
 int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
 {
+	uint64_t val;
+
 	tegra_fc_cpu_off(read_mpidr() & MPIDR_CPU_MASK);
 
 	/* Disable DCO operations */
 	denver_disable_dco();
 
 	/* Power down the CPU */
-	write_actlr_el1(DENVER_CPU_STATE_POWER_DOWN);
+	val = read_actlr_el1() & ~ACTLR_EL1_PMSTATE_MASK;
+	write_actlr_el1(val | DENVER_CPU_STATE_POWER_DOWN);
 
 	return PSCI_E_SUCCESS;
 }
 
 int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
 {
+	uint64_t val;
+
 #if ENABLE_ASSERTIONS
 	int cpu = read_mpidr() & MPIDR_CPU_MASK;
 
@@ -128,7 +133,8 @@
 	denver_disable_dco();
 
 	/* Program the suspend state ID */
-	write_actlr_el1(target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]);
+	val = read_actlr_el1() & ~ACTLR_EL1_PMSTATE_MASK;
+	write_actlr_el1(val | target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]);
 
 	return PSCI_E_SUCCESS;
 }
diff --git a/plat/nvidia/tegra/soc/t132/plat_setup.c b/plat/nvidia/tegra/soc/t132/plat_setup.c
index f72b73e..3f9cda9 100644
--- a/plat/nvidia/tegra/soc/t132/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t132/plat_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,25 +7,10 @@
 #include <arch_helpers.h>
 #include <common/bl_common.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
-
+#include <platform.h>
 #include <tegra_def.h>
 #include <tegra_private.h>
 
-/*******************************************************************************
- * The Tegra power domain tree has a single system level power domain i.e. a
- * single root node. The first entry in the power domain descriptor specifies
- * the number of power domains at the highest power level.
- *******************************************************************************
- */
-const unsigned char tegra_power_domain_tree_desc[] = {
-	/* No of root nodes */
-	1,
-	/* No of clusters */
-	PLATFORM_CLUSTER_COUNT,
-	/* No of CPU cores */
-	PLATFORM_CORE_COUNT,
-};
-
 /* sets of MMIO ranges setup */
 #define MMIO_RANGE_0_ADDR	0x50000000
 #define MMIO_RANGE_1_ADDR	0x60000000
@@ -54,6 +39,29 @@
 	return tegra_mmap;
 }
 
+/*******************************************************************************
+ * The Tegra power domain tree has a single system level power domain i.e. a
+ * single root node. The first entry in the power domain descriptor specifies
+ * the number of power domains at the highest power level.
+ *******************************************************************************
+ */
+const unsigned char tegra_power_domain_tree_desc[] = {
+	/* No of root nodes */
+	1,
+	/* No of clusters */
+	PLATFORM_CLUSTER_COUNT,
+	/* No of CPU cores */
+	PLATFORM_CORE_COUNT,
+};
+
+/*******************************************************************************
+ * This function returns the Tegra default topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return tegra_power_domain_tree_desc;
+}
+
 unsigned int plat_get_syscnt_freq2(void)
 {
 	return 12000000;
diff --git a/plat/nvidia/tegra/soc/t132/plat_sip_calls.c b/plat/nvidia/tegra/soc/t132/plat_sip_calls.c
index 02dd1cd..90c6bb2 100644
--- a/plat/nvidia/tegra/soc/t132/plat_sip_calls.c
+++ b/plat/nvidia/tegra/soc/t132/plat_sip_calls.c
@@ -38,7 +38,7 @@
 		     uint64_t x2,
 		     uint64_t x3,
 		     uint64_t x4,
-		     void *cookie,
+		     const void *cookie,
 		     void *handle,
 		     uint64_t flags)
 {
diff --git a/plat/nvidia/tegra/soc/t132/platform_t132.mk b/plat/nvidia/tegra/soc/t132/platform_t132.mk
index f15ee74..bb7b7ee 100644
--- a/plat/nvidia/tegra/soc/t132/platform_t132.mk
+++ b/plat/nvidia/tegra/soc/t132/platform_t132.mk
@@ -19,7 +19,8 @@
 MAX_MMAP_REGIONS		:= 8
 $(eval $(call add_define,MAX_MMAP_REGIONS))
 
-BL31_SOURCES		+=	lib/cpus/aarch64/denver.S		\
+BL31_SOURCES		+=	drivers/ti/uart/aarch64/16550_console.S		\
+				lib/cpus/aarch64/denver.S		\
 				${COMMON_DIR}/drivers/flowctrl/flowctrl.c	\
 				${COMMON_DIR}/drivers/memctrl/memctrl_v1.c	\
 				${SOC_DIR}/plat_psci_handlers.c		\
diff --git a/plat/nvidia/tegra/soc/t186/drivers/include/mce_private.h b/plat/nvidia/tegra/soc/t186/drivers/include/mce_private.h
index 96a5525..203f61a 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/include/mce_private.h
+++ b/plat/nvidia/tegra/soc/t186/drivers/include/mce_private.h
@@ -64,19 +64,17 @@
 #define MCA_ARG_FINISH_MASK			U(0xFF)
 
 /*******************************************************************************
- * Uncore PERFMON ARI struct
+ * Uncore PERFMON ARI macros
  ******************************************************************************/
 #define UNCORE_PERFMON_CMD_READ			U(0)
 #define UNCORE_PERFMON_CMD_WRITE		U(1)
 
 #define UNCORE_PERFMON_CMD_MASK			U(0xFF)
-#define UNCORE_PERFMON_CMD_SHIFT		U(24)
 #define UNCORE_PERFMON_UNIT_GRP_MASK		U(0xF)
 #define UNCORE_PERFMON_SELECTOR_MASK		U(0xF)
 #define UNCORE_PERFMON_REG_MASK			U(0xFF)
 #define UNCORE_PERFMON_CTR_MASK			U(0xFF)
 #define UNCORE_PERFMON_RESP_STATUS_MASK		U(0xFF)
-#define UNCORE_PERFMON_RESP_STATUS_SHIFT	U(24)
 
 /*******************************************************************************
  * Structure populated by arch specific code to export routines which perform
diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
index 1429a61..a57bc11 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
@@ -35,8 +35,8 @@
 #define ARI_REQUEST_VALID_BIT		(1U << 8)
 #define ARI_EVT_MASK_STANDBYWFI_BIT	(1U << 7)
 
-/* default timeout (ms) to wait for ARI completion */
-#define ARI_MAX_RETRY_COUNT		2000
+/* default timeout (us) to wait for ARI completion */
+#define ARI_MAX_RETRY_COUNT		U(2000000)
 
 /*******************************************************************************
  * ARI helper functions
@@ -80,7 +80,7 @@
 static int32_t ari_request_wait(uint32_t ari_base, uint32_t evt_mask, uint32_t req,
 		uint32_t lo, uint32_t hi)
 {
-	uint32_t retries = ARI_MAX_RETRY_COUNT;
+	uint32_t retries = (uint32_t)ARI_MAX_RETRY_COUNT;
 	uint32_t status;
 	int32_t ret = 0;
 
@@ -99,9 +99,9 @@
 		ret = 0;
 	} else {
 		/* For shutdown/reboot commands, we dont have to check for timeouts */
-		if ((req == (uint32_t)TEGRA_ARI_MISC_CCPLEX) &&
-		    ((lo == (uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF) ||
-		     (lo == (uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT))) {
+		if ((req == TEGRA_ARI_MISC_CCPLEX) &&
+		    ((lo == TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF) ||
+		     (lo == TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT))) {
 				ret = 0;
 		} else {
 			/*
@@ -115,8 +115,8 @@
 					break;
 				}
 
-				/* delay 1 ms */
-				mdelay(1);
+				/* delay 1 us */
+				udelay(1);
 
 				/* decrement the retry count */
 				retries--;
@@ -151,7 +151,7 @@
 
 		/* Enter the cstate, to be woken up after wake_time (TSC ticks) */
 		ret = ari_request_wait(ari_base, ARI_EVT_MASK_STANDBYWFI_BIT,
-		TEGRA_ARI_ENTER_CSTATE, state, wake_time);
+			(uint32_t)TEGRA_ARI_ENTER_CSTATE, state, wake_time);
 	}
 
 	return ret;
@@ -161,38 +161,38 @@
 	uint32_t system, uint8_t sys_state_force, uint32_t wake_mask,
 	uint8_t update_wake_mask)
 {
-	uint32_t val = 0U;
+	uint64_t val = 0U;
 
 	/* clean the previous response state */
 	ari_clobber_response(ari_base);
 
 	/* update CLUSTER_CSTATE? */
 	if (cluster != 0U) {
-		val |= (cluster & (uint32_t)CLUSTER_CSTATE_MASK) |
-			(uint32_t)CLUSTER_CSTATE_UPDATE_BIT;
+		val |= (cluster & CLUSTER_CSTATE_MASK) |
+			CLUSTER_CSTATE_UPDATE_BIT;
 	}
 
 	/* update CCPLEX_CSTATE? */
 	if (ccplex != 0U) {
-		val |= ((ccplex & (uint32_t)CCPLEX_CSTATE_MASK) << (uint32_t)CCPLEX_CSTATE_SHIFT) |
-			(uint32_t)CCPLEX_CSTATE_UPDATE_BIT;
+		val |= ((ccplex & CCPLEX_CSTATE_MASK) << CCPLEX_CSTATE_SHIFT) |
+			CCPLEX_CSTATE_UPDATE_BIT;
 	}
 
 	/* update SYSTEM_CSTATE? */
 	if (system != 0U) {
-		val |= ((system & (uint32_t)SYSTEM_CSTATE_MASK) << (uint32_t)SYSTEM_CSTATE_SHIFT) |
-		       (((uint32_t)sys_state_force << SYSTEM_CSTATE_FORCE_UPDATE_SHIFT) |
-			(uint32_t)SYSTEM_CSTATE_UPDATE_BIT);
+		val |= ((system & SYSTEM_CSTATE_MASK) << SYSTEM_CSTATE_SHIFT) |
+		       (((uint64_t)sys_state_force << SYSTEM_CSTATE_FORCE_UPDATE_SHIFT) |
+			SYSTEM_CSTATE_UPDATE_BIT);
 	}
 
 	/* update wake mask value? */
 	if (update_wake_mask != 0U) {
-		val |= (uint32_t)CSTATE_WAKE_MASK_UPDATE_BIT;
+		val |= CSTATE_WAKE_MASK_UPDATE_BIT;
 	}
 
 	/* set the updated cstate info */
-	return ari_request_wait(ari_base, 0U, TEGRA_ARI_UPDATE_CSTATE_INFO, val,
-			wake_mask);
+	return ari_request_wait(ari_base, 0U, (uint32_t)TEGRA_ARI_UPDATE_CSTATE_INFO,
+				(uint32_t)val, wake_mask);
 }
 
 int32_t ari_update_crossover_time(uint32_t ari_base, uint32_t type, uint32_t time)
@@ -208,8 +208,8 @@
 		ari_clobber_response(ari_base);
 
 		/* update crossover threshold time */
-		ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_UPDATE_CROSSOVER,
-			type, time);
+		ret = ari_request_wait(ari_base, 0U,
+				(uint32_t)TEGRA_ARI_UPDATE_CROSSOVER, type, time);
 	}
 
 	return ret;
@@ -227,7 +227,8 @@
 		/* clean the previous response state */
 		ari_clobber_response(ari_base);
 
-		ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_CSTATE_STATS, state, 0U);
+		ret = ari_request_wait(ari_base, 0U,
+				(uint32_t)TEGRA_ARI_CSTATE_STATS, state, 0U);
 		if (ret != 0) {
 			result = EINVAL;
 		} else {
@@ -243,8 +244,8 @@
 	ari_clobber_response(ari_base);
 
 	/* write the cstate stats */
-	return ari_request_wait(ari_base, 0U, TEGRA_ARI_WRITE_CSTATE_STATS, state,
-			stats);
+	return ari_request_wait(ari_base, 0U, (uint32_t)TEGRA_ARI_WRITE_CSTATE_STATS,
+			state, stats);
 }
 
 uint64_t ari_enumeration_misc(uint32_t ari_base, uint32_t cmd, uint32_t data)
@@ -261,7 +262,7 @@
 		local_data = 0U;
 	}
 
-	ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_MISC, cmd, local_data);
+	ret = ari_request_wait(ari_base, 0U, (uint32_t)TEGRA_ARI_MISC, cmd, local_data);
 	if (ret != 0) {
 		resp = (uint64_t)ret;
 	} else {
@@ -281,8 +282,8 @@
 	/* clean the previous response state */
 	ari_clobber_response(ari_base);
 
-	ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_IS_CCX_ALLOWED, state & 0x7U,
-			wake_time);
+	ret = ari_request_wait(ari_base, 0U, (uint32_t)TEGRA_ARI_IS_CCX_ALLOWED,
+			state & 0x7U, wake_time);
 	if (ret != 0) {
 		ERROR("%s: failed (%d)\n", __func__, ret);
 		result = 0U;
@@ -299,18 +300,16 @@
 	int32_t ret, result;
 
 	/* check for allowed power state */
-	if ((state != TEGRA_ARI_CORE_C0) &&
-	    (state != TEGRA_ARI_CORE_C1) &&
-	    (state != TEGRA_ARI_CORE_C6) &&
-	    (state != TEGRA_ARI_CORE_C7)) {
+	if ((state != TEGRA_ARI_CORE_C0) && (state != TEGRA_ARI_CORE_C1) &&
+	    (state != TEGRA_ARI_CORE_C6) && (state != TEGRA_ARI_CORE_C7)) {
 		ERROR("%s: unknown cstate (%d)\n", __func__, state);
 		result = EINVAL;
 	} else {
 		/* clean the previous response state */
 		ari_clobber_response(ari_base);
 
-		ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_IS_SC7_ALLOWED, state,
-				wake_time);
+		ret = ari_request_wait(ari_base, 0U,
+			(uint32_t)TEGRA_ARI_IS_SC7_ALLOWED, state, wake_time);
 		if (ret != 0) {
 			ERROR("%s: failed (%d)\n", __func__, ret);
 			result = 0;
@@ -325,10 +324,10 @@
 
 int32_t ari_online_core(uint32_t ari_base, uint32_t core)
 {
-	uint64_t cpu = read_mpidr() & (uint64_t)(MPIDR_CPU_MASK);
-	uint64_t cluster = (read_mpidr() & (uint64_t)(MPIDR_CLUSTER_MASK)) >>
-			   (uint64_t)(MPIDR_AFFINITY_BITS);
-	uint64_t impl = (read_midr() >> (uint64_t)MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK;
+	uint64_t cpu = read_mpidr() & (MPIDR_CPU_MASK);
+	uint64_t cluster = (read_mpidr() & (MPIDR_CLUSTER_MASK)) >>
+			   (MPIDR_AFFINITY_BITS);
+	uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
 	int32_t ret;
 
 	/* construct the current CPU # */
@@ -342,14 +341,14 @@
 		/*
 		 * The Denver cluster has 2 CPUs only - 0, 1.
 		 */
-		if ((impl == (uint32_t)DENVER_IMPL) &&
-		    ((core == 2U) || (core == 3U))) {
+		if ((impl == DENVER_IMPL) && ((core == 2U) || (core == 3U))) {
 			ERROR("%s: unknown core id (%d)\n", __func__, core);
 			ret = EINVAL;
 		} else {
 			/* clean the previous response state */
 			ari_clobber_response(ari_base);
-			ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_ONLINE_CORE, core, 0U);
+			ret = ari_request_wait(ari_base, 0U,
+				(uint32_t)TEGRA_ARI_ONLINE_CORE, core, 0U);
 		}
 	}
 
@@ -377,7 +376,8 @@
 		((volt & MCE_AUTO_CC3_VTG_MASK) << MCE_AUTO_CC3_VTG_SHIFT) |\
 		((enable != 0U) ? MCE_AUTO_CC3_ENABLE_BIT : 0U));
 
-	return ari_request_wait(ari_base, 0U, TEGRA_ARI_CC3_CTRL, val, 0U);
+	return ari_request_wait(ari_base, 0U,
+			(uint32_t)TEGRA_ARI_CC3_CTRL, val, 0U);
 }
 
 int32_t ari_reset_vector_update(uint32_t ari_base)
@@ -389,7 +389,8 @@
 	 * Need to program the CPU reset vector one time during cold boot
 	 * and SC7 exit
 	 */
-	(void)ari_request_wait(ari_base, 0U, TEGRA_ARI_COPY_MISCREG_AA64_RST, 0U, 0U);
+	(void)ari_request_wait(ari_base, 0U,
+			(uint32_t)TEGRA_ARI_COPY_MISCREG_AA64_RST, 0U, 0U);
 
 	return 0;
 }
@@ -399,8 +400,8 @@
 	/* clean the previous response state */
 	ari_clobber_response(ari_base);
 
-	return ari_request_wait(ari_base, 0U, TEGRA_ARI_ROC_FLUSH_CACHE_TRBITS,
-			0U, 0U);
+	return ari_request_wait(ari_base, 0U,
+			(uint32_t)TEGRA_ARI_ROC_FLUSH_CACHE_TRBITS, 0U, 0U);
 }
 
 int32_t ari_roc_flush_cache(uint32_t ari_base)
@@ -408,8 +409,8 @@
 	/* clean the previous response state */
 	ari_clobber_response(ari_base);
 
-	return ari_request_wait(ari_base, 0U, TEGRA_ARI_ROC_FLUSH_CACHE_ONLY,
-			0U, 0U);
+	return ari_request_wait(ari_base, 0U,
+			(uint32_t)TEGRA_ARI_ROC_FLUSH_CACHE_ONLY, 0U, 0U);
 }
 
 int32_t ari_roc_clean_cache(uint32_t ari_base)
@@ -417,8 +418,8 @@
 	/* clean the previous response state */
 	ari_clobber_response(ari_base);
 
-	return ari_request_wait(ari_base, 0U, TEGRA_ARI_ROC_CLEAN_CACHE_ONLY,
-			0U, 0U);
+	return ari_request_wait(ari_base, 0U,
+			(uint32_t)TEGRA_ARI_ROC_CLEAN_CACHE_ONLY, 0U, 0U);
 }
 
 uint64_t ari_read_write_mca(uint32_t ari_base, uint64_t cmd, uint64_t *data)
@@ -435,7 +436,7 @@
 	ari_write_32(ari_base, (uint32_t)cmd, ARI_RESPONSE_DATA_LO);
 	ari_write_32(ari_base, (uint32_t)(cmd >> 32U), ARI_RESPONSE_DATA_HI);
 
-	ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_MCA,
+	ret = ari_request_wait(ari_base, 0U, (uint32_t)TEGRA_ARI_MCA,
 			       (uint32_t)mca_arg_data,
 			       (uint32_t)(mca_arg_data >> 32U));
 	if (ret == 0) {
@@ -465,7 +466,7 @@
 {
 	int32_t ret = 0;
 	/* sanity check GSC ID */
-	if (gsc_idx > (uint32_t)TEGRA_ARI_GSC_VPR_IDX) {
+	if (gsc_idx > TEGRA_ARI_GSC_VPR_IDX) {
 		ret = EINVAL;
 	} else {
 		/* clean the previous response state */
@@ -476,7 +477,8 @@
 		 * the ID, from the MC registers and update the internal GSC registers
 		 * of the CCPLEX.
 		 */
-		(void)ari_request_wait(ari_base, 0U, TEGRA_ARI_UPDATE_CCPLEX_GSC, gsc_idx, 0U);
+		(void)ari_request_wait(ari_base, 0U,
+				(uint32_t)TEGRA_ARI_UPDATE_CCPLEX_GSC, gsc_idx, 0U);
 	}
 
 	return ret;
@@ -490,17 +492,18 @@
 	/*
 	 * The MCE will shutdown or restart the entire system
 	 */
-	(void)ari_request_wait(ari_base, 0U, TEGRA_ARI_MISC_CCPLEX, state_idx, 0U);
+	(void)ari_request_wait(ari_base, 0U,
+			(uint32_t)TEGRA_ARI_MISC_CCPLEX, state_idx, 0U);
 }
 
 int32_t ari_read_write_uncore_perfmon(uint32_t ari_base, uint64_t req,
 		uint64_t *data)
 {
 	int32_t ret, result;
-	uint32_t val;
-	uint8_t req_cmd, req_status;
+	uint32_t val, req_status;
+	uint8_t req_cmd;
 
-	req_cmd = (uint8_t)(req >> UNCORE_PERFMON_CMD_SHIFT);
+	req_cmd = (uint8_t)(req & UNCORE_PERFMON_CMD_MASK);
 
 	/* clean the previous response state */
 	ari_clobber_response(ari_base);
@@ -517,20 +520,20 @@
 		val = (req_cmd == UNCORE_PERFMON_CMD_WRITE) ?
 			(uint32_t)*data : 0U;
 
-		ret = ari_request_wait(ari_base, 0U, TEGRA_ARI_PERFMON, val,
-				       (uint32_t)req);
+		ret = ari_request_wait(ari_base, 0U,
+			(uint32_t)TEGRA_ARI_PERFMON, val, (uint32_t)req);
 		if (ret != 0) {
 			result = ret;
 		} else {
 			/* read the command status value */
-			req_status = (uint8_t)ari_get_response_high(ari_base) &
+			req_status = ari_get_response_high(ari_base) &
 					 UNCORE_PERFMON_RESP_STATUS_MASK;
 
 			/*
 			 * For "read" commands get the data from the uncore
 			 * perfmon registers
 			 */
-			req_status >>= UNCORE_PERFMON_RESP_STATUS_SHIFT;
+			req_status &= UNCORE_PERFMON_RESP_STATUS_MASK;
 			if ((req_status == 0U) && (req_cmd == UNCORE_PERFMON_CMD_READ)) {
 				*data = ari_get_response_low(ari_base);
 			}
@@ -555,6 +558,7 @@
 	} else {
 		/* clean the previous response state */
 		ari_clobber_response(ari_base);
-		(void)ari_request_wait(ari_base, 0U, TEGRA_ARI_MISC_CCPLEX, index, value);
+		(void)ari_request_wait(ari_base, 0U,
+			(uint32_t)TEGRA_ARI_MISC_CCPLEX, index, value);
 	}
 }
diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
index 828ad3c..9e42b2b 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
@@ -111,8 +111,8 @@
 static uint32_t mce_get_curr_cpu_ari_base(void)
 {
 	uint64_t mpidr = read_mpidr();
-	uint64_t cpuid = mpidr & (uint64_t)MPIDR_CPU_MASK;
-	uint64_t impl = (read_midr() >> (uint64_t)MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK;
+	uint64_t cpuid = mpidr & MPIDR_CPU_MASK;
+	uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
 
 	/*
 	 * T186 has 2 CPU clusters, one with Denver CPUs and the other with
@@ -131,9 +131,9 @@
 static arch_mce_ops_t *mce_get_curr_cpu_ops(void)
 {
 	uint64_t mpidr = read_mpidr();
-	uint64_t cpuid = mpidr & (uint64_t)MPIDR_CPU_MASK;
-	uint64_t impl = (read_midr() >> (uint64_t)MIDR_IMPL_SHIFT) &
-			(uint64_t)MIDR_IMPL_MASK;
+	uint64_t cpuid = mpidr & MPIDR_CPU_MASK;
+	uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) &
+			MIDR_IMPL_MASK;
 
 	/*
 	 * T186 has 2 CPU clusters, one with Denver CPUs and the other with
@@ -170,121 +170,89 @@
 	cpu_ari_base = mce_get_curr_cpu_ari_base();
 
 	switch (cmd) {
-	case MCE_CMD_ENTER_CSTATE:
+	case (uint64_t)MCE_CMD_ENTER_CSTATE:
 		ret = ops->enter_cstate(cpu_ari_base, arg0, arg1);
-		if (ret < 0) {
-			ERROR("%s: enter_cstate failed(%d)\n", __func__, ret);
-		}
 
 		break;
 
-	case MCE_CMD_UPDATE_CSTATE_INFO:
+	case (uint64_t)MCE_CMD_UPDATE_CSTATE_INFO:
 		/*
 		 * get the parameters required for the update cstate info
 		 * command
 		 */
-		arg3 = read_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X4));
-		arg4 = read_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X5));
-		arg5 = read_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X6));
+		arg3 = read_ctx_reg(gp_regs, CTX_GPREG_X4);
+		arg4 = read_ctx_reg(gp_regs, CTX_GPREG_X5);
+		arg5 = read_ctx_reg(gp_regs, CTX_GPREG_X6);
 
 		ret = ops->update_cstate_info(cpu_ari_base, (uint32_t)arg0,
 				(uint32_t)arg1, (uint32_t)arg2, (uint8_t)arg3,
 				(uint32_t)arg4, (uint8_t)arg5);
-		if (ret < 0) {
-			ERROR("%s: update_cstate_info failed(%d)\n",
-				__func__, ret);
-		}
 
-		write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X4), (0));
-		write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X5), (0));
-		write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X6), (0));
+		write_ctx_reg(gp_regs, CTX_GPREG_X4, (0ULL));
+		write_ctx_reg(gp_regs, CTX_GPREG_X5, (0ULL));
+		write_ctx_reg(gp_regs, CTX_GPREG_X6, (0ULL));
 
 		break;
 
-	case MCE_CMD_UPDATE_CROSSOVER_TIME:
+	case (uint64_t)MCE_CMD_UPDATE_CROSSOVER_TIME:
 		ret = ops->update_crossover_time(cpu_ari_base, arg0, arg1);
-		if (ret < 0) {
-			ERROR("%s: update_crossover_time failed(%d)\n",
-				__func__, ret);
-		}
 
 		break;
 
-	case MCE_CMD_READ_CSTATE_STATS:
+	case (uint64_t)MCE_CMD_READ_CSTATE_STATS:
 		ret64 = ops->read_cstate_stats(cpu_ari_base, arg0);
 
 		/* update context to return cstate stats value */
-		write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1), (ret64));
-		write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X2), (ret64));
+		write_ctx_reg(gp_regs, CTX_GPREG_X1, (ret64));
+		write_ctx_reg(gp_regs, CTX_GPREG_X2, (ret64));
 
 		break;
 
-	case MCE_CMD_WRITE_CSTATE_STATS:
+	case (uint64_t)MCE_CMD_WRITE_CSTATE_STATS:
 		ret = ops->write_cstate_stats(cpu_ari_base, arg0, arg1);
-		if (ret < 0) {
-			ERROR("%s: write_cstate_stats failed(%d)\n",
-				__func__, ret);
-		}
 
 		break;
 
-	case MCE_CMD_IS_CCX_ALLOWED:
+	case (uint64_t)MCE_CMD_IS_CCX_ALLOWED:
 		ret = ops->is_ccx_allowed(cpu_ari_base, arg0, arg1);
-		if (ret < 0) {
-			ERROR("%s: is_ccx_allowed failed(%d)\n", __func__, ret);
-			break;
-		}
 
 		/* update context to return CCx status value */
-		write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1),
-			      (uint64_t)(ret));
+		write_ctx_reg(gp_regs, CTX_GPREG_X1, (uint64_t)(ret));
 
 		break;
 
-	case MCE_CMD_IS_SC7_ALLOWED:
+	case (uint64_t)MCE_CMD_IS_SC7_ALLOWED:
 		ret = ops->is_sc7_allowed(cpu_ari_base, arg0, arg1);
-		if (ret < 0) {
-			ERROR("%s: is_sc7_allowed failed(%d)\n", __func__, ret);
-			break;
-		}
 
 		/* update context to return SC7 status value */
-		write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1),
-			      (uint64_t)(ret));
-		write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X3),
-			      (uint64_t)(ret));
+		write_ctx_reg(gp_regs, CTX_GPREG_X1, (uint64_t)(ret));
+		write_ctx_reg(gp_regs, CTX_GPREG_X3, (uint64_t)(ret));
 
 		break;
 
-	case MCE_CMD_ONLINE_CORE:
+	case (uint64_t)MCE_CMD_ONLINE_CORE:
 		ret = ops->online_core(cpu_ari_base, arg0);
-		if (ret < 0) {
-			ERROR("%s: online_core failed(%d)\n", __func__, ret);
-		}
 
 		break;
 
-	case MCE_CMD_CC3_CTRL:
+	case (uint64_t)MCE_CMD_CC3_CTRL:
 		ret = ops->cc3_ctrl(cpu_ari_base, arg0, arg1, arg2);
-		if (ret < 0) {
-			ERROR("%s: cc3_ctrl failed(%d)\n", __func__, ret);
-		}
 
 		break;
 
-	case MCE_CMD_ECHO_DATA:
+	case (uint64_t)MCE_CMD_ECHO_DATA:
 		ret64 = ops->call_enum_misc(cpu_ari_base, TEGRA_ARI_MISC_ECHO,
 				arg0);
 
 		/* update context to return if echo'd data matched source */
-		write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1),
-			      ((ret64 == arg0) ? 1ULL : 0ULL));
-		write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X2),
-			      ((ret64 == arg0) ? 1ULL : 0ULL));
+		write_ctx_reg(gp_regs, CTX_GPREG_X1, ((ret64 == arg0) ?
+			      1ULL : 0ULL));
+		write_ctx_reg(gp_regs, CTX_GPREG_X2, ((ret64 == arg0) ?
+			      1ULL : 0ULL));
 
 		break;
 
-	case MCE_CMD_READ_VERSIONS:
+	case (uint64_t)MCE_CMD_READ_VERSIONS:
 		ret64 = ops->call_enum_misc(cpu_ari_base, TEGRA_ARI_MISC_VERSION,
 			arg0);
 
@@ -292,68 +260,56 @@
 		 * version = minor(63:32) | major(31:0). Update context
 		 * to return major and minor version number.
 		 */
-		write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1),
-			      (ret64));
-		write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X2),
-			      (ret64 >> 32ULL));
+		write_ctx_reg(gp_regs, CTX_GPREG_X1, (ret64));
+		write_ctx_reg(gp_regs, CTX_GPREG_X2, (ret64 >> 32ULL));
 
 		break;
 
-	case MCE_CMD_ENUM_FEATURES:
+	case (uint64_t)MCE_CMD_ENUM_FEATURES:
 		ret64 = ops->call_enum_misc(cpu_ari_base,
 				TEGRA_ARI_MISC_FEATURE_LEAF_0, arg0);
 
 		/* update context to return features value */
-		write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1), (ret64));
+		write_ctx_reg(gp_regs, CTX_GPREG_X1, (ret64));
 
 		break;
 
-	case MCE_CMD_ROC_FLUSH_CACHE_TRBITS:
+	case (uint64_t)MCE_CMD_ROC_FLUSH_CACHE_TRBITS:
 		ret = ops->roc_flush_cache_trbits(cpu_ari_base);
-		if (ret < 0) {
-			ERROR("%s: flush cache_trbits failed(%d)\n", __func__,
-				ret);
-		}
 
 		break;
 
-	case MCE_CMD_ROC_FLUSH_CACHE:
+	case (uint64_t)MCE_CMD_ROC_FLUSH_CACHE:
 		ret = ops->roc_flush_cache(cpu_ari_base);
-		if (ret < 0) {
-			ERROR("%s: flush cache failed(%d)\n", __func__, ret);
-		}
 
 		break;
 
-	case MCE_CMD_ROC_CLEAN_CACHE:
+	case (uint64_t)MCE_CMD_ROC_CLEAN_CACHE:
 		ret = ops->roc_clean_cache(cpu_ari_base);
-		if (ret < 0) {
-			ERROR("%s: clean cache failed(%d)\n", __func__, ret);
-		}
 
 		break;
 
-	case MCE_CMD_ENUM_READ_MCA:
+	case (uint64_t)MCE_CMD_ENUM_READ_MCA:
 		ret64 = ops->read_write_mca(cpu_ari_base, arg0, &arg1);
 
 		/* update context to return MCA data/error */
-		write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1), (ret64));
-		write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X2), (arg1));
-		write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X3), (ret64));
+		write_ctx_reg(gp_regs, CTX_GPREG_X1, (ret64));
+		write_ctx_reg(gp_regs, CTX_GPREG_X2, (arg1));
+		write_ctx_reg(gp_regs, CTX_GPREG_X3, (ret64));
 
 		break;
 
-	case MCE_CMD_ENUM_WRITE_MCA:
+	case (uint64_t)MCE_CMD_ENUM_WRITE_MCA:
 		ret64 = ops->read_write_mca(cpu_ari_base, arg0, &arg1);
 
 		/* update context to return MCA error */
-		write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1), (ret64));
-		write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X3), (ret64));
+		write_ctx_reg(gp_regs, CTX_GPREG_X1, (ret64));
+		write_ctx_reg(gp_regs, CTX_GPREG_X3, (ret64));
 
 		break;
 
 #if ENABLE_CHIP_VERIFICATION_HARNESS
-	case MCE_CMD_ENABLE_LATIC:
+	case (uint64_t)MCE_CMD_ENABLE_LATIC:
 		/*
 		 * This call is not for production use. The constant value,
 		 * 0xFFFF0000, is specific to allowing for enabling LATIC on
@@ -371,14 +327,14 @@
 		break;
 #endif
 
-	case MCE_CMD_UNCORE_PERFMON_REQ:
+	case (uint64_t)MCE_CMD_UNCORE_PERFMON_REQ:
 		ret = ops->read_write_uncore_perfmon(cpu_ari_base, arg0, &arg1);
 
 		/* update context to return data */
-		write_ctx_reg((gp_regs), (uint32_t)(CTX_GPREG_X1), (arg1));
+		write_ctx_reg(gp_regs, CTX_GPREG_X1, (arg1));
 		break;
 
-	case MCE_CMD_MISC_CCPLEX:
+	case (uint64_t)MCE_CMD_MISC_CCPLEX:
 		ops->misc_ccplex(cpu_ari_base, arg0, arg1);
 
 		break;
diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c b/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c
index 1ac3710..cbc9aa3 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c
@@ -14,10 +14,12 @@
 
 #include <mce_private.h>
 #include <t18x_ari.h>
+#include <tegra_private.h>
 
 int32_t nvg_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time)
 {
 	int32_t ret = 0;
+	uint64_t val = 0ULL;
 
 	(void)ari_base;
 
@@ -28,10 +30,11 @@
 		ret = EINVAL;
 	} else {
 		/* time (TSC ticks) until the core is expected to get a wake event */
-		nvg_set_request_data(TEGRA_NVG_CHANNEL_WAKE_TIME, wake_time);
+		nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_WAKE_TIME, wake_time);
 
 		/* set the core cstate */
-		write_actlr_el1(state);
+		val = read_actlr_el1() & ~ACTLR_EL1_PMSTATE_MASK;
+		write_actlr_el1(val | (uint64_t)state);
 	}
 
 	return ret;
@@ -78,7 +81,7 @@
 	val |= ((uint64_t)wake_mask << CSTATE_WAKE_MASK_SHIFT);
 
 	/* set the updated cstate info */
-	nvg_set_request_data(TEGRA_NVG_CHANNEL_CSTATE_INFO, val);
+	nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_CSTATE_INFO, val);
 
 	return 0;
 }
@@ -189,7 +192,7 @@
 				((uint64_t)state & MCE_SC7_ALLOWED_MASK);
 
 		/* issue command to check if SC7 is allowed */
-		nvg_set_request_data(TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED, val);
+		nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED, val);
 
 		/* 1 = SC7 allowed, 0 = SC7 not allowed */
 		ret = (nvg_get_result() != 0ULL) ? 1 : 0;
@@ -200,15 +203,14 @@
 
 int32_t nvg_online_core(uint32_t ari_base, uint32_t core)
 {
-	uint64_t cpu = read_mpidr() & (uint64_t)MPIDR_CPU_MASK;
-	uint64_t impl = (read_midr() >> (uint64_t)MIDR_IMPL_SHIFT) &
-			(uint64_t)MIDR_IMPL_MASK;
+	uint64_t cpu = read_mpidr() & MPIDR_CPU_MASK;
+	uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
 	int32_t ret = 0;
 
 	(void)ari_base;
 
 	/* sanity check code id */
-	if ((core >= (uint32_t)MCE_CORE_ID_MAX) || (cpu == core)) {
+	if ((core >= MCE_CORE_ID_MAX) || (cpu == core)) {
 		ERROR("%s: unsupported core id (%d)\n", __func__, core);
 		ret = EINVAL;
 	} else {
@@ -220,7 +222,7 @@
 			ret = EINVAL;
 		} else {
 			/* get a core online */
-			nvg_set_request_data(TEGRA_NVG_CHANNEL_ONLINE_CORE,
+			nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_ONLINE_CORE,
 				((uint64_t)core & MCE_CORE_ID_MASK));
 		}
 	}
@@ -248,7 +250,7 @@
 		((volt & MCE_AUTO_CC3_VTG_MASK) << MCE_AUTO_CC3_VTG_SHIFT) |\
 		((enable != 0U) ? MCE_AUTO_CC3_ENABLE_BIT : 0U));
 
-	nvg_set_request_data(TEGRA_NVG_CHANNEL_CC3_CTRL, (uint64_t)val);
+	nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_CC3_CTRL, (uint64_t)val);
 
 	return 0;
 }
diff --git a/plat/nvidia/tegra/soc/t186/plat_memctrl.c b/plat/nvidia/tegra/soc/t186/plat_memctrl.c
index 38dffb2..376ee86 100644
--- a/plat/nvidia/tegra/soc/t186/plat_memctrl.c
+++ b/plat/nvidia/tegra/soc/t186/plat_memctrl.c
@@ -4,9 +4,13 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <assert.h>
 #include <common/bl_common.h>
 
+#include <mce.h>
 #include <memctrl_v2.h>
+#include <tegra_mc_def.h>
+#include <tegra_platform.h>
 
 /*******************************************************************************
  * Array to hold stream_id override config register offsets
@@ -201,16 +205,330 @@
 	mc_make_txn_override_cfg(SCEW, CGID_TAG_ADR),
 };
 
+static void tegra186_memctrl_reconfig_mss_clients(void)
+{
+#if ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS
+	uint32_t val, wdata_0, wdata_1;
+
+	/*
+	 * Assert Memory Controller's HOTRESET_FLUSH_ENABLE signal for
+	 * boot and strongly ordered MSS clients to flush existing memory
+	 * traffic and stall future requests.
+	 */
+	val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL0);
+	assert(val == MC_CLIENT_HOTRESET_CTRL0_RESET_VAL);
+
+	wdata_0 = MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB |
+#if ENABLE_AFI_DEVICE
+		  MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB |
+#endif
+		  MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB;
+	tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0);
+
+	/* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
+	do {
+		val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0);
+	} while ((val & wdata_0) != wdata_0);
+
+	/* Wait one more time due to SW WAR for known legacy issue */
+	do {
+		val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0);
+	} while ((val & wdata_0) != wdata_0);
+
+	val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL1);
+	assert(val == MC_CLIENT_HOTRESET_CTRL1_RESET_VAL);
+
+	wdata_1 = MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB |
+		  MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB;
+	tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1);
+
+	/* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
+	do {
+		val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1);
+	} while ((val & wdata_1) != wdata_1);
+
+	/* Wait one more time due to SW WAR for known legacy issue */
+	do {
+		val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1);
+	} while ((val & wdata_1) != wdata_1);
+
+	/*
+	 * Change MEMTYPE_OVERRIDE from SO_DEV -> PASSTHRU for boot and
+	 * strongly ordered MSS clients. ROC needs to be single point
+	 * of control on overriding the memory type. So, remove TSA's
+	 * memtype override.
+	 *
+	 * MC clients with default SO_DEV override still enabled at TSA:
+	 * AONW, BPMPW, SCEW, APEW
+	 */
+#if ENABLE_AFI_DEVICE
+	mc_set_tsa_passthrough(AFIW);
+#endif
+	mc_set_tsa_passthrough(HDAW);
+	mc_set_tsa_passthrough(SATAW);
+	mc_set_tsa_passthrough(XUSB_HOSTW);
+	mc_set_tsa_passthrough(XUSB_DEVW);
+	mc_set_tsa_passthrough(SDMMCWAB);
+	mc_set_tsa_passthrough(APEDMAW);
+	mc_set_tsa_passthrough(SESWR);
+	mc_set_tsa_passthrough(ETRW);
+	mc_set_tsa_passthrough(AXISW);
+	mc_set_tsa_passthrough(EQOSW);
+	mc_set_tsa_passthrough(UFSHCW);
+	mc_set_tsa_passthrough(BPMPDMAW);
+	mc_set_tsa_passthrough(AONDMAW);
+	mc_set_tsa_passthrough(SCEDMAW);
+
+	/* Parker has no IO Coherency support and need the following:
+	 * Ordered MC Clients on Parker are AFI, EQOS, SATA, XUSB.
+	 * ISO clients(DISP, VI, EQOS) should never snoop caches and
+	 *     don't need ROC/PCFIFO ordering.
+	 * ISO clients(EQOS) that need ordering should use PCFIFO ordering
+	 *     and bypass ROC ordering by using FORCE_NON_COHERENT path.
+	 * FORCE_NON_COHERENT/FORCE_COHERENT config take precedence
+	 *     over SMMU attributes.
+	 * Force all Normal memory transactions from ISO and non-ISO to be
+	 *     non-coherent(bypass ROC, avoid cache snoop to avoid perf hit).
+	 * Force the SO_DEV transactions from ordered ISO clients(EQOS) to
+	 *     non-coherent path and enable MC PCFIFO interlock for ordering.
+	 * Force the SO_DEV transactions from ordered non-ISO clients (PCIe,
+	 *     XUSB, SATA) to coherent so that the transactions are
+	 *     ordered by ROC.
+	 * PCFIFO ensure write ordering.
+	 * Read after Write ordering is maintained/enforced by MC clients.
+	 * Clients that need PCIe type write ordering must
+	 *     go through ROC ordering.
+	 * Ordering enable for Read clients is not necessary.
+	 * R5's and A9 would get necessary ordering from AXI and
+	 *     don't need ROC ordering enable:
+	 *     - MMIO ordering is through dev mapping and MMIO
+	 *       accesses bypass SMMU.
+	 *     - Normal memory is accessed through SMMU and ordering is
+	 *       ensured by client and AXI.
+	 *     - Ack point for Normal memory is WCAM in MC.
+	 *     - MMIO's can be early acked and AXI ensures dev memory ordering,
+	 *       Client ensures read/write direction change ordering.
+	 *     - See Bug 200312466 for more details.
+	 *
+	 * CGID_TAG_ADR is only present from T186 A02. As this code is common
+	 *    between A01 and A02, tegra_memctrl_set_overrides() programs
+	 *    CGID_TAG_ADR for the necessary clients on A02.
+	 */
+	mc_set_txn_override(HDAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(BPMPW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(PTCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(NVDISPLAYR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(EQOSW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(NVJPGSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(ISPRA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(SDMMCWAA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(VICSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(MPCOREW, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(GPUSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(AXISR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(SCEDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(SDMMCW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(EQOSR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	/* See bug 200131110 comment #35*/
+	mc_set_txn_override(APEDMAR, CGID_TAG_CLIENT_AXI_ID, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(NVENCSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(SDMMCRAB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(VICSRD1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(BPMPDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(VIW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(SDMMCRAA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(AXISW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(XUSB_DEVR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(UFSHCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(TSECSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(GPUSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(SATAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(XUSB_HOSTW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT);
+	mc_set_txn_override(TSECSWRB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(GPUSRD2, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(SCEDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(GPUSWR2, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(AONDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	/* See bug 200131110 comment #35*/
+	mc_set_txn_override(APEDMAW, CGID_TAG_CLIENT_AXI_ID, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(AONW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(HOST1XDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(ETRR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(SESWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(NVJPGSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(NVDECSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(TSECSRDB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(BPMPDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(APER, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(NVDECSRD1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(XUSB_HOSTR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(ISPWA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(SESRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(SCER, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(AONR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(MPCORER, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+	mc_set_txn_override(SDMMCWA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(HDAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(NVDECSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(UFSHCW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(AONDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(SATAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT);
+	mc_set_txn_override(ETRW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(VICSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(NVENCSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	/* See bug 200131110 comment #35 */
+	mc_set_txn_override(AFIR, CGID_TAG_DEFAULT, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(SDMMCWAB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(SDMMCRA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(NVDISPLAYR1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(ISPWB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(BPMPR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(APEW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(SDMMCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	mc_set_txn_override(XUSB_DEVW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT);
+	mc_set_txn_override(TSECSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+	/*
+	 * See bug 200131110 comment #35 - there are no normal requests
+	 * and AWID for SO/DEV requests is hardcoded in RTL for a
+	 * particular PCIE controller
+	 */
+	mc_set_txn_override(AFIW, CGID_TAG_DEFAULT, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_COHERENT);
+	mc_set_txn_override(SCEW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+
+	/*
+	 * At this point, ordering can occur at ROC. So, remove PCFIFO's
+	 * control over ordering requests.
+	 *
+	 * Change PCFIFO_*_ORDERED_CLIENT from ORDERED -> UNORDERED for
+	 * boot and strongly ordered MSS clients
+	 */
+	val = MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL &
+#if ENABLE_AFI_DEVICE
+		mc_set_pcfifo_unordered_boot_so_mss(1, AFIW) &
+#endif
+		mc_set_pcfifo_unordered_boot_so_mss(1, HDAW) &
+		mc_set_pcfifo_unordered_boot_so_mss(1, SATAW);
+	tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG1, val);
+
+	val = MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL &
+		mc_set_pcfifo_unordered_boot_so_mss(2, XUSB_HOSTW) &
+		mc_set_pcfifo_unordered_boot_so_mss(2, XUSB_DEVW);
+	tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG2, val);
+
+	val = MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL &
+		mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCWAB);
+	tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG3, val);
+
+	val = MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL &
+		mc_set_pcfifo_unordered_boot_so_mss(4, SESWR) &
+		mc_set_pcfifo_unordered_boot_so_mss(4, ETRW) &
+		mc_set_pcfifo_unordered_boot_so_mss(4, AXISW) &
+		mc_set_pcfifo_unordered_boot_so_mss(4, UFSHCW) &
+		mc_set_pcfifo_unordered_boot_so_mss(4, BPMPDMAW) &
+		mc_set_pcfifo_unordered_boot_so_mss(4, AONDMAW) &
+		mc_set_pcfifo_unordered_boot_so_mss(4, SCEDMAW);
+	/* EQOSW is the only client that has PCFIFO order enabled. */
+	val |= mc_set_pcfifo_ordered_boot_so_mss(4, EQOSW);
+	tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG4, val);
+
+	val = MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL &
+		mc_set_pcfifo_unordered_boot_so_mss(5, APEDMAW);
+	tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG5, val);
+
+	/*
+	 * Deassert HOTRESET FLUSH_ENABLE for boot and strongly ordered MSS
+	 * clients to allow memory traffic from all clients to start passing
+	 * through ROC
+	 */
+	val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL0);
+	assert(val == wdata_0);
+
+	wdata_0 = MC_CLIENT_HOTRESET_CTRL0_RESET_VAL;
+	tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0);
+
+	val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL1);
+	assert(val == wdata_1);
+
+	wdata_1 = MC_CLIENT_HOTRESET_CTRL1_RESET_VAL;
+	tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1);
+
+#endif
+}
+
+static void tegra186_memctrl_set_overrides(void)
+{
+	const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings();
+	const mc_txn_override_cfg_t *mc_txn_override_cfgs;
+	uint32_t num_txn_override_cfgs;
+	uint32_t i, val;
+
+	/* Get the settings from the platform */
+	assert(plat_mc_settings != NULL);
+	mc_txn_override_cfgs = plat_mc_settings->txn_override_cfg;
+	num_txn_override_cfgs = plat_mc_settings->num_txn_override_cfgs;
+
+	/*
+	 * Set the MC_TXN_OVERRIDE registers for write clients.
+	 */
+	if ((tegra_chipid_is_t186()) &&
+	    (!tegra_platform_is_silicon() ||
+	    (tegra_platform_is_silicon() && (tegra_get_chipid_minor() == 1U)))) {
+
+		/*
+		 * GPU and NVENC settings for Tegra186 simulation and
+		 * Silicon rev. A01
+		 */
+		val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR);
+		val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK;
+		tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR,
+			val | MC_TXN_OVERRIDE_CGID_TAG_ZERO);
+
+		val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR2);
+		val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK;
+		tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR2,
+			val | MC_TXN_OVERRIDE_CGID_TAG_ZERO);
+
+		val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_NVENCSWR);
+		val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK;
+		tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_NVENCSWR,
+			val | MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID);
+
+	} else {
+
+		/*
+		 * Settings for Tegra186 silicon rev. A02 and onwards.
+		 */
+		for (i = 0; i < num_txn_override_cfgs; i++) {
+			val = tegra_mc_read_32(mc_txn_override_cfgs[i].offset);
+			val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK;
+			tegra_mc_write_32(mc_txn_override_cfgs[i].offset,
+				val | mc_txn_override_cfgs[i].cgid_tag);
+		}
+	}
+}
+
 /*******************************************************************************
  * Struct to hold the memory controller settings
  ******************************************************************************/
 static tegra_mc_settings_t tegra186_mc_settings = {
 	.streamid_override_cfg = tegra186_streamid_override_regs,
-	.num_streamid_override_cfgs = ARRAY_SIZE(tegra186_streamid_override_regs),
+	.num_streamid_override_cfgs = (uint32_t)ARRAY_SIZE(tegra186_streamid_override_regs),
 	.streamid_security_cfg = tegra186_streamid_sec_cfgs,
-	.num_streamid_security_cfgs = ARRAY_SIZE(tegra186_streamid_sec_cfgs),
+	.num_streamid_security_cfgs = (uint32_t)ARRAY_SIZE(tegra186_streamid_sec_cfgs),
 	.txn_override_cfg = tegra186_txn_override_cfgs,
-	.num_txn_override_cfgs = ARRAY_SIZE(tegra186_txn_override_cfgs)
+	.num_txn_override_cfgs = (uint32_t)ARRAY_SIZE(tegra186_txn_override_cfgs),
+	.reconfig_mss_clients = tegra186_memctrl_reconfig_mss_clients,
+	.set_txn_overrides = tegra186_memctrl_set_overrides,
 };
 
 /*******************************************************************************
@@ -220,3 +538,45 @@
 {
 	return &tegra186_mc_settings;
 }
+
+/*******************************************************************************
+ * Handler to program the scratch registers with TZDRAM settings for the
+ * resume firmware
+ ******************************************************************************/
+void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes)
+{
+	uint32_t val;
+
+	/*
+	 * Setup the Memory controller to allow only secure accesses to
+	 * the TZDRAM carveout
+	 */
+	INFO("Configuring TrustZone DRAM Memory Carveout\n");
+
+	tegra_mc_write_32(MC_SECURITY_CFG0_0, (uint32_t)phys_base);
+	tegra_mc_write_32(MC_SECURITY_CFG3_0, (uint32_t)(phys_base >> 32));
+	tegra_mc_write_32(MC_SECURITY_CFG1_0, size_in_bytes >> 20);
+
+	/*
+	 * When TZ encryption is enabled, we need to setup TZDRAM
+	 * before CPU accesses TZ Carveout, else CPU will fetch
+	 * non-decrypted data. So save TZDRAM setting for SC7 resume
+	 * FW to restore.
+	 *
+	 * Scratch registers map:
+	 *  RSV55_0 = CFG1[12:0] | CFG0[31:20]
+	 *  RSV55_1 = CFG3[1:0]
+	 */
+	val = tegra_mc_read_32(MC_SECURITY_CFG1_0) & MC_SECURITY_SIZE_MB_MASK;
+	val |= tegra_mc_read_32(MC_SECURITY_CFG0_0) & MC_SECURITY_BOM_MASK;
+	mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_TZDRAM_ADDR_LO, val);
+
+	val = tegra_mc_read_32(MC_SECURITY_CFG3_0) & MC_SECURITY_BOM_HI_MASK;
+	mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_TZDRAM_ADDR_HI, val);
+
+	/*
+	 * MCE propagates the security configuration values across the
+	 * CCPLEX.
+	 */
+	(void)mce_update_gsc_tzdram();
+}
diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
index fb94bce..09e257d 100644
--- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
@@ -12,6 +12,7 @@
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <context.h>
+#include <cortex_a57.h>
 #include <denver.h>
 #include <lib/el3_runtime/context_mgmt.h>
 #include <lib/psci/psci.h>
@@ -19,42 +20,37 @@
 
 #include <mce.h>
 #include <smmu.h>
+#include <stdbool.h>
 #include <t18x_ari.h>
+#include <tegra186_private.h>
 #include <tegra_private.h>
 
 extern void memcpy16(void *dest, const void *src, unsigned int length);
 
-extern void prepare_cpu_pwr_dwn(void);
-extern void tegra186_cpu_reset_handler(void);
-extern uint32_t __tegra186_cpu_reset_handler_end,
-		__tegra186_smmu_context;
-
 /* state id mask */
-#define TEGRA186_STATE_ID_MASK		0xF
+#define TEGRA186_STATE_ID_MASK		0xFU
 /* constants to get power state's wake time */
-#define TEGRA186_WAKE_TIME_MASK		0x0FFFFFF0
-#define TEGRA186_WAKE_TIME_SHIFT	4
+#define TEGRA186_WAKE_TIME_MASK		0x0FFFFFF0U
+#define TEGRA186_WAKE_TIME_SHIFT	4U
 /* default core wake mask for CPU_SUSPEND */
-#define TEGRA186_CORE_WAKE_MASK		0x180c
+#define TEGRA186_CORE_WAKE_MASK		0x180cU
 /* context size to save during system suspend */
-#define TEGRA186_SE_CONTEXT_SIZE	3
+#define TEGRA186_SE_CONTEXT_SIZE	3U
 
 static uint32_t se_regs[TEGRA186_SE_CONTEXT_SIZE];
-static struct t18x_psci_percpu_data {
-	unsigned int wake_time;
-} __aligned(CACHE_WRITEBACK_GRANULE) percpu_data[PLATFORM_CORE_COUNT];
+static struct tegra_psci_percpu_data {
+	uint32_t wake_time;
+} __aligned(CACHE_WRITEBACK_GRANULE) tegra_percpu_data[PLATFORM_CORE_COUNT];
 
-/* System power down state */
-uint32_t tegra186_system_powerdn_state = TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF;
-
-int32_t tegra_soc_validate_power_state(unsigned int power_state,
+int32_t tegra_soc_validate_power_state(uint32_t power_state,
 					psci_power_state_t *req_state)
 {
-	int state_id = psci_get_pstate_id(power_state) & TEGRA186_STATE_ID_MASK;
-	int cpu = plat_my_core_pos();
+	uint8_t state_id = (uint8_t)psci_get_pstate_id(power_state) & TEGRA186_STATE_ID_MASK;
+	uint32_t cpu = plat_my_core_pos();
+	int32_t ret = PSCI_E_SUCCESS;
 
 	/* save the core wake time (in TSC ticks)*/
-	percpu_data[cpu].wake_time = (power_state & TEGRA186_WAKE_TIME_MASK)
+	tegra_percpu_data[cpu].wake_time = (power_state & TEGRA186_WAKE_TIME_MASK)
 			<< TEGRA186_WAKE_TIME_SHIFT;
 
 	/*
@@ -64,8 +60,8 @@
 	 * from DRAM in that function, because the L2 cache is not flushed
 	 * unless the cluster is entering CC6/CC7.
 	 */
-	clean_dcache_range((uint64_t)&percpu_data[cpu],
-			sizeof(percpu_data[cpu]));
+	clean_dcache_range((uint64_t)&tegra_percpu_data[cpu],
+			sizeof(tegra_percpu_data[cpu]));
 
 	/* Sanity check the requested state id */
 	switch (state_id) {
@@ -80,18 +76,19 @@
 
 	default:
 		ERROR("%s: unsupported state id (%d)\n", __func__, state_id);
-		return PSCI_E_INVALID_PARAMS;
+		ret = PSCI_E_INVALID_PARAMS;
+		break;
 	}
 
-	return PSCI_E_SUCCESS;
+	return ret;
 }
 
-int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
+int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
 {
 	const plat_local_state_t *pwr_domain_state;
-	unsigned int stateid_afflvl0, stateid_afflvl2;
-	int cpu = plat_my_core_pos();
-	plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+	uint8_t stateid_afflvl0, stateid_afflvl2;
+	uint32_t cpu = plat_my_core_pos();
+	const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
 	mce_cstate_info_t cstate_info = { 0 };
 	uint64_t smmu_ctx_base;
 	uint32_t val;
@@ -108,9 +105,9 @@
 
 		/* Enter CPU idle/powerdown */
 		val = (stateid_afflvl0 == PSTATE_ID_CORE_IDLE) ?
-			TEGRA_ARI_CORE_C6 : TEGRA_ARI_CORE_C7;
-		(void)mce_command_handler(MCE_CMD_ENTER_CSTATE, val,
-				percpu_data[cpu].wake_time, 0);
+			(uint32_t)TEGRA_ARI_CORE_C6 : (uint32_t)TEGRA_ARI_CORE_C7;
+		(void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE, (uint64_t)val,
+				tegra_percpu_data[cpu].wake_time, 0U);
 
 	} else if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
 
@@ -124,121 +121,156 @@
 
 		/* save 'Secure Boot' Processor Feature Config Register */
 		val = mmio_read_32(TEGRA_MISC_BASE + MISCREG_PFCFG);
-		mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV6, val);
+		mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_BOOTP_FCFG, val);
 
 		/* save SMMU context to TZDRAM */
 		smmu_ctx_base = params_from_bl2->tzdram_base +
-			((uintptr_t)&__tegra186_smmu_context -
-			 (uintptr_t)tegra186_cpu_reset_handler);
+				tegra186_get_smmu_ctx_offset();
 		tegra_smmu_save_context((uintptr_t)smmu_ctx_base);
 
 		/* Prepare for system suspend */
-		cstate_info.cluster = TEGRA_ARI_CLUSTER_CC7;
-		cstate_info.system = TEGRA_ARI_SYSTEM_SC7;
+		cstate_info.cluster = (uint32_t)TEGRA_ARI_CLUSTER_CC7;
+		cstate_info.system = (uint32_t)TEGRA_ARI_SYSTEM_SC7;
 		cstate_info.system_state_force = 1;
 		cstate_info.update_wake_mask = 1;
 		mce_update_cstate_info(&cstate_info);
 
 		/* Loop until system suspend is allowed */
 		do {
-			val = mce_command_handler(MCE_CMD_IS_SC7_ALLOWED,
-					TEGRA_ARI_CORE_C7,
+			val = (uint32_t)mce_command_handler(
+					(uint64_t)MCE_CMD_IS_SC7_ALLOWED,
+					(uint64_t)TEGRA_ARI_CORE_C7,
 					MCE_CORE_SLEEP_TIME_INFINITE,
-					0);
-		} while (val == 0);
+					0U);
+		} while (val == 0U);
 
 		/* Instruct the MCE to enter system suspend state */
-		(void)mce_command_handler(MCE_CMD_ENTER_CSTATE,
-			TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0);
+		(void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE,
+			(uint64_t)TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0U);
+
+		/* set system suspend state for house-keeping */
+		tegra186_set_system_suspend_entry();
+
+	} else {
+		; /* do nothing */
 	}
 
 	return PSCI_E_SUCCESS;
 }
 
 /*******************************************************************************
- * Platform handler to calculate the proper target power level at the
- * specified affinity level
+ * Helper function to check if this is the last ON CPU in the cluster
  ******************************************************************************/
-plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl,
-					     const plat_local_state_t *states,
-					     unsigned int ncpu)
+static bool tegra_last_cpu_in_cluster(const plat_local_state_t *states,
+			uint32_t ncpu)
 {
-	plat_local_state_t target = *states;
-	int cpu = plat_my_core_pos(), ret, cluster_powerdn = 1;
-	int core_pos = read_mpidr() & MPIDR_CPU_MASK;
-	mce_cstate_info_t cstate_info = { 0 };
+	plat_local_state_t target;
+	bool last_on_cpu = true;
+	uint32_t num_cpus = ncpu, pos = 0;
 
-	/* get the power state at this level */
-	if (lvl == MPIDR_AFFLVL1)
-		target = *(states + core_pos);
-	if (lvl == MPIDR_AFFLVL2)
-		target = *(states + cpu);
+	do {
+		target = states[pos];
+		if (target != PLAT_MAX_OFF_STATE) {
+			last_on_cpu = false;
+		}
+		--num_cpus;
+		pos++;
+	} while (num_cpus != 0U);
 
-	/* CPU suspend */
-	if (lvl == MPIDR_AFFLVL1 && target == PSTATE_ID_CORE_POWERDN) {
+	return last_on_cpu;
+}
 
+/*******************************************************************************
+ * Helper function to get target power state for the cluster
+ ******************************************************************************/
+static plat_local_state_t tegra_get_afflvl1_pwr_state(const plat_local_state_t *states,
+			uint32_t ncpu)
+{
+	uint32_t core_pos = (uint32_t)read_mpidr() & (uint32_t)MPIDR_CPU_MASK;
+	uint32_t cpu = plat_my_core_pos();
+	int32_t ret;
+	plat_local_state_t target = states[core_pos];
+	mce_cstate_info_t cstate_info = { 0 };
+
+	/* CPU suspend */
+	if (target == PSTATE_ID_CORE_POWERDN) {
 		/* Program default wake mask */
 		cstate_info.wake_mask = TEGRA186_CORE_WAKE_MASK;
 		cstate_info.update_wake_mask = 1;
 		mce_update_cstate_info(&cstate_info);
 
 		/* Check if CCx state is allowed. */
-		ret = mce_command_handler(MCE_CMD_IS_CCX_ALLOWED,
-				TEGRA_ARI_CORE_C7, percpu_data[cpu].wake_time,
-				0);
-		if (ret)
-			return PSTATE_ID_CORE_POWERDN;
+		ret = mce_command_handler((uint64_t)MCE_CMD_IS_CCX_ALLOWED,
+				(uint64_t)TEGRA_ARI_CORE_C7,
+				tegra_percpu_data[cpu].wake_time,
+				0U);
+		if (ret == 0) {
+			target = PSCI_LOCAL_STATE_RUN;
+		}
 	}
 
 	/* CPU off */
-	if (lvl == MPIDR_AFFLVL1 && target == PLAT_MAX_OFF_STATE) {
-
-		/* find out the number of ON cpus in the cluster */
-		do {
-			target = *states++;
-			if (target != PLAT_MAX_OFF_STATE)
-				cluster_powerdn = 0;
-		} while (--ncpu);
-
+	if (target == PLAT_MAX_OFF_STATE) {
 		/* Enable cluster powerdn from last CPU in the cluster */
-		if (cluster_powerdn) {
-
+		if (tegra_last_cpu_in_cluster(states, ncpu)) {
 			/* Enable CC7 state and turn off wake mask */
-			cstate_info.cluster = TEGRA_ARI_CLUSTER_CC7;
+			cstate_info.cluster = (uint32_t)TEGRA_ARI_CLUSTER_CC7;
 			cstate_info.update_wake_mask = 1;
 			mce_update_cstate_info(&cstate_info);
 
 			/* Check if CCx state is allowed. */
-			ret = mce_command_handler(MCE_CMD_IS_CCX_ALLOWED,
-						  TEGRA_ARI_CORE_C7,
+			ret = mce_command_handler((uint64_t)MCE_CMD_IS_CCX_ALLOWED,
+						  (uint64_t)TEGRA_ARI_CORE_C7,
 						  MCE_CORE_SLEEP_TIME_INFINITE,
-						  0);
-			if (ret)
-				return PSTATE_ID_CORE_POWERDN;
+						  0U);
+			if (ret == 0) {
+				target = PSCI_LOCAL_STATE_RUN;
+			}
 
 		} else {
 
 			/* Turn off wake_mask */
 			cstate_info.update_wake_mask = 1;
 			mce_update_cstate_info(&cstate_info);
+			target = PSCI_LOCAL_STATE_RUN;
 		}
 	}
 
+	return target;
+}
+
+/*******************************************************************************
+ * Platform handler to calculate the proper target power level at the
+ * specified affinity level
+ ******************************************************************************/
+plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl,
+					     const plat_local_state_t *states,
+					     uint32_t ncpu)
+{
+	plat_local_state_t target = PSCI_LOCAL_STATE_RUN;
+	uint32_t cpu = plat_my_core_pos();
+
 	/* System Suspend */
-	if (((lvl == MPIDR_AFFLVL2) || (lvl == MPIDR_AFFLVL1)) &&
-	    (target == PSTATE_ID_SOC_POWERDN))
-		return PSTATE_ID_SOC_POWERDN;
+	if ((lvl == (uint32_t)MPIDR_AFFLVL2) &&
+	    (states[cpu] == PSTATE_ID_SOC_POWERDN)) {
+		target = PSTATE_ID_SOC_POWERDN;
+	}
 
-	/* default state */
-	return PSCI_LOCAL_STATE_RUN;
+	/* CPU off, CPU suspend */
+	if (lvl == (uint32_t)MPIDR_AFFLVL1) {
+		target = tegra_get_afflvl1_pwr_state(states, ncpu);
+	}
+
+	/* target cluster/system state */
+	return target;
 }
 
-int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
+int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
 {
 	const plat_local_state_t *pwr_domain_state =
 		target_state->pwr_domain_state;
-	plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
-	unsigned int stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] &
+	const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+	uint8_t stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] &
 		TEGRA186_STATE_ID_MASK;
 	uint64_t val;
 
@@ -249,8 +281,7 @@
 		 * BL3-1 over to TZDRAM.
 		 */
 		val = params_from_bl2->tzdram_base +
-			((uintptr_t)&__tegra186_cpu_reset_handler_end -
-			 (uintptr_t)tegra186_cpu_reset_handler);
+			tegra186_get_cpu_reset_handler_size();
 		memcpy16((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE,
 			 (uintptr_t)&__BL31_END__ - (uintptr_t)BL31_BASE);
 	}
@@ -258,32 +289,50 @@
 	return PSCI_E_SUCCESS;
 }
 
-int tegra_soc_pwr_domain_on(u_register_t mpidr)
+int32_t tegra_soc_pwr_domain_on(u_register_t mpidr)
 {
-	uint32_t target_cpu = mpidr & MPIDR_CPU_MASK;
-	uint32_t target_cluster = (mpidr & MPIDR_CLUSTER_MASK) >>
+	int32_t ret = PSCI_E_SUCCESS;
+	uint64_t target_cpu = mpidr & MPIDR_CPU_MASK;
+	uint64_t target_cluster = (mpidr & MPIDR_CLUSTER_MASK) >>
 			MPIDR_AFFINITY_BITS;
 
-	if (target_cluster > MPIDR_AFFLVL1) {
+	if (target_cluster > ((uint32_t)PLATFORM_CLUSTER_COUNT - 1U)) {
+
 		ERROR("%s: unsupported CPU (0x%lx)\n", __func__, mpidr);
-		return PSCI_E_NOT_PRESENT;
-	}
+		ret = PSCI_E_NOT_PRESENT;
 
-	/* construct the target CPU # */
-	target_cpu |= (target_cluster << 2);
+	} else {
+		/* construct the target CPU # */
+		target_cpu |= (target_cluster << 2);
 
-	mce_command_handler(MCE_CMD_ONLINE_CORE, target_cpu, 0, 0);
+		(void)mce_command_handler((uint64_t)MCE_CMD_ONLINE_CORE, target_cpu, 0U, 0U);
+	}
 
-	return PSCI_E_SUCCESS;
+	return ret;
 }
 
-int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
+int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
 {
-	int stateid_afflvl2 = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL];
-	int stateid_afflvl0 = target_state->pwr_domain_state[MPIDR_AFFLVL0];
+	uint8_t stateid_afflvl2 = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL];
+	uint8_t stateid_afflvl0 = target_state->pwr_domain_state[MPIDR_AFFLVL0];
 	mce_cstate_info_t cstate_info = { 0 };
+	uint64_t impl, val;
+	const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
+
+	impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
 
 	/*
+	 * Enable ECC and Parity Protection for Cortex-A57 CPUs (Tegra186
+	 * A02p and beyond).
+	 */
+	if ((plat_params->l2_ecc_parity_prot_dis != 1) && (impl != DENVER_IMPL)) {
+
+		val = read_l2ctlr_el1();
+		val |= CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT;
+		write_l2ctlr_el1(val);
+	}
+
+	/*
 	 * Reset power state info for CPUs when onlining, we set
 	 * deepest power when offlining a core but that may not be
 	 * requested by non-secure sw which controls idle states. It
@@ -292,7 +341,7 @@
 	 */
 	if (stateid_afflvl0 == PLAT_MAX_OFF_STATE) {
 
-		cstate_info.cluster = TEGRA_ARI_CLUSTER_CC1;
+		cstate_info.cluster = (uint32_t)TEGRA_ARI_CLUSTER_CC1;
 		cstate_info.update_wake_mask = 1;
 		mce_update_cstate_info(&cstate_info);
 	}
@@ -319,8 +368,8 @@
 		 * and SC7 for SC7 entry which may not be requested by
 		 * non-secure SW which controls idle states.
 		 */
-		cstate_info.cluster = TEGRA_ARI_CLUSTER_CC7;
-		cstate_info.system = TEGRA_ARI_SYSTEM_SC1;
+		cstate_info.cluster = (uint32_t)TEGRA_ARI_CLUSTER_CC7;
+		cstate_info.system = (uint32_t)TEGRA_ARI_SYSTEM_SC1;
 		cstate_info.update_wake_mask = 1;
 		mce_update_cstate_info(&cstate_info);
 	}
@@ -328,65 +377,28 @@
 	return PSCI_E_SUCCESS;
 }
 
-int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
+int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
 {
-	int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
+	uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK;
+
+	(void)target_state;
 
 	/* Disable Denver's DCO operations */
-	if (impl == DENVER_IMPL)
+	if (impl == DENVER_IMPL) {
 		denver_disable_dco();
+	}
 
 	/* Turn off CPU */
-	(void)mce_command_handler(MCE_CMD_ENTER_CSTATE, TEGRA_ARI_CORE_C7,
-			MCE_CORE_SLEEP_TIME_INFINITE, 0);
+	(void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE,
+			(uint64_t)TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0U);
 
 	return PSCI_E_SUCCESS;
 }
 
 __dead2 void tegra_soc_prepare_system_off(void)
 {
-	mce_cstate_info_t cstate_info = { 0 };
-	uint32_t val;
-
-	if (tegra186_system_powerdn_state == TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF) {
-
-		/* power off the entire system */
-		mce_enter_ccplex_state(tegra186_system_powerdn_state);
-
-	} else if (tegra186_system_powerdn_state == TEGRA_ARI_SYSTEM_SC8) {
-
-		/* Prepare for quasi power down */
-		cstate_info.cluster = TEGRA_ARI_CLUSTER_CC7;
-		cstate_info.system = TEGRA_ARI_SYSTEM_SC8;
-		cstate_info.system_state_force = 1;
-		cstate_info.update_wake_mask = 1;
-		mce_update_cstate_info(&cstate_info);
-
-		/* loop until other CPUs power down */
-		do {
-			val = mce_command_handler(MCE_CMD_IS_SC7_ALLOWED,
-					TEGRA_ARI_CORE_C7,
-					MCE_CORE_SLEEP_TIME_INFINITE,
-					0);
-		} while (val == 0);
-
-		/* Enter quasi power down state */
-		(void)mce_command_handler(MCE_CMD_ENTER_CSTATE,
-			TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0);
-
-		/* disable GICC */
-		tegra_gic_cpuif_deactivate();
-
-		/* power down core */
-		prepare_cpu_pwr_dwn();
-
-		/* flush L1/L2 data caches */
-		dcsw_op_all(DCCISW);
-
-	} else {
-		ERROR("%s: unsupported power down state (%d)\n", __func__,
-			tegra186_system_powerdn_state);
-	}
+	/* power off the entire system */
+	mce_enter_ccplex_state((uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF);
 
 	wfi();
 
@@ -396,9 +408,9 @@
 	}
 }
 
-int tegra_soc_prepare_system_reset(void)
+int32_t tegra_soc_prepare_system_reset(void)
 {
-	mce_enter_ccplex_state(TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT);
+	mce_enter_ccplex_state((uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT);
 
 	return PSCI_E_SUCCESS;
 }
diff --git a/plat/nvidia/tegra/soc/t186/plat_secondary.c b/plat/nvidia/tegra/soc/t186/plat_secondary.c
index 4485e27..1650809 100644
--- a/plat/nvidia/tegra/soc/t186/plat_secondary.c
+++ b/plat/nvidia/tegra/soc/t186/plat_secondary.c
@@ -11,65 +11,56 @@
 #include <lib/mmio.h>
 
 #include <mce.h>
+#include <tegra186_private.h>
 #include <tegra_def.h>
 #include <tegra_private.h>
 
-#define MISCREG_CPU_RESET_VECTOR	0x2000
-#define MISCREG_AA64_RST_LOW		0x2004
-#define MISCREG_AA64_RST_HIGH		0x2008
+#define MISCREG_AA64_RST_LOW		0x2004U
+#define MISCREG_AA64_RST_HIGH		0x2008U
 
-#define SCRATCH_SECURE_RSV1_SCRATCH_0	0x658
-#define SCRATCH_SECURE_RSV1_SCRATCH_1	0x65C
+#define SCRATCH_SECURE_RSV1_SCRATCH_0	0x658U
+#define SCRATCH_SECURE_RSV1_SCRATCH_1	0x65CU
 
-#define CPU_RESET_MODE_AA64		1
+#define CPU_RESET_MODE_AA64		1U
 
 extern void memcpy16(void *dest, const void *src, unsigned int length);
 
-extern uint64_t tegra_bl31_phys_base;
-extern uint64_t __tegra186_cpu_reset_handler_end;
-
 /*******************************************************************************
  * Setup secondary CPU vectors
  ******************************************************************************/
 void plat_secondary_setup(void)
 {
 	uint32_t addr_low, addr_high;
-	plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
-	uint64_t cpu_reset_handler_base;
+	const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+	uint64_t cpu_reset_handler_base, cpu_reset_handler_size;
 
 	INFO("Setting up secondary CPU boot\n");
 
-	if ((tegra_bl31_phys_base >= TEGRA_TZRAM_BASE) &&
-	    (tegra_bl31_phys_base <= (TEGRA_TZRAM_BASE + TEGRA_TZRAM_SIZE))) {
-
-		/*
-		 * The BL31 code resides in the TZSRAM which loses state
-		 * when we enter System Suspend. Copy the wakeup trampoline
-		 * code to TZDRAM to help us exit from System Suspend.
-		 */
-		cpu_reset_handler_base = params_from_bl2->tzdram_base;
-		memcpy16((void *)((uintptr_t)cpu_reset_handler_base),
-			 (void *)(uintptr_t)tegra186_cpu_reset_handler,
-			 (uintptr_t)&__tegra186_cpu_reset_handler_end -
-			 (uintptr_t)tegra186_cpu_reset_handler);
+	/*
+	 * The BL31 code resides in the TZSRAM which loses state
+	 * when we enter System Suspend. Copy the wakeup trampoline
+	 * code to TZDRAM to help us exit from System Suspend.
+	 */
+	cpu_reset_handler_base = tegra186_get_cpu_reset_handler_base();
+	cpu_reset_handler_size = tegra186_get_cpu_reset_handler_size();
+	(void)memcpy16((void *)(uintptr_t)params_from_bl2->tzdram_base,
+			(const void *)(uintptr_t)cpu_reset_handler_base,
+			cpu_reset_handler_size);
 
-	} else {
-		cpu_reset_handler_base = (uintptr_t)tegra_secure_entrypoint;
-	}
-
-	addr_low = (uint32_t)cpu_reset_handler_base | CPU_RESET_MODE_AA64;
-	addr_high = (uint32_t)((cpu_reset_handler_base >> 32) & 0x7ff);
+	/* TZDRAM base will be used as the "resume" address */
+	addr_low = (uint32_t)params_from_bl2->tzdram_base | CPU_RESET_MODE_AA64;
+	addr_high = (uint32_t)((params_from_bl2->tzdram_base >> 32U) & 0x7ffU);
 
 	/* write lower 32 bits first, then the upper 11 bits */
 	mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_LOW, addr_low);
 	mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_HIGH, addr_high);
 
 	/* save reset vector to be used during SYSTEM_SUSPEND exit */
-	mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_RSV1_SCRATCH_0,
+	mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_LO,
 			addr_low);
-	mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_RSV1_SCRATCH_1,
+	mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_HI,
 			addr_high);
 
 	/* update reset vector address to the CCPLEX */
-	mce_update_reset_vector();
+	(void)mce_update_reset_vector();
 }
diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c
index 15dbd16..fd109e5 100644
--- a/plat/nvidia/tegra/soc/t186/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t186/plat_setup.c
@@ -27,15 +27,12 @@
 #include <tegra_platform.h>
 #include <tegra_private.h>
 
-DEFINE_RENAME_SYSREG_RW_FUNCS(l2ctlr_el1, CORTEX_A57_L2CTLR_EL1)
-extern uint64_t tegra_enable_l2_ecc_parity_prot;
-
 /*******************************************************************************
  * Tegra186 CPU numbers in cluster #0
  *******************************************************************************
  */
-#define TEGRA186_CLUSTER0_CORE2		2
-#define TEGRA186_CLUSTER0_CORE3		3
+#define TEGRA186_CLUSTER0_CORE2		2U
+#define TEGRA186_CLUSTER0_CORE3		3U
 
 /*******************************************************************************
  * The Tegra power domain tree has a single system level power domain i.e. a
@@ -43,7 +40,7 @@
  * the number of power domains at the highest power level.
  *******************************************************************************
  */
-const unsigned char tegra_power_domain_tree_desc[] = {
+static const uint8_t tegra_power_domain_tree_desc[] = {
 	/* No of root nodes */
 	1,
 	/* No of clusters */
@@ -54,45 +51,53 @@
 	PLATFORM_MAX_CPUS_PER_CLUSTER
 };
 
+/*******************************************************************************
+ * This function returns the Tegra default topology tree information.
+ ******************************************************************************/
+const uint8_t *plat_get_power_domain_tree_desc(void)
+{
+	return tegra_power_domain_tree_desc;
+}
+
 /*
  * Table of regions to map using the MMU.
  */
 static const mmap_region_t tegra_mmap[] = {
-	MAP_REGION_FLAT(TEGRA_MISC_BASE, 0x10000, /* 64KB */
+	MAP_REGION_FLAT(TEGRA_MISC_BASE, 0x10000U, /* 64KB */
 			MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(TEGRA_TSA_BASE, 0x20000, /* 128KB */
+	MAP_REGION_FLAT(TEGRA_TSA_BASE, 0x20000U, /* 128KB */
 			MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(TEGRA_MC_STREAMID_BASE, 0x10000, /* 64KB */
+	MAP_REGION_FLAT(TEGRA_MC_STREAMID_BASE, 0x10000U, /* 64KB */
 			MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(TEGRA_MC_BASE, 0x10000, /* 64KB */
+	MAP_REGION_FLAT(TEGRA_MC_BASE, 0x10000U, /* 64KB */
 			MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(TEGRA_UARTA_BASE, 0x20000, /* 128KB - UART A, B*/
+	MAP_REGION_FLAT(TEGRA_UARTA_BASE, 0x20000U, /* 128KB - UART A, B*/
 			MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(TEGRA_UARTC_BASE, 0x20000, /* 128KB - UART C, G */
+	MAP_REGION_FLAT(TEGRA_UARTC_BASE, 0x20000U, /* 128KB - UART C, G */
 			MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(TEGRA_UARTD_BASE, 0x30000, /* 192KB - UART D, E, F */
+	MAP_REGION_FLAT(TEGRA_UARTD_BASE, 0x30000U, /* 192KB - UART D, E, F */
 			MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(TEGRA_FUSE_BASE, 0x10000, /* 64KB */
+	MAP_REGION_FLAT(TEGRA_FUSE_BASE, 0x10000U, /* 64KB */
 			MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(TEGRA_GICD_BASE, 0x20000, /* 128KB */
+	MAP_REGION_FLAT(TEGRA_GICD_BASE, 0x20000U, /* 128KB */
 			MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(TEGRA_SE0_BASE, 0x10000, /* 64KB */
+	MAP_REGION_FLAT(TEGRA_SE0_BASE, 0x10000U, /* 64KB */
 			MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(TEGRA_PKA1_BASE, 0x10000, /* 64KB */
+	MAP_REGION_FLAT(TEGRA_PKA1_BASE, 0x10000U, /* 64KB */
 			MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(TEGRA_RNG1_BASE, 0x10000, /* 64KB */
+	MAP_REGION_FLAT(TEGRA_RNG1_BASE, 0x10000U, /* 64KB */
 			MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(TEGRA_CAR_RESET_BASE, 0x10000, /* 64KB */
+	MAP_REGION_FLAT(TEGRA_CAR_RESET_BASE, 0x10000U, /* 64KB */
 			MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(TEGRA_PMC_BASE, 0x40000, /* 256KB */
+	MAP_REGION_FLAT(TEGRA_PMC_BASE, 0x40000U, /* 256KB */
 			MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(TEGRA_SCRATCH_BASE, 0x10000, /* 64KB */
+	MAP_REGION_FLAT(TEGRA_SCRATCH_BASE, 0x10000U, /* 64KB */
 			MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(TEGRA_MMCRAB_BASE, 0x60000, /* 384KB */
+	MAP_REGION_FLAT(TEGRA_MMCRAB_BASE, 0x60000U, /* 384KB */
 			MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(TEGRA_ARM_ACTMON_CTR_BASE, 0x20000, /* 128KB - ARM/Denver */
+	MAP_REGION_FLAT(TEGRA_ARM_ACTMON_CTR_BASE, 0x20000U, /* 128KB - ARM/Denver */
 			MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(TEGRA_SMMU0_BASE, 0x1000000, /* 64KB */
+	MAP_REGION_FLAT(TEGRA_SMMU0_BASE, 0x1000000U, /* 64KB */
 			MT_DEVICE | MT_RW | MT_SECURE),
 	{0}
 };
@@ -109,7 +114,7 @@
 /*******************************************************************************
  * Handler to get the System Counter Frequency
  ******************************************************************************/
-unsigned int plat_get_syscnt_freq2(void)
+uint32_t plat_get_syscnt_freq2(void)
 {
 	return 31250000;
 }
@@ -136,56 +141,42 @@
 /*******************************************************************************
  * Retrieve the UART controller base to be used as the console
  ******************************************************************************/
-uint32_t plat_get_console_from_id(int id)
+uint32_t plat_get_console_from_id(int32_t id)
 {
-	if (id > TEGRA186_MAX_UART_PORTS)
-		return 0;
+	uint32_t ret;
 
-	return tegra186_uart_addresses[id];
-}
+	if (id > TEGRA186_MAX_UART_PORTS) {
+		ret = 0;
+	} else {
+		ret = tegra186_uart_addresses[id];
+	}
 
-/* represent chip-version as concatenation of major (15:12), minor (11:8) and subrev (7:0) */
-#define TEGRA186_VER_A02P	0x1201
+	return ret;
+}
 
 /*******************************************************************************
  * Handler for early platform setup
  ******************************************************************************/
 void plat_early_platform_setup(void)
 {
-	int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
-	uint32_t chip_subrev, val;
+	uint64_t impl, val;
+	const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
 
 	/* sanity check MCE firmware compatibility */
 	mce_verify_firmware_version();
 
+	impl = (read_midr() >> MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK;
+
 	/*
-	 * Enable ECC and Parity Protection for Cortex-A57 CPUs
-	 * for Tegra A02p SKUs
+	 * Enable ECC and Parity Protection for Cortex-A57 CPUs (Tegra186
+	 * A02p and beyond).
 	 */
-	if (impl != DENVER_IMPL) {
-
-		/* get the major, minor and sub-version values */
-		chip_subrev = mmio_read_32(TEGRA_FUSE_BASE + OPT_SUBREVISION) &
-			      SUBREVISION_MASK;
+	if ((plat_params->l2_ecc_parity_prot_dis != 1) &&
+	    (impl != (uint64_t)DENVER_IMPL)) {
 
-		/* prepare chip version number */
-		val = (tegra_get_chipid_major() << 12) |
-		      (tegra_get_chipid_minor() << 8) |
-		       chip_subrev;
-
-		/* enable L2 ECC for Tegra186 A02P and beyond */
-		if (val >= TEGRA186_VER_A02P) {
-
-			val = read_l2ctlr_el1();
-			val |= CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT;
-			write_l2ctlr_el1(val);
-
-			/*
-			 * Set the flag to enable ECC/Parity Protection
-			 * when we exit System Suspend or Cluster Powerdn
-			 */
-			tegra_enable_l2_ecc_parity_prot = 1;
-		}
+		val = read_l2ctlr_el1();
+		val |= CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT;
+		write_l2ctlr_el1(val);
 	}
 }
 
@@ -208,8 +199,9 @@
 	 * Initialize the FIQ handler only if the platform supports any
 	 * FIQ interrupt sources.
 	 */
-	if (sizeof(tegra186_interrupt_props) > 0)
+	if (sizeof(tegra186_interrupt_props) > 0U) {
 		tegra_fiq_handler_setup();
+	}
 }
 
 /*******************************************************************************
@@ -219,7 +211,7 @@
 {
 	uint32_t val;
 
-	val = mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV53_LO);
+	val = mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_BL31_PARAMS_ADDR);
 
 	return (struct tegra_bl31_params *)(uintptr_t)val;
 }
@@ -231,7 +223,7 @@
 {
 	uint32_t val;
 
-	val = mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV53_HI);
+	val = mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_BL31_PLAT_PARAMS_ADDR);
 
 	return (plat_params_from_bl2_t *)(uintptr_t)val;
 }
@@ -242,33 +234,34 @@
  * to convert an MPIDR to a unique linear index. An error code (-1) is returned
  * in case the MPIDR is invalid.
  ******************************************************************************/
-int plat_core_pos_by_mpidr(u_register_t mpidr)
+int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
 {
-	unsigned int cluster_id, cpu_id, pos;
+	u_register_t cluster_id, cpu_id, pos;
+	int32_t ret;
 
-	cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
-	cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+	cluster_id = (mpidr >> (u_register_t)MPIDR_AFF1_SHIFT) & (u_register_t)MPIDR_AFFLVL_MASK;
+	cpu_id = (mpidr >> (u_register_t)MPIDR_AFF0_SHIFT) & (u_register_t)MPIDR_AFFLVL_MASK;
 
 	/*
 	 * Validate cluster_id by checking whether it represents
 	 * one of the two clusters present on the platform.
-	 */
-	if (cluster_id >= PLATFORM_CLUSTER_COUNT)
-		return PSCI_E_NOT_PRESENT;
-
-	/*
 	 * Validate cpu_id by checking whether it represents a CPU in
 	 * one of the two clusters present on the platform.
 	 */
-	if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER)
-		return PSCI_E_NOT_PRESENT;
+	if ((cluster_id >= (u_register_t)PLATFORM_CLUSTER_COUNT) ||
+	    (cpu_id >= (u_register_t)PLATFORM_MAX_CPUS_PER_CLUSTER)) {
+		ret = PSCI_E_NOT_PRESENT;
+	} else {
+		/* calculate the core position */
+		pos = cpu_id + (cluster_id << 2U);
 
-	/* calculate the core position */
-	pos = cpu_id + (cluster_id << 2);
-
-	/* check for non-existent CPUs */
-	if (pos == TEGRA186_CLUSTER0_CORE2 || pos == TEGRA186_CLUSTER0_CORE3)
-		return PSCI_E_NOT_PRESENT;
+		/* check for non-existent CPUs */
+		if ((pos == TEGRA186_CLUSTER0_CORE2) || (pos == TEGRA186_CLUSTER0_CORE3)) {
+			ret = PSCI_E_NOT_PRESENT;
+		} else {
+			ret = (int32_t)pos;
+		}
+	}
 
-	return pos;
+	return ret;
 }
diff --git a/plat/nvidia/tegra/soc/t186/plat_sip_calls.c b/plat/nvidia/tegra/soc/t186/plat_sip_calls.c
index bf98fcf..4de8a9e 100644
--- a/plat/nvidia/tegra/soc/t186/plat_sip_calls.c
+++ b/plat/nvidia/tegra/soc/t186/plat_sip_calls.c
@@ -20,17 +20,14 @@
 #include <t18x_ari.h>
 #include <tegra_private.h>
 
-extern uint32_t tegra186_system_powerdn_state;
-
 /*******************************************************************************
  * Offset to read the ref_clk counter value
  ******************************************************************************/
-#define REF_CLK_OFFSET		4
+#define REF_CLK_OFFSET		4ULL
 
 /*******************************************************************************
  * Tegra186 SiP SMCs
  ******************************************************************************/
-#define TEGRA_SIP_SYSTEM_SHUTDOWN_STATE			0xC2FFFE01
 #define TEGRA_SIP_GET_ACTMON_CLK_COUNTERS		0xC2FFFE02
 #define TEGRA_SIP_MCE_CMD_ENTER_CSTATE			0xC2FFFF00
 #define TEGRA_SIP_MCE_CMD_UPDATE_CSTATE_INFO		0xC2FFFF01
@@ -38,7 +35,7 @@
 #define TEGRA_SIP_MCE_CMD_READ_CSTATE_STATS		0xC2FFFF03
 #define TEGRA_SIP_MCE_CMD_WRITE_CSTATE_STATS		0xC2FFFF04
 #define TEGRA_SIP_MCE_CMD_IS_SC7_ALLOWED		0xC2FFFF05
-#define TEGRA_SIP_MCE_CMD_ONLINE_CORE			0xC2FFFF06
+
 #define TEGRA_SIP_MCE_CMD_CC3_CTRL			0xC2FFFF07
 #define TEGRA_SIP_MCE_CMD_ECHO_DATA			0xC2FFFF08
 #define TEGRA_SIP_MCE_CMD_READ_VERSIONS			0xC2FFFF09
@@ -55,33 +52,39 @@
 /*******************************************************************************
  * This function is responsible for handling all T186 SiP calls
  ******************************************************************************/
-int plat_sip_handler(uint32_t smc_fid,
+int32_t plat_sip_handler(uint32_t smc_fid,
 		     uint64_t x1,
 		     uint64_t x2,
 		     uint64_t x3,
 		     uint64_t x4,
-		     void *cookie,
+		     const void *cookie,
 		     void *handle,
 		     uint64_t flags)
 {
-	int mce_ret;
-	int impl, cpu;
+	int32_t mce_ret, ret = 0;
+	uint32_t impl, cpu;
 	uint32_t base, core_clk_ctr, ref_clk_ctr;
+	uint32_t local_smc_fid = smc_fid;
+	uint64_t local_x1 = x1, local_x2 = x2, local_x3 = x3;
+
+	(void)x4;
+	(void)cookie;
+	(void)flags;
 
 	if (((smc_fid >> FUNCID_CC_SHIFT) & FUNCID_CC_MASK) == SMC_32) {
 		/* 32-bit function, clear top parameter bits */
 
-		x1 = (uint32_t)x1;
-		x2 = (uint32_t)x2;
-		x3 = (uint32_t)x3;
+		local_x1 = (uint32_t)x1;
+		local_x2 = (uint32_t)x2;
+		local_x3 = (uint32_t)x3;
 	}
 
 	/*
 	 * Convert SMC FID to SMC64, to support SMC32/SMC64 configurations
 	 */
-	smc_fid |= (SMC_64 << FUNCID_CC_SHIFT);
+	local_smc_fid |= (SMC_64 << FUNCID_CC_SHIFT);
 
-	switch (smc_fid) {
+	switch (local_smc_fid) {
 	/*
 	 * Micro Coded Engine (MCE) commands reside in the 0x82FFFF00 -
 	 * 0x82FFFFFF SiP SMC space
@@ -106,41 +109,13 @@
 	case TEGRA_SIP_MCE_CMD_MISC_CCPLEX:
 
 		/* clean up the high bits */
-		smc_fid &= MCE_CMD_MASK;
+		local_smc_fid &= MCE_CMD_MASK;
 
 		/* execute the command and store the result */
-		mce_ret = mce_command_handler(smc_fid, x1, x2, x3);
-		write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X0,
-			      (uint64_t)mce_ret);
-
-		return 0;
-
-	case TEGRA_SIP_SYSTEM_SHUTDOWN_STATE:
-
-		/* clean up the high bits */
-		x1 = (uint32_t)x1;
-
-		/*
-		 * SC8 is a special Tegra186 system state where the CPUs and
-		 * DRAM are powered down but the other subsystem is still
-		 * alive.
-		 */
-		if ((x1 == TEGRA_ARI_SYSTEM_SC8) ||
-		    (x1 == TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF)) {
-
-			tegra186_system_powerdn_state = x1;
-			flush_dcache_range(
-				(uintptr_t)&tegra186_system_powerdn_state,
-				sizeof(tegra186_system_powerdn_state));
-
-		} else {
-
-			ERROR("%s: unhandled powerdn state (%d)\n", __func__,
-				(uint32_t)x1);
-			return -ENOTSUP;
-		}
-
-		return 0;
+		mce_ret = mce_command_handler(local_smc_fid, local_x1, local_x2, local_x3);
+		write_ctx_reg(get_gpregs_ctx(handle),
+			      CTX_GPREG_X0, (uint64_t)(mce_ret));
+		break;
 
 	/*
 	 * This function ID reads the Activity monitor's core/ref clock
@@ -155,28 +130,30 @@
 		impl = ((uint32_t)x2 >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
 
 		/* sanity check target CPU number */
-		if (cpu > PLATFORM_MAX_CPUS_PER_CLUSTER)
-			return -EINVAL;
-
-		/* get the base address for the current CPU */
-		base = (impl == DENVER_IMPL) ? TEGRA_DENVER_ACTMON_CTR_BASE :
-			TEGRA_ARM_ACTMON_CTR_BASE;
+		if (cpu > (uint32_t)PLATFORM_MAX_CPUS_PER_CLUSTER) {
+			ret = -EINVAL;
+		} else {
+			/* get the base address for the current CPU */
+			base = (impl == DENVER_IMPL) ? TEGRA_DENVER_ACTMON_CTR_BASE :
+				TEGRA_ARM_ACTMON_CTR_BASE;
 
-		/* read the clock counter values */
-		core_clk_ctr = mmio_read_32(base + (8 * cpu));
-		ref_clk_ctr = mmio_read_32(base + (8 * cpu) + REF_CLK_OFFSET);
+			/* read the clock counter values */
+			core_clk_ctr = mmio_read_32(base + (8ULL * cpu));
+			ref_clk_ctr = mmio_read_32(base + (8ULL * cpu) + REF_CLK_OFFSET);
 
-		/* return the counter values as two different parameters */
-		write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X1,
-			      (uint64_t)core_clk_ctr);
-		write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X2,
-			      (uint64_t)ref_clk_ctr);
+			/* return the counter values as two different parameters */
+			write_ctx_reg(get_gpregs_ctx(handle),
+				      CTX_GPREG_X1, (core_clk_ctr));
+			write_ctx_reg(get_gpregs_ctx(handle),
+				      CTX_GPREG_X2, (ref_clk_ctr));
+		}
 
-		return 0;
+		break;
 
 	default:
+		ret = -ENOTSUP;
 		break;
 	}
 
-	return -ENOTSUP;
+	return ret;
 }
diff --git a/plat/nvidia/tegra/soc/t186/plat_smmu.c b/plat/nvidia/tegra/soc/t186/plat_smmu.c
index 19e065c..95f6def 100644
--- a/plat/nvidia/tegra/soc/t186/plat_smmu.c
+++ b/plat/nvidia/tegra/soc/t186/plat_smmu.c
@@ -8,6 +8,9 @@
 
 #include <smmu.h>
 #include <tegra_def.h>
+#include <tegra_mc_def.h>
+
+#define MAX_NUM_SMMU_DEVICES	U(1)
 
 /*******************************************************************************
  * Array to hold SMMU context for Tegra186
@@ -305,7 +308,15 @@
 smmu_regs_t *plat_get_smmu_ctx(void)
 {
 	/* index of _END_OF_TABLE_ */
-	tegra186_smmu_context[0].val = ARRAY_SIZE(tegra186_smmu_context) - 1;
+	tegra186_smmu_context[0].val = (uint32_t)(ARRAY_SIZE(tegra186_smmu_context)) - 1U;
 
 	return tegra186_smmu_context;
 }
+
+/*******************************************************************************
+ * Handler to return the support SMMU devices number
+ ******************************************************************************/
+uint32_t plat_get_num_smmu_devices(void)
+{
+	return MAX_NUM_SMMU_DEVICES;
+}
diff --git a/plat/nvidia/tegra/soc/t186/plat_trampoline.S b/plat/nvidia/tegra/soc/t186/plat_trampoline.S
index 69ca798..e3393e9 100644
--- a/plat/nvidia/tegra/soc/t186/plat_trampoline.S
+++ b/plat/nvidia/tegra/soc/t186/plat_trampoline.S
@@ -10,23 +10,32 @@
 #include <plat/common/common_def.h>
 #include <tegra_def.h>
 
+#define TEGRA186_STATE_SYSTEM_SUSPEND	0x5C7
+#define TEGRA186_STATE_SYSTEM_RESUME	0x600D
 #define TEGRA186_SMMU_CTX_SIZE		0x420
 
 	.globl	tegra186_cpu_reset_handler
 
 /* CPU reset handler routine */
 func tegra186_cpu_reset_handler _align=4
-	/*
-	 * The TZRAM loses state during System Suspend. We use this
-	 * information to decide if the reset handler is running after a
-	 * System Suspend. Resume from system suspend requires restoring
-	 * the entire state from TZDRAM to TZRAM.
-	 */
-	mov	x0, #BL31_BASE
-	ldr	x0, [x0]
-	cbnz	x0, boot_cpu
+	/* check if we are exiting system suspend state */
+	adr	x0, __tegra186_system_suspend_state
+	ldr	x1, [x0]
+	mov	x2, #TEGRA186_STATE_SYSTEM_SUSPEND
+	lsl	x2, x2, #16
+	add	x2, x2, #TEGRA186_STATE_SYSTEM_SUSPEND
+	cmp	x1, x2
+	bne	boot_cpu
 
-	/* resume from system suspend */
+	/* set system resume state */
+	mov	x1, #TEGRA186_STATE_SYSTEM_RESUME
+	lsl	x1, x1, #16
+	mov	x2, #TEGRA186_STATE_SYSTEM_RESUME
+	add	x1, x1, x2
+	str	x1, [x0]
+	dsb	sy
+
+	/* prepare to relocate to TZSRAM */
 	mov	x0, #BL31_BASE
 	adr	x1, __tegra186_cpu_reset_handler_end
 	adr	x2, __tegra186_cpu_reset_handler_data
@@ -69,6 +78,12 @@
 __tegra186_cpu_reset_handler_data:
 	.quad	tegra_secure_entrypoint
 	.quad	__BL31_END__ - BL31_BASE
+
+	.globl	__tegra186_system_suspend_state
+__tegra186_system_suspend_state:
+	.quad	0
+
+	.align 4
 	.globl	__tegra186_smmu_context
 __tegra186_smmu_context:
 	.rept	TEGRA186_SMMU_CTX_SIZE
@@ -80,3 +95,50 @@
 	.align 4
 	.globl	__tegra186_cpu_reset_handler_end
 __tegra186_cpu_reset_handler_end:
+
+	.globl tegra186_get_cpu_reset_handler_size
+	.globl tegra186_get_cpu_reset_handler_base
+	.globl tegra186_get_smmu_ctx_offset
+	.globl tegra186_set_system_suspend_entry
+
+/* return size of the CPU reset handler */
+func tegra186_get_cpu_reset_handler_size
+	adr	x0, __tegra186_cpu_reset_handler_end
+	adr	x1, tegra186_cpu_reset_handler
+	sub	x0, x0, x1
+	ret
+endfunc tegra186_get_cpu_reset_handler_size
+
+/* return the start address of the CPU reset handler */
+func tegra186_get_cpu_reset_handler_base
+	adr	x0, tegra186_cpu_reset_handler
+	ret
+endfunc tegra186_get_cpu_reset_handler_base
+
+/* return the size of the SMMU context */
+func tegra186_get_smmu_ctx_offset
+	adr	x0, __tegra186_smmu_context
+	adr	x1, tegra186_cpu_reset_handler
+	sub	x0, x0, x1
+	ret
+endfunc tegra186_get_smmu_ctx_offset
+
+/* set system suspend state before SC7 entry */
+func tegra186_set_system_suspend_entry
+	mov	x0, #TEGRA_MC_BASE
+	mov	x3, #MC_SECURITY_CFG3_0
+	ldr	w1, [x0, x3]
+	lsl	x1, x1, #32
+	mov	x3, #MC_SECURITY_CFG0_0
+	ldr	w2, [x0, x3]
+	orr	x3, x1, x2			/* TZDRAM base */
+	adr	x0, __tegra186_system_suspend_state
+	adr	x1, tegra186_cpu_reset_handler
+	sub	x2, x0, x1			/* offset in TZDRAM */
+	mov	x0, #TEGRA186_STATE_SYSTEM_SUSPEND
+	lsl	x0, x0, #16
+	add	x0, x0, #TEGRA186_STATE_SYSTEM_SUSPEND
+	str	x0, [x3, x2]			/* set value in TZDRAM */
+	dsb	sy
+	ret
+endfunc tegra186_set_system_suspend_entry
diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk
index c905323..fdeb886 100644
--- a/plat/nvidia/tegra/soc/t186/platform_t186.mk
+++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk
@@ -11,18 +11,9 @@
 ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS	:= 1
 $(eval $(call add_define,ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS))
 
-RELOCATE_TO_BL31_BASE			:= 1
-$(eval $(call add_define,RELOCATE_TO_BL31_BASE))
-
 ENABLE_CHIP_VERIFICATION_HARNESS	:= 0
 $(eval $(call add_define,ENABLE_CHIP_VERIFICATION_HARNESS))
 
-ENABLE_SMMU_DEVICE			:= 1
-$(eval $(call add_define,ENABLE_SMMU_DEVICE))
-
-NUM_SMMU_DEVICES			:= 1
-$(eval $(call add_define,NUM_SMMU_DEVICES))
-
 RESET_TO_BL31				:= 1
 
 PROGRAMMABLE_RESET_ADDRESS		:= 1
@@ -48,8 +39,10 @@
 # platform files
 PLAT_INCLUDES		+=	-I${SOC_DIR}/drivers/include
 
-BL31_SOURCES		+=	lib/cpus/aarch64/denver.S		\
+BL31_SOURCES		+=	drivers/ti/uart/aarch64/16550_console.S	\
+				lib/cpus/aarch64/denver.S		\
 				lib/cpus/aarch64/cortex_a57.S		\
+				${COMMON_DIR}/drivers/gpcdma/gpcdma.c	\
 				${COMMON_DIR}/drivers/memctrl/memctrl_v2.c \
 				${COMMON_DIR}/drivers/smmu/smmu.c	\
 				${SOC_DIR}/drivers/mce/mce.c		\
@@ -64,3 +57,13 @@
 				${SOC_DIR}/plat_smmu.c			\
 				${SOC_DIR}/plat_trampoline.S
 
+# Enable workarounds for selected Cortex-A57 erratas.
+A57_DISABLE_NON_TEMPORAL_HINT	:=	1
+ERRATA_A57_806969		:=	1
+ERRATA_A57_813419		:=	1
+ERRATA_A57_813420		:=	1
+ERRATA_A57_826974		:=	1
+ERRATA_A57_826977		:=	1
+ERRATA_A57_828024		:=	1
+ERRATA_A57_829520		:=	1
+ERRATA_A57_833471		:=	1
diff --git a/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h b/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h
new file mode 100644
index 0000000..be1f9cc
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h
@@ -0,0 +1,659 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SE_PRIVATE_H
+#define SE_PRIVATE_H
+
+#include <stdbool.h>
+#include <security_engine.h>
+
+/*
+ * PMC registers
+ */
+
+/* Secure scratch registers */
+#define PMC_SECURE_SCRATCH4_OFFSET		0xC0U
+#define PMC_SECURE_SCRATCH5_OFFSET		0xC4U
+#define PMC_SECURE_SCRATCH6_OFFSET		0x224U
+#define PMC_SECURE_SCRATCH7_OFFSET		0x228U
+#define PMC_SECURE_SCRATCH116_OFFSET		0xB28U
+#define PMC_SECURE_SCRATCH117_OFFSET		0xB2CU
+#define PMC_SECURE_SCRATCH120_OFFSET		0xB38U
+#define PMC_SECURE_SCRATCH121_OFFSET		0xB3CU
+#define PMC_SECURE_SCRATCH122_OFFSET		0xB40U
+#define PMC_SECURE_SCRATCH123_OFFSET		0xB44U
+
+/*
+ * AHB arbitration memory write queue
+ */
+#define ARAHB_MEM_WRQUE_MST_ID_OFFSET		0xFCU
+#define ARAHB_MST_ID_SE2_MASK			(0x1U << 13)
+#define ARAHB_MST_ID_SE_MASK			(0x1U << 14)
+
+/**
+ * SE registers
+ */
+#define TEGRA_SE_AES_KEYSLOT_COUNT		16
+#define SE_MAX_LAST_BLOCK_SIZE			0xFFFFF
+
+/* SE Status register */
+#define SE_STATUS_OFFSET			0x800U
+#define SE_STATUS_SHIFT				0
+#define SE_STATUS_IDLE	\
+		((0U) << SE_STATUS_SHIFT)
+#define SE_STATUS_BUSY	\
+		((1U) << SE_STATUS_SHIFT)
+#define SE_STATUS(x)	\
+		((x) & ((0x3U) << SE_STATUS_SHIFT))
+
+#define SE_MEM_INTERFACE_SHIFT			2
+#define SE_MEM_INTERFACE_IDLE			0
+#define SE_MEM_INTERFACE_BUSY			1
+#define SE_MEM_INTERFACE(x)	((x) << SE_STATUS_SHIFT)
+
+/* SE register definitions */
+#define SE_SECURITY_REG_OFFSET			0x0
+#define SE_SECURITY_TZ_LOCK_SOFT_SHIFT		5
+#define SE_SECURE				0x0
+#define SE_SECURITY_TZ_LOCK_SOFT(x)	((x) << SE_SECURITY_TZ_LOCK_SOFT_SHIFT)
+
+#define SE_SEC_ENG_DIS_SHIFT			1
+#define SE_DISABLE_FALSE			0
+#define SE_DISABLE_TRUE				1
+#define SE_SEC_ENG_DISABLE(x)((x) << SE_SEC_ENG_DIS_SHIFT)
+
+/* SE config register */
+#define SE_CONFIG_REG_OFFSET			0x14U
+#define SE_CONFIG_ENC_ALG_SHIFT 		12
+#define SE_CONFIG_ENC_ALG_AES_ENC	\
+		((1U) << SE_CONFIG_ENC_ALG_SHIFT)
+#define SE_CONFIG_ENC_ALG_RNG	\
+		((2U) << SE_CONFIG_ENC_ALG_SHIFT)
+#define SE_CONFIG_ENC_ALG_SHA	\
+		((3U) << SE_CONFIG_ENC_ALG_SHIFT)
+#define SE_CONFIG_ENC_ALG_RSA	\
+		((4U) << SE_CONFIG_ENC_ALG_SHIFT)
+#define SE_CONFIG_ENC_ALG_NOP	\
+		((0U) << SE_CONFIG_ENC_ALG_SHIFT)
+#define SE_CONFIG_ENC_ALG(x)	\
+		((x) & ((0xFU) << SE_CONFIG_ENC_ALG_SHIFT))
+
+#define SE_CONFIG_DEC_ALG_SHIFT 		8
+#define SE_CONFIG_DEC_ALG_AES	\
+		((1U) << SE_CONFIG_DEC_ALG_SHIFT)
+#define SE_CONFIG_DEC_ALG_NOP	\
+		((0U) << SE_CONFIG_DEC_ALG_SHIFT)
+#define SE_CONFIG_DEC_ALG(x)	\
+		((x) & ((0xFU) << SE_CONFIG_DEC_ALG_SHIFT))
+
+#define SE_CONFIG_DST_SHIFT	 		2
+#define SE_CONFIG_DST_MEMORY	\
+		((0U) << SE_CONFIG_DST_SHIFT)
+#define SE_CONFIG_DST_HASHREG	\
+		((1U) << SE_CONFIG_DST_SHIFT)
+#define SE_CONFIG_DST_KEYTAB	\
+		((2U) << SE_CONFIG_DST_SHIFT)
+#define SE_CONFIG_DST_SRK	\
+		((3U) << SE_CONFIG_DST_SHIFT)
+#define SE_CONFIG_DST_RSAREG	\
+		((4U) << SE_CONFIG_DST_SHIFT)
+#define SE_CONFIG_DST(x)	\
+		((x) & ((0x7U) << SE_CONFIG_DST_SHIFT))
+
+#define SE_CONFIG_ENC_MODE_SHIFT		24
+#define SE_CONFIG_ENC_MODE_KEY128	\
+			((0UL) << SE_CONFIG_ENC_MODE_SHIFT)
+#define SE_CONFIG_ENC_MODE_KEY192	\
+			((1UL) << SE_CONFIG_ENC_MODE_SHIFT)
+#define SE_CONFIG_ENC_MODE_KEY256	\
+			((2UL) << SE_CONFIG_ENC_MODE_SHIFT)
+#define SE_CONFIG_ENC_MODE_SHA1				\
+			((0UL) << SE_CONFIG_ENC_MODE_SHIFT)
+#define SE_CONFIG_ENC_MODE_SHA224	\
+			((4UL) << SE_CONFIG_ENC_MODE_SHIFT)
+#define SE_CONFIG_ENC_MODE_SHA256	\
+			((5UL) << SE_CONFIG_ENC_MODE_SHIFT)
+#define SE_CONFIG_ENC_MODE_SHA384	\
+			((6UL) << SE_CONFIG_ENC_MODE_SHIFT)
+#define SE_CONFIG_ENC_MODE_SHA512	\
+			((7UL) << SE_CONFIG_ENC_MODE_SHIFT)
+#define SE_CONFIG_ENC_MODE(x)\
+			((x) & ((0xFFUL) << SE_CONFIG_ENC_MODE_SHIFT))
+
+#define SE_CONFIG_DEC_MODE_SHIFT		16
+#define SE_CONFIG_DEC_MODE_KEY128	\
+			((0UL) << SE_CONFIG_DEC_MODE_SHIFT)
+#define SE_CONFIG_DEC_MODE_KEY192	\
+			((1UL) << SE_CONFIG_DEC_MODE_SHIFT)
+#define SE_CONFIG_DEC_MODE_KEY256	\
+			((2UL) << SE_CONFIG_DEC_MODE_SHIFT)
+#define SE_CONFIG_DEC_MODE_SHA1				\
+			((0UL) << SE_CONFIG_DEC_MODE_SHIFT)
+#define SE_CONFIG_DEC_MODE_SHA224	\
+			((4UL) << SE_CONFIG_DEC_MODE_SHIFT)
+#define SE_CONFIG_DEC_MODE_SHA256	\
+			((5UL) << SE_CONFIG_DEC_MODE_SHIFT)
+#define SE_CONFIG_DEC_MODE_SHA384	\
+			((6UL) << SE_CONFIG_DEC_MODE_SHIFT)
+#define SE_CONFIG_DEC_MODE_SHA512	\
+			((7UL) << SE_CONFIG_DEC_MODE_SHIFT)
+#define SE_CONFIG_DEC_MODE(x)\
+			((x) & ((0xFFUL) << SE_CONFIG_DEC_MODE_SHIFT))
+
+
+/* DRBG random number generator config */
+#define SE_RNG_CONFIG_REG_OFFSET		0x340
+
+#define DRBG_MODE_SHIFT				0
+#define DRBG_MODE_NORMAL		\
+		((0U) << DRBG_MODE_SHIFT)
+#define DRBG_MODE_FORCE_INSTANTION  \
+		((1U) << DRBG_MODE_SHIFT)
+#define DRBG_MODE_FORCE_RESEED	  \
+		((2U) << DRBG_MODE_SHIFT)
+#define SE_RNG_CONFIG_MODE(x)   \
+		((x) & ((0x3U) << DRBG_MODE_SHIFT))
+
+#define DRBG_SRC_SHIFT				2
+#define DRBG_SRC_NONE	   \
+		((0U) << DRBG_SRC_SHIFT)
+#define DRBG_SRC_ENTROPY	\
+		((1U) << DRBG_SRC_SHIFT)
+#define DRBG_SRC_LFSR	   \
+		((2U) << DRBG_SRC_SHIFT)
+#define SE_RNG_SRC_CONFIG_MODE(x)   \
+		((x) & ((0x3U) << DRBG_SRC_SHIFT))
+
+/* DRBG random number generator entropy config */
+
+#define SE_RNG_SRC_CONFIG_REG_OFFSET		0x344U
+
+#define DRBG_RO_ENT_SRC_SHIFT			1
+#define DRBG_RO_ENT_SRC_ENABLE	\
+		((1U) << DRBG_RO_ENT_SRC_SHIFT)
+#define DRBG_RO_ENT_SRC_DISABLE	\
+		((0U) << DRBG_RO_ENT_SRC_SHIFT)
+#define SE_RNG_SRC_CONFIG_RO_ENT_SRC(x)	\
+		((x) & ((0x1U) << DRBG_RO_ENT_SRC_SHIFT))
+
+#define DRBG_RO_ENT_SRC_LOCK_SHIFT		0
+#define DRBG_RO_ENT_SRC_LOCK_ENABLE	\
+		((1U) << DRBG_RO_ENT_SRC_LOCK_SHIFT)
+#define DRBG_RO_ENT_SRC_LOCK_DISABLE	\
+		((0U) << DRBG_RO_ENT_SRC_LOCK_SHIFT)
+#define SE_RNG_SRC_CONFIG_RO_ENT_SRC_LOCK(x)	\
+		((x) & ((0x1U) << DRBG_RO_ENT_SRC_LOCK_SHIFT))
+
+#define DRBG_RO_ENT_IGNORE_MEM_SHIFT		12
+#define DRBG_RO_ENT_IGNORE_MEM_ENABLE	\
+		((1U) << DRBG_RO_ENT_IGNORE_MEM_SHIFT)
+#define DRBG_RO_ENT_IGNORE_MEM_DISABLE	\
+		((0U) << DRBG_RO_ENT_IGNORE_MEM_SHIFT)
+#define SE_RNG_SRC_CONFIG_RO_ENT_IGNORE_MEM(x)	\
+		((x) & ((0x1U) << DRBG_RO_ENT_IGNORE_MEM_SHIFT))
+
+#define SE_RNG_RESEED_INTERVAL_REG_OFFSET	0x348
+
+/* SE CRYPTO */
+#define SE_CRYPTO_REG_OFFSET			0x304
+#define SE_CRYPTO_HASH_SHIFT			0
+#define SE_CRYPTO_HASH_DISABLE	\
+		((0U) << SE_CRYPTO_HASH_SHIFT)
+#define SE_CRYPTO_HASH_ENABLE	\
+		((1U) << SE_CRYPTO_HASH_SHIFT)
+
+#define SE_CRYPTO_XOR_POS_SHIFT			1
+#define SE_CRYPTO_XOR_BYPASS	\
+		((0U) << SE_CRYPTO_XOR_POS_SHIFT)
+#define SE_CRYPTO_XOR_TOP	\
+		((2U) << SE_CRYPTO_XOR_POS_SHIFT)
+#define SE_CRYPTO_XOR_BOTTOM	\
+		((3U) << SE_CRYPTO_XOR_POS_SHIFT)
+
+#define SE_CRYPTO_INPUT_SEL_SHIFT		3
+#define SE_CRYPTO_INPUT_AHB 	\
+		((0U) << SE_CRYPTO_INPUT_SEL_SHIFT)
+#define SE_CRYPTO_INPUT_RANDOM	\
+		((1U) << SE_CRYPTO_INPUT_SEL_SHIFT)
+#define SE_CRYPTO_INPUT_AESOUT	\
+		((2U) << SE_CRYPTO_INPUT_SEL_SHIFT)
+#define SE_CRYPTO_INPUT_LNR_CTR \
+		((3U) << SE_CRYPTO_INPUT_SEL_SHIFT)
+
+#define SE_CRYPTO_VCTRAM_SEL_SHIFT		 5
+#define SE_CRYPTO_VCTRAM_AHB	\
+		((0U) << SE_CRYPTO_VCTRAM_SEL_SHIFT)
+#define SE_CRYPTO_VCTRAM_AESOUT \
+		((2U) << SE_CRYPTO_VCTRAM_SEL_SHIFT)
+#define SE_CRYPTO_VCTRAM_PREVAHB	\
+		((3U) << SE_CRYPTO_VCTRAM_SEL_SHIFT)
+
+#define SE_CRYPTO_IV_SEL_SHIFT			 7
+#define SE_CRYPTO_IV_ORIGINAL	\
+		((0U) << SE_CRYPTO_IV_SEL_SHIFT)
+#define SE_CRYPTO_IV_UPDATED	\
+		((1U) << SE_CRYPTO_IV_SEL_SHIFT)
+
+#define SE_CRYPTO_CORE_SEL_SHIFT		8
+#define SE_CRYPTO_CORE_DECRYPT	\
+		((0U) << SE_CRYPTO_CORE_SEL_SHIFT)
+#define SE_CRYPTO_CORE_ENCRYPT	\
+		((1U) << SE_CRYPTO_CORE_SEL_SHIFT)
+
+#define SE_CRYPTO_KEY_INDEX_SHIFT		24
+#define SE_CRYPTO_KEY_INDEX(x) (x << SE_CRYPTO_KEY_INDEX_SHIFT)
+
+#define SE_CRYPTO_MEMIF_AHB	\
+		((0U) << SE_CRYPTO_MEMIF_SHIFT)
+#define SE_CRYPTO_MEMIF_MCCIF	\
+		((1U) << SE_CRYPTO_MEMIF_SHIFT)
+#define SE_CRYPTO_MEMIF_SHIFT			31
+
+/* KEY TABLE */
+#define SE_KEYTABLE_REG_OFFSET			0x31C
+
+/* KEYIV PKT - key slot */
+#define SE_KEYTABLE_SLOT_SHIFT			4
+#define SE_KEYTABLE_SLOT(x)	(x << SE_KEYTABLE_SLOT_SHIFT)
+
+/* KEYIV PKT - KEYIV select */
+#define SE_KEYIV_PKT_KEYIV_SEL_SHIFT		3
+#define SE_CRYPTO_KEYIV_KEY	\
+		((0U) << SE_KEYIV_PKT_KEYIV_SEL_SHIFT)
+#define SE_CRYPTO_KEYIV_IVS	\
+		((1U) << SE_KEYIV_PKT_KEYIV_SEL_SHIFT)
+
+/* KEYIV PKT - IV select */
+#define SE_KEYIV_PKT_IV_SEL_SHIFT		2
+#define SE_CRYPTO_KEYIV_IVS_OIV	\
+		((0U) << SE_KEYIV_PKT_IV_SEL_SHIFT)
+#define SE_CRYPTO_KEYIV_IVS_UIV \
+		((1U) << SE_KEYIV_PKT_IV_SEL_SHIFT)
+
+/* KEYIV PKT - key word */
+#define SE_KEYIV_PKT_KEY_WORD_SHIFT		0
+#define SE_KEYIV_PKT_KEY_WORD(x)	\
+		((x) << SE_KEYIV_PKT_KEY_WORD_SHIFT)
+
+/* KEYIV PKT - iv word */
+#define SE_KEYIV_PKT_IV_WORD_SHIFT		0
+#define SE_KEYIV_PKT_IV_WORD(x)		\
+		((x) << SE_KEYIV_PKT_IV_WORD_SHIFT)
+
+/* SE OPERATION */
+#define SE_OPERATION_REG_OFFSET 		0x8U
+#define SE_OPERATION_SHIFT			0
+#define SE_OP_ABORT	\
+		((0x0U) << SE_OPERATION_SHIFT)
+#define SE_OP_START	\
+		((0x1U) << SE_OPERATION_SHIFT)
+#define SE_OP_RESTART	\
+		((0x2U) << SE_OPERATION_SHIFT)
+#define SE_OP_CTX_SAVE	\
+		((0x3U) << SE_OPERATION_SHIFT)
+#define SE_OP_RESTART_IN	\
+		((0x4U) << SE_OPERATION_SHIFT)
+#define SE_OPERATION(x)	\
+		((x) & ((0x7U) << SE_OPERATION_SHIFT))
+
+/* SE CONTEXT */
+#define SE_CTX_SAVE_CONFIG_REG_OFFSET		0x70
+#define SE_CTX_SAVE_WORD_QUAD_SHIFT		0
+#define SE_CTX_SAVE_WORD_QUAD(x)	\
+		(x << SE_CTX_SAVE_WORD_QUAD_SHIFT)
+#define SE_CTX_SAVE_WORD_QUAD_KEYS_0_3	\
+		((0U) << SE_CTX_SAVE_WORD_QUAD_SHIFT)
+#define SE_CTX_SAVE_WORD_QUAD_KEYS_4_7	\
+		((1U) << SE_CTX_SAVE_WORD_QUAD_SHIFT)
+#define SE_CTX_SAVE_WORD_QUAD_ORIG_IV	\
+		((2U) << SE_CTX_SAVE_WORD_QUAD_SHIFT)
+#define SE_CTX_SAVE_WORD_QUAD_UPD_IV	\
+		((3U) << SE_CTX_SAVE_WORD_QUAD_SHIFT)
+
+#define SE_CTX_SAVE_KEY_INDEX_SHIFT		8
+#define SE_CTX_SAVE_KEY_INDEX(x)	(x << SE_CTX_SAVE_KEY_INDEX_SHIFT)
+
+#define SE_CTX_SAVE_STICKY_WORD_QUAD_SHIFT	24
+#define SE_CTX_SAVE_STICKY_WORD_QUAD_STICKY_0_3	\
+		((0U) << SE_CTX_SAVE_STICKY_WORD_QUAD_SHIFT)
+#define SE_CTX_SAVE_STICKY_WORD_QUAD_STICKY_4_7	\
+		((1U) << SE_CTX_SAVE_STICKY_WORD_QUAD_SHIFT)
+#define SE_CTX_SAVE_STICKY_WORD_QUAD(x)	\
+		(x << SE_CTX_SAVE_STICKY_WORD_QUAD_SHIFT)
+
+#define SE_CTX_SAVE_SRC_SHIFT			29
+#define SE_CTX_SAVE_SRC_STICKY_BITS	\
+		((0U) << SE_CTX_SAVE_SRC_SHIFT)
+#define SE_CTX_SAVE_SRC_RSA_KEYTABLE	\
+		((1U) << SE_CTX_SAVE_SRC_SHIFT)
+#define SE_CTX_SAVE_SRC_AES_KEYTABLE	\
+		((2U) << SE_CTX_SAVE_SRC_SHIFT)
+#define SE_CTX_SAVE_SRC_PKA1_STICKY_BITS	\
+		((3U) << SE_CTX_SAVE_SRC_SHIFT)
+#define SE_CTX_SAVE_SRC_MEM	\
+		((4U) << SE_CTX_SAVE_SRC_SHIFT)
+#define SE_CTX_SAVE_SRC_SRK	\
+		((6U) << SE_CTX_SAVE_SRC_SHIFT)
+#define SE_CTX_SAVE_SRC_PKA1_KEYTABLE	\
+		((7U) << SE_CTX_SAVE_SRC_SHIFT)
+
+#define SE_CTX_STICKY_WORD_QUAD_SHIFT		24
+#define SE_CTX_STICKY_WORD_QUAD_WORDS_0_3 \
+		((0U) << SE_CTX_STICKY_WORD_QUAD_SHIFT)
+#define SE_CTX_STICKY_WORD_QUAD_WORDS_4_7 \
+		((1U) << SE_CTX_STICKY_WORD_QUAD_SHIFT)
+#define SE_CTX_STICKY_WORD_QUAD(x)	 (x << SE_CTX_STICKY_WORD_QUAD_SHIFT)
+
+#define SE_CTX_SAVE_RSA_KEY_INDEX_SHIFT		16
+#define SE_CTX_SAVE_RSA_KEY_INDEX(x)				\
+			(x << SE_CTX_SAVE_RSA_KEY_INDEX_SHIFT)
+
+#define SE_CTX_RSA_WORD_QUAD_SHIFT		12
+#define SE_CTX_RSA_WORD_QUAD(x)	\
+			(x << SE_CTX_RSA_WORD_QUAD_SHIFT)
+
+#define SE_CTX_PKA1_WORD_QUAD_L_SHIFT		0
+#define SE_CTX_PKA1_WORD_QUAD_L_SIZE		\
+			((true ? 4:0) - \
+			(false ? 4:0) + 1)
+#define SE_CTX_PKA1_WORD_QUAD_L(x)\
+			(((x) << SE_CTX_PKA1_WORD_QUAD_L_SHIFT) & 0x1f)
+
+#define SE_CTX_PKA1_WORD_QUAD_H_SHIFT		12
+#define SE_CTX_PKA1_WORD_QUAD_H(x)\
+			((((x) >> SE_CTX_PKA1_WORD_QUAD_L_SIZE) & 0xf) \
+			<< SE_CTX_PKA1_WORD_QUAD_H_SHIFT)
+
+#define SE_RSA_KEY_INDEX_SLOT0_EXP		0
+#define SE_RSA_KEY_INDEX_SLOT0_MOD		1
+#define SE_RSA_KEY_INDEX_SLOT1_EXP		2
+#define SE_RSA_KEY_INDEX_SLOT1_MOD		3
+
+
+/* SE_CTX_SAVE_AUTO */
+#define SE_CTX_SAVE_AUTO_REG_OFFSET 		0x74U
+
+/* Enable */
+#define SE_CTX_SAVE_AUTO_ENABLE_SHIFT		0
+#define SE_CTX_SAVE_AUTO_DIS	\
+		((0U) << SE_CTX_SAVE_AUTO_ENABLE_SHIFT)
+#define SE_CTX_SAVE_AUTO_EN	\
+		((1U) << SE_CTX_SAVE_AUTO_ENABLE_SHIFT)
+#define SE_CTX_SAVE_AUTO_ENABLE(x)	\
+		((x) & ((0x1U) << SE_CTX_SAVE_AUTO_ENABLE_SHIFT))
+
+/* Lock */
+#define SE_CTX_SAVE_AUTO_LOCK_SHIFT 		8
+#define SE_CTX_SAVE_AUTO_LOCK_EN	\
+		((1U) << SE_CTX_SAVE_AUTO_LOCK_SHIFT)
+#define SE_CTX_SAVE_AUTO_LOCK_DIS	\
+		((0U) << SE_CTX_SAVE_AUTO_LOCK_SHIFT)
+#define SE_CTX_SAVE_AUTO_LOCK(x)	\
+		((x) & ((0x1U) << SE_CTX_SAVE_AUTO_LOCK_SHIFT))
+
+/* Current context save number of blocks*/
+#define SE_CTX_SAVE_AUTO_CURR_CNT_SHIFT		16
+#define SE_CTX_SAVE_AUTO_CURR_CNT_MASK 		0x3FFU
+#define SE_CTX_SAVE_GET_BLK_COUNT(x)	\
+		(((x) >> SE_CTX_SAVE_AUTO_CURR_CNT_SHIFT) & \
+		SE_CTX_SAVE_AUTO_CURR_CNT_MASK)
+
+#define SE_CTX_SAVE_SIZE_BLOCKS_SE1		133
+#define SE_CTX_SAVE_SIZE_BLOCKS_SE2	 	646
+
+/* SE TZRAM OPERATION - only for SE1 */
+#define SE_TZRAM_OPERATION			0x540U
+
+#define SE_TZRAM_OP_MODE_SHIFT			1
+#define SE_TZRAM_OP_COMMAND_INIT		1
+#define SE_TZRAM_OP_COMMAND_SHIFT		0
+#define SE_TZRAM_OP_MODE_SAVE		\
+		((0U) << SE_TZRAM_OP_MODE_SHIFT)
+#define SE_TZRAM_OP_MODE_RESTORE	\
+		((1U) << SE_TZRAM_OP_MODE_SHIFT)
+#define SE_TZRAM_OP_MODE(x)		\
+		((x) & ((0x1U) << SE_TZRAM_OP_MODE_SHIFT))
+
+#define SE_TZRAM_OP_BUSY_SHIFT			2
+#define SE_TZRAM_OP_BUSY_OFF	\
+		((0U) << SE_TZRAM_OP_BUSY_SHIFT)
+#define SE_TZRAM_OP_BUSY_ON	\
+		((1U) << SE_TZRAM_OP_BUSY_SHIFT)
+#define SE_TZRAM_OP_BUSY(x)	\
+		((x) & ((0x1U) << SE_TZRAM_OP_BUSY_SHIFT))
+
+#define SE_TZRAM_OP_REQ_SHIFT			0
+#define SE_TZRAM_OP_REQ_IDLE	\
+		((0U) << SE_TZRAM_OP_REQ_SHIFT)
+#define SE_TZRAM_OP_REQ_INIT	\
+		((1U) << SE_TZRAM_OP_REQ_SHIFT)
+#define SE_TZRAM_OP_REQ(x)	\
+		((x) & ((0x1U) << SE_TZRAM_OP_REQ_SHIFT))
+
+/* SE Interrupt */
+#define SE_INT_STATUS_REG_OFFSET		0x10U
+#define SE_INT_OP_DONE_SHIFT			4
+#define SE_INT_OP_DONE_CLEAR	\
+		((0U) << SE_INT_OP_DONE_SHIFT)
+#define SE_INT_OP_DONE_ACTIVE	\
+		((1U) << SE_INT_OP_DONE_SHIFT)
+#define SE_INT_OP_DONE(x)	\
+		((x) & ((0x1U) << SE_INT_OP_DONE_SHIFT))
+
+/* SE TZRAM SECURITY */
+#define SE_TZRAM_SEC_REG_OFFSET			0x4
+
+#define SE_TZRAM_SEC_SETTING_SHIFT		 0
+#define SE_TZRAM_SECURE		\
+		((0UL) << SE_TZRAM_SEC_SETTING_SHIFT)
+#define SE_TZRAM_NONSECURE	 \
+		((1UL) << SE_TZRAM_SEC_SETTING_SHIFT)
+#define SE_TZRAM_SEC_SETTING(x)		\
+		((x) & ((0x1UL) << SE_TZRAM_SEC_SETTING_SHIFT))
+
+/* PKA1 KEY SLOTS */
+#define TEGRA_SE_PKA1_KEYSLOT_COUNT		4
+
+
+/* SE error status */
+#define SE_ERR_STATUS_REG_OFFSET		0x804U
+#define SE_CRYPTO_KEYTABLE_DST_REG_OFFSET	0x330
+#define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT	0
+#define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD(x)	\
+			(x << SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT)
+
+#define SE_KEY_INDEX_SHIFT			8
+#define SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(x)	(x << SE_KEY_INDEX_SHIFT)
+
+
+/* SE linked list (LL) register */
+#define SE_IN_LL_ADDR_REG_OFFSET		0x18U
+#define SE_OUT_LL_ADDR_REG_OFFSET		0x24U
+#define SE_BLOCK_COUNT_REG_OFFSET		0x318U
+
+/* AES data sizes */
+#define TEGRA_SE_KEY_256_SIZE			32
+#define TEGRA_SE_KEY_192_SIZE			24
+#define TEGRA_SE_KEY_128_SIZE			16
+#define TEGRA_SE_AES_BLOCK_SIZE 		16
+#define TEGRA_SE_AES_MIN_KEY_SIZE		16
+#define TEGRA_SE_AES_MAX_KEY_SIZE		32
+#define TEGRA_SE_AES_IV_SIZE			16
+
+#define TEGRA_SE_RNG_IV_SIZE			16
+#define TEGRA_SE_RNG_DT_SIZE			16
+#define TEGRA_SE_RNG_KEY_SIZE			16
+#define TEGRA_SE_RNG_SEED_SIZE	(TEGRA_SE_RNG_IV_SIZE + \
+									TEGRA_SE_RNG_KEY_SIZE + \
+									TEGRA_SE_RNG_DT_SIZE)
+#define TEGRA_SE_RSA512_DIGEST_SIZE		64
+#define TEGRA_SE_RSA1024_DIGEST_SIZE		128
+#define TEGRA_SE_RSA1536_DIGEST_SIZE		192
+#define TEGRA_SE_RSA2048_DIGEST_SIZE		256
+
+#define SE_KEY_TABLE_ACCESS_REG_OFFSET		0x284
+#define SE_KEY_READ_DISABLE_SHIFT		0
+
+#define SE_CTX_BUFER_SIZE			1072
+#define SE_CTX_DRBG_BUFER_SIZE			2112
+
+/* SE blobs size in bytes */
+#define SE_CTX_SAVE_RSA_KEY_LENGTH		1024
+#define SE_CTX_SAVE_RANDOM_DATA_SIZE		16
+#define SE_CTX_SAVE_STICKY_BITS_SIZE		16
+#define SE2_CONTEXT_SAVE_PKA1_STICKY_BITS_LENGTH 16
+#define SE2_CONTEXT_SAVE_PKA1_KEYS_LENGTH	8192
+#define SE_CTX_KNOWN_PATTERN_SIZE		16
+#define SE_CTX_KNOWN_PATTERN_SIZE_WORDS		(SE_CTX_KNOWN_PATTERN_SIZE/4)
+
+/* SE RSA */
+#define TEGRA_SE_RSA_KEYSLOT_COUNT		2
+#define SE_RSA_KEY_SIZE_REG_OFFSET		0x404
+#define SE_RSA_EXP_SIZE_REG_OFFSET		0x408
+#define SE_RSA_MAX_EXP_BIT_SIZE			2048
+#define SE_RSA_MAX_EXP_SIZE32	\
+		(SE_RSA_MAX_EXP_BIT_SIZE >> 5)
+#define SE_RSA_MAX_MOD_BIT_SIZE			2048
+#define SE_RSA_MAX_MOD_SIZE32	\
+		(SE_RSA_MAX_MOD_BIT_SIZE >> 5)
+
+/* SE_RSA_KEYTABLE_ADDR */
+#define SE_RSA_KEYTABLE_ADDR			0x420
+#define RSA_KEY_PKT_WORD_ADDR_SHIFT		0
+#define RSA_KEY_PKT_EXPMOD_SEL_SHIFT	\
+		((6U) << RSA_KEY_PKT_WORD_ADDR_SHIFT)
+#define RSA_KEY_MOD	\
+		((1U) << RSA_KEY_PKT_EXPMOD_SEL_SHIFT)
+#define RSA_KEY_EXP	\
+		((0U) << RSA_KEY_PKT_EXPMOD_SEL_SHIFT)
+#define RSA_KEY_PKT_SLOT_SHIFT			7
+#define RSA_KEY_SLOT_1	\
+		((0U) << RSA_KEY_PKT_SLOT_SHIFT)
+#define RSA_KEY_SLOT_2	\
+		((1U) << RSA_KEY_PKT_SLOT_SHIFT)
+#define RSA_KEY_PKT_INPUT_MODE_SHIFT		8
+#define RSA_KEY_REG_INPUT	\
+		((0U) << RSA_KEY_PKT_INPUT_MODE_SHIFT)
+#define RSA_KEY_DMA_INPUT	\
+		((1U) << RSA_KEY_PKT_INPUT_MODE_SHIFT)
+
+/* SE_RSA_KEYTABLE_DATA */
+#define SE_RSA_KEYTABLE_DATA			0x424
+
+/* SE_RSA_CONFIG register */
+#define SE_RSA_CONFIG				0x400
+#define RSA_KEY_SLOT_SHIFT			24
+#define RSA_KEY_SLOT(x) \
+		((x) << RSA_KEY_SLOT_SHIFT)
+
+/*******************************************************************************
+ * Structure definition
+ ******************************************************************************/
+
+/* SE context blob */
+#pragma pack(push, 1)
+typedef struct tegra_aes_key_slot {
+	/* 0 - 7 AES key */
+	uint32_t key[8];
+	/* 8 - 11 Original IV */
+	uint32_t oiv[4];
+	/* 12 - 15 Updated IV */
+	uint32_t uiv[4];
+} tegra_se_aes_key_slot_t;
+#pragma pack(pop)
+
+#pragma pack(push, 1)
+typedef struct tegra_se_context {
+	/* random number */
+	unsigned char rand_data[SE_CTX_SAVE_RANDOM_DATA_SIZE];
+	/* Sticky bits */
+	unsigned char sticky_bits[SE_CTX_SAVE_STICKY_BITS_SIZE * 2];
+	/* AES key slots */
+	tegra_se_aes_key_slot_t key_slots[TEGRA_SE_AES_KEYSLOT_COUNT];
+	/* RSA key slots */
+	unsigned char rsa_keys[SE_CTX_SAVE_RSA_KEY_LENGTH];
+} tegra_se_context_t;
+#pragma pack(pop)
+
+/* PKA context blob */
+#pragma pack(push, 1)
+typedef struct tegra_pka_context {
+	unsigned char sticky_bits[SE2_CONTEXT_SAVE_PKA1_STICKY_BITS_LENGTH];
+	unsigned char pka_keys[SE2_CONTEXT_SAVE_PKA1_KEYS_LENGTH];
+} tegra_pka_context_t;
+#pragma pack(pop)
+
+/* SE context blob */
+#pragma pack(push, 1)
+typedef struct tegra_se_context_blob {
+	/* SE context */
+	tegra_se_context_t se_ctx;
+	/* Known Pattern */
+	unsigned char known_pattern[SE_CTX_KNOWN_PATTERN_SIZE];
+} tegra_se_context_blob_t;
+#pragma pack(pop)
+
+/* SE2 and PKA1 context blob */
+#pragma pack(push, 1)
+typedef struct tegra_se2_context_blob {
+	/* SE2 context */
+	tegra_se_context_t se_ctx;
+	/* PKA1 context */
+	tegra_pka_context_t pka_ctx;
+	/* Known Pattern */
+	unsigned char known_pattern[SE_CTX_KNOWN_PATTERN_SIZE];
+} tegra_se2_context_blob_t;
+#pragma pack(pop)
+
+/* SE AES key type 128bit, 192bit, 256bit */
+typedef enum {
+	SE_AES_KEY128,
+	SE_AES_KEY192,
+	SE_AES_KEY256,
+} tegra_se_aes_key_type_t;
+
+/* SE RSA key slot */
+typedef struct tegra_se_rsa_key_slot {
+	/* 0 - 63 exponent key */
+	uint32_t exponent[SE_RSA_MAX_EXP_SIZE32];
+	/* 64 - 127 modulus key */
+	uint32_t modulus[SE_RSA_MAX_MOD_SIZE32];
+} tegra_se_rsa_key_slot_t;
+
+
+/*******************************************************************************
+ * Inline functions definition
+ ******************************************************************************/
+
+static inline uint32_t tegra_se_read_32(const tegra_se_dev_t *dev, uint32_t offset)
+{
+	return mmio_read_32(dev->se_base + offset);
+}
+
+static inline void tegra_se_write_32(const tegra_se_dev_t *dev, uint32_t offset, uint32_t val)
+{
+	mmio_write_32(dev->se_base + offset, val);
+}
+
+static inline uint32_t tegra_pka_read_32(tegra_pka_dev_t *dev, uint32_t offset)
+{
+	return mmio_read_32(dev->pka_base + offset);
+}
+
+static inline void tegra_pka_write_32(tegra_pka_dev_t *dev, uint32_t offset,
+uint32_t val)
+{
+	mmio_write_32(dev->pka_base + offset, val);
+}
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+int tegra_se_start_normal_operation(const tegra_se_dev_t *, uint32_t);
+int tegra_se_start_ctx_save_operation(const tegra_se_dev_t *, uint32_t);
+
+#endif /* SE_PRIVATE_H */
diff --git a/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c b/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c
new file mode 100644
index 0000000..e0a0d6c
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c
@@ -0,0 +1,1084 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <common/debug.h>
+#include <delay_timer.h>
+#include <errno.h>
+#include <mmio.h>
+#include <psci.h>
+#include <se_private.h>
+#include <security_engine.h>
+#include <tegra_platform.h>
+
+/*******************************************************************************
+ * Constants and Macros
+ ******************************************************************************/
+
+#define TIMEOUT_100MS	100U	// Timeout in 100ms
+#define RNG_AES_KEY_INDEX   1
+
+/*******************************************************************************
+ * Data structure and global variables
+ ******************************************************************************/
+
+/* The security engine contexts are formatted as follows:
+ *
+ * SE1 CONTEXT:
+ * #--------------------------------#
+ * |        Random Data   1 Block   |
+ * #--------------------------------#
+ * |        Sticky Bits   2 Blocks  |
+ * #--------------------------------#
+ * | Key Table           64 Blocks  |
+ * |     For each Key (x16):        |
+ * |      Key:         2 Blocks     |
+ * |      Original-IV: 1 Block      |
+ * |      Updated-IV:  1 Block      |
+ * #--------------------------------#
+ * |        RSA Keys     64 Blocks  |
+ * #--------------------------------#
+ * |        Known Pattern 1 Block   |
+ * #--------------------------------#
+ *
+ * SE2/PKA1 CONTEXT:
+ * #--------------------------------#
+ * |        Random Data   1 Block   |
+ * #--------------------------------#
+ * |        Sticky Bits   2 Blocks  |
+ * #--------------------------------#
+ * | Key Table           64 Blocks  |
+ * |     For each Key (x16):        |
+ * |      Key:         2 Blocks     |
+ * |      Original-IV: 1 Block      |
+ * |      Updated-IV:  1 Block      |
+ * #--------------------------------#
+ * |        RSA Keys     64 Blocks  |
+ * #--------------------------------#
+ * |        PKA sticky bits 1 Block |
+ * #--------------------------------#
+ * |        PKA keys    512 Blocks  |
+ * #--------------------------------#
+ * |        Known Pattern 1 Block   |
+ * #--------------------------------#
+ */
+
+/* Known pattern data */
+static const uint32_t se_ctx_known_pattern_data[SE_CTX_KNOWN_PATTERN_SIZE_WORDS] = {
+	/* 128 bit AES block */
+	0x0C0D0E0F,
+	0x08090A0B,
+	0x04050607,
+	0x00010203,
+};
+
+/* SE input and output linked list buffers */
+static tegra_se_io_lst_t se1_src_ll_buf;
+static tegra_se_io_lst_t se1_dst_ll_buf;
+
+/* SE2 input and output linked list buffers */
+static tegra_se_io_lst_t se2_src_ll_buf;
+static tegra_se_io_lst_t se2_dst_ll_buf;
+
+/* SE1 security engine device handle */
+static tegra_se_dev_t se_dev_1 = {
+	.se_num = 1,
+	/* Setup base address for se */
+	.se_base = TEGRA_SE1_BASE,
+	/* Setup context size in AES blocks */
+	.ctx_size_blks = SE_CTX_SAVE_SIZE_BLOCKS_SE1,
+	/* Setup SRC buffers for SE operations */
+	.src_ll_buf = &se1_src_ll_buf,
+	/* Setup DST buffers for SE operations */
+	.dst_ll_buf = &se1_dst_ll_buf,
+	/* Setup context save destination */
+	.ctx_save_buf = (uint32_t *)(TEGRA_TZRAM_CARVEOUT_BASE),
+};
+
+/* SE2 security engine device handle */
+static tegra_se_dev_t se_dev_2 = {
+	.se_num = 2,
+	/* Setup base address for se */
+	.se_base = TEGRA_SE2_BASE,
+	/* Setup context size in AES blocks */
+	.ctx_size_blks = SE_CTX_SAVE_SIZE_BLOCKS_SE2,
+	/* Setup SRC buffers for SE operations */
+	.src_ll_buf = &se2_src_ll_buf,
+	/* Setup DST buffers for SE operations */
+	.dst_ll_buf = &se2_dst_ll_buf,
+	/* Setup context save destination */
+	.ctx_save_buf = (uint32_t *)(TEGRA_TZRAM_CARVEOUT_BASE + 0x1000),
+};
+
+static bool ecid_valid;
+
+/*******************************************************************************
+ * Functions Definition
+ ******************************************************************************/
+
+static void tegra_se_make_data_coherent(const tegra_se_dev_t *se_dev)
+{
+	flush_dcache_range(((uint64_t)(se_dev->src_ll_buf)),
+			sizeof(tegra_se_io_lst_t));
+	flush_dcache_range(((uint64_t)(se_dev->dst_ll_buf)),
+			sizeof(tegra_se_io_lst_t));
+}
+
+/*
+ * Check that SE operation has completed after kickoff
+ * This function is invoked after an SE operation has been started,
+ * and it checks the following conditions:
+ * 1. SE_INT_STATUS = SE_OP_DONE
+ * 2. SE_STATUS = IDLE
+ * 3. AHB bus data transfer complete.
+ * 4. SE_ERR_STATUS is clean.
+ */
+static int32_t tegra_se_operation_complete(const tegra_se_dev_t *se_dev)
+{
+	uint32_t val = 0;
+	int32_t ret = 0;
+	uint32_t timeout;
+
+	/* Poll the SE interrupt register to ensure H/W operation complete */
+	val = tegra_se_read_32(se_dev, SE_INT_STATUS_REG_OFFSET);
+	for (timeout = 0; (SE_INT_OP_DONE(val) == SE_INT_OP_DONE_CLEAR) &&
+			(timeout < TIMEOUT_100MS); timeout++) {
+		mdelay(1);
+		val = tegra_se_read_32(se_dev, SE_INT_STATUS_REG_OFFSET);
+	}
+
+	if (timeout == TIMEOUT_100MS) {
+		ERROR("%s: ERR: Atomic context save operation timeout!\n",
+				__func__);
+		ret = -ETIMEDOUT;
+	}
+
+	/* Poll the SE status idle to ensure H/W operation complete */
+	if (ret == 0) {
+		val = tegra_se_read_32(se_dev, SE_STATUS_OFFSET);
+		for (timeout = 0; (val != 0U) && (timeout < TIMEOUT_100MS);
+				timeout++) {
+			mdelay(1);
+			val = tegra_se_read_32(se_dev, SE_STATUS_OFFSET);
+		}
+
+		if (timeout == TIMEOUT_100MS) {
+			ERROR("%s: ERR: MEM_INTERFACE and SE state "
+					"idle state timeout.\n", __func__);
+			ret = -ETIMEDOUT;
+		}
+	}
+
+	/* Check AHB bus transfer complete */
+	if (ret == 0) {
+		val = mmio_read_32(TEGRA_AHB_ARB_BASE + ARAHB_MEM_WRQUE_MST_ID_OFFSET);
+		for (timeout = 0; ((val & (ARAHB_MST_ID_SE_MASK | ARAHB_MST_ID_SE2_MASK)) != 0U) &&
+				(timeout < TIMEOUT_100MS); timeout++) {
+			mdelay(1);
+			val = mmio_read_32(TEGRA_AHB_ARB_BASE + ARAHB_MEM_WRQUE_MST_ID_OFFSET);
+		}
+
+		if (timeout == TIMEOUT_100MS) {
+			ERROR("%s: SE write over AHB timeout.\n", __func__);
+			ret = -ETIMEDOUT;
+		}
+	}
+
+	/* Ensure that no errors are thrown during operation */
+	if (ret == 0) {
+		val = tegra_se_read_32(se_dev, SE_ERR_STATUS_REG_OFFSET);
+		if (val != 0U) {
+			ERROR("%s: error during SE operation! 0x%x", __func__, val);
+			ret = -ENOTSUP;
+		}
+	}
+
+	return ret;
+}
+
+/*
+ * Returns true if the SE engine is configured to perform SE context save in
+ * hardware.
+ */
+static inline bool tegra_se_atomic_save_enabled(const tegra_se_dev_t *se_dev)
+{
+	uint32_t val;
+
+	val = tegra_se_read_32(se_dev, SE_CTX_SAVE_AUTO_REG_OFFSET);
+	return (SE_CTX_SAVE_AUTO_ENABLE(val) == SE_CTX_SAVE_AUTO_EN);
+}
+
+/*
+ * Wait for SE engine to be idle and clear pending interrupts before
+ * starting the next SE operation.
+ */
+static int32_t tegra_se_operation_prepare(const tegra_se_dev_t *se_dev)
+{
+	int32_t ret = 0;
+	uint32_t val = 0;
+	uint32_t timeout;
+
+	/* Wait for previous operation to finish */
+	val = tegra_se_read_32(se_dev, SE_STATUS_OFFSET);
+	for (timeout = 0; (val != 0U) && (timeout < TIMEOUT_100MS); timeout++) {
+		mdelay(1);
+		val = tegra_se_read_32(se_dev, SE_STATUS_OFFSET);
+	}
+
+	if (timeout == TIMEOUT_100MS) {
+		ERROR("%s: ERR: SE status is not idle!\n", __func__);
+		ret = -ETIMEDOUT;
+	}
+
+	/* Clear any pending interrupts from  previous operation */
+	val = tegra_se_read_32(se_dev, SE_INT_STATUS_REG_OFFSET);
+	tegra_se_write_32(se_dev, SE_INT_STATUS_REG_OFFSET, val);
+	return ret;
+}
+
+/*
+ * SE atomic context save. At SC7 entry, SE driver triggers the
+ * hardware automatically performs the context save operation.
+ */
+static int32_t tegra_se_context_save_atomic(const tegra_se_dev_t *se_dev)
+{
+	int32_t ret = 0;
+	uint32_t val = 0;
+	uint32_t blk_count_limit = 0;
+	uint32_t block_count;
+
+	/* Check that previous operation is finalized */
+	ret = tegra_se_operation_prepare(se_dev);
+
+	/* Read the context save progress counter: block_count
+	 * Ensure no previous context save has been triggered
+	 * SE_CTX_SAVE_AUTO.CURR_CNT == 0
+	 */
+	if (ret == 0) {
+		val = tegra_se_read_32(se_dev, SE_CTX_SAVE_AUTO_REG_OFFSET);
+		block_count = SE_CTX_SAVE_GET_BLK_COUNT(val);
+		if (block_count != 0U) {
+			ERROR("%s: ctx_save triggered multiple times\n",
+					__func__);
+			ret = -EALREADY;
+		}
+	}
+
+	/* Set the destination block count when the context save complete */
+	if (ret == 0) {
+		blk_count_limit = block_count + se_dev->ctx_size_blks;
+	}
+
+	/* Program SE_CONFIG register as for RNG operation
+	 * SE_CONFIG.ENC_ALG = RNG
+	 * SE_CONFIG.DEC_ALG = NOP
+	 * SE_CONFIG.ENC_MODE is ignored
+	 * SE_CONFIG.DEC_MODE is ignored
+	 * SE_CONFIG.DST = MEMORY
+	 */
+	if (ret == 0) {
+		val = (SE_CONFIG_ENC_ALG_RNG |
+			SE_CONFIG_DEC_ALG_NOP |
+			SE_CONFIG_DST_MEMORY);
+		tegra_se_write_32(se_dev, SE_CONFIG_REG_OFFSET, val);
+
+		tegra_se_make_data_coherent(se_dev);
+
+		/* SE_CTX_SAVE operation */
+		tegra_se_write_32(se_dev, SE_OPERATION_REG_OFFSET,
+				SE_OP_CTX_SAVE);
+
+		ret = tegra_se_operation_complete(se_dev);
+	}
+
+	/* Check that context has written the correct number of blocks */
+	if (ret == 0) {
+		val = tegra_se_read_32(se_dev, SE_CTX_SAVE_AUTO_REG_OFFSET);
+		if (SE_CTX_SAVE_GET_BLK_COUNT(val) != blk_count_limit) {
+			ERROR("%s: expected %d blocks but %d were written\n",
+					__func__, blk_count_limit, val);
+			ret = -ECANCELED;
+		}
+	}
+
+	return ret;
+}
+
+/*
+ * Security engine primitive operations, including normal operation
+ * and the context save operation.
+ */
+static int tegra_se_perform_operation(const tegra_se_dev_t *se_dev, uint32_t nbytes,
+					bool context_save)
+{
+	uint32_t nblocks = nbytes / TEGRA_SE_AES_BLOCK_SIZE;
+	int ret = 0;
+
+	assert(se_dev);
+
+	/* Use device buffers for in and out */
+	tegra_se_write_32(se_dev, SE_OUT_LL_ADDR_REG_OFFSET, ((uint64_t)(se_dev->dst_ll_buf)));
+	tegra_se_write_32(se_dev, SE_IN_LL_ADDR_REG_OFFSET, ((uint64_t)(se_dev->src_ll_buf)));
+
+	/* Check that previous operation is finalized */
+	ret = tegra_se_operation_prepare(se_dev);
+	if (ret != 0) {
+		goto op_error;
+	}
+
+	/* Program SE operation size */
+	if (nblocks) {
+		tegra_se_write_32(se_dev, SE_BLOCK_COUNT_REG_OFFSET, nblocks - 1);
+	}
+
+	/* Make SE LL data coherent before the SE operation */
+	tegra_se_make_data_coherent(se_dev);
+
+	/* Start hardware operation */
+	if (context_save)
+		tegra_se_write_32(se_dev, SE_OPERATION_REG_OFFSET, SE_OP_CTX_SAVE);
+	else
+		tegra_se_write_32(se_dev, SE_OPERATION_REG_OFFSET, SE_OP_START);
+
+	/* Wait for operation to finish */
+	ret = tegra_se_operation_complete(se_dev);
+
+op_error:
+	return ret;
+}
+
+/*
+ * Normal security engine operations other than the context save
+ */
+int tegra_se_start_normal_operation(const tegra_se_dev_t *se_dev, uint32_t nbytes)
+{
+	return tegra_se_perform_operation(se_dev, nbytes, false);
+}
+
+/*
+ * Security engine context save operation
+ */
+int tegra_se_start_ctx_save_operation(const tegra_se_dev_t *se_dev, uint32_t nbytes)
+{
+	return tegra_se_perform_operation(se_dev, nbytes, true);
+}
+
+/*
+ * Security Engine sequence to generat SRK
+ * SE and SE2 will generate different SRK by different
+ * entropy seeds.
+ */
+static int tegra_se_generate_srk(const tegra_se_dev_t *se_dev)
+{
+	int ret = PSCI_E_INTERN_FAIL;
+	uint32_t val;
+
+	/* Confgure the following hardware register settings:
+	 * SE_CONFIG.DEC_ALG = NOP
+	 * SE_CONFIG.ENC_ALG = RNG
+	 * SE_CONFIG.DST = SRK
+	 * SE_OPERATION.OP = START
+	 * SE_CRYPTO_LAST_BLOCK = 0
+	 */
+	se_dev->src_ll_buf->last_buff_num = 0;
+	se_dev->dst_ll_buf->last_buff_num = 0;
+
+	/* Configure random number generator */
+	if (ecid_valid)
+		val = (DRBG_MODE_FORCE_INSTANTION | DRBG_SRC_ENTROPY);
+	else
+		val = (DRBG_MODE_FORCE_RESEED | DRBG_SRC_ENTROPY);
+	tegra_se_write_32(se_dev, SE_RNG_CONFIG_REG_OFFSET, val);
+
+	/* Configure output destination = SRK */
+	val = (SE_CONFIG_ENC_ALG_RNG |
+		SE_CONFIG_DEC_ALG_NOP |
+		SE_CONFIG_DST_SRK);
+	tegra_se_write_32(se_dev, SE_CONFIG_REG_OFFSET, val);
+
+	/* Perform hardware operation */
+	ret = tegra_se_start_normal_operation(se_dev, 0);
+
+	return ret;
+}
+
+/*
+ * Generate plain text random data to some memory location using
+ * SE/SE2's SP800-90 random number generator. The random data size
+ * must be some multiple of the AES block size (16 bytes).
+ */
+static int tegra_se_lp_generate_random_data(tegra_se_dev_t *se_dev)
+{
+	int ret = 0;
+	uint32_t val;
+
+	/* Set some arbitrary memory location to store the random data */
+	se_dev->dst_ll_buf->last_buff_num = 0;
+	if (!se_dev->ctx_save_buf) {
+		ERROR("%s: ERR: context save buffer NULL pointer!\n", __func__);
+		return PSCI_E_NOT_PRESENT;
+	}
+	se_dev->dst_ll_buf->buffer[0].addr = ((uint64_t)(&(((tegra_se_context_t *)
+					se_dev->ctx_save_buf)->rand_data)));
+	se_dev->dst_ll_buf->buffer[0].data_len = SE_CTX_SAVE_RANDOM_DATA_SIZE;
+
+
+	/* Confgure the following hardware register settings:
+	 * SE_CONFIG.DEC_ALG = NOP
+	 * SE_CONFIG.ENC_ALG = RNG
+	 * SE_CONFIG.ENC_MODE = KEY192
+	 * SE_CONFIG.DST = MEMORY
+	 */
+	val = (SE_CONFIG_ENC_ALG_RNG |
+		SE_CONFIG_DEC_ALG_NOP |
+		SE_CONFIG_ENC_MODE_KEY192 |
+		SE_CONFIG_DST_MEMORY);
+	tegra_se_write_32(se_dev, SE_CONFIG_REG_OFFSET, val);
+
+	/* Program the RNG options in SE_CRYPTO_CONFIG as follows:
+	 * XOR_POS = BYPASS
+	 * INPUT_SEL = RANDOM (Entropy or LFSR)
+	 * HASH_ENB = DISABLE
+	 */
+	val = (SE_CRYPTO_INPUT_RANDOM |
+		SE_CRYPTO_XOR_BYPASS |
+		SE_CRYPTO_CORE_ENCRYPT |
+		SE_CRYPTO_HASH_DISABLE |
+		SE_CRYPTO_KEY_INDEX(RNG_AES_KEY_INDEX) |
+		SE_CRYPTO_IV_ORIGINAL);
+	tegra_se_write_32(se_dev, SE_CRYPTO_REG_OFFSET, val);
+
+	/* Configure RNG */
+	if (ecid_valid)
+		val = (DRBG_MODE_FORCE_INSTANTION | DRBG_SRC_LFSR);
+	else
+		val = (DRBG_MODE_FORCE_RESEED | DRBG_SRC_LFSR);
+	tegra_se_write_32(se_dev, SE_RNG_CONFIG_REG_OFFSET, val);
+
+	/* SE normal operation */
+	ret = tegra_se_start_normal_operation(se_dev, SE_CTX_SAVE_RANDOM_DATA_SIZE);
+
+	return ret;
+}
+
+/*
+ * Encrypt memory blocks with SRK as part of the security engine context.
+ * The data blocks include: random data and the known pattern data, where
+ * the random data is the first block and known pattern is the last block.
+ */
+static int tegra_se_lp_data_context_save(tegra_se_dev_t *se_dev,
+		uint64_t src_addr, uint64_t dst_addr, uint32_t data_size)
+{
+	int ret = 0;
+
+	se_dev->src_ll_buf->last_buff_num = 0;
+	se_dev->dst_ll_buf->last_buff_num = 0;
+	se_dev->src_ll_buf->buffer[0].addr = src_addr;
+	se_dev->src_ll_buf->buffer[0].data_len = data_size;
+	se_dev->dst_ll_buf->buffer[0].addr = dst_addr;
+	se_dev->dst_ll_buf->buffer[0].data_len = data_size;
+
+	/* By setting the context source from memory and calling the context save
+	 * operation, the SE encrypts the memory data with SRK.
+	 */
+	tegra_se_write_32(se_dev, SE_CTX_SAVE_CONFIG_REG_OFFSET, SE_CTX_SAVE_SRC_MEM);
+
+	ret = tegra_se_start_ctx_save_operation(se_dev, data_size);
+
+	return ret;
+}
+
+/*
+ * Context save the key table access control sticky bits and
+ * security status of each key-slot. The encrypted sticky-bits are
+ * 32 bytes (2 AES blocks) and formatted as the following structure:
+ * {	bit in registers			bit in context save
+ *	SECURITY_0[4]				158
+ *	SE_RSA_KEYTABLE_ACCE4SS_1[2:0]		157:155
+ *	SE_RSA_KEYTABLE_ACCE4SS_0[2:0]		154:152
+ *	SE_RSA_SECURITY_PERKEY_0[1:0]		151:150
+ *	SE_CRYPTO_KEYTABLE_ACCESS_15[7:0]	149:142
+ *	...,
+ *	SE_CRYPTO_KEYTABLE_ACCESS_0[7:0]	29:22
+ *	SE_CRYPTO_SECURITY_PERKEY_0[15:0]	21:6
+ *	SE_TZRAM_SECURITY_0[1:0]		5:4
+ *	SE_SECURITY_0[16]			3:3
+ *	SE_SECURITY_0[2:0] }			2:0
+ */
+static int tegra_se_lp_sticky_bits_context_save(tegra_se_dev_t *se_dev)
+{
+	int ret = PSCI_E_INTERN_FAIL;
+	uint32_t val = 0;
+
+	se_dev->dst_ll_buf->last_buff_num = 0;
+	if (!se_dev->ctx_save_buf) {
+		ERROR("%s: ERR: context save buffer NULL pointer!\n", __func__);
+		return PSCI_E_NOT_PRESENT;
+	}
+	se_dev->dst_ll_buf->buffer[0].addr = ((uint64_t)(&(((tegra_se_context_t *)
+						se_dev->ctx_save_buf)->sticky_bits)));
+	se_dev->dst_ll_buf->buffer[0].data_len = SE_CTX_SAVE_STICKY_BITS_SIZE;
+
+	/*
+	 * The 1st AES block save the sticky-bits context 1 - 16 bytes (0 - 3 words).
+	 * The 2nd AES block save the sticky-bits context 17 - 32 bytes (4 - 7 words).
+	 */
+	for (int i = 0; i < 2; i++) {
+		val = SE_CTX_SAVE_SRC_STICKY_BITS |
+			SE_CTX_SAVE_STICKY_WORD_QUAD(i);
+		tegra_se_write_32(se_dev, SE_CTX_SAVE_CONFIG_REG_OFFSET, val);
+
+		/* SE context save operation */
+		ret = tegra_se_start_ctx_save_operation(se_dev,
+				SE_CTX_SAVE_STICKY_BITS_SIZE);
+		if (ret)
+			break;
+		se_dev->dst_ll_buf->buffer[0].addr += SE_CTX_SAVE_STICKY_BITS_SIZE;
+	}
+
+	return ret;
+}
+
+static int tegra_se_aeskeytable_context_save(tegra_se_dev_t *se_dev)
+{
+	uint32_t val = 0;
+	int ret = 0;
+
+	se_dev->dst_ll_buf->last_buff_num = 0;
+	if (!se_dev->ctx_save_buf) {
+		ERROR("%s: ERR: context save buffer NULL pointer!\n", __func__);
+		ret = -EINVAL;
+		goto aes_keytable_save_err;
+	}
+
+	/* AES key context save */
+	for (int slot = 0; slot < TEGRA_SE_AES_KEYSLOT_COUNT; slot++) {
+		se_dev->dst_ll_buf->buffer[0].addr = ((uint64_t)(&(
+						((tegra_se_context_t *)se_dev->
+						 ctx_save_buf)->key_slots[slot].key)));
+		se_dev->dst_ll_buf->buffer[0].data_len = TEGRA_SE_KEY_128_SIZE;
+		for (int i = 0; i < 2; i++) {
+			val = SE_CTX_SAVE_SRC_AES_KEYTABLE |
+				SE_CTX_SAVE_KEY_INDEX(slot) |
+				SE_CTX_SAVE_WORD_QUAD(i);
+			tegra_se_write_32(se_dev, SE_CTX_SAVE_CONFIG_REG_OFFSET, val);
+
+			/* SE context save operation */
+			ret = tegra_se_start_ctx_save_operation(se_dev,
+					TEGRA_SE_KEY_128_SIZE);
+			if (ret) {
+				ERROR("%s: ERR: AES key CTX_SAVE OP failed, "
+						"slot=%d, word_quad=%d.\n",
+						__func__, slot, i);
+				goto aes_keytable_save_err;
+			}
+			se_dev->dst_ll_buf->buffer[0].addr += TEGRA_SE_KEY_128_SIZE;
+		}
+
+		/* OIV context save */
+		se_dev->dst_ll_buf->last_buff_num = 0;
+		se_dev->dst_ll_buf->buffer[0].addr = ((uint64_t)(&(
+						((tegra_se_context_t *)se_dev->
+						 ctx_save_buf)->key_slots[slot].oiv)));
+		se_dev->dst_ll_buf->buffer[0].data_len = TEGRA_SE_AES_IV_SIZE;
+
+		val = SE_CTX_SAVE_SRC_AES_KEYTABLE |
+			SE_CTX_SAVE_KEY_INDEX(slot) |
+			SE_CTX_SAVE_WORD_QUAD_ORIG_IV;
+		tegra_se_write_32(se_dev, SE_CTX_SAVE_CONFIG_REG_OFFSET, val);
+
+		/* SE context save operation */
+		ret = tegra_se_start_ctx_save_operation(se_dev, TEGRA_SE_AES_IV_SIZE);
+		if (ret) {
+			ERROR("%s: ERR: OIV CTX_SAVE OP failed, slot=%d.\n",
+					__func__, slot);
+			goto aes_keytable_save_err;
+		}
+
+		/* UIV context save */
+		se_dev->dst_ll_buf->last_buff_num = 0;
+		se_dev->dst_ll_buf->buffer[0].addr = ((uint64_t)(&(
+						((tegra_se_context_t *)se_dev->
+						 ctx_save_buf)->key_slots[slot].uiv)));
+		se_dev->dst_ll_buf->buffer[0].data_len = TEGRA_SE_AES_IV_SIZE;
+
+		val = SE_CTX_SAVE_SRC_AES_KEYTABLE |
+			SE_CTX_SAVE_KEY_INDEX(slot) |
+			SE_CTX_SAVE_WORD_QUAD_UPD_IV;
+		tegra_se_write_32(se_dev, SE_CTX_SAVE_CONFIG_REG_OFFSET, val);
+
+		/* SE context save operation */
+		ret = tegra_se_start_ctx_save_operation(se_dev, TEGRA_SE_AES_IV_SIZE);
+		if (ret) {
+			ERROR("%s: ERR: UIV CTX_SAVE OP failed, slot=%d\n",
+					__func__, slot);
+			goto aes_keytable_save_err;
+		}
+	}
+
+aes_keytable_save_err:
+	return ret;
+}
+
+static int tegra_se_lp_rsakeytable_context_save(tegra_se_dev_t *se_dev)
+{
+	uint32_t val = 0;
+	int ret = 0;
+	/* First the modulus and then the exponent must be
+	 * encrypted and saved. This is repeated for SLOT 0
+	 * and SLOT 1. Hence the order:
+	 * SLOT 0 exponent : RSA_KEY_INDEX : 0
+	 * SLOT 0 modulus : RSA_KEY_INDEX : 1
+	 * SLOT 1 exponent : RSA_KEY_INDEX : 2
+	 * SLOT 1 modulus : RSA_KEY_INDEX : 3
+	 */
+	const unsigned int key_index_mod[TEGRA_SE_RSA_KEYSLOT_COUNT][2] = {
+		/* RSA key slot 0 */
+		{SE_RSA_KEY_INDEX_SLOT0_EXP, SE_RSA_KEY_INDEX_SLOT0_MOD},
+		/* RSA key slot 1 */
+		{SE_RSA_KEY_INDEX_SLOT1_EXP, SE_RSA_KEY_INDEX_SLOT1_MOD},
+	};
+
+	se_dev->dst_ll_buf->last_buff_num = 0;
+	se_dev->dst_ll_buf->buffer[0].addr = ((uint64_t)(&(
+					((tegra_se_context_t *)se_dev->
+					 ctx_save_buf)->rsa_keys)));
+	se_dev->dst_ll_buf->buffer[0].data_len = TEGRA_SE_KEY_128_SIZE;
+
+	for (int slot = 0; slot < TEGRA_SE_RSA_KEYSLOT_COUNT; slot++) {
+		/* loop for modulus and exponent */
+		for (int index = 0; index < 2; index++) {
+			for (int word_quad = 0; word_quad < 16; word_quad++) {
+				val = SE_CTX_SAVE_SRC_RSA_KEYTABLE |
+					SE_CTX_SAVE_RSA_KEY_INDEX(
+						key_index_mod[slot][index]) |
+					SE_CTX_RSA_WORD_QUAD(word_quad);
+				tegra_se_write_32(se_dev,
+					SE_CTX_SAVE_CONFIG_REG_OFFSET, val);
+
+				/* SE context save operation */
+				ret = tegra_se_start_ctx_save_operation(se_dev,
+						TEGRA_SE_KEY_128_SIZE);
+				if (ret) {
+					ERROR("%s: ERR: slot=%d.\n",
+						__func__, slot);
+					goto rsa_keytable_save_err;
+				}
+
+				/* Update the pointer to the next word quad */
+				se_dev->dst_ll_buf->buffer[0].addr +=
+					TEGRA_SE_KEY_128_SIZE;
+			}
+		}
+	}
+
+rsa_keytable_save_err:
+	return ret;
+}
+
+static int tegra_se_pkakeytable_sticky_bits_save(tegra_se_dev_t *se_dev)
+{
+	int ret = 0;
+
+	se_dev->dst_ll_buf->last_buff_num = 0;
+	se_dev->dst_ll_buf->buffer[0].addr = ((uint64_t)(&(
+					((tegra_se2_context_blob_t *)se_dev->
+					 ctx_save_buf)->pka_ctx.sticky_bits)));
+	se_dev->dst_ll_buf->buffer[0].data_len = TEGRA_SE_AES_BLOCK_SIZE;
+
+	/* PKA1 sticky bits are 1 AES block (16 bytes) */
+	tegra_se_write_32(se_dev, SE_CTX_SAVE_CONFIG_REG_OFFSET,
+			SE_CTX_SAVE_SRC_PKA1_STICKY_BITS |
+			SE_CTX_STICKY_WORD_QUAD_WORDS_0_3);
+
+	/* SE context save operation */
+	ret = tegra_se_start_ctx_save_operation(se_dev, 0);
+	if (ret) {
+		ERROR("%s: ERR: PKA1 sticky bits CTX_SAVE OP failed\n",
+				__func__);
+		goto pka_sticky_bits_save_err;
+	}
+
+pka_sticky_bits_save_err:
+	return ret;
+}
+
+static int tegra_se_pkakeytable_context_save(tegra_se_dev_t *se_dev)
+{
+	uint32_t val = 0;
+	int ret = 0;
+
+	se_dev->dst_ll_buf->last_buff_num = 0;
+	se_dev->dst_ll_buf->buffer[0].addr = ((uint64_t)(&(
+					((tegra_se2_context_blob_t *)se_dev->
+					 ctx_save_buf)->pka_ctx.pka_keys)));
+	se_dev->dst_ll_buf->buffer[0].data_len = TEGRA_SE_KEY_128_SIZE;
+
+	/* for each slot, save word quad 0-127 */
+	for (int slot = 0; slot < TEGRA_SE_PKA1_KEYSLOT_COUNT; slot++) {
+		for (int word_quad = 0; word_quad < 512/4; word_quad++) {
+			val = SE_CTX_SAVE_SRC_PKA1_KEYTABLE |
+				SE_CTX_PKA1_WORD_QUAD_L((slot * 128) +
+						word_quad) |
+				SE_CTX_PKA1_WORD_QUAD_H((slot * 128) +
+						word_quad);
+			tegra_se_write_32(se_dev,
+					SE_CTX_SAVE_CONFIG_REG_OFFSET, val);
+
+			/* SE context save operation */
+			ret = tegra_se_start_ctx_save_operation(se_dev,
+					TEGRA_SE_KEY_128_SIZE);
+			if (ret) {
+				ERROR("%s: ERR: pka1 keytable ctx save error\n",
+						__func__);
+				goto pka_keytable_save_err;
+			}
+
+			/* Update the pointer to the next word quad */
+			se_dev->dst_ll_buf->buffer[0].addr +=
+				TEGRA_SE_KEY_128_SIZE;
+		}
+	}
+
+pka_keytable_save_err:
+	return ret;
+}
+
+static int tegra_se_save_SRK(tegra_se_dev_t *se_dev)
+{
+	tegra_se_write_32(se_dev, SE_CTX_SAVE_CONFIG_REG_OFFSET,
+			SE_CTX_SAVE_SRC_SRK);
+
+	/* SE context save operation */
+	return tegra_se_start_ctx_save_operation(se_dev, 0);
+}
+
+/*
+ *  Lock both SE from non-TZ clients.
+ */
+static inline void tegra_se_lock(tegra_se_dev_t *se_dev)
+{
+	uint32_t val;
+
+	assert(se_dev);
+	val = tegra_se_read_32(se_dev, SE_SECURITY_REG_OFFSET);
+	val |= SE_SECURITY_TZ_LOCK_SOFT(SE_SECURE);
+	tegra_se_write_32(se_dev, SE_SECURITY_REG_OFFSET, val);
+}
+
+/*
+ * Use SRK to encrypt SE state and save to TZRAM carveout
+ */
+static int tegra_se_context_save_sw(tegra_se_dev_t *se_dev)
+{
+	int err = 0;
+
+	assert(se_dev);
+
+	/* Lock entire SE/SE2 as TZ protected */
+	tegra_se_lock(se_dev);
+
+	INFO("%s: generate SRK\n", __func__);
+	/* Generate SRK */
+	err = tegra_se_generate_srk(se_dev);
+	if (err) {
+		ERROR("%s: ERR: SRK generation failed\n", __func__);
+		return err;
+	}
+
+	INFO("%s: generate random data\n", __func__);
+	/* Generate random data */
+	err = tegra_se_lp_generate_random_data(se_dev);
+	if (err) {
+		ERROR("%s: ERR: LP random pattern generation failed\n", __func__);
+		return err;
+	}
+
+	INFO("%s: encrypt random data\n", __func__);
+	/* Encrypt the random data block */
+	err = tegra_se_lp_data_context_save(se_dev,
+		((uint64_t)(&(((tegra_se_context_t *)se_dev->
+					ctx_save_buf)->rand_data))),
+		((uint64_t)(&(((tegra_se_context_t *)se_dev->
+					ctx_save_buf)->rand_data))),
+		SE_CTX_SAVE_RANDOM_DATA_SIZE);
+	if (err) {
+		ERROR("%s: ERR: random pattern encryption failed\n", __func__);
+		return err;
+	}
+
+	INFO("%s: save SE sticky bits\n", __func__);
+	/* Save AES sticky bits context */
+	err = tegra_se_lp_sticky_bits_context_save(se_dev);
+	if (err) {
+		ERROR("%s: ERR: sticky bits context save failed\n", __func__);
+		return err;
+	}
+
+	INFO("%s: save AES keytables\n", __func__);
+	/* Save AES key table context */
+	err = tegra_se_aeskeytable_context_save(se_dev);
+	if (err) {
+		ERROR("%s: ERR: LP keytable save failed\n", __func__);
+		return err;
+	}
+
+	/* RSA key slot table context save */
+	INFO("%s: save RSA keytables\n", __func__);
+	err = tegra_se_lp_rsakeytable_context_save(se_dev);
+	if (err) {
+		ERROR("%s: ERR: rsa key table context save failed\n", __func__);
+		return err;
+	}
+
+	/* Only SE2 has an interface with PKA1; thus, PKA1's context is saved
+	 * via SE2.
+	 */
+	if (se_dev->se_num == 2) {
+		/* Encrypt PKA1 sticky bits on SE2 only */
+		INFO("%s: save PKA sticky bits\n", __func__);
+		err = tegra_se_pkakeytable_sticky_bits_save(se_dev);
+		if (err) {
+			ERROR("%s: ERR: PKA sticky bits context save failed\n", __func__);
+			return err;
+		}
+
+		/* Encrypt PKA1 keyslots on SE2 only */
+		INFO("%s: save PKA keytables\n", __func__);
+		err = tegra_se_pkakeytable_context_save(se_dev);
+		if (err) {
+			ERROR("%s: ERR: PKA key table context save failed\n", __func__);
+			return err;
+		}
+	}
+
+	/* Encrypt known pattern */
+	if (se_dev->se_num == 1) {
+		err = tegra_se_lp_data_context_save(se_dev,
+			((uint64_t)(&se_ctx_known_pattern_data)),
+			((uint64_t)(&(((tegra_se_context_blob_t *)se_dev->ctx_save_buf)->known_pattern))),
+			SE_CTX_KNOWN_PATTERN_SIZE);
+	} else if (se_dev->se_num == 2) {
+		err = tegra_se_lp_data_context_save(se_dev,
+			((uint64_t)(&se_ctx_known_pattern_data)),
+			((uint64_t)(&(((tegra_se2_context_blob_t *)se_dev->ctx_save_buf)->known_pattern))),
+			SE_CTX_KNOWN_PATTERN_SIZE);
+	}
+	if (err) {
+		ERROR("%s: ERR: save LP known pattern failure\n", __func__);
+		return err;
+	}
+
+	/* Write lp context buffer address into PMC scratch register */
+	if (se_dev->se_num == 1) {
+		/* SE context address */
+		mmio_write_32((uint64_t)TEGRA_PMC_BASE + PMC_SECURE_SCRATCH117_OFFSET,
+				((uint64_t)(se_dev->ctx_save_buf)));
+	} else if (se_dev->se_num == 2) {
+		/* SE2 & PKA1 context address */
+		mmio_write_32((uint64_t)TEGRA_PMC_BASE + PMC_SECURE_SCRATCH116_OFFSET,
+				((uint64_t)(se_dev->ctx_save_buf)));
+	}
+
+	/* Saves SRK to PMC secure scratch registers for BootROM, which
+	 * verifies and restores the security engine context on warm boot.
+	 */
+	err = tegra_se_save_SRK(se_dev);
+	if (err < 0) {
+		ERROR("%s: ERR: LP SRK save failure\n", __func__);
+		return err;
+	}
+
+	INFO("%s: SE context save done \n", __func__);
+
+	return err;
+}
+
+/*
+ * Initialize the SE engine handle
+ */
+void tegra_se_init(void)
+{
+	uint32_t val = 0;
+	INFO("%s: start SE init\n", __func__);
+
+	/* Generate random SRK to initialize DRBG */
+	tegra_se_generate_srk(&se_dev_1);
+	tegra_se_generate_srk(&se_dev_2);
+
+	/* determine if ECID is valid */
+	val = mmio_read_32(TEGRA_FUSE_BASE + FUSE_JTAG_SECUREID_VALID);
+	ecid_valid = (val == ECID_VALID);
+
+	INFO("%s: SE init done\n", __func__);
+}
+
+static void tegra_se_enable_clocks(void)
+{
+	uint32_t val = 0;
+
+	/* Enable entropy clock */
+	val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_W);
+	val |= ENTROPY_CLK_ENB_BIT;
+	mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_W, val);
+
+	/* De-Assert Entropy Reset */
+	val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEVICES_W);
+	val &= ~ENTROPY_RESET_BIT;
+	mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEVICES_W, val);
+
+	/* Enable SE clock */
+	val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_V);
+	val |= SE_CLK_ENB_BIT;
+	mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_V, val);
+
+	/* De-Assert SE Reset */
+	val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEVICES_V);
+	val &= ~SE_RESET_BIT;
+	mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEVICES_V, val);
+}
+
+static void tegra_se_disable_clocks(void)
+{
+	uint32_t val = 0;
+
+	/* Disable entropy clock */
+	val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_W);
+	val &= ~ENTROPY_CLK_ENB_BIT;
+	mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_W, val);
+
+	/* Disable SE clock */
+	val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_V);
+	val &= ~SE_CLK_ENB_BIT;
+	mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_V, val);
+}
+
+/*
+ * Security engine power suspend entry point.
+ * This function is invoked from PSCI power domain suspend handler.
+ */
+int32_t tegra_se_suspend(void)
+{
+	int32_t ret = 0;
+	uint32_t val = 0;
+
+	/* SE does not use SMMU in EL3, disable SMMU.
+	 * This will be re-enabled by kernel on resume */
+	val = mmio_read_32(TEGRA_MC_BASE + MC_SMMU_PPCS_ASID_0);
+	val &= ~PPCS_SMMU_ENABLE;
+	mmio_write_32(TEGRA_MC_BASE + MC_SMMU_PPCS_ASID_0, val);
+
+	tegra_se_enable_clocks();
+
+	if (tegra_se_atomic_save_enabled(&se_dev_2) &&
+			tegra_se_atomic_save_enabled(&se_dev_1)) {
+		/* Atomic context save se2 and pka1 */
+		INFO("%s: SE2/PKA1 atomic context save\n", __func__);
+		if (ret == 0) {
+			ret = tegra_se_context_save_atomic(&se_dev_2);
+		}
+
+		/* Atomic context save se */
+		if (ret == 0) {
+			INFO("%s: SE1 atomic context save\n", __func__);
+			ret = tegra_se_context_save_atomic(&se_dev_1);
+		}
+
+		if (ret == 0) {
+			INFO("%s: SE atomic context save done\n", __func__);
+		}
+	} else if (!tegra_se_atomic_save_enabled(&se_dev_2) &&
+			!tegra_se_atomic_save_enabled(&se_dev_1)) {
+		/* SW context save se2 and pka1 */
+		INFO("%s: SE2/PKA1 legacy(SW) context save\n", __func__);
+		if (ret == 0) {
+			ret = tegra_se_context_save_sw(&se_dev_2);
+		}
+
+		/* SW context save se */
+		if (ret == 0) {
+			INFO("%s: SE1 legacy(SW) context save\n", __func__);
+			ret = tegra_se_context_save_sw(&se_dev_1);
+		}
+
+		if (ret == 0) {
+			INFO("%s: SE SW context save done\n", __func__);
+		}
+	} else {
+		ERROR("%s: One SE set for atomic CTX save, the other is not\n",
+			 __func__);
+	}
+
+	tegra_se_disable_clocks();
+
+	return ret;
+}
+
+/*
+ * Save TZRAM to shadow TZRAM in AON
+ */
+int32_t tegra_se_save_tzram(void)
+{
+	uint32_t val = 0;
+	int32_t ret = 0;
+	uint32_t timeout;
+
+	INFO("%s: SE TZRAM save start\n", __func__);
+	tegra_se_enable_clocks();
+
+	val = (SE_TZRAM_OP_REQ_INIT | SE_TZRAM_OP_MODE_SAVE);
+	tegra_se_write_32(&se_dev_1, SE_TZRAM_OPERATION, val);
+
+	val = tegra_se_read_32(&se_dev_1, SE_TZRAM_OPERATION);
+	for (timeout = 0; (SE_TZRAM_OP_BUSY(val) == SE_TZRAM_OP_BUSY_ON) &&
+			(timeout < TIMEOUT_100MS); timeout++) {
+		mdelay(1);
+		val = tegra_se_read_32(&se_dev_1, SE_TZRAM_OPERATION);
+	}
+
+	if (timeout == TIMEOUT_100MS) {
+		ERROR("%s: ERR: TZRAM save timeout!\n", __func__);
+		ret = -ETIMEDOUT;
+	}
+
+	if (ret == 0) {
+		INFO("%s: SE TZRAM save done!\n", __func__);
+	}
+
+	tegra_se_disable_clocks();
+
+	return ret;
+}
+
+/*
+ * The function is invoked by SE resume
+ */
+static void tegra_se_warm_boot_resume(const tegra_se_dev_t *se_dev)
+{
+	uint32_t val;
+
+	assert(se_dev);
+
+	/* Lock RNG source to ENTROPY on resume */
+	val = DRBG_RO_ENT_IGNORE_MEM_ENABLE |
+		DRBG_RO_ENT_SRC_LOCK_ENABLE |
+		DRBG_RO_ENT_SRC_ENABLE;
+	tegra_se_write_32(se_dev, SE_RNG_SRC_CONFIG_REG_OFFSET, val);
+
+	/* Set a random value to SRK to initialize DRBG */
+	tegra_se_generate_srk(se_dev);
+}
+
+/*
+ * The function is invoked on SC7 resume
+ */
+void tegra_se_resume(void)
+{
+	tegra_se_warm_boot_resume(&se_dev_1);
+	tegra_se_warm_boot_resume(&se_dev_2);
+}
diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
index 27786d3..f52d975 100644
--- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
@@ -1,13 +1,11 @@
 /*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <assert.h>
-
-#include <platform_def.h>
-
+#include <cortex_a57.h>
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <drivers/delay_timer.h>
@@ -15,10 +13,14 @@
 #include <lib/psci/psci.h>
 #include <plat/common/platform.h>
 
+#include <bpmp.h>
 #include <flowctrl.h>
 #include <pmc.h>
+#include <platform_def.h>
+#include <security_engine.h>
 #include <tegra_def.h>
 #include <tegra_private.h>
+#include <tegra_platform.h>
 
 /*
  * Register used to clear CPU reset signals. Each CPU has two reset
@@ -55,7 +57,7 @@
 		 * Cluster powerdown/idle request only for afflvl 1
 		 */
 		req_state->pwr_domain_state[MPIDR_AFFLVL1] = state_id;
-		req_state->pwr_domain_state[MPIDR_AFFLVL0] = state_id;
+		req_state->pwr_domain_state[MPIDR_AFFLVL0] = PSTATE_ID_CORE_POWERDN;
 
 		break;
 
@@ -87,9 +89,11 @@
 					     const plat_local_state_t *states,
 					     unsigned int ncpu)
 {
-	plat_local_state_t target = *states;
+	plat_local_state_t target = PSCI_LOCAL_STATE_RUN;
 	int cpu = plat_my_core_pos();
 	int core_pos = read_mpidr() & MPIDR_CPU_MASK;
+	uint32_t bpmp_reply, data[3];
+	int ret;
 
 	/* get the power state at this level */
 	if (lvl == MPIDR_AFFLVL1)
@@ -97,19 +101,71 @@
 	if (lvl == MPIDR_AFFLVL2)
 		target = *(states + cpu);
 
-	/* Cluster idle/power-down */
-	if ((lvl == MPIDR_AFFLVL1) && ((target == PSTATE_ID_CLUSTER_IDLE) ||
-	    (target == PSTATE_ID_CLUSTER_POWERDN))) {
-		return target;
-	}
+	if ((lvl == MPIDR_AFFLVL1) && (target == PSTATE_ID_CLUSTER_IDLE)) {
+
+		/* initialize the bpmp interface */
+		ret = tegra_bpmp_init();
+		if (ret != 0U) {
+
+			/* Cluster idle not allowed */
+			target = PSCI_LOCAL_STATE_RUN;
+		} else {
+
+			/* Cluster idle */
+			data[0] = (uint32_t)cpu;
+			data[1] = TEGRA_PM_CC6;
+			data[2] = TEGRA_PM_SC1;
+			ret = tegra_bpmp_send_receive_atomic(MRQ_DO_IDLE,
+					(void *)&data, (int)sizeof(data),
+					(void *)&bpmp_reply,
+					(int)sizeof(bpmp_reply));
+
+			/* check if cluster idle entry is allowed */
+			if ((ret != 0L) || (bpmp_reply != BPMP_CCx_ALLOWED)) {
+
+				/* Cluster idle not allowed */
+				target = PSCI_LOCAL_STATE_RUN;
+			}
+		}
 
-	/* System Suspend */
-	if (((lvl == MPIDR_AFFLVL2) || (lvl == MPIDR_AFFLVL1)) &&
-	    (target == PSTATE_ID_SOC_POWERDN))
-		return PSTATE_ID_SOC_POWERDN;
+	} else if ((lvl == MPIDR_AFFLVL1) && (target == PSTATE_ID_CLUSTER_POWERDN)) {
+
+		/* initialize the bpmp interface */
+		ret = tegra_bpmp_init();
+		if (ret != 0U) {
+
+			/* Cluster power down not allowed */
+			target = PSCI_LOCAL_STATE_RUN;
+		} else {
+
+			/* Cluster power-down */
+			data[0] = (uint32_t)cpu;
+			data[1] = TEGRA_PM_CC7;
+			data[2] = TEGRA_PM_SC1;
+			ret = tegra_bpmp_send_receive_atomic(MRQ_DO_IDLE,
+					(void *)&data, (int)sizeof(data),
+					(void *)&bpmp_reply,
+					(int)sizeof(bpmp_reply));
+
+			/* check if cluster power down is allowed */
+			if ((ret != 0L) || (bpmp_reply != BPMP_CCx_ALLOWED)) {
+
+				/* Cluster power down not allowed */
+				target = PSCI_LOCAL_STATE_RUN;
+			}
+		}
+
+	} else if (((lvl == MPIDR_AFFLVL2) || (lvl == MPIDR_AFFLVL1)) &&
+	    (target == PSTATE_ID_SOC_POWERDN)) {
+
+		/* System Suspend */
+		target = PSTATE_ID_SOC_POWERDN;
+
+	} else {
+		; /* do nothing */
+	}
 
-	/* default state */
-	return PSCI_LOCAL_STATE_RUN;
+	return target;
 }
 
 int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
@@ -120,27 +176,33 @@
 	unsigned int stateid_afflvl2 = pwr_domain_state[MPIDR_AFFLVL2];
 	unsigned int stateid_afflvl1 = pwr_domain_state[MPIDR_AFFLVL1];
 	unsigned int stateid_afflvl0 = pwr_domain_state[MPIDR_AFFLVL0];
+	int ret = PSCI_E_SUCCESS;
 
 	if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
 
 		assert((stateid_afflvl0 == PLAT_MAX_OFF_STATE) ||
-		       (stateid_afflvl0 == PSTATE_ID_SOC_POWERDN));
+			(stateid_afflvl0 == PSTATE_ID_SOC_POWERDN));
 		assert((stateid_afflvl1 == PLAT_MAX_OFF_STATE) ||
-		       (stateid_afflvl1 == PSTATE_ID_SOC_POWERDN));
+			(stateid_afflvl1 == PSTATE_ID_SOC_POWERDN));
 
-		/* suspend the entire soc */
-		tegra_fc_soc_powerdn(mpidr);
+		if (tegra_chipid_is_t210_b01()) {
+
+			/* Suspend se/se2 and pka1 */
+			if (tegra_se_suspend() != 0) {
+				ret = PSCI_E_INTERN_FAIL;
+			}
+		}
 
 	} else if (stateid_afflvl1 == PSTATE_ID_CLUSTER_IDLE) {
 
-		assert(stateid_afflvl0 == PSTATE_ID_CLUSTER_IDLE);
+		assert(stateid_afflvl0 == PSTATE_ID_CORE_POWERDN);
 
 		/* Prepare for cluster idle */
 		tegra_fc_cluster_idle(mpidr);
 
 	} else if (stateid_afflvl1 == PSTATE_ID_CLUSTER_POWERDN) {
 
-		assert(stateid_afflvl0 == PSTATE_ID_CLUSTER_POWERDN);
+		assert(stateid_afflvl0 == PSTATE_ID_CORE_POWERDN);
 
 		/* Prepare for cluster powerdn */
 		tegra_fc_cluster_powerdn(mpidr);
@@ -151,8 +213,30 @@
 		tegra_fc_cpu_powerdn(mpidr);
 
 	} else {
-		ERROR("%s: Unknown state id\n", __func__);
-		return PSCI_E_NOT_SUPPORTED;
+		ERROR("%s: Unknown state id (%d, %d, %d)\n", __func__,
+			stateid_afflvl2, stateid_afflvl1, stateid_afflvl0);
+		ret = PSCI_E_NOT_SUPPORTED;
+	}
+
+	return ret;
+}
+
+int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
+{
+	u_register_t mpidr = read_mpidr();
+	const plat_local_state_t *pwr_domain_state =
+		target_state->pwr_domain_state;
+	unsigned int stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL];
+
+	if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
+
+		if (tegra_chipid_is_t210_b01()) {
+			/* Save tzram contents */
+			tegra_se_save_tzram();
+		}
+
+		/* enter system suspend */
+		tegra_fc_soc_powerdn(mpidr);
 	}
 
 	return PSCI_E_SUCCESS;
@@ -160,8 +244,17 @@
 
 int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
 {
+	const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
 	uint32_t val;
 
+	/* platform parameter passed by the previous bootloader */
+	if (plat_params->l2_ecc_parity_prot_dis != 1) {
+		/* Enable ECC Parity Protection for Cortex-A57 CPUs */
+		val = read_l2ctlr_el1();
+		val |= (uint64_t)CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT;
+		write_l2ctlr_el1(val);
+	}
+
 	/*
 	 * Check if we are exiting from SOC_POWERDN.
 	 */
@@ -169,6 +262,13 @@
 			PLAT_SYS_SUSPEND_STATE_ID) {
 
 		/*
+		 * Security engine resume
+		 */
+		if (tegra_chipid_is_t210_b01()) {
+			tegra_se_resume();
+		}
+
+		/*
 		 * Lock scratch registers which hold the CPU vectors
 		 */
 		tegra_pmc_lock_cpu_vectors();
@@ -231,7 +331,7 @@
 	 * for the PMC APB clock would not be changed due to system reset.
 	 */
 	mmio_write_32((uintptr_t)TEGRA_CAR_RESET_BASE + SCLK_BURST_POLICY,
-		       SCLK_BURST_POLICY_DEFAULT);
+		SCLK_BURST_POLICY_DEFAULT);
 	mmio_write_32((uintptr_t)TEGRA_CAR_RESET_BASE + SCLK_RATE, 0);
 
 	/* Wait 1 ms to make sure clock source/device logic is stabilized. */
diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c
index c7f7165..6246dde 100644
--- a/plat/nvidia/tegra/soc/t210/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t210/plat_setup.c
@@ -1,34 +1,21 @@
 /*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <arch_helpers.h>
+#include <bpmp.h>
+#include <cortex_a57.h>
 #include <common/bl_common.h>
 #include <drivers/console.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
-
+#include <platform.h>
+#include <security_engine.h>
 #include <tegra_def.h>
+#include <tegra_platform.h>
 #include <tegra_private.h>
 
-/*******************************************************************************
- * The Tegra power domain tree has a single system level power domain i.e. a
- * single root node. The first entry in the power domain descriptor specifies
- * the number of power domains at the highest power level.
- *******************************************************************************
- */
-const unsigned char tegra_power_domain_tree_desc[] = {
-	/* No of root nodes */
-	1,
-	/* No of clusters */
-	PLATFORM_CLUSTER_COUNT,
-	/* No of CPU cores - cluster0 */
-	PLATFORM_MAX_CPUS_PER_CLUSTER,
-	/* No of CPU cores - cluster1 */
-	PLATFORM_MAX_CPUS_PER_CLUSTER
-};
-
 /* sets of MMIO ranges setup */
 #define MMIO_RANGE_0_ADDR	0x50000000
 #define MMIO_RANGE_1_ADDR	0x60000000
@@ -39,6 +26,8 @@
  * Table of regions to map using the MMU.
  */
 static const mmap_region_t tegra_mmap[] = {
+	MAP_REGION_FLAT(TEGRA_IRAM_BASE, 0x40000, /* 256KB */
+			MT_DEVICE | MT_RW | MT_SECURE),
 	MAP_REGION_FLAT(MMIO_RANGE_0_ADDR, MMIO_RANGE_SIZE,
 			MT_DEVICE | MT_RW | MT_SECURE),
 	MAP_REGION_FLAT(MMIO_RANGE_1_ADDR, MMIO_RANGE_SIZE,
@@ -53,11 +42,44 @@
  ******************************************************************************/
 const mmap_region_t *plat_get_mmio_map(void)
 {
+	/* Add the map region for security engine SE2 */
+	if (tegra_chipid_is_t210_b01()) {
+		mmap_add_region((uint64_t)TEGRA_SE2_BASE,
+				(uint64_t)TEGRA_SE2_BASE,
+				(uint64_t)TEGRA_SE2_RANGE_SIZE,
+				MT_DEVICE | MT_RW | MT_SECURE);
+	}
+
 	/* MMIO space */
 	return tegra_mmap;
 }
 
 /*******************************************************************************
+ * The Tegra power domain tree has a single system level power domain i.e. a
+ * single root node. The first entry in the power domain descriptor specifies
+ * the number of power domains at the highest power level.
+ *******************************************************************************
+ */
+const unsigned char tegra_power_domain_tree_desc[] = {
+	/* No of root nodes */
+	1,
+	/* No of clusters */
+	PLATFORM_CLUSTER_COUNT,
+	/* No of CPU cores - cluster0 */
+	PLATFORM_MAX_CPUS_PER_CLUSTER,
+	/* No of CPU cores - cluster1 */
+	PLATFORM_MAX_CPUS_PER_CLUSTER
+};
+
+/*******************************************************************************
+ * This function returns the Tegra default topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return tegra_power_domain_tree_desc;
+}
+
+/*******************************************************************************
  * Handler to get the System Counter Frequency
  ******************************************************************************/
 unsigned int plat_get_syscnt_freq2(void)
@@ -94,6 +116,28 @@
 }
 
 /*******************************************************************************
+ * Handler for early platform setup
+ ******************************************************************************/
+void plat_early_platform_setup(void)
+{
+	const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
+	uint64_t val;
+
+	/* platform parameter passed by the previous bootloader */
+	if (plat_params->l2_ecc_parity_prot_dis != 1) {
+		/* Enable ECC Parity Protection for Cortex-A57 CPUs */
+		val = read_l2ctlr_el1();
+		val |= (uint64_t)CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT;
+		write_l2ctlr_el1(val);
+	}
+
+	/* Initialize security engine driver */
+	if (tegra_chipid_is_t210_b01()) {
+		tegra_se_init();
+	}
+}
+
+/*******************************************************************************
  * Initialize the GIC and SGIs
  ******************************************************************************/
 void plat_gic_setup(void)
diff --git a/plat/nvidia/tegra/soc/t210/platform_t210.mk b/plat/nvidia/tegra/soc/t210/platform_t210.mk
index b0a474c..e23d7e3 100644
--- a/plat/nvidia/tegra/soc/t210/platform_t210.mk
+++ b/plat/nvidia/tegra/soc/t210/platform_t210.mk
@@ -16,18 +16,23 @@
 PLATFORM_MAX_CPUS_PER_CLUSTER		:= 4
 $(eval $(call add_define,PLATFORM_MAX_CPUS_PER_CLUSTER))
 
-MAX_XLAT_TABLES				:= 4
+MAX_XLAT_TABLES				:= 10
 $(eval $(call add_define,MAX_XLAT_TABLES))
 
-MAX_MMAP_REGIONS			:= 8
+MAX_MMAP_REGIONS			:= 15
 $(eval $(call add_define,MAX_MMAP_REGIONS))
 
-BL31_SOURCES		+=	lib/cpus/aarch64/cortex_a53.S			\
+PLAT_INCLUDES		+=	-I${SOC_DIR}/drivers/se
+
+BL31_SOURCES		+=	drivers/ti/uart/aarch64/16550_console.S		\
+				lib/cpus/aarch64/cortex_a53.S			\
 				lib/cpus/aarch64/cortex_a57.S			\
+				${COMMON_DIR}/drivers/bpmp/bpmp.c		\
 				${COMMON_DIR}/drivers/flowctrl/flowctrl.c	\
 				${COMMON_DIR}/drivers/memctrl/memctrl_v1.c	\
 				${SOC_DIR}/plat_psci_handlers.c			\
 				${SOC_DIR}/plat_setup.c				\
+				${SOC_DIR}/drivers/se/security_engine.c		\
 				${SOC_DIR}/plat_secondary.c
 
 # Enable workarounds for selected Cortex-A57 erratas.
diff --git a/plat/qemu/qemu_private.h b/plat/qemu/qemu_private.h
index ab2bf1b..754831a 100644
--- a/plat/qemu/qemu_private.h
+++ b/plat/qemu/qemu_private.h
@@ -9,8 +9,6 @@
 
 #include <stdint.h>
 
-#include "../../bl1/bl1_private.h"
-
 void qemu_configure_mmu_svc_mon(unsigned long total_base,
 			unsigned long total_size,
 			unsigned long code_start, unsigned long code_limit,
diff --git a/plat/renesas/rcar/bl2_cpg_init.c b/plat/renesas/rcar/bl2_cpg_init.c
index 883fc9a..1dff690 100644
--- a/plat/renesas/rcar/bl2_cpg_init.c
+++ b/plat/renesas/rcar/bl2_cpg_init.c
@@ -28,7 +28,7 @@
 static void bl2_system_cpg_init_m3n(void);
 #endif
 
-#if (RCAR_LSI == RCAR_E3)
+#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_E3)
 static void bl2_realtime_cpg_init_e3(void);
 static void bl2_system_cpg_init_e3(void);
 #endif
@@ -193,7 +193,7 @@
 }
 #endif
 
-#if (RCAR_LSI == RCAR_E3)
+#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_E3)
 static void bl2_realtime_cpg_init_e3(void)
 {
 	/* Realtime Module Stop Control Registers */
@@ -251,6 +251,9 @@
 		case RCAR_PRODUCT_M3N:
 			bl2_realtime_cpg_init_m3n();
 			break;
+		case RCAR_PRODUCT_E3:
+			bl2_realtime_cpg_init_e3();
+			break;
 		default:
 			panic();
 			break;
@@ -284,6 +287,9 @@
 	case RCAR_PRODUCT_M3N:
 		bl2_system_cpg_init_m3n();
 		break;
+	case RCAR_PRODUCT_E3:
+		bl2_system_cpg_init_e3();
+		break;
 	default:
 		panic();
 		break;
diff --git a/plat/renesas/rcar/include/rcar_def.h b/plat/renesas/rcar/include/rcar_def.h
index 1829e59..3bb03f2 100644
--- a/plat/renesas/rcar/include/rcar_def.h
+++ b/plat/renesas/rcar/include/rcar_def.h
@@ -204,8 +204,6 @@
 #define	EXTAL_MD14_MD13_TYPE_3		U(16666600)	/* MD14=1 MD13=1 */
 #define	EXTAL_SALVATOR_XS		U(8320000)	/* Salvator-XS */
 #define EXTAL_EBISU			U(24000000)	/* Ebisu */
-/* CPU Auxiliary Control Register */
-#define RCAR_CA57_DIS_LOAD_PASS_STORE	(ULL(1) << 55)
 /* CPG write protect registers 	*/
 #define	CPGWPR_PASSWORD			(0x5A5AFFFFU)
 #define	CPGWPCR_PASSWORD		(0xA5A50000U)
diff --git a/plat/renesas/rcar/plat_pm.c b/plat/renesas/rcar/plat_pm.c
index 245a45a..47eda9a 100644
--- a/plat/renesas/rcar/plat_pm.c
+++ b/plat/renesas/rcar/plat_pm.c
@@ -175,7 +175,7 @@
 	uint64_t cpu = read_mpidr_el1() & 0x0000ffff;
 	int32_t rtn_on;
 
-	rtn_on = cpu_on_check(cpu);
+	rtn_on = rcar_pwrc_cpu_on_check(cpu);
 
 	if (cpu == rcar_boot_mpidr)
 		panic();
diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk
index b9c0802..629a3cf 100644
--- a/plat/renesas/rcar/platform.mk
+++ b/plat/renesas/rcar/platform.mk
@@ -4,7 +4,7 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-PROGRAMMABLE_RESET_ADDRESS	:= 1
+PROGRAMMABLE_RESET_ADDRESS	:= 0
 COLD_BOOT_SINGLE_CPU		:= 1
 ARM_CCI_PRODUCT_ID		:= 500
 TRUSTED_BOARD_BOOT		:= 1
diff --git a/plat/rockchip/common/rockchip_gicv2.c b/plat/rockchip/common/rockchip_gicv2.c
index 222a882..8db2b30 100644
--- a/plat/rockchip/common/rockchip_gicv2.c
+++ b/plat/rockchip/common/rockchip_gicv2.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
  */
@@ -22,11 +22,10 @@
 #pragma weak plat_rockchip_gic_pcpu_init
 
 /******************************************************************************
- * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
- * interrupts.
+ * List of interrupts.
  *****************************************************************************/
 static const interrupt_prop_t g0_interrupt_props[] = {
-	PLAT_RK_GICV2_G1S_IRQS
+	PLAT_RK_GICV2_G0_IRQS
 };
 
 /*
diff --git a/plat/rockchip/rk3328/rk3328_def.h b/plat/rockchip/rk3328/rk3328_def.h
index 4704a72..0ce13ad 100644
--- a/plat/rockchip/rk3328/rk3328_def.h
+++ b/plat/rockchip/rk3328/rk3328_def.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
  */
@@ -131,15 +131,13 @@
 #define RK_IRQ_SEC_SGI_7	15
 
 /*
- * 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 a list of Group 0 interrupts.
  */
-#define PLAT_RK_GICV2_G1S_IRQS						\
+#define PLAT_RK_GICV2_G0_IRQS						\
 	INTR_PROP_DESC(RK_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY,	\
-		       GICV2_INTR_GROUP1, GIC_INTR_CFG_LEVEL),		\
+		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),		\
 	INTR_PROP_DESC(RK_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY,	\
-		       GICV2_INTR_GROUP1, GIC_INTR_CFG_LEVEL)
+		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL)
 
 #define SHARE_MEM_BASE          0x100000/* [1MB, 1MB+60K]*/
 #define SHARE_MEM_PAGE_NUM      15
diff --git a/plat/rockchip/rk3368/rk3368_def.h b/plat/rockchip/rk3368/rk3368_def.h
index a7be7c3..10ac77b 100644
--- a/plat/rockchip/rk3368/rk3368_def.h
+++ b/plat/rockchip/rk3368/rk3368_def.h
@@ -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
  */
@@ -96,12 +96,10 @@
 #define RK_IRQ_SEC_SGI_7	15
 
 /*
- * 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 a list of Group 0 interrupts.
  */
-#define PLAT_RK_GICV2_G1S_IRQS						\
+#define PLAT_RK_GICV2_G0_IRQS						\
 	INTR_PROP_DESC(RK_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY,	\
-		       GICV2_INTR_GROUP1, GIC_INTR_CFG_LEVEL)
+		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL)
 
 #endif /* RK3368_DEF_H */
diff --git a/plat/rpi3/platform.mk b/plat/rpi3/platform.mk
index 559f316..ded92bd 100644
--- a/plat/rpi3/platform.mk
+++ b/plat/rpi3/platform.mk
@@ -27,6 +27,10 @@
 				drivers/io/io_fip.c			\
 				drivers/io/io_memmap.c			\
 				drivers/io/io_storage.c			\
+				drivers/gpio/gpio.c			\
+				drivers/delay_timer/delay_timer.c	\
+				drivers/delay_timer/generic_delay_timer.c \
+				drivers/rpi3/gpio/rpi3_gpio.c		\
 				plat/common/aarch64/platform_mp_stack.S	\
 				plat/rpi3/aarch64/plat_helpers.S	\
 				plat/rpi3/aarch64/rpi3_bl2_mem_params_desc.c \
@@ -130,7 +134,9 @@
 $(eval $(call add_define,RPI3_BL32_RAM_LOCATION_ID))
 $(eval $(call add_define,RPI3_BL33_IN_AARCH32))
 $(eval $(call add_define,RPI3_DIRECT_LINUX_BOOT))
+ifdef RPI3_PRELOADED_DTB_BASE
 $(eval $(call add_define,RPI3_PRELOADED_DTB_BASE))
+endif
 $(eval $(call add_define,RPI3_RUNTIME_UART))
 $(eval $(call add_define,RPI3_USE_UEFI_MAP))
 
diff --git a/plat/rpi3/rpi3_bl1_setup.c b/plat/rpi3/rpi3_bl1_setup.c
index ea4215d..b869e9d 100644
--- a/plat/rpi3/rpi3_bl1_setup.c
+++ b/plat/rpi3/rpi3_bl1_setup.c
@@ -13,7 +13,6 @@
 #include <lib/xlat_tables/xlat_mmu_helpers.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
 
-#include "../../bl1/bl1_private.h"
 #include "rpi3_private.h"
 
 /* Data structure which holds the extents of the trusted SRAM for BL1 */
diff --git a/plat/rpi3/rpi3_bl2_setup.c b/plat/rpi3/rpi3_bl2_setup.c
index 53a2c72..09f0562 100644
--- a/plat/rpi3/rpi3_bl2_setup.c
+++ b/plat/rpi3/rpi3_bl2_setup.c
@@ -15,12 +15,25 @@
 #include <lib/optee_utils.h>
 #include <lib/xlat_tables/xlat_mmu_helpers.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
+#include <drivers/generic_delay_timer.h>
+#include <drivers/rpi3/gpio/rpi3_gpio.h>
 
 #include "rpi3_private.h"
 
 /* Data structure which holds the extents of the trusted SRAM for BL2 */
 static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
 
+/* rpi3 GPIO setup function. */
+static void rpi3_gpio_setup(void)
+{
+	struct rpi3_gpio_params params;
+
+	memset(&params, 0, sizeof(struct rpi3_gpio_params));
+	params.reg_base = RPI3_GPIO_BASE;
+
+	rpi3_gpio_init(&params);
+}
+
 /*******************************************************************************
  * BL1 has passed the extents of the trusted SRAM that should be visible to BL2
  * in x0. This memory layout is sitting at the base of the free trusted SRAM.
@@ -35,6 +48,12 @@
 	/* Initialize the console to provide early debug support */
 	rpi3_console_init();
 
+	/* Enable arch timer */
+	generic_delay_timer_init();
+
+	/* Setup GPIO driver */
+	rpi3_gpio_setup();
+
 	/* Setup the BL2 memory layout */
 	bl2_tzram_layout = *mem_layout;
 
diff --git a/plat/rpi3/rpi3_bl31_setup.c b/plat/rpi3/rpi3_bl31_setup.c
index af7f806..d5c691e 100644
--- a/plat/rpi3/rpi3_bl31_setup.c
+++ b/plat/rpi3/rpi3_bl31_setup.c
@@ -141,6 +141,7 @@
 	enable_mmu_el3(0);
 }
 
+#ifdef RPI3_PRELOADED_DTB_BASE
 /*
  * Add information to the device tree (if any) about the reserved DRAM used by
  * the Trusted Firmware.
@@ -204,6 +205,7 @@
 	INFO("rpi3: Reserved 0x%llx - 0x%llx in DTB\n", SEC_SRAM_BASE,
 	     SEC_SRAM_BASE + SEC_SRAM_SIZE);
 }
+#endif
 
 void bl31_platform_setup(void)
 {
diff --git a/plat/rpi3/rpi3_hw.h b/plat/rpi3/rpi3_hw.h
index 9d86eb8..61d1837 100644
--- a/plat/rpi3/rpi3_hw.h
+++ b/plat/rpi3/rpi3_hw.h
@@ -84,6 +84,12 @@
 #define RPI3_MINI_UART_CLK_IN_HZ	ULL(500000000)
 
 /*
+ * GPIO controller
+ */
+#define RPI3_IO_GPIO_OFFSET		ULL(0x00200000)
+#define RPI3_GPIO_BASE			(RPI3_IO_BASE + RPI3_IO_GPIO_OFFSET)
+
+/*
  * Local interrupt controller
  */
 #define RPI3_INTC_BASE_ADDRESS			ULL(0x40000000)
diff --git a/plat/rpi3/rpi3_io_storage.c b/plat/rpi3/rpi3_io_storage.c
index 7e66deb..49c6a76 100644
--- a/plat/rpi3/rpi3_io_storage.c
+++ b/plat/rpi3/rpi3_io_storage.c
@@ -133,11 +133,6 @@
 		(uintptr_t)&bl32_uuid_spec,
 		open_fip
 	},
-	[BL32_IMAGE_ID] = {
-		&fip_dev_handle,
-		(uintptr_t)&bl32_uuid_spec,
-		open_fip
-	},
 	[BL32_EXTRA1_IMAGE_ID] = {
 		&fip_dev_handle,
 		(uintptr_t)&bl32_extra1_uuid_spec,
diff --git a/plat/rpi3/rpi3_pm.c b/plat/rpi3/rpi3_pm.c
index 3a077d3..4f586b5 100644
--- a/plat/rpi3/rpi3_pm.c
+++ b/plat/rpi3/rpi3_pm.c
@@ -140,7 +140,7 @@
  * being turned off earlier. The target_state encodes the low power state that
  * each level has woken up from.
  ******************************************************************************/
-void rpi3_pwr_domain_on_finish(const psci_power_state_t *target_state)
+static void rpi3_pwr_domain_on_finish(const psci_power_state_t *target_state)
 {
 	assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] ==
 					PLAT_LOCAL_STATE_OFF);
diff --git a/plat/socionext/synquacer/include/plat.ld.S b/plat/socionext/synquacer/include/plat.ld.S
new file mode 100644
index 0000000..1b7f699
--- /dev/null
+++ b/plat/socionext/synquacer/include/plat.ld.S
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SYNQUACER_PLAT_LD_S__
+#define SYNQUACER_PLAT_LD_S__
+
+#include <xlat_tables_defs.h>
+
+#define SPM_SHIM_EXCEPTIONS_VMA		SP_DRAM
+
+MEMORY {
+	SP_DRAM (rw): ORIGIN = PLAT_SQ_SP_PRIV_BASE, LENGTH = PLAT_SQ_SP_PRIV_SIZE
+}
+
+SECTIONS
+{
+	/*
+	 * Put the page tables in secure DRAM so that the PTW can make cacheable
+	 * accesses, as the core SPM code expects. (The SRAM on SynQuacer does
+	 * not support inner shareable WBWA mappings so it is mapped normal
+	 * non-cacheable)
+	 */
+	sp_xlat_table (NOLOAD) : ALIGN(PAGE_SIZE) {
+		*(sp_xlat_table)
+		*(.bss.sp_base_xlat_table)
+	} >SP_DRAM
+}
+
+#endif /* SYNQUACER_PLAT_LD_S__ */
diff --git a/plat/socionext/synquacer/include/platform_def.h b/plat/socionext/synquacer/include/platform_def.h
index de6be7d..0cec81b 100644
--- a/plat/socionext/synquacer/include/platform_def.h
+++ b/plat/socionext/synquacer/include/platform_def.h
@@ -29,8 +29,8 @@
 
 #define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
 #define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
-#define MAX_XLAT_TABLES			4
-#define MAX_MMAP_REGIONS		6
+#define MAX_XLAT_TABLES			8
+#define MAX_MMAP_REGIONS		8
 
 #define PLATFORM_STACK_SIZE		0x400
 
@@ -38,6 +38,10 @@
 #define BL31_SIZE			0x00080000
 #define BL31_LIMIT			(BL31_BASE + BL31_SIZE)
 
+#define BL32_BASE			0xfc000000
+#define BL32_SIZE			0x03c00000
+#define BL32_LIMIT			(BL32_BASE + BL32_SIZE)
+
 #define PLAT_SQ_CCN_BASE		0x32000000
 #define PLAT_SQ_CLUSTER_TO_CCN_ID_MAP					\
 					0,	/* Cluster 0 */		\
@@ -79,4 +83,77 @@
 
 #define PLAT_SQ_GPIO_BASE		0x51000000
 
+#define PLAT_SPM_BUF_BASE		(BL32_LIMIT - 32 * PLAT_SPM_BUF_SIZE)
+#define PLAT_SPM_BUF_SIZE		ULL(0x10000)
+#define PLAT_SPM_SPM_BUF_EL0_MMAP	MAP_REGION2(PLAT_SPM_BUF_BASE, \
+						    PLAT_SPM_BUF_BASE, \
+						    PLAT_SPM_BUF_SIZE, \
+						    MT_RO_DATA | MT_SECURE | \
+						    MT_USER, PAGE_SIZE)
+
+#define PLAT_SP_IMAGE_NS_BUF_BASE	BL32_LIMIT
+#define PLAT_SP_IMAGE_NS_BUF_SIZE	ULL(0x200000)
+#define PLAT_SP_IMAGE_NS_BUF_MMAP	MAP_REGION2(PLAT_SP_IMAGE_NS_BUF_BASE, \
+						    PLAT_SP_IMAGE_NS_BUF_BASE, \
+						    PLAT_SP_IMAGE_NS_BUF_SIZE, \
+						    MT_RW_DATA | MT_NS | \
+						    MT_USER, PAGE_SIZE)
+
+#define PLAT_SP_IMAGE_STACK_PCPU_SIZE	ULL(0x10000)
+#define PLAT_SP_IMAGE_STACK_SIZE	(32 * PLAT_SP_IMAGE_STACK_PCPU_SIZE)
+#define PLAT_SP_IMAGE_STACK_BASE	(PLAT_SQ_SP_HEAP_BASE + PLAT_SQ_SP_HEAP_SIZE)
+
+#define PLAT_SQ_SP_IMAGE_SIZE		ULL(0x200000)
+#define PLAT_SQ_SP_IMAGE_MMAP		MAP_REGION2(BL32_BASE, BL32_BASE, \
+						    PLAT_SQ_SP_IMAGE_SIZE, \
+						    MT_CODE | MT_SECURE | \
+						    MT_USER, PAGE_SIZE)
+
+#define PLAT_SQ_SP_HEAP_BASE		(BL32_BASE + PLAT_SQ_SP_IMAGE_SIZE)
+#define PLAT_SQ_SP_HEAP_SIZE		ULL(0x800000)
+
+#define PLAT_SQ_SP_IMAGE_RW_MMAP	MAP_REGION2(PLAT_SQ_SP_HEAP_BASE, \
+						    PLAT_SQ_SP_HEAP_BASE, \
+						    (PLAT_SQ_SP_HEAP_SIZE + \
+						     PLAT_SP_IMAGE_STACK_SIZE), \
+						    MT_RW_DATA | MT_SECURE | \
+						    MT_USER, PAGE_SIZE)
+
+#define PLAT_SQ_SP_PRIV_BASE		(PLAT_SP_IMAGE_STACK_BASE + \
+					 PLAT_SP_IMAGE_STACK_SIZE)
+#define PLAT_SQ_SP_PRIV_SIZE		ULL(0x40000)
+
+#define PLAT_SP_PRI			0x20
+#define PLAT_PRI_BITS			2
+#define PLAT_SPM_COOKIE_0		ULL(0)
+#define PLAT_SPM_COOKIE_1		ULL(0)
+
+/* Total number of memory regions with distinct properties */
+#define PLAT_SP_IMAGE_NUM_MEM_REGIONS	6
+
+#define PLAT_SP_IMAGE_MMAP_REGIONS	30
+#define PLAT_SP_IMAGE_MAX_XLAT_TABLES	20
+#define PLAT_SP_IMAGE_XLAT_SECTION_NAME	"sp_xlat_table"
+
+#define PLAT_SQ_UART1_BASE		PLAT_SQ_BOOT_UART_BASE
+#define PLAT_SQ_UART1_SIZE		ULL(0x1000)
+#define PLAT_SQ_UART1_MMAP		MAP_REGION_FLAT(PLAT_SQ_UART1_BASE, \
+							PLAT_SQ_UART1_SIZE, \
+							MT_DEVICE | MT_RW | \
+							MT_NS | MT_PRIVILEGED)
+
+#define PLAT_SQ_PERIPH_BASE		0x50000000
+#define PLAT_SQ_PERIPH_SIZE		ULL(0x8000000)
+#define PLAT_SQ_PERIPH_MMAP		MAP_REGION_FLAT(PLAT_SQ_PERIPH_BASE, \
+							PLAT_SQ_PERIPH_SIZE, \
+							MT_DEVICE | MT_RW | \
+							MT_NS | MT_USER)
+
+#define PLAT_SQ_FLASH_BASE		0x08000000
+#define PLAT_SQ_FLASH_SIZE		ULL(0x8000000)
+#define PLAT_SQ_FLASH_MMAP		MAP_REGION_FLAT(PLAT_SQ_FLASH_BASE, \
+							PLAT_SQ_FLASH_SIZE, \
+							MT_DEVICE | MT_RW | \
+							MT_NS | MT_USER)
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/socionext/synquacer/platform.mk b/plat/socionext/synquacer/platform.mk
index 1bee20a..53c39a0 100644
--- a/plat/socionext/synquacer/platform.mk
+++ b/plat/socionext/synquacer/platform.mk
@@ -17,10 +17,6 @@
 # Libraries
 include lib/xlat_tables_v2/xlat_tables.mk
 
-ifeq (${SPD},opteed)
-TF_CFLAGS_aarch64	+=	-DBL32_BASE=0xfc000000
-endif
-
 PLAT_PATH		:=	plat/socionext/synquacer
 PLAT_INCLUDES		:=	-I$(PLAT_PATH)/include		\
 				-I$(PLAT_PATH)/drivers/scpi	\
@@ -47,3 +43,9 @@
 				$(PLAT_PATH)/sq_xlat_setup.c		\
 				$(PLAT_PATH)/drivers/scpi/sq_scpi.c	\
 				$(PLAT_PATH)/drivers/mhu/sq_mhu.c
+
+ifeq (${ENABLE_SPM},1)
+$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
+
+BL31_SOURCES		+=	$(PLAT_PATH)/sq_spm.c
+endif
diff --git a/plat/socionext/synquacer/sq_bl31_setup.c b/plat/socionext/synquacer/sq_bl31_setup.c
index f8d2526..fef84ef 100644
--- a/plat/socionext/synquacer/sq_bl31_setup.c
+++ b/plat/socionext/synquacer/sq_bl31_setup.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
  */
@@ -21,6 +21,10 @@
 static entry_point_info_t bl32_image_ep_info;
 static entry_point_info_t bl33_image_ep_info;
 
+IMPORT_SYM(uintptr_t, __SPM_SHIM_EXCEPTIONS_START__, SPM_SHIM_EXCEPTIONS_START);
+IMPORT_SYM(uintptr_t, __SPM_SHIM_EXCEPTIONS_END__,   SPM_SHIM_EXCEPTIONS_END);
+IMPORT_SYM(uintptr_t, __SPM_SHIM_EXCEPTIONS_LMA__,   SPM_SHIM_EXCEPTIONS_LMA);
+
 entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
 {
 	assert(sec_state_is_valid(type));
@@ -76,7 +80,7 @@
 	/* Initialize power controller before setting up topology */
 	plat_sq_pwrc_setup();
 
-#ifdef BL32_BASE
+#ifdef SPD_opteed
 	struct draminfo di = {0};
 
 	scpi_get_draminfo(&di);
@@ -98,7 +102,7 @@
 	} else {
 		NOTICE("OP-TEE has not been loaded by SCP firmware\n");
 	}
-#endif /* BL32_BASE */
+#endif /* SPD_opteed */
 
 	/* Populate entry point information for BL33 */
 	SET_PARAM_HEAD(&bl33_image_ep_info,
@@ -155,8 +159,27 @@
 
 void bl31_plat_arch_setup(void)
 {
-	sq_mmap_setup(BL31_BASE, BL31_SIZE, NULL);
+	static const mmap_region_t secure_partition_mmap[] = {
+#if ENABLE_SPM && SPM_MM
+		MAP_REGION_FLAT(PLAT_SPM_BUF_BASE,
+				PLAT_SPM_BUF_SIZE,
+				MT_RW_DATA | MT_SECURE),
+		MAP_REGION_FLAT(PLAT_SQ_SP_PRIV_BASE,
+				PLAT_SQ_SP_PRIV_SIZE,
+				MT_RW_DATA | MT_SECURE),
+#endif
+		{0},
+	};
+
+	sq_mmap_setup(BL31_BASE, BL31_SIZE, secure_partition_mmap);
 	enable_mmu_el3(XLAT_TABLE_NC);
+
+#if ENABLE_SPM && SPM_MM
+	memcpy((void *)SPM_SHIM_EXCEPTIONS_START,
+	       (void *)SPM_SHIM_EXCEPTIONS_LMA,
+	       (uintptr_t)SPM_SHIM_EXCEPTIONS_END -
+	       (uintptr_t)SPM_SHIM_EXCEPTIONS_START);
+#endif
 }
 
 void bl31_plat_enable_mmu(uint32_t flags)
diff --git a/plat/socionext/synquacer/sq_spm.c b/plat/socionext/synquacer/sq_spm.c
new file mode 100644
index 0000000..01cce17
--- /dev/null
+++ b/plat/socionext/synquacer/sq_spm.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <platform_def.h>
+
+#include <bl31/ehf.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <services/secure_partition.h>
+
+static const mmap_region_t plat_arm_secure_partition_mmap[] = {
+	PLAT_SQ_FLASH_MMAP,
+	PLAT_SQ_UART1_MMAP,
+	PLAT_SQ_PERIPH_MMAP,
+	PLAT_SQ_SP_IMAGE_MMAP,
+	PLAT_SP_IMAGE_NS_BUF_MMAP,
+	PLAT_SQ_SP_IMAGE_RW_MMAP,
+	PLAT_SPM_SPM_BUF_EL0_MMAP,
+	{0}
+};
+
+/*
+ * 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[] = {
+	{0x80000000, 0}, {0x80000001, 0}, {0x80000100, 0}, {0x80000101, 0},
+	{0x80000200, 0}, {0x80000201, 0}, {0x80000300, 0}, {0x80000301, 0},
+	{0x80000400, 0}, {0x80000401, 0}, {0x80000500, 0}, {0x80000501, 0},
+	{0x80000600, 0}, {0x80000601, 0}, {0x80000700, 0}, {0x80000701, 0},
+	{0x80000800, 0}, {0x80000801, 0}, {0x80000900, 0}, {0x80000901, 0},
+	{0x80000a00, 0}, {0x80000a01, 0}, {0x80000b00, 0}, {0x80000b01, 0},
+};
+
+const secure_partition_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.attr			= 0,
+	.sp_mem_base		= BL32_BASE,
+	.sp_mem_limit		= BL32_LIMIT,
+	.sp_image_base		= BL32_BASE,
+	.sp_stack_base		= PLAT_SP_IMAGE_STACK_BASE,
+	.sp_heap_base		= PLAT_SQ_SP_HEAP_BASE,
+	.sp_ns_comm_buf_base	= PLAT_SP_IMAGE_NS_BUF_BASE,
+	.sp_shared_buf_base	= PLAT_SPM_BUF_BASE,
+	.sp_image_size		= PLAT_SQ_SP_IMAGE_SIZE,
+	.sp_pcpu_stack_size	= PLAT_SP_IMAGE_STACK_PCPU_SIZE,
+	.sp_heap_size		= PLAT_SQ_SP_HEAP_SIZE,
+	.sp_ns_comm_buf_size	= PLAT_SP_IMAGE_NS_BUF_SIZE,
+	.sp_shared_buf_size	= PLAT_SPM_BUF_SIZE,
+	.num_sp_mem_regions	= PLAT_SP_IMAGE_NUM_MEM_REGIONS,
+	.num_cpus		= PLATFORM_CORE_COUNT,
+	.mp_info		= sp_mp_info,
+};
+
+const struct mmap_region *plat_get_secure_partition_mmap(void *cookie)
+{
+	return plat_arm_secure_partition_mmap;
+}
+
+const struct secure_partition_boot_info *plat_get_secure_partition_boot_info(
+		void *cookie)
+{
+	return &plat_arm_secure_partition_boot_info;
+}
+
+static ehf_pri_desc_t sq_exceptions[] = {
+	EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SP_PRI),
+};
+EHF_REGISTER_PRIORITIES(sq_exceptions, ARRAY_SIZE(sq_exceptions), PLAT_PRI_BITS);
diff --git a/plat/st/stm32mp1/bl2_io_storage.c b/plat/st/stm32mp1/bl2_io_storage.c
index 45a352e..8ccbc24 100644
--- a/plat/st/stm32mp1/bl2_io_storage.c
+++ b/plat/st/stm32mp1/bl2_io_storage.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
  */
@@ -58,13 +58,26 @@
 static uintptr_t storage_dev_handle;
 static const io_dev_connector_t *mmc_dev_con;
 
-#define IMG_IDX_BL33		0
+static const io_block_spec_t bl32_block_spec = {
+	.offset = BL32_BASE,
+	.length = STM32MP1_BL32_SIZE
+};
+
+static const io_block_spec_t bl2_block_spec = {
+	.offset = BL2_BASE,
+	.length = STM32MP1_BL2_SIZE,
+};
 
 static const struct stm32image_part_info bl33_partition_spec = {
 	.name = BL33_IMAGE_NAME,
 	.binary_type = BL33_BINARY_TYPE,
 };
 
+enum {
+	IMG_IDX_BL33,
+	IMG_IDX_NUM
+};
+
 static struct stm32image_device_info stm32image_dev_info_spec = {
 	.lba_size = MMC_BLOCK_SIZE,
 	.part_info[IMG_IDX_BL33] = {
@@ -73,19 +86,12 @@
 	},
 };
 
-static io_block_spec_t stm32image_block_spec;
-
-static const io_dev_connector_t *stm32image_dev_con;
-
-static const io_block_spec_t bl32_block_spec = {
-	.offset = BL32_BASE,
-	.length = STM32MP1_BL32_SIZE
+static io_block_spec_t stm32image_block_spec = {
+	.offset = 0,
+	.length = 0,
 };
 
-static const io_block_spec_t bl2_block_spec = {
-	.offset = BL2_BASE,
-	.length = STM32MP1_BL2_SIZE,
-};
+static const io_dev_connector_t *stm32image_dev_con;
 
 static int open_dummy(const uintptr_t spec);
 static int open_image(const uintptr_t spec);
@@ -158,85 +164,20 @@
 	if (boot_context->boot_interface_instance != 0U) {
 		INFO("  Instance %d\n", boot_context->boot_interface_instance);
 	}
-}
-
-static void print_reset_reason(void)
-{
-	uint32_t rstsr = mmio_read_32(RCC_BASE + RCC_MP_RSTSCLRR);
-
-	if (rstsr == 0U) {
-		WARN("Reset reason unknown\n");
-		return;
-	}
-
-	INFO("Reset reason (0x%x):\n", rstsr);
-
-	if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) == 0U) {
-		if ((rstsr & RCC_MP_RSTSCLRR_STDBYRSTF) != 0U) {
-			INFO("System exits from STANDBY\n");
-			return;
-		}
-
-		if ((rstsr & RCC_MP_RSTSCLRR_CSTDBYRSTF) != 0U) {
-			INFO("MPU exits from CSTANDBY\n");
-			return;
-		}
-	}
-
-	if ((rstsr & RCC_MP_RSTSCLRR_PORRSTF) != 0U) {
-		INFO("  Power-on Reset (rst_por)\n");
-		return;
-	}
-
-	if ((rstsr & RCC_MP_RSTSCLRR_BORRSTF) != 0U) {
-		INFO("  Brownout Reset (rst_bor)\n");
-		return;
-	}
-
-	if ((rstsr & RCC_MP_RSTSCLRR_MPSYSRSTF) != 0U) {
-		INFO("  System reset generated by MPU (MPSYSRST)\n");
-		return;
-	}
-
-	if ((rstsr & RCC_MP_RSTSCLRR_HCSSRSTF) != 0U) {
-		INFO("  Reset due to a clock failure on HSE\n");
-		return;
-	}
-
-	if ((rstsr & RCC_MP_RSTSCLRR_IWDG1RSTF) != 0U) {
-		INFO("  IWDG1 Reset (rst_iwdg1)\n");
-		return;
-	}
-
-	if ((rstsr & RCC_MP_RSTSCLRR_IWDG2RSTF) != 0U) {
-		INFO("  IWDG2 Reset (rst_iwdg2)\n");
-		return;
-	}
-
-	if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) != 0U) {
-		INFO("  Pad Reset from NRST\n");
-		return;
-	}
-
-	if ((rstsr & RCC_MP_RSTSCLRR_VCORERSTF) != 0U) {
-		INFO("  Reset due to a failure of VDD_CORE\n");
-		return;
-	}
-
-	ERROR("  Unidentified reset reason\n");
 }
 
 void stm32mp1_io_setup(void)
 {
 	int io_result __unused;
+	uint8_t idx;
+	struct stm32image_part_info *part;
 	struct stm32_sdmmc2_params params;
 	struct mmc_device_info device_info;
 	uintptr_t mmc_default_instance;
+	const partition_entry_t *entry;
 	boot_api_context_t *boot_context =
 		(boot_api_context_t *)stm32mp1_get_boot_ctx_address();
 
-	print_reset_reason();
-
 	print_boot_device(boot_context);
 
 	if ((boot_context->boot_partition_used_toboot == 1U) ||
@@ -255,7 +196,7 @@
 	switch (boot_context->boot_interface_selected) {
 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
-		dmb();
+		dmbsy();
 
 		memset(&params, 0, sizeof(struct stm32_sdmmc2_params));
 
@@ -309,14 +250,19 @@
 
 		stm32image_dev_info_spec.device_size =
 			stm32_sdmmc2_mmc_get_device_size();
-		stm32image_dev_info_spec.part_info[IMG_IDX_BL33].part_offset =
-			get_partition_entry(BL33_IMAGE_NAME)->start;
-		stm32image_dev_info_spec.part_info[IMG_IDX_BL33].bkp_offset =
-			get_partition_entry(BL33_IMAGE_NAME)->length;
 
-		stm32image_block_spec.offset = 0;
-		stm32image_block_spec.length =
-			get_partition_entry(BL33_IMAGE_NAME)->length;
+		for (idx = 0U; idx < IMG_IDX_NUM; idx++) {
+			part = &stm32image_dev_info_spec.part_info[idx];
+			entry = get_partition_entry(part->name);
+			if (entry == NULL) {
+				ERROR("Partition %s not found\n",
+				      part->name);
+				panic();
+			}
+
+			part->part_offset = entry->start;
+			part->bkp_offset = 0U;
+		}
 
 		/*
 		 * Re-open MMC with io_mmc, for better perfs compared to
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index 6af65fd..a1ffd5a 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_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
  */
@@ -16,8 +16,8 @@
 #include <drivers/delay_timer.h>
 #include <drivers/generic_delay_timer.h>
 #include <drivers/st/stm32_console.h>
+#include <drivers/st/stm32mp_pmic.h>
 #include <drivers/st/stm32mp1_clk.h>
-#include <drivers/st/stm32mp1_pmic.h>
 #include <drivers/st/stm32mp1_pwr.h>
 #include <drivers/st/stm32mp1_ram.h>
 #include <drivers/st/stm32mp1_rcc.h>
@@ -33,8 +33,95 @@
 
 static struct console_stm32 console;
 
-void bl2_el3_early_platform_setup(u_register_t arg0, u_register_t arg1,
-				  u_register_t arg2, u_register_t arg3)
+static void print_reset_reason(void)
+{
+	uint32_t rstsr = mmio_read_32(RCC_BASE + RCC_MP_RSTSCLRR);
+
+	if (rstsr == 0U) {
+		WARN("Reset reason unknown\n");
+		return;
+	}
+
+	INFO("Reset reason (0x%x):\n", rstsr);
+
+	if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) == 0U) {
+		if ((rstsr & RCC_MP_RSTSCLRR_STDBYRSTF) != 0U) {
+			INFO("System exits from STANDBY\n");
+			return;
+		}
+
+		if ((rstsr & RCC_MP_RSTSCLRR_CSTDBYRSTF) != 0U) {
+			INFO("MPU exits from CSTANDBY\n");
+			return;
+		}
+	}
+
+	if ((rstsr & RCC_MP_RSTSCLRR_PORRSTF) != 0U) {
+		INFO("  Power-on Reset (rst_por)\n");
+		return;
+	}
+
+	if ((rstsr & RCC_MP_RSTSCLRR_BORRSTF) != 0U) {
+		INFO("  Brownout Reset (rst_bor)\n");
+		return;
+	}
+
+	if ((rstsr & RCC_MP_RSTSCLRR_MCSYSRSTF) != 0U) {
+		if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) != 0U) {
+			INFO("  System reset generated by MCU (MCSYSRST)\n");
+		} else {
+			INFO("  Local reset generated by MCU (MCSYSRST)\n");
+		}
+		return;
+	}
+
+	if ((rstsr & RCC_MP_RSTSCLRR_MPSYSRSTF) != 0U) {
+		INFO("  System reset generated by MPU (MPSYSRST)\n");
+		return;
+	}
+
+	if ((rstsr & RCC_MP_RSTSCLRR_HCSSRSTF) != 0U) {
+		INFO("  Reset due to a clock failure on HSE\n");
+		return;
+	}
+
+	if ((rstsr & RCC_MP_RSTSCLRR_IWDG1RSTF) != 0U) {
+		INFO("  IWDG1 Reset (rst_iwdg1)\n");
+		return;
+	}
+
+	if ((rstsr & RCC_MP_RSTSCLRR_IWDG2RSTF) != 0U) {
+		INFO("  IWDG2 Reset (rst_iwdg2)\n");
+		return;
+	}
+
+	if ((rstsr & RCC_MP_RSTSCLRR_MPUP0RSTF) != 0U) {
+		INFO("  MPU Processor 0 Reset\n");
+		return;
+	}
+
+	if ((rstsr & RCC_MP_RSTSCLRR_MPUP1RSTF) != 0U) {
+		INFO("  MPU Processor 1 Reset\n");
+		return;
+	}
+
+	if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) != 0U) {
+		INFO("  Pad Reset from NRST\n");
+		return;
+	}
+
+	if ((rstsr & RCC_MP_RSTSCLRR_VCORERSTF) != 0U) {
+		INFO("  Reset due to a failure of VDD_CORE\n");
+		return;
+	}
+
+	ERROR("  Unidentified reset reason\n");
+}
+
+void bl2_el3_early_platform_setup(u_register_t arg0,
+				  u_register_t arg1 __unused,
+				  u_register_t arg2 __unused,
+				  u_register_t arg3 __unused)
 {
 	stm32mp1_save_boot_ctx_address(arg0);
 }
@@ -59,12 +146,38 @@
 void bl2_el3_plat_arch_setup(void)
 {
 	int32_t result;
-	struct dt_node_info dt_dev_info;
+	struct dt_node_info dt_uart_info;
 	const char *board_model;
 	boot_api_context_t *boot_context =
 		(boot_api_context_t *)stm32mp1_get_boot_ctx_address();
 	uint32_t clk_rate;
 
+	mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
+			BL_CODE_END - BL_CODE_BASE,
+			MT_CODE | MT_SECURE);
+
+	/* Prevent corruption of preloaded BL32 */
+	mmap_add_region(BL32_BASE, BL32_BASE,
+			BL32_LIMIT - BL32_BASE,
+			MT_MEMORY | MT_RO | MT_SECURE);
+
+	/* Map non secure DDR for BL33 load and DDR training area restore */
+	mmap_add_region(STM32MP1_DDR_BASE,
+			STM32MP1_DDR_BASE,
+			STM32MP1_DDR_MAX_SIZE,
+			MT_MEMORY | MT_RW | MT_NS);
+
+	/* Prevent corruption of preloaded Device Tree */
+	mmap_add_region(DTB_BASE, DTB_BASE,
+			DTB_LIMIT - DTB_BASE,
+			MT_MEMORY | MT_RO | MT_SECURE);
+
+	configure_mmu();
+
+	if (dt_open_and_check() < 0) {
+		panic();
+	}
+
 	/*
 	 * Disable the backup domain write protection.
 	 * The protection is enable at each reset by hardware
@@ -88,28 +201,8 @@
 		mmio_clrbits_32(RCC_BASE + RCC_BDCR, RCC_BDCR_VSWRST);
 	}
 
-	mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
-			BL_CODE_END - BL_CODE_BASE,
-			MT_CODE | MT_SECURE);
-
-	/* Prevent corruption of preloaded BL32 */
-	mmap_add_region(BL32_BASE, BL32_BASE,
-			BL32_LIMIT - BL32_BASE,
-			MT_MEMORY | MT_RO | MT_SECURE);
-
-	/* Prevent corruption of preloaded Device Tree */
-	mmap_add_region(DTB_BASE, DTB_BASE,
-			DTB_LIMIT - DTB_BASE,
-			MT_MEMORY | MT_RO | MT_SECURE);
-
-	configure_mmu();
-
 	generic_delay_timer_init();
 
-	if (dt_open_and_check() < 0) {
-		panic();
-	}
-
 	if (stm32mp1_clk_probe() < 0) {
 		panic();
 	}
@@ -118,12 +211,12 @@
 		panic();
 	}
 
-	result = dt_get_stdout_uart_info(&dt_dev_info);
+	result = dt_get_stdout_uart_info(&dt_uart_info);
 
 	if ((result <= 0) ||
-	    (dt_dev_info.status == 0U) ||
-	    (dt_dev_info.clock < 0) ||
-	    (dt_dev_info.reset < 0)) {
+	    (dt_uart_info.status == 0U) ||
+	    (dt_uart_info.clock < 0) ||
+	    (dt_uart_info.reset < 0)) {
 		goto skip_console_init;
 	}
 
@@ -131,25 +224,25 @@
 		goto skip_console_init;
 	}
 
-	if (stm32mp1_clk_enable((unsigned long)dt_dev_info.clock) != 0) {
+	if (stm32mp1_clk_enable((unsigned long)dt_uart_info.clock) != 0) {
 		goto skip_console_init;
 	}
 
-	stm32mp1_reset_assert((uint32_t)dt_dev_info.reset);
+	stm32mp1_reset_assert((uint32_t)dt_uart_info.reset);
 	udelay(2);
-	stm32mp1_reset_deassert((uint32_t)dt_dev_info.reset);
+	stm32mp1_reset_deassert((uint32_t)dt_uart_info.reset);
 	mdelay(1);
 
-	clk_rate = stm32mp1_clk_get_rate((unsigned long)dt_dev_info.clock);
+	clk_rate = stm32mp1_clk_get_rate((unsigned long)dt_uart_info.clock);
 
-	if (console_stm32_register(dt_dev_info.base, clk_rate,
+	if (console_stm32_register(dt_uart_info.base, clk_rate,
 				   STM32MP1_UART_BAUDRATE, &console) == 0) {
 		panic();
 	}
 
 	board_model = dt_get_board_model();
 	if (board_model != NULL) {
-		NOTICE("%s\n", board_model);
+		NOTICE("Model: %s\n", board_model);
 	}
 
 skip_console_init:
@@ -162,5 +255,7 @@
 
 	stm32mp1_arch_security_setup();
 
+	print_reset_reason();
+
 	stm32mp1_io_setup();
 }
diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h
index 1b4df16..6d3d36d 100644
--- a/plat/st/stm32mp1/include/platform_def.h
+++ b/plat/st/stm32mp1/include/platform_def.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
  */
@@ -30,8 +30,8 @@
 #define BL33_BINARY_TYPE		U(0x0)
 
 #define STM32MP1_PRIMARY_CPU		U(0x0)
+#define STM32MP1_SECONDARY_CPU		U(0x1)
 
-#define PLATFORM_CACHE_LINE_SIZE	64
 #define PLATFORM_CLUSTER_COUNT		ULL(1)
 #define PLATFORM_CLUSTER0_CORE_COUNT	U(2)
 #define PLATFORM_CLUSTER1_CORE_COUNT	U(0)
@@ -39,9 +39,9 @@
 					 PLATFORM_CLUSTER0_CORE_COUNT)
 #define PLATFORM_MAX_CPUS_PER_CLUSTER	2
 
-#define MAX_IO_DEVICES			4
-#define MAX_IO_HANDLES			4
-#define MAX_IO_BLOCK_DEVICES		1
+#define MAX_IO_DEVICES			U(4)
+#define MAX_IO_HANDLES			U(4)
+#define MAX_IO_BLOCK_DEVICES		U(1)
 
 /*******************************************************************************
  * BL2 specific defines.
@@ -81,8 +81,8 @@
 /*******************************************************************************
  * Platform specific page table and MMU setup constants
  ******************************************************************************/
-#define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
-#define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
+#define PLAT_PHY_ADDR_SPACE_SIZE	(ULL(1) << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(ULL(1) << 32)
 
 /*******************************************************************************
  * Declarations and constants to access the mailboxes safely. Each mailbox is
@@ -123,9 +123,6 @@
 	INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER,		\
 		       GIC_HIGHEST_SEC_PRIORITY,	\
 		       grp, GIC_INTR_CFG_LEVEL),	\
-	INTR_PROP_DESC(STM32MP1_IRQ_TAMPSERRS,		\
-		       GIC_HIGHEST_SEC_PRIORITY,	\
-		       grp, GIC_INTR_CFG_LEVEL),	\
 	INTR_PROP_DESC(STM32MP1_IRQ_AXIERRIRQ,		\
 		       GIC_HIGHEST_SEC_PRIORITY,	\
 		       grp, GIC_INTR_CFG_LEVEL),	\
diff --git a/plat/st/stm32mp1/include/stm32mp1_dt.h b/plat/st/stm32mp1/include/stm32mp1_dt.h
index 19549ee..d5640c1 100644
--- a/plat/st/stm32mp1/include/stm32mp1_dt.h
+++ b/plat/st/stm32mp1/include/stm32mp1_dt.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
  */
@@ -9,12 +9,16 @@
 
 #include <stdbool.h>
 
+#define DT_DISABLED		U(0)
+#define DT_NON_SECURE		U(1)
+#define DT_SECURE		U(2)
+#define DT_SHARED		(DT_NON_SECURE | DT_SECURE)
+
 struct dt_node_info {
 	uint32_t base;
 	int32_t clock;
 	int32_t reset;
-	bool status;
-	bool sec_status;
+	uint32_t status;
 };
 
 /*******************************************************************************
@@ -23,13 +27,11 @@
 int dt_open_and_check(void);
 int fdt_get_address(void **fdt_addr);
 bool fdt_check_node(int node);
-bool fdt_check_status(int node);
-bool fdt_check_secure_status(int node);
+uint32_t fdt_get_status(int node);
 uint32_t fdt_read_uint32_default(int node, const char *prop_name,
 				 uint32_t dflt_value);
 int fdt_read_uint32_array(int node, const char *prop_name,
 			  uint32_t *array, uint32_t count);
-int dt_set_pinctrl_config(int node);
 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/stm32mp1/include/stm32mp1_private.h b/plat/st/stm32mp1/include/stm32mp1_private.h
index 3404bc6..04c9a9a 100644
--- a/plat/st/stm32mp1/include/stm32mp1_private.h
+++ b/plat/st/stm32mp1/include/stm32mp1_private.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
  */
@@ -21,4 +21,8 @@
 void stm32mp1_gic_pcpu_init(void);
 void stm32mp1_gic_init(void);
 
+uintptr_t stm32_get_gpio_bank_base(unsigned int bank);
+unsigned long stm32_get_gpio_bank_clock(unsigned int bank);
+uint32_t stm32_get_gpio_bank_offset(unsigned int bank);
+
 #endif /* STM32MP1_PRIVATE_H */
diff --git a/plat/st/stm32mp1/include/stm32mp1_smc.h b/plat/st/stm32mp1/include/stm32mp1_smc.h
new file mode 100644
index 0000000..b872758
--- /dev/null
+++ b/plat/st/stm32mp1/include/stm32mp1_smc.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP1_SMC_H
+#define STM32MP1_SMC_H
+
+/*
+ * SMC function IDs for STM32 Service queries
+ * STM32 SMC services use the space between 0x82000000 and 0x8200FFFF
+ * like this is defined in SMC calling Convention by ARM
+ * for SiP (silicon Partner)
+ * https://developer.arm.com/docs/den0028/latest
+ */
+
+/* Secure Service access from Non-secure */
+
+/*
+ * STM32_SMC_BSEC call API
+ *
+ * Argument a0: (input) SMCC ID
+ *		(output) status return code
+ * Argument a1: (input) Service ID (STM32_SMC_BSEC_xxx)
+ * Argument a2: (input) OTP index
+ *		(output) OTP read value, if applicable
+ * Argument a3: (input) OTP value if applicable
+ */
+#define STM32_SMC_BSEC			0x82001003
+
+/* SMC function IDs for SiP Service queries */
+#define STM32_SIP_SVC_CALL_COUNT	0x8200ff00
+#define STM32_SIP_SVC_UID		0x8200ff01
+/*					0x8200ff02 is reserved */
+#define STM32_SIP_SVC_VERSION		0x8200ff03
+
+/* STM32 SiP Service Calls version numbers */
+#define STM32_SIP_SVC_VERSION_MAJOR	0x0
+#define STM32_SIP_SVC_VERSION_MINOR	0x1
+
+/* Number of STM32 SiP Calls implemented */
+#define STM32_COMMON_SIP_NUM_CALLS	4
+
+/* Service for BSEC */
+#define STM32_SMC_READ_SHADOW		0x01
+#define STM32_SMC_PROG_OTP		0x02
+#define STM32_SMC_WRITE_SHADOW		0x03
+#define STM32_SMC_READ_OTP		0x04
+
+#endif /* STM32MP1_SMC_H */
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index 60852c6..4288f23 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -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
 #
@@ -24,8 +24,8 @@
 PLAT_INCLUDES		:=	-Iplat/st/stm32mp1/include/
 
 # Device tree
-STM32_DTB_FILE_NAME	?=	stm32mp157c-ev1.dtb
-FDT_SOURCES		:=	$(addprefix fdts/, $(patsubst %.dtb,%.dts,$(STM32_DTB_FILE_NAME)))
+DTB_FILE_NAME		?=	stm32mp157c-ev1.dtb
+FDT_SOURCES		:=	$(addprefix fdts/, $(patsubst %.dtb,%.dts,$(DTB_FILE_NAME)))
 DTC_FLAGS		+=	-Wno-unit_address_vs_reg
 
 include lib/libfdt/libfdt.mk
@@ -47,13 +47,14 @@
 				drivers/arm/tzc/tzc400.c				\
 				drivers/delay_timer/delay_timer.c			\
 				drivers/delay_timer/generic_delay_timer.c		\
+				drivers/st/bsec/bsec.c					\
 				drivers/st/clk/stm32mp1_clk.c				\
 				drivers/st/clk/stm32mp1_clkfunc.c			\
 				drivers/st/ddr/stm32mp1_ddr_helpers.c			\
 				drivers/st/gpio/stm32_gpio.c				\
-				drivers/st/pmic/stm32_i2c.c				\
-				drivers/st/pmic/stm32mp1_pmic.c				\
-				drivers/st/pmic/stpmu1.c				\
+				drivers/st/i2c/stm32_i2c.c				\
+				drivers/st/pmic/stm32mp_pmic.c				\
+				drivers/st/pmic/stpmic1.c				\
 				drivers/st/reset/stm32mp1_reset.c			\
 				plat/st/stm32mp1/stm32mp1_context.c			\
 				plat/st/stm32mp1/stm32mp1_dt.c				\
@@ -82,13 +83,13 @@
 
 # Macros and rules to build TF binary
 STM32_TF_ELF_LDFLAGS	:=	--hash-style=gnu --as-needed
-STM32_DT_BASENAME	:=	$(STM32_DTB_FILE_NAME:.dtb=)
+STM32_DT_BASENAME	:=	$(DTB_FILE_NAME:.dtb=)
 STM32_TF_STM32		:=	${BUILD_PLAT}/tf-a-${STM32_DT_BASENAME}.stm32
 STM32_TF_BINARY		:=	$(STM32_TF_STM32:.stm32=.bin)
 STM32_TF_MAPFILE	:=	$(STM32_TF_STM32:.stm32=.map)
 STM32_TF_LINKERFILE	:=	$(STM32_TF_STM32:.stm32=.ld)
 STM32_TF_ELF		:=	$(STM32_TF_STM32:.stm32=.elf)
-STM32_TF_DTBFILE	:=      ${BUILD_PLAT}/fdts/${STM32_DTB_FILE_NAME}
+STM32_TF_DTBFILE	:=      ${BUILD_PLAT}/fdts/${DTB_FILE_NAME}
 STM32_TF_OBJS		:=	${BUILD_PLAT}/stm32mp1.o
 
 # Variables for use with stm32image
@@ -131,7 +132,7 @@
 				-DDTB_BIN_PATH=\"${STM32_TF_DTBFILE}\" \
 				-c plat/st/stm32mp1/stm32mp1.S -o $@
 
-${STM32_TF_LINKERFILE}:	plat/st/stm32mp1/stm32mp1.ld.S
+${STM32_TF_LINKERFILE}:	plat/st/stm32mp1/stm32mp1.ld.S ${BUILD_PLAT}
 			@echo "  LDS     $<"
 			${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} -P -E $< -o $@
 
diff --git a/plat/st/stm32mp1/services/bsec_svc.c b/plat/st/stm32mp1/services/bsec_svc.c
new file mode 100644
index 0000000..2a60e43
--- /dev/null
+++ b/plat/st/stm32mp1/services/bsec_svc.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+
+#include <common/debug.h>
+#include <drivers/st/bsec.h>
+
+#include <stm32mp1_smc.h>
+
+#include "bsec_svc.h"
+
+uint32_t bsec_main(uint32_t x1, uint32_t x2, uint32_t x3,
+		   uint32_t *ret_otp_value)
+{
+	uint32_t result;
+	uint32_t tmp_data = 0U;
+
+	switch (x1) {
+	case STM32_SMC_READ_SHADOW:
+		result = bsec_read_otp(ret_otp_value, x2);
+		break;
+	case STM32_SMC_PROG_OTP:
+		*ret_otp_value = 0U;
+		result = bsec_program_otp(x3, x2);
+		break;
+	case STM32_SMC_WRITE_SHADOW:
+		*ret_otp_value = 0;
+		result = bsec_write_otp(x3, x2);
+		break;
+	case STM32_SMC_READ_OTP:
+		*ret_otp_value = 0;
+		result = bsec_read_otp(&tmp_data, x2);
+		if (result != BSEC_OK) {
+			break;
+		}
+
+		result = bsec_shadow_register(x2);
+		if (result != BSEC_OK) {
+			break;
+		}
+
+		result = bsec_read_otp(ret_otp_value, x2);
+		if (result != BSEC_OK) {
+			break;
+		}
+
+		result = bsec_write_otp(tmp_data, x2);
+		break;
+
+	default:
+		result = BSEC_ERROR;
+		break;
+	}
+
+	return result;
+}
diff --git a/plat/st/stm32mp1/services/bsec_svc.h b/plat/st/stm32mp1/services/bsec_svc.h
new file mode 100644
index 0000000..06752ef
--- /dev/null
+++ b/plat/st/stm32mp1/services/bsec_svc.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef BSEC_SVC_H
+#define BSEC_SVC_H
+
+#include <stdint.h>
+
+/* version of this service */
+/* must be increase at each structure modification */
+#define BSEC_SERVICE_VERSION		0x01U
+
+uint32_t bsec_main(uint32_t x1, uint32_t x2, uint32_t x3,
+		   uint32_t *ret_otp_value);
+
+#endif /* BSEC_SVC_H */
diff --git a/plat/st/stm32mp1/services/stm32mp1_svc_setup.c b/plat/st/stm32mp1/services/stm32mp1_svc_setup.c
new file mode 100644
index 0000000..72af9ff
--- /dev/null
+++ b/plat/st/stm32mp1/services/stm32mp1_svc_setup.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2014-2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/psci/psci.h>
+#include <tools_share/uuid.h>
+
+#include <stm32mp1_smc.h>
+
+#include "bsec_svc.h"
+
+/* STM32 SiP Service UUID */
+DEFINE_SVC_UUID2(stm32_sip_svc_uid,
+		 0xa778aa50, 0xf49b, 0x144a, 0x8a, 0x5e,
+		 0x26, 0x4d, 0x59, 0x94, 0xc2, 0x14);
+
+/* Setup STM32MP1 Standard Services */
+static int32_t stm32mp1_svc_setup(void)
+{
+	/*
+	 * PSCI is the only specification implemented as a Standard Service.
+	 * Invoke PSCI setup from here.
+	 */
+	return 0;
+}
+
+/*
+ * Top-level Standard Service SMC handler. This handler will in turn dispatch
+ * calls to PSCI SMC handler.
+ */
+static uintptr_t stm32mp1_svc_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 ret1 = 0U, ret2 = 0U;
+	bool ret_uid = false, ret2_enabled = false;
+
+	switch (smc_fid) {
+	case STM32_SIP_SVC_CALL_COUNT:
+		ret1 = STM32_COMMON_SIP_NUM_CALLS;
+		break;
+
+	case STM32_SIP_SVC_UID:
+		/* Return UUID to the caller */
+		ret_uid = true;
+		break;
+
+	case STM32_SIP_SVC_VERSION:
+		/* Return the version of current implementation */
+		ret1 = STM32_SIP_SVC_VERSION_MAJOR;
+		ret2 = STM32_SIP_SVC_VERSION_MINOR;
+		ret2_enabled = true;
+		break;
+
+	case STM32_SMC_BSEC:
+		ret1 = bsec_main(x1, x2, x3, &ret2);
+		ret2_enabled = true;
+		break;
+
+	default:
+		WARN("Unimplemented STM32MP1 Service Call: 0x%x\n", smc_fid);
+		ret1 = SMC_UNK;
+		break;
+	}
+
+	if (ret_uid) {
+		SMC_UUID_RET(handle, stm32_sip_svc_uid);
+	}
+
+	if (ret2_enabled) {
+		SMC_RET2(handle, ret1, ret2);
+	}
+
+	SMC_RET1(handle, ret1);
+}
+
+/* Register Standard Service Calls as runtime service */
+DECLARE_RT_SVC(stm32mp1_sip_svc,
+	       OEN_SIP_START,
+	       OEN_SIP_END,
+	       SMC_TYPE_FAST,
+	       stm32mp1_svc_setup,
+	       stm32mp1_svc_smc_handler
+);
diff --git a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
index 9fde153..4188cc5 100644
--- a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
+++ b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.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
 #
@@ -19,3 +19,7 @@
 
 # Generic PSCI
 BL32_SOURCES		+=	plat/common/plat_psci_common.c
+
+# stm32mp1 specific services
+BL32_SOURCES		+=	plat/st/stm32mp1/services/bsec_svc.c		\
+				plat/st/stm32mp1/services/stm32mp1_svc_setup.c
diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c
index f541379..0d76fb7 100644
--- a/plat/st/stm32mp1/sp_min/sp_min_setup.c
+++ b/plat/st/stm32mp1/sp_min/sp_min_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
  */
@@ -13,9 +13,12 @@
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <context.h>
+#include <drivers/arm/gicv2.h>
 #include <drivers/arm/tzc400.h>
 #include <drivers/generic_delay_timer.h>
+#include <drivers/st/bsec.h>
 #include <drivers/st/stm32_console.h>
+#include <drivers/st/stm32_gpio.h>
 #include <drivers/st/stm32mp1_clk.h>
 #include <dt-bindings/clock/stm32mp1-clks.h>
 #include <lib/el3_runtime/context_mgmt.h>
@@ -40,7 +43,7 @@
  ******************************************************************************/
 void sp_min_plat_fiq_handler(uint32_t id)
 {
-	switch (id) {
+	switch (id & INT_ID_MASK) {
 	case STM32MP1_IRQ_TZC400:
 		ERROR("STM32MP1_IRQ_TZC400 generated\n");
 		panic();
@@ -50,7 +53,7 @@
 		panic();
 		break;
 	default:
-		ERROR("SECURE IT handler not define for it : %i", id);
+		ERROR("SECURE IT handler not define for it : %u", id);
 		break;
 	}
 }
@@ -80,7 +83,7 @@
 void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 				  u_register_t arg2, u_register_t arg3)
 {
-	struct dt_node_info dt_dev_info;
+	struct dt_node_info dt_uart_info;
 	int result;
 	bl_params_t *params_from_bl2 = (bl_params_t *)arg0;
 
@@ -110,14 +113,18 @@
 		panic();
 	}
 
+	if (bsec_probe() != 0) {
+		panic();
+	}
+
 	if (stm32mp1_clk_probe() < 0) {
 		panic();
 	}
 
-	result = dt_get_stdout_uart_info(&dt_dev_info);
+	result = dt_get_stdout_uart_info(&dt_uart_info);
 
-	if ((result > 0) && dt_dev_info.status) {
-		if (console_stm32_register(dt_dev_info.base, 0,
+	if ((result > 0) && (dt_uart_info.status != 0U)) {
+		if (console_stm32_register(dt_uart_info.base, 0,
 					   STM32MP1_UART_BAUDRATE, &console) ==
 		    0) {
 			panic();
@@ -142,6 +149,16 @@
 	generic_delay_timer_init();
 
 	stm32mp1_gic_init();
+
+	/* Unlock ETZPC securable peripherals */
+#define STM32MP1_ETZPC_BASE	0x5C007000U
+#define ETZPC_DECPROT0		0x010U
+	mmio_write_32(STM32MP1_ETZPC_BASE + ETZPC_DECPROT0, 0xFFFFFFFF);
+
+	/* Set GPIO bank Z as non secure */
+	for (uint32_t pin = 0U; pin < STM32MP_GPIOZ_PIN_MAX_COUNT; pin++) {
+		set_gpio_secure_cfg(GPIO_BANK_Z, pin, false);
+	}
 }
 
 void sp_min_plat_arch_setup(void)
diff --git a/plat/st/stm32mp1/stm32mp1_common.c b/plat/st/stm32mp1/stm32mp1_common.c
index b54f313..cd93d2e 100644
--- a/plat/st/stm32mp1/stm32mp1_common.c
+++ b/plat/st/stm32mp1/stm32mp1_common.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
  */
@@ -12,6 +12,7 @@
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <drivers/arm/gicv2.h>
+#include <dt-bindings/clock/stm32mp1-clks.h>
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
@@ -39,26 +40,11 @@
 					MT_SECURE | \
 					MT_EXECUTE_NEVER)
 
-#define MAP_DDR		MAP_REGION_FLAT(STM32MP1_DDR_BASE, \
-					STM32MP1_DDR_MAX_SIZE, \
-					MT_MEMORY | \
-					MT_RW | \
-					MT_SECURE | \
-					MT_EXECUTE_NEVER)
-
-#define MAP_DDR_NS	MAP_REGION_FLAT(STM32MP1_DDR_BASE, \
-					STM32MP1_DDR_MAX_SIZE, \
-					MT_MEMORY | \
-					MT_RW | \
-					MT_NS | \
-					MT_EXECUTE_NEVER)
-
 #if defined(IMAGE_BL2)
 static const mmap_region_t stm32mp1_mmap[] = {
 	MAP_SRAM,
 	MAP_DEVICE1,
 	MAP_DEVICE2,
-	MAP_DDR,
 	{0}
 };
 #endif
@@ -67,7 +53,6 @@
 	MAP_SRAM,
 	MAP_DEVICE1,
 	MAP_DEVICE2,
-	MAP_DDR_NS,
 	{0}
 };
 #endif
@@ -102,3 +87,37 @@
 {
 	return boot_ctx_address;
 }
+
+uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
+{
+	switch (bank) {
+	case GPIO_BANK_A ... GPIO_BANK_K:
+		return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
+	case GPIO_BANK_Z:
+		return GPIOZ_BASE;
+	default:
+		panic();
+	}
+}
+
+/* Return clock ID on success, negative value on error */
+unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
+{
+	switch (bank) {
+	case GPIO_BANK_A ... GPIO_BANK_K:
+		return GPIOA + (bank - GPIO_BANK_A);
+	case GPIO_BANK_Z:
+		return GPIOZ;
+	default:
+		panic();
+	}
+}
+
+uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
+{
+	if (bank == GPIO_BANK_Z) {
+		return 0;
+	} else {
+		return bank * GPIO_BANK_OFFSET;
+	}
+}
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index 15f0432..8cd5aeb 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.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
  */
@@ -112,6 +112,39 @@
 #define PWR_BASE			U(0x50001000)
 
 /*******************************************************************************
+ * STM32MP1 GPIO
+ ******************************************************************************/
+#define GPIOA_BASE			U(0x50002000)
+#define GPIOB_BASE			U(0x50003000)
+#define GPIOC_BASE			U(0x50004000)
+#define GPIOD_BASE			U(0x50005000)
+#define GPIOE_BASE			U(0x50006000)
+#define GPIOF_BASE			U(0x50007000)
+#define GPIOG_BASE			U(0x50008000)
+#define GPIOH_BASE			U(0x50009000)
+#define GPIOI_BASE			U(0x5000A000)
+#define GPIOJ_BASE			U(0x5000B000)
+#define GPIOK_BASE			U(0x5000C000)
+#define GPIOZ_BASE			U(0x54004000)
+#define GPIO_BANK_OFFSET		U(0x1000)
+
+/* Bank IDs used in GPIO driver API */
+#define GPIO_BANK_A			U(0)
+#define GPIO_BANK_B			U(1)
+#define GPIO_BANK_C			U(2)
+#define GPIO_BANK_D			U(3)
+#define GPIO_BANK_E			U(4)
+#define GPIO_BANK_F			U(5)
+#define GPIO_BANK_G			U(6)
+#define GPIO_BANK_H			U(7)
+#define GPIO_BANK_I			U(8)
+#define GPIO_BANK_J			U(9)
+#define GPIO_BANK_K			U(10)
+#define GPIO_BANK_Z			U(25)
+
+#define STM32MP_GPIOZ_PIN_MAX_COUNT	8
+
+/*******************************************************************************
  * STM32MP1 UART
  ******************************************************************************/
 #define USART1_BASE			U(0x5C000000)
@@ -122,16 +155,21 @@
 #define USART6_BASE			U(0x44003000)
 #define UART7_BASE			U(0x40018000)
 #define UART8_BASE			U(0x40019000)
-#define STM32MP1_DEBUG_USART_BASE	UART4_BASE
-#define STM32MP1_UART_BAUDRATE		115200
+#define STM32MP1_UART_BAUDRATE		U(115200)
 
-/*******************************************************************************
- * STM32MP1 GIC-400
- ******************************************************************************/
-#define STM32MP1_GICD_BASE		U(0xA0021000)
-#define STM32MP1_GICC_BASE		U(0xA0022000)
-#define STM32MP1_GICH_BASE		U(0xA0024000)
-#define STM32MP1_GICV_BASE		U(0xA0026000)
+/* For UART crash console */
+#define STM32MP1_DEBUG_USART_BASE	UART4_BASE
+/* UART4 on HSI@64MHz, TX on GPIOG11 Alternate 6 */
+#define STM32MP1_DEBUG_USART_CLK_FRQ	64000000
+#define DEBUG_UART_TX_GPIO_BANK_ADDRESS	GPIOG_BASE
+#define DEBUG_UART_TX_GPIO_BANK_CLK_REG	RCC_MP_AHB4ENSETR
+#define DEBUG_UART_TX_GPIO_BANK_CLK_EN	RCC_MP_AHB4ENSETR_GPIOGEN
+#define DEBUG_UART_TX_GPIO_PORT		11
+#define DEBUG_UART_TX_GPIO_ALTERNATE	6
+#define DEBUG_UART_TX_CLKSRC_REG	RCC_UART24CKSELR
+#define DEBUG_UART_TX_CLKSRC		RCC_UART24CKSELR_HSI
+#define DEBUG_UART_TX_EN_REG		RCC_MP_APB1ENSETR
+#define DEBUG_UART_TX_EN		RCC_MP_APB1ENSETR_UART4EN
 
 /*******************************************************************************
  * STM32MP1 TZC (TZ400)
@@ -149,10 +187,7 @@
 #define STM32MP1_TZC_ETH_ID		U(10)
 #define STM32MP1_TZC_DAP_ID		U(15)
 
-#define STM32MP1_MEMORY_NS		0
-#define STM32MP1_MEMORY_SECURE		1
-
-#define STM32MP1_FILTER_BIT_ALL		3
+#define STM32MP1_FILTER_BIT_ALL		U(3)
 
 /*******************************************************************************
  * STM32MP1 SDMMC
@@ -168,6 +203,21 @@
 #define STM32MP1_EMMC_HIGH_SPEED_MAX_FREQ	52000000	/*52 MHz*/
 
 /*******************************************************************************
+ * STM32MP1 BSEC / OTP
+ ******************************************************************************/
+#define STM32MP1_OTP_MAX_ID		0x5FU
+#define STM32MP1_UPPER_OTP_START	0x20U
+
+#define OTP_MAX_SIZE			(STM32MP1_OTP_MAX_ID + 1U)
+
+/* OTP offsets */
+#define DATA0_OTP			U(0)
+
+/* OTP mask */
+/* DATA0 */
+#define DATA0_OTP_SECURED		BIT(6)
+
+/*******************************************************************************
  * STM32MP1 TAMP
  ******************************************************************************/
 #define TAMP_BASE			U(0x5C00A000)
diff --git a/plat/st/stm32mp1/stm32mp1_dt.c b/plat/st/stm32mp1/stm32mp1_dt.c
index 29e936a..8493b87 100644
--- a/plat/st/stm32mp1/stm32mp1_dt.c
+++ b/plat/st/stm32mp1/stm32mp1_dt.c
@@ -1,10 +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
  */
 
 #include <assert.h>
+#include <errno.h>
 
 #include <libfdt.h>
 
@@ -17,135 +18,13 @@
 #include <drivers/st/stm32mp1_ddr.h>
 #include <drivers/st/stm32mp1_ram.h>
 
-#include <stm32mp1_dt.h>
-
-#define DT_GPIO_BANK_SHIFT	12
-#define DT_GPIO_BANK_MASK	0x1F000U
-#define DT_GPIO_PIN_SHIFT	8
-#define DT_GPIO_PIN_MASK	0xF00U
-#define DT_GPIO_MODE_MASK	0xFFU
-
 static int fdt_checked;
 
 static void *fdt = (void *)(uintptr_t)STM32MP1_DTB_BASE;
 
 /*******************************************************************************
- * This function gets the pin settings from DT information.
- * When analyze and parsing is done, set the GPIO registers.
- * Return 0 on success, else return a negative FDT_ERR_xxx error code.
- ******************************************************************************/
-static int dt_set_gpio_config(int node)
-{
-	const fdt32_t *cuint, *slewrate;
-	int len, pinctrl_node, pinctrl_subnode;
-	uint32_t i;
-	uint32_t speed = GPIO_SPEED_LOW;
-	uint32_t pull = GPIO_NO_PULL;
-
-	cuint = fdt_getprop(fdt, node, "pinmux", &len);
-	if (cuint == NULL) {
-		return -FDT_ERR_NOTFOUND;
-	}
-
-	pinctrl_node = fdt_parent_offset(fdt, fdt_parent_offset(fdt, node));
-	if (pinctrl_node < 0) {
-		return -FDT_ERR_NOTFOUND;
-	}
-
-	slewrate = fdt_getprop(fdt, node, "slew-rate", NULL);
-	if (slewrate != NULL) {
-		speed = fdt32_to_cpu(*slewrate);
-	}
-
-	if (fdt_getprop(fdt, node, "bias-pull-up", NULL) != NULL) {
-		pull = GPIO_PULL_UP;
-	} else if (fdt_getprop(fdt, node, "bias-pull-down", NULL) != NULL) {
-		pull = GPIO_PULL_DOWN;
-	} else {
-		VERBOSE("No bias configured in node %d\n", node);
-	}
-
-	for (i = 0; i < ((uint32_t)len / sizeof(uint32_t)); i++) {
-		uint32_t pincfg;
-		uint32_t bank;
-		uint32_t pin;
-		uint32_t mode;
-		uint32_t alternate = GPIO_ALTERNATE_0;
-
-		pincfg = fdt32_to_cpu(*cuint);
-		cuint++;
-
-		bank = (pincfg & DT_GPIO_BANK_MASK) >> DT_GPIO_BANK_SHIFT;
-
-		pin = (pincfg & DT_GPIO_PIN_MASK) >> DT_GPIO_PIN_SHIFT;
-
-		mode = pincfg & DT_GPIO_MODE_MASK;
-
-		switch (mode) {
-		case 0:
-			mode = GPIO_MODE_INPUT;
-			break;
-		case 1 ... 16:
-			alternate = mode - 1U;
-			mode = GPIO_MODE_ALTERNATE;
-			break;
-		case 17:
-			mode = GPIO_MODE_ANALOG;
-			break;
-		default:
-			mode = GPIO_MODE_OUTPUT;
-			break;
-		}
-
-		if (fdt_getprop(fdt, node, "drive-open-drain", NULL) != NULL) {
-			mode |= GPIO_OPEN_DRAIN;
-		}
-
-		fdt_for_each_subnode(pinctrl_subnode, fdt, pinctrl_node) {
-			uint32_t bank_offset;
-			const fdt32_t *cuint2;
-
-			if (fdt_getprop(fdt, pinctrl_subnode,
-					"gpio-controller", NULL) == NULL) {
-				continue;
-			}
-
-			cuint2 = fdt_getprop(fdt, pinctrl_subnode, "reg", NULL);
-			if (cuint2 == NULL) {
-				continue;
-			}
-
-			if (bank == GPIO_BANK_Z) {
-				bank_offset = 0;
-			} else {
-				bank_offset = bank * STM32_GPIO_BANK_OFFSET;
-			}
-
-			if (fdt32_to_cpu(*cuint2) == bank_offset) {
-				int clk_id = fdt_get_clock_id(pinctrl_subnode);
-
-				if (clk_id < 0) {
-					return -FDT_ERR_NOTFOUND;
-				}
-
-				if (stm32mp1_clk_enable((unsigned long)clk_id) <
-				    0) {
-					return -FDT_ERR_BADVALUE;
-				}
-
-				break;
-			}
-		}
-
-		set_gpio(bank, pin, mode, speed, pull, alternate);
-	}
-
-	return 0;
-}
-
-/*******************************************************************************
  * This function checks device tree file with its header.
- * Returns 0 if success, and a negative value else.
+ * Returns 0 on success and a negative FDT error code on failure.
  ******************************************************************************/
 int dt_open_and_check(void)
 {
@@ -174,7 +53,7 @@
 
 /*******************************************************************************
  * This function check the presence of a node (generic use of fdt library).
- * Returns true if present, false else.
+ * Returns true if present, else return false.
  ******************************************************************************/
 bool fdt_check_node(int node)
 {
@@ -187,37 +66,30 @@
 }
 
 /*******************************************************************************
- * This function check the status of a node (generic use of fdt library).
- * Returns true if "okay" or missing, false else.
+ * This function return global node status (generic use of fdt library).
  ******************************************************************************/
-bool fdt_check_status(int node)
+uint32_t fdt_get_status(int node)
 {
+	uint32_t status = DT_DISABLED;
 	int len;
 	const char *cchar;
 
 	cchar = fdt_getprop(fdt, node, "status", &len);
-	if (cchar == NULL) {
-		return true;
+	if ((cchar == NULL) ||
+	    (strncmp(cchar, "okay", (size_t)len) == 0)) {
+		status |= DT_NON_SECURE;
 	}
 
-	return strncmp(cchar, "okay", (size_t)len) == 0;
-}
-
-/*******************************************************************************
- * This function check the secure-status of a node (generic use of fdt library).
- * Returns true if "okay" or missing, false else.
- ******************************************************************************/
-bool fdt_check_secure_status(int node)
-{
-	int len;
-	const char *cchar;
-
 	cchar = fdt_getprop(fdt, node, "secure-status", &len);
 	if (cchar == NULL) {
-		return true;
+		if (status == DT_NON_SECURE) {
+			status |= DT_SECURE;
+		}
+	} else if (strncmp(cchar, "okay", (size_t)len) == 0) {
+		status |= DT_SECURE;
 	}
 
-	return strncmp(cchar, "okay", (size_t)len) == 0;
+	return status;
 }
 
 /*******************************************************************************
@@ -245,7 +117,7 @@
  * (generic use of fdt library).
  * It reads the values inside the device tree, from property name and node.
  * The number of parameters is also indicated as entry parameter.
- * Returns 0 if success, and a negative value else.
+ * Returns 0 on success and a negative FDT error code on failure.
  * If success, values are stored at the third parameter address.
  ******************************************************************************/
 int fdt_read_uint32_array(int node, const char *prop_name, uint32_t *array,
@@ -274,52 +146,9 @@
 }
 
 /*******************************************************************************
- * This function gets the pin settings from DT information.
- * When analyze and parsing is done, set the GPIO registers.
- * Returns 0 if success, and a negative value else.
- ******************************************************************************/
-int dt_set_pinctrl_config(int node)
-{
-	const fdt32_t *cuint;
-	int lenp = 0;
-	uint32_t i;
-
-	if (!fdt_check_status(node)) {
-		return -FDT_ERR_NOTFOUND;
-	}
-
-	cuint = fdt_getprop(fdt, node, "pinctrl-0", &lenp);
-	if (cuint == NULL) {
-		return -FDT_ERR_NOTFOUND;
-	}
-
-	for (i = 0; i < ((uint32_t)lenp / 4U); i++) {
-		int phandle_node, phandle_subnode;
-
-		phandle_node =
-			fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
-		if (phandle_node < 0) {
-			return -FDT_ERR_NOTFOUND;
-		}
-
-		fdt_for_each_subnode(phandle_subnode, fdt, phandle_node) {
-			int ret = dt_set_gpio_config(phandle_subnode);
-
-			if (ret < 0) {
-				return ret;
-			}
-		}
-
-		cuint++;
-	}
-
-	return 0;
-}
-
-/*******************************************************************************
  * This function gets the stdout pin configuration information from the DT.
  * And then calls the sub-function to treat it and set GPIO registers.
- * Returns 0 if success, and a negative value else.
+ * Returns 0 on success and a negative FDT error code on failure.
  ******************************************************************************/
 int dt_set_stdout_pinctrl(void)
 {
@@ -363,13 +192,12 @@
 		info->reset = -1;
 	}
 
-	info->status = fdt_check_status(node);
-	info->sec_status = fdt_check_secure_status(node);
+	info->status = fdt_get_status(node);
 }
 
 /*******************************************************************************
  * This function retrieve the generic information from DT.
- * Returns node if success, and a negative value else.
+ * Returns node on success and a negative FDT error code on failure.
  ******************************************************************************/
 int dt_get_node(struct dt_node_info *info, int offset, const char *compat)
 {
@@ -387,7 +215,7 @@
 
 /*******************************************************************************
  * This function gets the UART instance info of stdout from the DT.
- * Returns node if success, and a negative value else.
+ * Returns node on success and a negative FDT error code on failure.
  ******************************************************************************/
 int dt_get_stdout_uart_info(struct dt_node_info *info)
 {
@@ -448,7 +276,7 @@
 
 /*******************************************************************************
  * This function gets DDR size information from the DT.
- * Returns value in bytes if success, and STM32MP1_DDR_SIZE_DFLT else.
+ * Returns value in bytes on success, and 0 on failure.
  ******************************************************************************/
 uint32_t dt_get_ddr_size(void)
 {
@@ -457,11 +285,10 @@
 	node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT);
 	if (node < 0) {
 		INFO("%s: Cannot read DDR node in DT\n", __func__);
-		return STM32MP1_DDR_SIZE_DFLT;
+		return 0;
 	}
 
-	return fdt_read_uint32_default(node, "st,mem-size",
-				       STM32MP1_DDR_SIZE_DFLT);
+	return fdt_read_uint32_default(node, "st,mem-size", 0);
 }
 
 /*******************************************************************************
diff --git a/plat/st/stm32mp1/stm32mp1_gic.c b/plat/st/stm32mp1/stm32mp1_gic.c
index fabed37..becb925 100644
--- a/plat/st/stm32mp1/stm32mp1_gic.c
+++ b/plat/st/stm32mp1/stm32mp1_gic.c
@@ -1,18 +1,28 @@
 /*
- * 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
  */
 
+#include <libfdt.h>
+
 #include <platform_def.h>
 
 #include <common/bl_common.h>
+#include <common/debug.h>
 #include <drivers/arm/gicv2.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <lib/utils.h>
 #include <plat/common/platform.h>
 
+#include <stm32mp1_dt.h>
 #include <stm32mp1_private.h>
 
+struct stm32_gic_instance {
+	uint32_t cells;
+	uint32_t phandle_node;
+};
+
 /******************************************************************************
  * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
  * interrupts.
@@ -22,19 +32,55 @@
 	PLATFORM_G0_PROPS(GICV2_INTR_GROUP0)
 };
 
-static unsigned int target_mask_array[PLATFORM_CORE_COUNT];
+/* Fix target_mask_array as secondary core is not able to initialize it */
+static unsigned int target_mask_array[PLATFORM_CORE_COUNT] = {1, 2};
 
-static const gicv2_driver_data_t platform_gic_data = {
-	.gicd_base = STM32MP1_GICD_BASE,
-	.gicc_base = STM32MP1_GICC_BASE,
+static gicv2_driver_data_t platform_gic_data = {
 	.interrupt_props = stm32mp1_interrupt_props,
 	.interrupt_props_num = ARRAY_SIZE(stm32mp1_interrupt_props),
 	.target_masks = target_mask_array,
 	.target_masks_num = ARRAY_SIZE(target_mask_array),
 };
 
+static struct stm32_gic_instance stm32_gic;
+
 void stm32mp1_gic_init(void)
 {
+	int node;
+	void *fdt;
+	const fdt32_t *cuint;
+	struct dt_node_info dt_gic;
+
+	if (fdt_get_address(&fdt) == 0) {
+		panic();
+	}
+
+	node = dt_get_node(&dt_gic, -1, "arm,cortex-a7-gic");
+	if (node < 0) {
+		panic();
+	}
+
+	platform_gic_data.gicd_base = dt_gic.base;
+
+	cuint = fdt_getprop(fdt, node, "reg", NULL);
+	if (cuint == NULL) {
+		panic();
+	}
+
+	platform_gic_data.gicc_base = fdt32_to_cpu(*(cuint + 2));
+
+	cuint = fdt_getprop(fdt, node, "#interrupt-cells", NULL);
+	if (cuint == NULL) {
+		panic();
+	}
+
+	stm32_gic.cells = fdt32_to_cpu(*cuint);
+
+	stm32_gic.phandle_node = fdt_get_phandle(fdt, node);
+	if (stm32_gic.phandle_node == 0U) {
+		panic();
+	}
+
 	gicv2_driver_init(&platform_gic_data);
 	gicv2_distif_init();
 
diff --git a/plat/st/stm32mp1/stm32mp1_helper.S b/plat/st/stm32mp1/stm32mp1_helper.S
index 61c587f..8c2e1b6 100644
--- a/plat/st/stm32mp1/stm32mp1_helper.S
+++ b/plat/st/stm32mp1/stm32mp1_helper.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
  */
@@ -12,11 +12,8 @@
 #include <drivers/st/stm32_gpio.h>
 #include <drivers/st/stm32mp1_rcc.h>
 
-#define GPIO_BANK_G_ADDRESS	0x50008000
-#define GPIO_TX_PORT		11
-#define GPIO_TX_SHIFT		(GPIO_TX_PORT << 1)
-#define GPIO_TX_ALT_SHIFT	((GPIO_TX_PORT - GPIO_ALT_LOWER_LIMIT) << 2)
-#define STM32MP1_HSI_CLK	64000000
+#define GPIO_TX_SHIFT		(DEBUG_UART_TX_GPIO_PORT << 1)
+#define GPIO_TX_ALT_SHIFT	((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2)
 
 	.globl	platform_mem_init
 	.globl	plat_report_exception
@@ -112,13 +109,13 @@
 	 * ---------------------------------------------
 	 */
 func plat_crash_console_init
-	/* Enable GPIOs for UART4 TX */
-	ldr	r1, =(RCC_BASE + RCC_MP_AHB4ENSETR)
+	/* Enable GPIOs for UART TX */
+	ldr	r1, =(RCC_BASE + DEBUG_UART_TX_GPIO_BANK_CLK_REG)
 	ldr	r2, [r1]
-	/* Configure GPIO G11 */
-	orr	r2, r2, #RCC_MP_AHB4ENSETR_GPIOGEN
+	/* Configure GPIO */
+	orr	r2, r2, #DEBUG_UART_TX_GPIO_BANK_CLK_EN
 	str	r2, [r1]
-	ldr	r1, =GPIO_BANK_G_ADDRESS
+	ldr	r1, =DEBUG_UART_TX_GPIO_BANK_ADDRESS
 	/* Set GPIO mode alternate */
 	ldr	r2, [r1, #GPIO_MODE_OFFSET]
 	bic	r2, r2, #(GPIO_MODE_MASK << GPIO_TX_SHIFT)
@@ -132,23 +129,22 @@
 	ldr	r2, [r1, #GPIO_PUPD_OFFSET]
 	bic	r2, r2, #(GPIO_PULL_MASK << GPIO_TX_SHIFT)
 	str	r2, [r1, #GPIO_PUPD_OFFSET]
-	/* Set alternate AF6 */
+	/* Set alternate */
 	ldr	r2, [r1, #GPIO_AFRH_OFFSET]
 	bic	r2, r2, #(GPIO_ALTERNATE_MASK << GPIO_TX_ALT_SHIFT)
-	orr	r2, r2, #(GPIO_ALTERNATE_6 << GPIO_TX_ALT_SHIFT)
+	orr	r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << GPIO_TX_ALT_SHIFT)
 	str	r2, [r1, #GPIO_AFRH_OFFSET]
-
-	/* Enable UART clock, with HSI source */
-	ldr	r1, =(RCC_BASE + RCC_UART24CKSELR)
-	mov	r2, #RCC_UART24CKSELR_HSI
+	/* Enable UART clock, with its source */
+	ldr	r1, =(RCC_BASE + DEBUG_UART_TX_CLKSRC_REG)
+	mov	r2, #DEBUG_UART_TX_CLKSRC
 	str	r2, [r1]
-	ldr	r1, =(RCC_BASE + RCC_MP_APB1ENSETR)
+	ldr	r1, =(RCC_BASE + DEBUG_UART_TX_EN_REG)
 	ldr	r2, [r1]
-	orr	r2, r2, #RCC_MP_APB1ENSETR_UART4EN
+	orr	r2, r2, #DEBUG_UART_TX_EN
 	str	r2, [r1]
 
 	ldr	r0, =STM32MP1_DEBUG_USART_BASE
-	ldr	r1, =STM32MP1_HSI_CLK
+	ldr	r1, =STM32MP1_DEBUG_USART_CLK_FRQ
 	ldr	r2, =STM32MP1_UART_BAUDRATE
 	b	console_stm32_core_init
 endfunc plat_crash_console_init
diff --git a/plat/st/stm32mp1/stm32mp1_pm.c b/plat/st/stm32mp1/stm32mp1_pm.c
index 85189ff..c0e9c4e 100644
--- a/plat/st/stm32mp1/stm32mp1_pm.c
+++ b/plat/st/stm32mp1/stm32mp1_pm.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
  */
@@ -23,11 +23,9 @@
 #include <boot_api.h>
 #include <stm32mp1_private.h>
 
-static uint32_t stm32_sec_entrypoint;
+static uintptr_t stm32_sec_entrypoint;
 static uint32_t cntfrq_core0;
 
-#define SEND_SECURE_IT_TO_CORE_1	0x20000U
-
 /*******************************************************************************
  * STM32MP1 handler called when a CPU is about to enter standby.
  * call by core 1 to enter in wfi
@@ -42,6 +40,7 @@
 	 * Enter standby state
 	 * dsb is good practice before using wfi to enter low power states
 	 */
+	isb();
 	dsb();
 	while (interrupt == GIC_SPURIOUS_INTERRUPT) {
 		wfi();
@@ -59,7 +58,7 @@
 /*******************************************************************************
  * STM32MP1 handler called when a power domain is about to be turned on. The
  * mpidr determines the CPU to be turned on.
- * call by core  0 to activate core 1
+ * call by core 0 to activate core 1
  ******************************************************************************/
 static int stm32_pwr_domain_on(u_register_t mpidr)
 {
@@ -102,8 +101,7 @@
 	}
 
 	/* Generate an IT to core 1 */
-	mmio_write_32(STM32MP1_GICD_BASE + GICD_SGIR,
-		      SEND_SECURE_IT_TO_CORE_1 | ARM_IRQ_SEC_SGI_0);
+	gicv2_raise_sgi(ARM_IRQ_SEC_SGI_0, STM32MP1_SECONDARY_CPU);
 
 	return PSCI_E_SUCCESS;
 }
diff --git a/plat/st/stm32mp1/stm32mp1_security.c b/plat/st/stm32mp1/stm32mp1_security.c
index 3992704..cfdbf31 100644
--- a/plat/st/stm32mp1/stm32mp1_security.c
+++ b/plat/st/stm32mp1/stm32mp1_security.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
  */
@@ -65,22 +65,6 @@
  ******************************************************************************/
 static void early_init_tzc400(void)
 {
-	uint32_t rstsr, rst_standby;
-
-	rstsr = mmio_read_32(RCC_BASE + RCC_MP_RSTSCLRR);
-
-	/* No warning if return from (C)STANDBY */
-	rst_standby = rstsr &
-		(RCC_MP_RSTSCLRR_STDBYRSTF | RCC_MP_RSTSCLRR_CSTDBYRSTF);
-
-	if (stm32mp1_clk_is_enabled(TZC1) && (rst_standby == 0U)) {
-		WARN("TZC400 port 1 clock already enable\n");
-	}
-
-	if (stm32mp1_clk_is_enabled(TZC2) && (rst_standby == 0U)) {
-		WARN("TZC400 port 2 clock already enable\n");
-	}
-
 	if (stm32mp1_clk_enable(TZC1) != 0) {
 		ERROR("Cannot enable TZC1 clock\n");
 		panic();
@@ -103,6 +87,7 @@
 				STM32MP1_DDR_BASE +
 				(STM32MP1_DDR_MAX_SIZE - 1U),
 				TZC_REGION_S_RDWR,
+				TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID) |
 				TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_SDMMC_ID));
 
 	/* Raise an exception if a NS device tries to access secure memory */
diff --git a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c
index 5dd54d4..49cecd4 100644
--- a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c
+++ b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c
@@ -139,10 +139,10 @@
 	if ((mmio_read_32(spt->scfg + SCFG_THREAD_CTRL) & SCFG_THREAD_CTRL_DIR_MASK)
 	    != (dir << SCFG_THREAD_CTRL_DIR_SHIFT)) {
 		if (dir)
-			ERROR("Trying to receive data on tx Thread %d\n",
+			ERROR("Trying to send data on RX Thread %d\n",
 			      spt->id);
 		else
-			ERROR("Trying to send data on rx Thread %d\n",
+			ERROR("Trying to receive data on TX Thread %d\n",
 			      spt->id);
 		return -EINVAL;
 	}
@@ -163,6 +163,44 @@
 }
 
 /**
+ * k3_sec_proxy_clear_rx_thread() - Clear Secure Proxy thread
+ *
+ * @id: Channel Identifier
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int k3_sec_proxy_clear_rx_thread(enum k3_sec_proxy_chan_id id)
+{
+	struct k3_sec_proxy_thread *spt = &spm.threads[id];
+
+	/* Check for any errors already available */
+	if (mmio_read_32(spt->rt + RT_THREAD_STATUS) &
+	    RT_THREAD_STATUS_ERROR_MASK) {
+		ERROR("Thread %d is corrupted, cannot send data\n", spt->id);
+		return -EINVAL;
+	}
+
+	/* Make sure thread is configured for right direction */
+	if (!(mmio_read_32(spt->scfg + SCFG_THREAD_CTRL) & SCFG_THREAD_CTRL_DIR_MASK)) {
+		ERROR("Cannot clear a transmit thread %d\n", spt->id);
+		return -EINVAL;
+	}
+
+	/* Read off messages from thread until empty */
+	uint32_t try_count = 10;
+	while (mmio_read_32(spt->rt + RT_THREAD_STATUS) & RT_THREAD_STATUS_CUR_CNT_MASK) {
+		if (!(try_count--)) {
+			ERROR("Could not clear all messages from thread %d\n", spt->id);
+			return -ETIMEDOUT;
+		}
+		WARN("Clearing message from thread %d\n", spt->id);
+		mmio_read_32(spt->data + spm.desc.data_end_offset);
+	}
+
+	return 0;
+}
+
+/**
  * k3_sec_proxy_send() - Send data over a Secure Proxy thread
  * @id: Channel Identifier
  * @msg: Pointer to k3_sec_proxy_msg
diff --git a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h
index 2d987f8..6c4f5df 100644
--- a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h
+++ b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h
@@ -44,6 +44,15 @@
  *
  * Return: 0 if all goes well, else appropriate error message
  */
+int k3_sec_proxy_clear_rx_thread(enum k3_sec_proxy_chan_id id);
+
+/**
+ * k3_sec_proxy_send() - Send data over a Secure Proxy thread
+ * @id: Channel Identifier
+ * @msg: Pointer to k3_sec_proxy_msg
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
 int k3_sec_proxy_send(enum k3_sec_proxy_chan_id id, const struct k3_sec_proxy_msg *msg);
 
 /**
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
index b211bdf..4a33d34 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
@@ -158,6 +158,13 @@
 	struct k3_sec_proxy_msg *msg = &xfer->tx_message;
 	int ret;
 
+	/* Clear any spurious messages in receive queue */
+	ret = k3_sec_proxy_clear_rx_thread(SP_RESPONSE);
+	if (ret) {
+		ERROR("Could not clear response queue (%d)\n", ret);
+		return ret;
+	}
+
 	/* Send the message */
 	ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, msg);
 	if (ret) {
@@ -165,6 +172,7 @@
 		return ret;
 	}
 
+	/* Get the response */
 	ret = ti_sci_get_response(xfer, SP_RESPONSE);
 	if (ret) {
 		ERROR("Failed to get response (%d)\n", ret);
@@ -1455,6 +1463,169 @@
 	*ctrl_flags = resp.control_flags;
 	*sts_flags = resp.status_flags;
 
+	return 0;
+}
+
+/**
+ * ti_sci_proc_wait_boot_status() - Wait for a processor boot status
+ *
+ * @proc_id:			Processor ID this request is for
+ * @num_wait_iterations		Total number of iterations we will check before
+ *				we will timeout and give up
+ * @num_match_iterations	How many iterations should we have continued
+ *				status to account for status bits glitching.
+ *				This is to make sure that match occurs for
+ *				consecutive checks. This implies that the
+ *				worst case should consider that the stable
+ *				time should at the worst be num_wait_iterations
+ *				num_match_iterations to prevent timeout.
+ * @delay_per_iteration_us	Specifies how long to wait (in micro seconds)
+ *				between each status checks. This is the minimum
+ *				duration, and overhead of register reads and
+ *				checks are on top of this and can vary based on
+ *				varied conditions.
+ * @delay_before_iterations_us	Specifies how long to wait (in micro seconds)
+ *				before the very first check in the first
+ *				iteration of status check loop. This is the
+ *				minimum duration, and overhead of register
+ *				reads and checks are.
+ * @status_flags_1_set_all_wait	If non-zero, Specifies that all bits of the
+ *				status matching this field requested MUST be 1.
+ * @status_flags_1_set_any_wait	If non-zero, Specifies that at least one of the
+ *				bits matching this field requested MUST be 1.
+ * @status_flags_1_clr_all_wait	If non-zero, Specifies that all bits of the
+ *				status matching this field requested MUST be 0.
+ * @status_flags_1_clr_any_wait	If non-zero, Specifies that at least one of the
+ *				bits matching this field requested MUST be 0.
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_proc_wait_boot_status(uint8_t proc_id, uint8_t num_wait_iterations,
+				 uint8_t num_match_iterations,
+				 uint8_t delay_per_iteration_us,
+				 uint8_t delay_before_iterations_us,
+				 uint32_t status_flags_1_set_all_wait,
+				 uint32_t status_flags_1_set_any_wait,
+				 uint32_t status_flags_1_clr_all_wait,
+				 uint32_t status_flags_1_clr_any_wait)
+{
+	struct ti_sci_msg_req_wait_proc_boot_status req;
+	struct ti_sci_msg_hdr resp;
+
+	struct ti_sci_xfer xfer;
+	int ret;
+
+	ret = ti_sci_setup_one_xfer(TISCI_MSG_WAIT_PROC_BOOT_STATUS,
+				    TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+				    &req, sizeof(req),
+				    &resp, sizeof(resp),
+				    &xfer);
+	if (ret) {
+		ERROR("Message alloc failed (%d)\n", ret);
+		return ret;
+	}
+
+	req.processor_id = proc_id;
+	req.num_wait_iterations = num_wait_iterations;
+	req.num_match_iterations = num_match_iterations;
+	req.delay_per_iteration_us = delay_per_iteration_us;
+	req.delay_before_iterations_us = delay_before_iterations_us;
+	req.status_flags_1_set_all_wait = status_flags_1_set_all_wait;
+	req.status_flags_1_set_any_wait = status_flags_1_set_any_wait;
+	req.status_flags_1_clr_all_wait = status_flags_1_clr_all_wait;
+	req.status_flags_1_clr_any_wait = status_flags_1_clr_any_wait;
+
+	ret = ti_sci_do_xfer(&xfer);
+	if (ret) {
+		ERROR("Transfer send failed (%d)\n", ret);
+		return ret;
+	}
+
+	if (!ti_sci_is_response_ack(&resp))
+		return -ENODEV;
+
+	return 0;
+}
+
+/**
+ * ti_sci_proc_shutdown() - Shutdown Processor without waiting for ACKs
+ *
+ * @proc_id:	Processor ID this request is for
+ * @dev_id:	Device identifier this request is for
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_proc_shutdown(uint8_t proc_id, uint32_t dev_id)
+{
+	struct ti_sci_msg_req_wait_proc_boot_status wait_req;
+	struct ti_sci_msg_req_set_device_state set_req;
+	/*
+	 * We will not be waiting for this response, but declare one anyway
+	 * to pass to the setup function so the checks will still pass
+	 */
+	struct ti_sci_msg_hdr resp;
+
+	struct ti_sci_xfer xfer;
+	int ret;
+
+	/* Start by sending wait command */
+
+	/* Setup with NORESPONSE flag to keep response queue clean */
+	ret = ti_sci_setup_one_xfer(TISCI_MSG_WAIT_PROC_BOOT_STATUS,
+				    TI_SCI_FLAG_REQ_GENERIC_NORESPONSE,
+				    &wait_req, sizeof(wait_req),
+				    &resp, sizeof(resp),
+				    &xfer);
+	if (ret) {
+		ERROR("Message alloc failed (%d)\n", ret);
+		return ret;
+	}
+
+	wait_req.processor_id = proc_id;
+	/*
+	 * Wait maximum time to give us the best chance to get
+	 * to WFI before this command timeouts
+	 */
+	wait_req.delay_before_iterations_us = UINT8_MAX;
+	wait_req.num_wait_iterations = UINT8_MAX;
+	wait_req.delay_per_iteration_us = UINT8_MAX;  /* TODO: optimize time */
+	wait_req.num_match_iterations = 2;
+	wait_req.status_flags_1_set_all_wait = 0;
+	/* Wait for either WFE or WFI */
+	wait_req.status_flags_1_set_any_wait = PROC_BOOT_STATUS_FLAG_ARMV8_WFE |
+					       PROC_BOOT_STATUS_FLAG_ARMV8_WFI;
+	wait_req.status_flags_1_clr_all_wait = 0;
+	wait_req.status_flags_1_clr_any_wait = 0;
+
+	/* Send wait message */
+	ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, &xfer.tx_message);
+	if (ret) {
+		ERROR("Message sending failed (%d)\n", ret);
+		return ret;
+	}
+
+	/* Now queue up the shutdown request */
+	ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_DEVICE_STATE,
+				    TI_SCI_FLAG_REQ_GENERIC_NORESPONSE,
+				    &set_req, sizeof(set_req),
+				    &resp, sizeof(resp),
+				    &xfer);
+	if (ret) {
+		ERROR("Message alloc failed (%d)\n", ret);
+		return ret;
+	}
+
+	set_req.id = dev_id;
+	set_req.state = MSG_DEVICE_SW_STATE_AUTO_OFF;
+
+	/* Send shutdown message */
+	ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, &xfer.tx_message);
+	if (ret) {
+		ERROR("Message sending failed (%d)\n", ret);
+		return ret;
+	}
+
+	/* Return without waiting for responses */
 	return 0;
 }
 
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.h b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
index 1176b00..d07ee61 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
@@ -179,6 +179,7 @@
  *                                 and then set the processor configuration flags.
  *              @cert_addr: Memory address at which payload image certificate is located.
  * - ti_sci_proc_get_boot_status - Command to get the processor boot status
+ * - ti_sci_proc_wait_boot_status - Command to wait for a processor boot status
  *
  * NOTE: for all these functions, the following are generic in nature:
  * @proc_id:	Processor ID
@@ -197,6 +198,15 @@
 				uint32_t *cfg_flags,
 				uint32_t *ctrl_flags,
 				uint32_t *sts_flags);
+int ti_sci_proc_wait_boot_status(uint8_t proc_id, uint8_t num_wait_iterations,
+				 uint8_t num_match_iterations,
+				 uint8_t delay_per_iteration_us,
+				 uint8_t delay_before_iterations_us,
+				 uint32_t status_flags_1_set_all_wait,
+				 uint32_t status_flags_1_set_any_wait,
+				 uint32_t status_flags_1_clr_all_wait,
+				 uint32_t status_flags_1_clr_any_wait);
+int ti_sci_proc_shutdown(uint8_t proc_id, uint32_t dev_id);
 
 /**
  * ti_sci_init() - Basic initialization
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
index c6d76d7..a921e51 100644
--- a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
@@ -46,6 +46,7 @@
 #define TISCI_MSG_SET_PROC_BOOT_CTRL	0xc101
 #define TISCI_MSG_PROC_AUTH_BOOT_IMIAGE	0xc120
 #define TISCI_MSG_GET_PROC_BOOT_STATUS	0xc400
+#define TISCI_MSG_WAIT_PROC_BOOT_STATUS	0xc401
 
 /**
  * struct ti_sci_msg_hdr - Generic Message Header for All messages and responses
@@ -647,4 +648,52 @@
 	uint32_t status_flags;
 } __packed;
 
+/**
+ * struct ti_sci_msg_req_wait_proc_boot_status - Wait for a processor boot status
+ * @hdr:			Generic Header
+ * @processor_id:		ID of processor
+ * @num_wait_iterations		Total number of iterations we will check before
+ *				we will timeout and give up
+ * @num_match_iterations	How many iterations should we have continued
+ *				status to account for status bits glitching.
+ *				This is to make sure that match occurs for
+ *				consecutive checks. This implies that the
+ *				worst case should consider that the stable
+ *				time should at the worst be num_wait_iterations
+ *				num_match_iterations to prevent timeout.
+ * @delay_per_iteration_us	Specifies how long to wait (in micro seconds)
+ *				between each status checks. This is the minimum
+ *				duration, and overhead of register reads and
+ *				checks are on top of this and can vary based on
+ *				varied conditions.
+ * @delay_before_iterations_us	Specifies how long to wait (in micro seconds)
+ *				before the very first check in the first
+ *				iteration of status check loop. This is the
+ *				minimum duration, and overhead of register
+ *				reads and checks are.
+ * @status_flags_1_set_all_wait	If non-zero, Specifies that all bits of the
+ *				status matching this field requested MUST be 1.
+ * @status_flags_1_set_any_wait	If non-zero, Specifies that at least one of the
+ *				bits matching this field requested MUST be 1.
+ * @status_flags_1_clr_all_wait	If non-zero, Specifies that all bits of the
+ *				status matching this field requested MUST be 0.
+ * @status_flags_1_clr_any_wait	If non-zero, Specifies that at least one of the
+ *				bits matching this field requested MUST be 0.
+ *
+ * Request type is TISCI_MSG_WAIT_PROC_BOOT_STATUS, response is appropriate
+ * message, or NACK in case of inability to satisfy request.
+ */
+struct ti_sci_msg_req_wait_proc_boot_status {
+	struct ti_sci_msg_hdr hdr;
+	uint8_t processor_id;
+	uint8_t num_wait_iterations;
+	uint8_t num_match_iterations;
+	uint8_t delay_per_iteration_us;
+	uint8_t delay_before_iterations_us;
+	uint32_t status_flags_1_set_all_wait;
+	uint32_t status_flags_1_set_any_wait;
+	uint32_t status_flags_1_clr_all_wait;
+	uint32_t status_flags_1_clr_any_wait;
+} __packed;
+
 #endif /* TI_SCI_PROTOCOL_H */
diff --git a/plat/ti/k3/common/k3_bl31_setup.c b/plat/ti/k3/common/k3_bl31_setup.c
index 3fa11b2..78fb696 100644
--- a/plat/ti/k3/common/k3_bl31_setup.c
+++ b/plat/ti/k3/common/k3_bl31_setup.c
@@ -23,8 +23,7 @@
 const mmap_region_t plat_k3_mmap[] = {
 	MAP_REGION_FLAT(SHARED_RAM_BASE, SHARED_RAM_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
 	MAP_REGION_FLAT(K3_USART_BASE_ADDRESS, K3_USART_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(K3_GICD_BASE, K3_GICD_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
-	MAP_REGION_FLAT(K3_GICR_BASE, K3_GICR_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(K3_GIC_BASE, K3_GIC_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
 	MAP_REGION_FLAT(SEC_PROXY_RT_BASE, SEC_PROXY_RT_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
 	MAP_REGION_FLAT(SEC_PROXY_SCFG_BASE, SEC_PROXY_SCFG_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
 	MAP_REGION_FLAT(SEC_PROXY_DATA_BASE, SEC_PROXY_DATA_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
@@ -116,7 +115,7 @@
 
 void bl31_platform_setup(void)
 {
-	k3_gic_driver_init(K3_GICD_BASE, K3_GICR_BASE);
+	k3_gic_driver_init(K3_GIC_BASE);
 	k3_gic_init();
 
 	ti_sci_init();
diff --git a/plat/ti/k3/common/k3_gicv3.c b/plat/ti/k3/common/k3_gicv3.c
index b7c7880..1932eaa 100644
--- a/plat/ti/k3/common/k3_gicv3.c
+++ b/plat/ti/k3/common/k3_gicv3.c
@@ -6,10 +6,12 @@
 
 #include <platform_def.h>
 
+#include <assert.h>
 #include <common/bl_common.h>
 #include <common/interrupt_props.h>
 #include <drivers/arm/gicv3.h>
 #include <lib/utils.h>
+#include <lib/mmio.h>
 #include <plat/common/platform.h>
 
 #include <k3_gicv3.h>
@@ -35,8 +37,25 @@
 	.mpidr_to_core_pos = k3_mpidr_to_core_pos,
 };
 
-void k3_gic_driver_init(uintptr_t gicd_base, uintptr_t gicr_base)
+void k3_gic_driver_init(uintptr_t gic_base)
 {
+	/* GIC Distributor is always at the base of the IP */
+	uintptr_t gicd_base = gic_base;
+	/* GIC Redistributor base is run-time detected */
+	uintptr_t gicr_base = 0;
+
+	for (unsigned int gicr_shift = 18; gicr_shift < 21; gicr_shift++) {
+		uintptr_t gicr_check = gic_base + BIT(gicr_shift);
+		uint32_t iidr = mmio_read_32(gicr_check + GICR_IIDR);
+		if (iidr != 0) {
+			/* Found the GICR base */
+			gicr_base = gicr_check;
+			break;
+		}
+	}
+	/* Assert if we have not found the GICR base */
+	assert(gicr_base != 0);
+
 	/*
 	 * The GICv3 driver is initialized in EL3 and does not need
 	 * to be initialized again in SEL1. This is because the S-EL1
diff --git a/plat/ti/k3/common/k3_psci.c b/plat/ti/k3/common/k3_psci.c
index cb75bf6..235e639 100644
--- a/plat/ti/k3/common/k3_psci.c
+++ b/plat/ti/k3/common/k3_psci.c
@@ -81,15 +81,16 @@
 
 void k3_pwr_domain_off(const psci_power_state_t *target_state)
 {
-	int core_id, device, ret;
+	int core_id, proc, device, ret;
 
 	/* Prevent interrupts from spuriously waking up this cpu */
 	k3_gic_cpuif_disable();
 
 	core_id = plat_my_core_pos();
+	proc = PLAT_PROC_START_ID + core_id;
 	device = PLAT_PROC_DEVICE_START_ID + core_id;
 
-	ret = ti_sci_device_put(device);
+	ret = ti_sci_proc_shutdown(proc, device);
 	if (ret) {
 		ERROR("Request to stop core failed: %d\n", ret);
 		return;
diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk
index 9b3e7d8..c91a035 100644
--- a/plat/ti/k3/common/plat_common.mk
+++ b/plat/ti/k3/common/plat_common.mk
@@ -30,6 +30,10 @@
 TI_16550_MDR_QUIRK	:=	1
 $(eval $(call add_define,TI_16550_MDR_QUIRK))
 
+# Allow customizing the UART baud rate
+K3_USART_BAUD		:=	115200
+$(eval $(call add_define,K3_USART_BAUD))
+
 # Libraries
 include lib/xlat_tables_v2/xlat_tables.mk
 
diff --git a/plat/ti/k3/include/k3_gicv3.h b/plat/ti/k3/include/k3_gicv3.h
index 52f34ff..2329a16 100644
--- a/plat/ti/k3/include/k3_gicv3.h
+++ b/plat/ti/k3/include/k3_gicv3.h
@@ -9,7 +9,7 @@
 
 #include <stdint.h>
 
-void k3_gic_driver_init(uintptr_t gicd_base, uintptr_t gicr_base);
+void k3_gic_driver_init(uintptr_t gic_base);
 void k3_gic_init(void);
 void k3_gic_cpuif_enable(void);
 void k3_gic_cpuif_disable(void);
diff --git a/plat/ti/k3/include/platform_def.h b/plat/ti/k3/include/platform_def.h
index 5d563b6..f1511c1 100644
--- a/plat/ti/k3/include/platform_def.h
+++ b/plat/ti/k3/include/platform_def.h
@@ -136,10 +136,6 @@
 #define K3_USART_CLK_SPEED 48000000
 #endif
 
-#ifndef K3_USART_BAUD
-#define K3_USART_BAUD 115200
-#endif
-
 /* Crash console defaults */
 #define CRASH_CONSOLE_BASE K3_USART_BASE_ADDRESS
 #define CRASH_CONSOLE_CLK K3_USART_CLK_SPEED
@@ -189,10 +185,8 @@
 	INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \
 			GIC_INTR_CFG_EDGE)
 
-#define K3_GICD_BASE  0x01800000
-#define K3_GICD_SIZE  0x10000
-#define K3_GICR_BASE  0x01880000
-#define K3_GICR_SIZE  0x100000
+#define K3_GIC_BASE	0x01800000
+#define K3_GIC_SIZE	0x200000
 
 #define SEC_PROXY_DATA_BASE	0x32C00000
 #define SEC_PROXY_DATA_SIZE	0x80000
diff --git a/plat/xilinx/zynqmp/zynqmp_ipi.h b/plat/xilinx/common/include/ipi.h
similarity index 68%
rename from plat/xilinx/zynqmp/zynqmp_ipi.h
rename to plat/xilinx/common/include/ipi.h
index b9b40dd..483902e 100644
--- a/plat/xilinx/zynqmp/zynqmp_ipi.h
+++ b/plat/xilinx/common/include/ipi.h
@@ -1,32 +1,17 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018, Xilinx, Inc. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-/* ZynqMP IPI management enums and defines */
+/* Xilinx IPI management configuration data and macros */
 
-#ifndef ZYNQMP_IPI_H
-#define ZYNQMP_IPI_H
+#ifndef IPI_H
+#define IPI_H
 
 #include <stdint.h>
 
 /*********************************************************************
- * IPI agent IDs macros
- ********************************************************************/
-#define IPI_ID_APU	0U
-#define IPI_ID_RPU0	1U
-#define IPI_ID_RPU1	2U
-#define IPI_ID_PMU0	3U
-#define IPI_ID_PMU1	4U
-#define IPI_ID_PMU2	5U
-#define IPI_ID_PMU3	6U
-#define IPI_ID_PL0	7U
-#define IPI_ID_PL1	8U
-#define IPI_ID_PL2	9U
-#define IPI_ID_PL3	10U
-
-/*********************************************************************
  * IPI mailbox status macros
  ********************************************************************/
 #define IPI_MB_STATUS_IDLE		0
@@ -40,9 +25,31 @@
 #define IPI_MB_CALL_SECURE	1
 
 /*********************************************************************
+ * IPI secure check
+ ********************************************************************/
+#define IPI_SECURE_MASK  0x1U
+#define IPI_IS_SECURE(I) ((ipi_table[(I)].secure_only & \
+			   IPI_SECURE_MASK) ? 1 : 0)
+
+/*********************************************************************
+ * Struct definitions
+ ********************************************************************/
+
+/* structure to maintain IPI configuration information */
+struct ipi_config {
+	unsigned int ipi_bit_mask;
+	unsigned int ipi_reg_base;
+	unsigned char secure_only;
+};
+
+/*********************************************************************
  * IPI APIs declarations
  ********************************************************************/
 
+/* Initialize IPI configuration table */
+void ipi_config_table_init(const struct ipi_config *ipi_table,
+			   uint32_t total_ipi);
+
 /* Validate IPI mailbox access */
 int ipi_mb_validate(uint32_t local, uint32_t remote, unsigned int is_secure);
 
@@ -67,4 +74,4 @@
 /* Enable IPI mailbox notification interrupt */
 void ipi_mb_enable_irq(uint32_t local, uint32_t remote);
 
-#endif /* ZYNQMP_IPI_H */
+#endif /* IPI_H */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_common.h b/plat/xilinx/common/include/pm_common.h
similarity index 60%
rename from plat/xilinx/zynqmp/pm_service/pm_common.h
rename to plat/xilinx/common/include/pm_common.h
index 94e0568..c0a51f0 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_common.h
+++ b/plat/xilinx/common/include/pm_common.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,28 +13,17 @@
 #define PM_COMMON_H
 
 #include <stdint.h>
-
-#include <common/debug.h>
-
-#include "pm_defs.h"
-
-#define PAYLOAD_ARG_CNT		6U
-#define PAYLOAD_ARG_SIZE	4U	/* size in bytes */
-
-#define ZYNQMP_TZ_VERSION_MAJOR		1
-#define ZYNQMP_TZ_VERSION_MINOR		0
-#define ZYNQMP_TZ_VERSION		((ZYNQMP_TZ_VERSION_MAJOR << 16) | \
-					ZYNQMP_TZ_VERSION_MINOR)
+#include <plat_pm_common.h>
 
 /**
  * pm_ipi - struct for capturing IPI-channel specific info
- * @apu_ipi_id	APU IPI agent ID
- * @pmu_ipi_id	PMU Agent ID
+ * @local_ipi_id	Local IPI agent ID
+ * @remote_ipi_id	Remote IPI Agent ID
  * @buffer_base	base address for payload buffer
  */
 struct pm_ipi {
-	const uint32_t apu_ipi_id;
-	const uint32_t pmu_ipi_id;
+	const uint32_t local_ipi_id;
+	const uint32_t remote_ipi_id;
 	const uintptr_t buffer_base;
 };
 
@@ -46,12 +35,11 @@
  *		(in APU all processors share one IPI channel)
  */
 struct pm_proc {
-	const enum pm_node_id node_id;
+	const uint32_t node_id;
 	const unsigned int pwrdn_mask;
 	const struct pm_ipi *ipi;
 };
 
 const struct pm_proc *pm_get_proc(unsigned int cpuid);
-const struct pm_proc *pm_get_proc_by_node(enum pm_node_id nid);
 
 #endif /* PM_COMMON_H */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_ipi.h b/plat/xilinx/common/include/pm_ipi.h
similarity index 78%
rename from plat/xilinx/zynqmp/pm_service/pm_ipi.h
rename to plat/xilinx/common/include/pm_ipi.h
index 650de52..16db5c5 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_ipi.h
+++ b/plat/xilinx/common/include/pm_ipi.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,8 +7,12 @@
 #ifndef PM_IPI_H
 #define PM_IPI_H
 
+#include <plat_ipi.h>
 #include "pm_common.h"
 
+#define IPI_BLOCKING		1
+#define IPI_NON_BLOCKING	0
+
 int pm_ipi_init(const struct pm_proc *proc);
 
 enum pm_ret_status pm_ipi_send(const struct pm_proc *proc,
@@ -21,5 +25,6 @@
 void pm_ipi_buff_read_callb(unsigned int *value, size_t count);
 void pm_ipi_irq_enable(const struct pm_proc *proc);
 void pm_ipi_irq_clear(const struct pm_proc *proc);
+uint32_t pm_ipi_irq_status(const struct pm_proc *proc);
 
 #endif /* PM_IPI_H */
diff --git a/plat/xilinx/common/ipi.c b/plat/xilinx/common/ipi.c
new file mode 100644
index 0000000..0b8020b
--- /dev/null
+++ b/plat/xilinx/common/ipi.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * Xilinx IPI agent registers access management
+ */
+
+#include <errno.h>
+#include <string.h>
+
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/bakery_lock.h>
+#include <lib/mmio.h>
+
+#include <ipi.h>
+#include <plat_ipi.h>
+#include <plat_private.h>
+
+/*********************************************************************
+ * Macros definitions
+ ********************************************************************/
+
+/* IPI registers offsets macros */
+#define IPI_TRIG_OFFSET 0x00U
+#define IPI_OBR_OFFSET  0x04U
+#define IPI_ISR_OFFSET  0x10U
+#define IPI_IMR_OFFSET  0x14U
+#define IPI_IER_OFFSET  0x18U
+#define IPI_IDR_OFFSET  0x1CU
+
+/* IPI register start offset */
+#define IPI_REG_BASE(I) (ipi_table[(I)].ipi_reg_base)
+
+/* IPI register bit mask */
+#define IPI_BIT_MASK(I) (ipi_table[(I)].ipi_bit_mask)
+
+/* IPI configuration table */
+const static struct ipi_config *ipi_table;
+
+/* Total number of IPI */
+static uint32_t ipi_total;
+
+/**
+ * ipi_config_init() - Initialize IPI configuration data
+ *
+ * @ipi_config_table  - IPI configuration table
+ * @ipi_total - Total number of IPI available
+ *
+ */
+void ipi_config_table_init(const struct ipi_config *ipi_config_table,
+			   uint32_t total_ipi)
+{
+	ipi_table = ipi_config_table;
+	ipi_total = total_ipi;
+}
+
+/* is_ipi_mb_within_range() - verify if IPI mailbox is within range
+ *
+ * @local  - local IPI ID
+ * @remote - remote IPI ID
+ *
+ * return - 1 if within range, 0 if not
+ */
+static inline int is_ipi_mb_within_range(uint32_t local, uint32_t remote)
+{
+	int ret = 1;
+
+	if (remote >= ipi_total || local >= ipi_total)
+		ret = 0;
+
+	return ret;
+}
+
+/**
+ * ipi_mb_validate() - validate IPI mailbox access
+ *
+ * @local  - local IPI ID
+ * @remote - remote IPI ID
+ * @is_secure - indicate if the requester is from secure software
+ *
+ * return - 0 success, negative value for errors
+ */
+int ipi_mb_validate(uint32_t local, uint32_t remote, unsigned int is_secure)
+{
+	int ret = 0;
+
+	if (!is_ipi_mb_within_range(local, remote))
+		ret = -EINVAL;
+	else if (IPI_IS_SECURE(local) && !is_secure)
+		ret = -EPERM;
+	else if (IPI_IS_SECURE(remote) && !is_secure)
+		ret = -EPERM;
+
+	return ret;
+}
+
+/**
+ * ipi_mb_open() - Open IPI mailbox.
+ *
+ * @local  - local IPI ID
+ * @remote - remote IPI ID
+ *
+ */
+void ipi_mb_open(uint32_t local, uint32_t remote)
+{
+	mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
+		      IPI_BIT_MASK(remote));
+	mmio_write_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET,
+		      IPI_BIT_MASK(remote));
+}
+
+/**
+ * ipi_mb_release() - Open IPI mailbox.
+ *
+ * @local  - local IPI ID
+ * @remote - remote IPI ID
+ *
+ */
+void ipi_mb_release(uint32_t local, uint32_t remote)
+{
+	mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
+		      IPI_BIT_MASK(remote));
+}
+
+/**
+ * ipi_mb_enquire_status() - Enquire IPI mailbox status
+ *
+ * @local  - local IPI ID
+ * @remote - remote IPI ID
+ *
+ * return - 0 idle, positive value for pending sending or receiving,
+ *          negative value for errors
+ */
+int ipi_mb_enquire_status(uint32_t local, uint32_t remote)
+{
+	int ret = 0;
+	uint32_t status;
+
+	status = mmio_read_32(IPI_REG_BASE(local) + IPI_OBR_OFFSET);
+	if (status & IPI_BIT_MASK(remote))
+		ret |= IPI_MB_STATUS_SEND_PENDING;
+	status = mmio_read_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
+	if (status & IPI_BIT_MASK(remote))
+		ret |= IPI_MB_STATUS_RECV_PENDING;
+
+	return ret;
+}
+
+/* ipi_mb_notify() - Trigger IPI mailbox notification
+ *
+ * @local - local IPI ID
+ * @remote - remote IPI ID
+ * @is_blocking - if to trigger the notification in blocking mode or not.
+ *
+ * It sets the remote bit in the IPI agent trigger register.
+ *
+ */
+void ipi_mb_notify(uint32_t local, uint32_t remote, uint32_t is_blocking)
+{
+	uint32_t status;
+
+	mmio_write_32(IPI_REG_BASE(local) + IPI_TRIG_OFFSET,
+		      IPI_BIT_MASK(remote));
+	if (is_blocking) {
+		do {
+			status = mmio_read_32(IPI_REG_BASE(local) +
+					      IPI_OBR_OFFSET);
+		} while (status & IPI_BIT_MASK(remote));
+	}
+}
+
+/* ipi_mb_ack() - Ack IPI mailbox notification from the other end
+ *
+ * @local - local IPI ID
+ * @remote - remote IPI ID
+ *
+ * It will clear the remote bit in the isr register.
+ *
+ */
+void ipi_mb_ack(uint32_t local, uint32_t remote)
+{
+	mmio_write_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET,
+		      IPI_BIT_MASK(remote));
+}
+
+/* ipi_mb_disable_irq() - Disable IPI mailbox notification interrupt
+ *
+ * @local - local IPI ID
+ * @remote - remote IPI ID
+ *
+ * It will mask the remote bit in the idr register.
+ *
+ */
+void ipi_mb_disable_irq(uint32_t local, uint32_t remote)
+{
+	mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
+		      IPI_BIT_MASK(remote));
+}
+
+/* ipi_mb_enable_irq() - Enable IPI mailbox notification interrupt
+ *
+ * @local - local IPI ID
+ * @remote - remote IPI ID
+ *
+ * It will mask the remote bit in the idr register.
+ *
+ */
+void ipi_mb_enable_irq(uint32_t local, uint32_t remote)
+{
+	mmio_write_32(IPI_REG_BASE(local) + IPI_IER_OFFSET,
+		      IPI_BIT_MASK(remote));
+}
diff --git a/plat/xilinx/zynqmp/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c
similarity index 75%
rename from plat/xilinx/zynqmp/pm_service/pm_ipi.c
rename to plat/xilinx/common/pm_service/pm_ipi.c
index b3d833d..034cd5b 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_ipi.c
+++ b/plat/xilinx/common/pm_service/pm_ipi.c
@@ -1,45 +1,28 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+
 #include <arch_helpers.h>
+
 #include <lib/bakery_lock.h>
 #include <lib/mmio.h>
+
+#include <ipi.h>
+#include <plat_ipi.h>
+#include <plat_private.h>
 #include <plat/common/platform.h>
 
-#include "../zynqmp_ipi.h"
-#include "../zynqmp_private.h"
 #include "pm_ipi.h"
 
-/* IPI message buffers */
-#define IPI_BUFFER_BASEADDR	0xFF990000U
-
-#define IPI_BUFFER_APU_BASE	(IPI_BUFFER_BASEADDR + 0x400U)
-#define IPI_BUFFER_PMU_BASE	(IPI_BUFFER_BASEADDR + 0xE00U)
-
-#define IPI_BUFFER_TARGET_APU_OFFSET	0x80U
-#define IPI_BUFFER_TARGET_PMU_OFFSET	0x1C0U
-
-#define IPI_BUFFER_MAX_WORDS	8
-
-#define IPI_BUFFER_REQ_OFFSET	0x0U
-#define IPI_BUFFER_RESP_OFFSET	0x20U
-
-#define IPI_BLOCKING		1
-#define IPI_NON_BLOCKING	0
 
 DEFINE_BAKERY_LOCK(pm_secure_lock);
 
-const struct pm_ipi apu_ipi = {
-	.apu_ipi_id = IPI_ID_APU,
-	.pmu_ipi_id = IPI_ID_PMU0,
-	.buffer_base = IPI_BUFFER_APU_BASE,
-};
-
 /**
- * pm_ipi_init() - Initialize IPI peripheral for communication with PMU
+ * pm_ipi_init() - Initialize IPI peripheral for communication with
+ *		   remote processor
  *
  * @proc	Pointer to the processor who is initiating request
  * @return	On success, the initialization function must return 0.
@@ -51,13 +34,13 @@
 int pm_ipi_init(const struct pm_proc *proc)
 {
 	bakery_lock_init(&pm_secure_lock);
-	ipi_mb_open(proc->ipi->apu_ipi_id, proc->ipi->pmu_ipi_id);
+	ipi_mb_open(proc->ipi->local_ipi_id, proc->ipi->remote_ipi_id);
 
 	return 0;
 }
 
 /**
- * pm_ipi_send_common() - Sends IPI request to the PMU
+ * pm_ipi_send_common() - Sends IPI request to the remote processor
  * @proc	Pointer to the processor who is initiating request
  * @payload	API id and call arguments to be written in IPI buffer
  *
@@ -72,7 +55,7 @@
 {
 	unsigned int offset = 0;
 	uintptr_t buffer_base = proc->ipi->buffer_base +
-					IPI_BUFFER_TARGET_PMU_OFFSET +
+					IPI_BUFFER_TARGET_REMOTE_OFFSET +
 					IPI_BUFFER_REQ_OFFSET;
 
 	/* Write payload into IPI buffer */
@@ -81,16 +64,16 @@
 		offset += PAYLOAD_ARG_SIZE;
 	}
 
-	/* Generate IPI to PMU */
-	ipi_mb_notify(proc->ipi->apu_ipi_id, proc->ipi->pmu_ipi_id,
+	/* Generate IPI to remote processor */
+	ipi_mb_notify(proc->ipi->local_ipi_id, proc->ipi->remote_ipi_id,
 		      is_blocking);
 
 	return PM_RET_SUCCESS;
 }
 
 /**
- * pm_ipi_send_non_blocking() - Sends IPI request to the PMU without blocking
- *			        notification
+ * pm_ipi_send_non_blocking() - Sends IPI request to the remote processor
+ *			        without blocking notification
  * @proc	Pointer to the processor who is initiating request
  * @payload	API id and call arguments to be written in IPI buffer
  *
@@ -113,7 +96,7 @@
 }
 
 /**
- * pm_ipi_send() - Sends IPI request to the PMU
+ * pm_ipi_send() - Sends IPI request to the remote processor
  * @proc	Pointer to the processor who is initiating request
  * @payload	API id and call arguments to be written in IPI buffer
  *
@@ -137,7 +120,8 @@
 
 
 /**
- * pm_ipi_buff_read() - Reads IPI response after PMU has handled interrupt
+ * pm_ipi_buff_read() - Reads IPI response after remote processor has handled
+ *			interrupt
  * @proc	Pointer to the processor who is waiting and reading response
  * @value	Used to return value from IPI buffer element (optional)
  * @count	Number of values to return in @value
@@ -149,7 +133,7 @@
 {
 	size_t i;
 	uintptr_t buffer_base = proc->ipi->buffer_base +
-				IPI_BUFFER_TARGET_PMU_OFFSET +
+				IPI_BUFFER_TARGET_REMOTE_OFFSET +
 				IPI_BUFFER_RESP_OFFSET;
 
 	/*
@@ -168,7 +152,8 @@
 }
 
 /**
- * pm_ipi_buff_read_callb() - Reads IPI response after PMU has handled interrupt
+ * pm_ipi_buff_read_callb() - Reads IPI response after remote processor has
+ *			      handled interrupt
  * @value	Used to return value from IPI buffer element (optional)
  * @count	Number of values to return in @value
  *
@@ -177,8 +162,8 @@
 void pm_ipi_buff_read_callb(unsigned int *value, size_t count)
 {
 	size_t i;
-	uintptr_t buffer_base = IPI_BUFFER_PMU_BASE +
-				IPI_BUFFER_TARGET_APU_OFFSET +
+	uintptr_t buffer_base = IPI_BUFFER_REMOTE_BASE +
+				IPI_BUFFER_TARGET_LOCAL_OFFSET +
 				IPI_BUFFER_REQ_OFFSET;
 
 	if (count > IPI_BUFFER_MAX_WORDS)
@@ -191,7 +176,7 @@
 }
 
 /**
- * pm_ipi_send_sync() - Sends IPI request to the PMU
+ * pm_ipi_send_sync() - Sends IPI request to the remote processor
  * @proc	Pointer to the processor who is initiating request
  * @payload	API id and call arguments to be written in IPI buffer
  * @value	Used to return value from IPI buffer element (optional)
@@ -224,10 +209,22 @@
 
 void pm_ipi_irq_enable(const struct pm_proc *proc)
 {
-	ipi_mb_enable_irq(proc->ipi->apu_ipi_id, proc->ipi->pmu_ipi_id);
+	ipi_mb_enable_irq(proc->ipi->local_ipi_id, proc->ipi->remote_ipi_id);
 }
 
 void pm_ipi_irq_clear(const struct pm_proc *proc)
 {
+	ipi_mb_ack(proc->ipi->local_ipi_id, proc->ipi->remote_ipi_id);
+}
+
+uint32_t pm_ipi_irq_status(const struct pm_proc *proc)
+{
-	ipi_mb_ack(proc->ipi->apu_ipi_id, proc->ipi->pmu_ipi_id);
+	int ret;
+
+	ret = ipi_mb_enquire_status(proc->ipi->local_ipi_id,
+				    proc->ipi->remote_ipi_id);
+	if (ret & IPI_MB_STATUS_RECV_PENDING)
+		return 1;
+	else
+		return 0;
 }
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
index 23c02e0..8ff6c43 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
@@ -11,9 +11,9 @@
 #include <drivers/generic_delay_timer.h>
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_tables.h>
+#include <plat_private.h>
 #include <plat/common/platform.h>
 
-#include "../zynqmp_private.h"
 #include "pm_api_sys.h"
 
 /*
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index 01cd781..b0eb66c 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -11,10 +11,10 @@
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <drivers/console.h>
-#include <plat_arm.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include "zynqmp_private.h"
+#include <plat_private.h>
 
 #define BL31_END (unsigned long)(&__BL31_END__)
 
diff --git a/plat/xilinx/zynqmp/include/plat_ipi.h b/plat/xilinx/zynqmp/include/plat_ipi.h
new file mode 100644
index 0000000..bccd2f1
--- /dev/null
+++ b/plat/xilinx/zynqmp/include/plat_ipi.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* ZynqMP IPI management enums and defines */
+
+#ifndef PLAT_IPI_H
+#define PLAT_IPI_H
+
+#include <stdint.h>
+#include <ipi.h>
+
+/*********************************************************************
+ * IPI agent IDs macros
+ ********************************************************************/
+#define IPI_ID_APU	0U
+#define IPI_ID_RPU0	1U
+#define IPI_ID_RPU1	2U
+#define IPI_ID_PMU0	3U
+#define IPI_ID_PMU1	4U
+#define IPI_ID_PMU2	5U
+#define IPI_ID_PMU3	6U
+#define IPI_ID_PL0	7U
+#define IPI_ID_PL1	8U
+#define IPI_ID_PL2	9U
+#define IPI_ID_PL3	10U
+
+/*********************************************************************
+ * IPI message buffers
+ ********************************************************************/
+#define IPI_BUFFER_BASEADDR	0xFF990000U
+
+#define IPI_BUFFER_APU_BASE	(IPI_BUFFER_BASEADDR + 0x400U)
+#define IPI_BUFFER_PMU_BASE	(IPI_BUFFER_BASEADDR + 0xE00U)
+
+#define IPI_BUFFER_LOCAL_BASE	IPI_BUFFER_APU_BASE
+#define IPI_BUFFER_REMOTE_BASE	IPI_BUFFER_PMU_BASE
+
+#define IPI_BUFFER_TARGET_LOCAL_OFFSET	0x80U
+#define IPI_BUFFER_TARGET_REMOTE_OFFSET	0x1C0U
+
+#define IPI_BUFFER_MAX_WORDS	8
+
+#define IPI_BUFFER_REQ_OFFSET	0x0U
+#define IPI_BUFFER_RESP_OFFSET	0x20U
+
+/*********************************************************************
+ * Platform specific IPI API declarations
+ ********************************************************************/
+
+/* Configure IPI table for zynqmp */
+void zynqmp_ipi_config_table_init(void);
+
+#endif /* PLAT_IPI_H */
diff --git a/plat/xilinx/zynqmp/include/plat_macros.S b/plat/xilinx/zynqmp/include/plat_macros.S
index e54cfc4..bf1ff82 100644
--- a/plat/xilinx/zynqmp/include/plat_macros.S
+++ b/plat/xilinx/zynqmp/include/plat_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,7 +8,7 @@
 
 #include <arm_macros.S>
 #include <cci_macros.S>
-#include "../zynqmp_def.h"
+#include "zynqmp_def.h"
 
 	/* ---------------------------------------------
 	 * The below required platform porting macro
diff --git a/plat/xilinx/zynqmp/include/plat_pm_common.h b/plat/xilinx/zynqmp/include/plat_pm_common.h
new file mode 100644
index 0000000..1b371cc
--- /dev/null
+++ b/plat/xilinx/zynqmp/include/plat_pm_common.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * Contains platform specific definitions of commonly used macros data types
+ * for PU Power Management. This file should be common for all PU's.
+ */
+
+#ifndef PLAT_PM_COMMON_H
+#define PLAT_PM_COMMON_H
+
+#include <stdint.h>
+#include <common/debug.h>
+#include "pm_defs.h"
+
+#define PAYLOAD_ARG_CNT		6U
+#define PAYLOAD_ARG_SIZE	4U	/* size in bytes */
+
+#define ZYNQMP_TZ_VERSION_MAJOR		1
+#define ZYNQMP_TZ_VERSION_MINOR		0
+#define ZYNQMP_TZ_VERSION		((ZYNQMP_TZ_VERSION_MAJOR << 16) | \
+					ZYNQMP_TZ_VERSION_MINOR)
+#endif /* _PLAT_PM_COMMON_H_ */
diff --git a/plat/xilinx/zynqmp/zynqmp_private.h b/plat/xilinx/zynqmp/include/plat_private.h
similarity index 91%
rename from plat/xilinx/zynqmp/zynqmp_private.h
rename to plat/xilinx/zynqmp/include/plat_private.h
index a8ebceb..99d0bc6 100644
--- a/plat/xilinx/zynqmp/zynqmp_private.h
+++ b/plat/xilinx/zynqmp/include/plat_private.h
@@ -4,8 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#ifndef ZYNQMP_PRIVATE_H
-#define ZYNQMP_PRIVATE_H
+#ifndef PLAT_PRIVATE_H
+#define PLAT_PRIVATE_H
 
 #include <stdint.h>
 
@@ -39,4 +39,4 @@
 enum fsbl_handoff fsbl_atf_handover(entry_point_info_t *bl32_image_ep_info,
 		       entry_point_info_t *bl33_image_ep_info);
 
-#endif /* ZYNQMP_PRIVATE_H */
+#endif /* PLAT_PRIVATE_H */
diff --git a/plat/xilinx/zynqmp/include/platform_def.h b/plat/xilinx/zynqmp/include/platform_def.h
index e3c9fcc..fb10411 100644
--- a/plat/xilinx/zynqmp/include/platform_def.h
+++ b/plat/xilinx/zynqmp/include/platform_def.h
@@ -12,7 +12,7 @@
 #include <drivers/arm/gic_common.h>
 #include <lib/utils_def.h>
 
-#include "../zynqmp_def.h"
+#include "zynqmp_def.h"
 
 /*******************************************************************************
  * Generic platform constants
diff --git a/plat/xilinx/zynqmp/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h
similarity index 94%
rename from plat/xilinx/zynqmp/zynqmp_def.h
rename to plat/xilinx/zynqmp/include/zynqmp_def.h
index f75530e..8648b9a 100644
--- a/plat/xilinx/zynqmp/zynqmp_def.h
+++ b/plat/xilinx/zynqmp/include/zynqmp_def.h
@@ -60,8 +60,10 @@
 #define CRL_APB_BOOT_PIN_MASK		(U(0xf0f) << 0)
 #define CRL_APB_BOOT_DRIVE_PIN_1_SHIFT	U(9)
 #define CRL_APB_BOOT_ENABLE_PIN_1_SHIFT	U(1)
-#define CRL_APB_BOOT_ENABLE_PIN_1	(U(0x1) << CRL_APB_BOOT_ENABLE_PIN_1_SHIFT)
-#define CRL_APB_BOOT_DRIVE_PIN_1	(U(0x1) << CRL_APB_BOOT_DRIVE_PIN_1_SHIFT)
+#define CRL_APB_BOOT_ENABLE_PIN_1	(U(0x1) << \
+					CRL_APB_BOOT_ENABLE_PIN_1_SHIFT)
+#define CRL_APB_BOOT_DRIVE_PIN_1	(U(0x1) << \
+					CRL_APB_BOOT_DRIVE_PIN_1_SHIFT)
 #define ZYNQMP_BOOTMODE_JTAG		U(0)
 #define ZYNQMP_ULPI_RESET_VAL_HIGH	(CRL_APB_BOOT_ENABLE_PIN_1 | \
 					 CRL_APB_BOOT_DRIVE_PIN_1)
@@ -137,7 +139,7 @@
 #define ZYNQMP_UART0_BASE		0xFF000000
 #define ZYNQMP_UART1_BASE		0xFF010000
 
-#if ZYNQMP_CONSOLE_IS(cadence)
+#if ZYNQMP_CONSOLE_IS(cadence) || ZYNQMP_CONSOLE_IS(dcc)
 # define ZYNQMP_UART_BASE	ZYNQMP_UART0_BASE
 #elif ZYNQMP_CONSOLE_IS(cadence1)
 # define ZYNQMP_UART_BASE	ZYNQMP_UART1_BASE
@@ -167,22 +169,27 @@
 #define ZYNQMP_CSU_IDCODE_OFFSET	0x40
 
 #define ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT	0
-#define ZYNQMP_CSU_IDCODE_XILINX_ID_MASK	(0xFFF << ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT)
+#define ZYNQMP_CSU_IDCODE_XILINX_ID_MASK	(0xFFF << \
+					ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT)
 #define ZYNQMP_CSU_IDCODE_XILINX_ID		0x093
 
 #define ZYNQMP_CSU_IDCODE_SVD_SHIFT		12
 #define ZYNQMP_CSU_IDCODE_SVD_MASK		(0x7 << \
 						 ZYNQMP_CSU_IDCODE_SVD_SHIFT)
 #define ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT	15
-#define ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK	(0xF << ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT)
+#define ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK	(0xF << \
+					ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT)
 #define ZYNQMP_CSU_IDCODE_SUB_FAMILY_SHIFT	19
-#define ZYNQMP_CSU_IDCODE_SUB_FAMILY_MASK	(0x3 << ZYNQMP_CSU_IDCODE_SUB_FAMILY_SHIFT)
+#define ZYNQMP_CSU_IDCODE_SUB_FAMILY_MASK	(0x3 << \
+					ZYNQMP_CSU_IDCODE_SUB_FAMILY_SHIFT)
 #define ZYNQMP_CSU_IDCODE_FAMILY_SHIFT		21
-#define ZYNQMP_CSU_IDCODE_FAMILY_MASK		(0x7F << ZYNQMP_CSU_IDCODE_FAMILY_SHIFT)
+#define ZYNQMP_CSU_IDCODE_FAMILY_MASK		(0x7F << \
+					ZYNQMP_CSU_IDCODE_FAMILY_SHIFT)
 #define ZYNQMP_CSU_IDCODE_FAMILY		0x23
 
 #define ZYNQMP_CSU_IDCODE_REVISION_SHIFT	28
-#define ZYNQMP_CSU_IDCODE_REVISION_MASK		(0xF << ZYNQMP_CSU_IDCODE_REVISION_SHIFT)
+#define ZYNQMP_CSU_IDCODE_REVISION_MASK		(0xF << \
+					ZYNQMP_CSU_IDCODE_REVISION_SHIFT)
 #define ZYNQMP_CSU_IDCODE_REVISION		0
 
 #define ZYNQMP_CSU_VERSION_OFFSET	0x44
diff --git a/plat/xilinx/zynqmp/ipi_mailbox_service/ipi_mailbox_svc.c b/plat/xilinx/zynqmp/ipi_mailbox_service/ipi_mailbox_svc.c
index 11f382a..c499d78 100644
--- a/plat/xilinx/zynqmp/ipi_mailbox_service/ipi_mailbox_svc.c
+++ b/plat/xilinx/zynqmp/ipi_mailbox_service/ipi_mailbox_svc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,9 +16,11 @@
 #include <lib/bakery_lock.h>
 #include <lib/mmio.h>
 
+#include <ipi.h>
+#include <plat_ipi.h>
+#include <plat_private.h>
+
 #include "ipi_mailbox_svc.h"
-#include "../zynqmp_ipi.h"
-#include "../zynqmp_private.h"
 #include "../../../services/spd/trusty/smcall.h"
 
 /*********************************************************************
diff --git a/plat/xilinx/zynqmp/plat_psci.c b/plat/xilinx/zynqmp/plat_psci.c
index 4183979..a32e089 100644
--- a/plat/xilinx/zynqmp/plat_psci.c
+++ b/plat/xilinx/zynqmp/plat_psci.c
@@ -12,12 +12,12 @@
 #include <drivers/arm/gicv2.h>
 #include <lib/mmio.h>
 #include <lib/psci/psci.h>
+#include <plat/arm/common/plat_arm.h>
 #include <plat/common/platform.h>
 
-#include <plat_arm.h>
+#include <plat_private.h>
 #include "pm_api_sys.h"
 #include "pm_client.h"
-#include "zynqmp_private.h"
 
 uintptr_t zynqmp_sec_entry;
 
diff --git a/plat/xilinx/zynqmp/plat_startup.c b/plat/xilinx/zynqmp/plat_startup.c
index 03f0e3d..cd2c3ba 100644
--- a/plat/xilinx/zynqmp/plat_startup.c
+++ b/plat/xilinx/zynqmp/plat_startup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,9 +9,9 @@
 #include <arch_helpers.h>
 #include <common/debug.h>
 #include <lib/mmio.h>
+#include <plat_private.h>
 
 #include "zynqmp_def.h"
-#include "zynqmp_private.h"
 
 /*
  * ATFHandoffParams
diff --git a/plat/xilinx/zynqmp/plat_zynqmp.c b/plat/xilinx/zynqmp/plat_zynqmp.c
index ad18aaf..906ce1b 100644
--- a/plat/xilinx/zynqmp/plat_zynqmp.c
+++ b/plat/xilinx/zynqmp/plat_zynqmp.c
@@ -4,10 +4,9 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <plat_private.h>
 #include <plat/common/platform.h>
 
-#include "zynqmp_private.h"
-
 int plat_core_pos_by_mpidr(u_register_t mpidr)
 {
 	if (mpidr & MPIDR_CLUSTER_MASK)
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index 35c8983..b2f91cd 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -45,8 +45,8 @@
 $(eval $(call add_define,ZYNQMP_WDT_RESTART))
 endif
 
-PLAT_INCLUDES		:=	-Iinclude/plat/arm/common/			\
-				-Iinclude/plat/arm/common/aarch64/		\
+PLAT_INCLUDES		:=	-Iinclude/plat/arm/common/aarch64/		\
+				-Iplat/xilinx/common/include/			\
 				-Iplat/xilinx/zynqmp/include/			\
 				-Iplat/xilinx/zynqmp/pm_service/		\
 				-Iplat/xilinx/zynqmp/ipi_mailbox_service/
@@ -64,6 +64,7 @@
 				plat/arm/common/arm_common.c			\
 				plat/arm/common/arm_gicv2.c			\
 				plat/common/plat_gicv2.c			\
+				plat/xilinx/common/ipi.c			\
 				plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S	\
 				plat/xilinx/zynqmp/aarch64/zynqmp_common.c
 
@@ -71,6 +72,7 @@
 				lib/cpus/aarch64/aem_generic.S			\
 				lib/cpus/aarch64/cortex_a53.S			\
 				plat/common/plat_psci_common.c			\
+				plat/xilinx/common/pm_service/pm_ipi.c		\
 				plat/xilinx/zynqmp/bl31_zynqmp_setup.c		\
 				plat/xilinx/zynqmp/plat_psci.c			\
 				plat/xilinx/zynqmp/plat_zynqmp.c		\
@@ -83,6 +85,5 @@
 				plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c	\
 				plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c	\
 				plat/xilinx/zynqmp/pm_service/pm_api_clock.c	\
-				plat/xilinx/zynqmp/pm_service/pm_ipi.c		\
 				plat/xilinx/zynqmp/pm_service/pm_client.c	\
 				plat/xilinx/zynqmp/ipi_mailbox_service/ipi_mailbox_svc.c
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
index d3f1fbf..44acb4b 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c
@@ -12,6 +12,7 @@
 #include <drivers/delay_timer.h>
 #include <lib/mmio.h>
 #include <plat/common/platform.h>
+#include <zynqmp_def.h>
 
 #include "pm_api_clock.h"
 #include "pm_api_ioctl.h"
@@ -19,7 +20,6 @@
 #include "pm_client.h"
 #include "pm_common.h"
 #include "pm_ipi.h"
-#include "../zynqmp_def.h"
 
 /**
  * pm_ioctl_get_rpu_oper_mode () - Get current RPU operation mode
diff --git a/plat/xilinx/zynqmp/pm_service/pm_client.c b/plat/xilinx/zynqmp/pm_service/pm_client.c
index bebb74c..163e891 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_client.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_client.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,7 +19,8 @@
 #include <lib/mmio.h>
 #include <lib/utils.h>
 
-#include "../zynqmp_def.h"
+#include <plat_ipi.h>
+#include <zynqmp_def.h>
 #include "pm_api_sys.h"
 #include "pm_client.h"
 #include "pm_ipi.h"
@@ -35,6 +36,12 @@
 
 extern const struct pm_ipi apu_ipi;
 
+const struct pm_ipi apu_ipi = {
+	.local_ipi_id = IPI_ID_APU,
+	.remote_ipi_id = IPI_ID_PMU0,
+	.buffer_base = IPI_BUFFER_APU_BASE,
+};
+
 static uint32_t suspend_mode = PM_SUSPEND_MODE_STD;
 
 /* Order in pm_procs_all array must match cpu ids */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_client.h b/plat/xilinx/zynqmp/pm_service/pm_client.h
index 0a34a07..adbb76f 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_client.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_client.h
@@ -21,6 +21,7 @@
 void pm_client_wakeup(const struct pm_proc *proc);
 enum pm_ret_status set_ocm_retention(void);
 enum pm_ret_status pm_set_suspend_mode(uint32_t mode);
+const struct pm_proc *pm_get_proc_by_node(enum pm_node_id nid);
 
 /* Global variables to be set in pm_client.c */
 extern const struct pm_proc *primary_proc;
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
index 0b8fc23..faa2827 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
@@ -20,7 +20,7 @@
 #include <plat/common/platform.h>
 #endif
 
-#include "../zynqmp_private.h"
+#include <plat_private.h>
 #include "pm_api_sys.h"
 #include "pm_client.h"
 #include "pm_ipi.h"
diff --git a/plat/xilinx/zynqmp/sip_svc_setup.c b/plat/xilinx/zynqmp/sip_svc_setup.c
index 8d23a01..edb81f5 100644
--- a/plat/xilinx/zynqmp/sip_svc_setup.c
+++ b/plat/xilinx/zynqmp/sip_svc_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,9 +9,9 @@
 #include <common/runtime_svc.h>
 #include <tools_share/uuid.h>
 
+#include <plat_ipi.h>
 #include "ipi_mailbox_svc.h"
 #include "pm_svc_main.h"
-#include "zynqmp_ipi.h"
 
 /* SMC function IDs for SiP Service queries */
 #define ZYNQMP_SIP_SVC_CALL_COUNT	0x8200ff00
@@ -41,6 +41,9 @@
  */
 static int32_t sip_svc_setup(void)
 {
+	/* Configure IPI data for ZynqMP */
+	zynqmp_ipi_config_table_init();
+
 	/* PM implementation as SiP Service */
 	pm_setup();
 
diff --git a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
index 25359f9..902e4b3 100644
--- a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
+++ b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
@@ -7,11 +7,11 @@
 #include <common/bl_common.h>
 #include <common/debug.h>
 #include <drivers/console.h>
+#include <plat/arm/common/plat_arm.h>
 
-#include <plat_arm.h>
+#include <plat_private.h>
 #include <platform_tsp.h>
 
-#include "../zynqmp_private.h"
 
 #define BL32_END (unsigned long)(&__BL32_END__)
 
diff --git a/plat/xilinx/zynqmp/zynqmp_ipi.c b/plat/xilinx/zynqmp/zynqmp_ipi.c
index 54b1838..f57369f 100644
--- a/plat/xilinx/zynqmp/zynqmp_ipi.c
+++ b/plat/xilinx/zynqmp/zynqmp_ipi.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,48 +16,12 @@
 #include <lib/bakery_lock.h>
 #include <lib/mmio.h>
 
-#include "zynqmp_ipi.h"
-#include "../zynqmp_private.h"
-
-/*********************************************************************
- * Macros definitions
- ********************************************************************/
-
-/* IPI registers base address */
-#define IPI_REGS_BASE   0xFF300000U
-
-/* IPI registers offsets macros */
-#define IPI_TRIG_OFFSET 0x00U
-#define IPI_OBR_OFFSET  0x04U
-#define IPI_ISR_OFFSET  0x10U
-#define IPI_IMR_OFFSET  0x14U
-#define IPI_IER_OFFSET  0x18U
-#define IPI_IDR_OFFSET  0x1CU
-
-/* IPI register start offset */
-#define IPI_REG_BASE(I) (zynqmp_ipi_table[(I)].ipi_reg_base)
-
-/* IPI register bit mask */
-#define IPI_BIT_MASK(I) (zynqmp_ipi_table[(I)].ipi_bit_mask)
-
-/* IPI secure check */
-#define IPI_SECURE_MASK  0x1U
-#define IPI_IS_SECURE(I) ((zynqmp_ipi_table[(I)].secure_only & \
-			   IPI_SECURE_MASK) ? 1 : 0)
-
-/*********************************************************************
- * Struct definitions
- ********************************************************************/
-
-/* structure to maintain IPI configuration information */
-struct zynqmp_ipi_config {
-	unsigned int ipi_bit_mask;
-	unsigned int ipi_reg_base;
-	unsigned char secure_only;
-};
+#include <ipi.h>
+#include <plat_ipi.h>
+#include <plat_private.h>
 
 /* Zynqmp ipi configuration table */
-const static struct zynqmp_ipi_config zynqmp_ipi_table[] = {
+const static struct ipi_config zynqmp_ipi_table[] = {
 	/* APU IPI */
 	{
 		.ipi_bit_mask = 0x1,
@@ -126,160 +90,11 @@
 	},
 };
 
-/* is_ipi_mb_within_range() - verify if IPI mailbox is within range
- *
- * @local  - local IPI ID
- * @remote - remote IPI ID
- *
- * return - 1 if within range, 0 if not
- */
-static inline int is_ipi_mb_within_range(uint32_t local, uint32_t remote)
-{
-	int ret = 1;
-	uint32_t ipi_total = ARRAY_SIZE(zynqmp_ipi_table);
-
-	if (remote >= ipi_total || local >= ipi_total)
-		ret = 0;
-
-	return ret;
-}
-
-/**
- * ipi_mb_validate() - validate IPI mailbox access
- *
- * @local  - local IPI ID
- * @remote - remote IPI ID
- * @is_secure - indicate if the requester is from secure software
- *
- * return - 0 success, negative value for errors
- */
-int ipi_mb_validate(uint32_t local, uint32_t remote, unsigned int is_secure)
-{
-	int ret = 0;
-
-	if (!is_ipi_mb_within_range(local, remote))
-		ret = -EINVAL;
-	else if (IPI_IS_SECURE(local) && !is_secure)
-		ret = -EPERM;
-	else if (IPI_IS_SECURE(remote) && !is_secure)
-		ret = -EPERM;
-
-	return ret;
-}
-
-/**
- * ipi_mb_open() - Open IPI mailbox.
- *
- * @local  - local IPI ID
- * @remote - remote IPI ID
- *
- */
-void ipi_mb_open(uint32_t local, uint32_t remote)
-{
-	mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
-		      IPI_BIT_MASK(remote));
-	mmio_write_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET,
-		      IPI_BIT_MASK(remote));
-}
-
-/**
- * ipi_mb_release() - Open IPI mailbox.
- *
- * @local  - local IPI ID
- * @remote - remote IPI ID
- *
- */
-void ipi_mb_release(uint32_t local, uint32_t remote)
-{
-	mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
-		      IPI_BIT_MASK(remote));
-}
-
 /**
- * ipi_mb_enquire_status() - Enquire IPI mailbox status
- *
- * @local  - local IPI ID
- * @remote - remote IPI ID
- *
- * return - 0 idle, positive value for pending sending or receiving,
- *          negative value for errors
- */
-int ipi_mb_enquire_status(uint32_t local, uint32_t remote)
-{
-	int ret = 0;
-	uint32_t status;
-
-	status = mmio_read_32(IPI_REG_BASE(local) + IPI_OBR_OFFSET);
-	if (status & IPI_BIT_MASK(remote))
-		ret |= IPI_MB_STATUS_SEND_PENDING;
-	status = mmio_read_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
-	if (status & IPI_BIT_MASK(remote))
-		ret |= IPI_MB_STATUS_RECV_PENDING;
-
-	return ret;
-}
-
-/* ipi_mb_notify() - Trigger IPI mailbox notification
- *
- * @local - local IPI ID
- * @remote - remote IPI ID
- * @is_blocking - if to trigger the notification in blocking mode or not.
- *
- * It sets the remote bit in the IPI agent trigger register.
- *
- */
-void ipi_mb_notify(uint32_t local, uint32_t remote, uint32_t is_blocking)
-{
-	uint32_t status;
-
-	mmio_write_32(IPI_REG_BASE(local) + IPI_TRIG_OFFSET,
-		      IPI_BIT_MASK(remote));
-	if (is_blocking) {
-		do {
-			status = mmio_read_32(IPI_REG_BASE(local) +
-					      IPI_OBR_OFFSET);
-		} while (status & IPI_BIT_MASK(remote));
-	}
-}
-
-/* ipi_mb_ack() - Ack IPI mailbox notification from the other end
- *
- * @local - local IPI ID
- * @remote - remote IPI ID
- *
- * It will clear the remote bit in the isr register.
- *
- */
-void ipi_mb_ack(uint32_t local, uint32_t remote)
-{
-	mmio_write_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET,
-		      IPI_BIT_MASK(remote));
-}
-
-/* ipi_mb_disable_irq() - Disable IPI mailbox notification interrupt
- *
- * @local - local IPI ID
- * @remote - remote IPI ID
- *
- * It will mask the remote bit in the idr register.
- *
- */
-void ipi_mb_disable_irq(uint32_t local, uint32_t remote)
-{
-	mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
-		      IPI_BIT_MASK(remote));
-}
-
-/* ipi_mb_enable_irq() - Enable IPI mailbox notification interrupt
- *
- * @local - local IPI ID
- * @remote - remote IPI ID
- *
- * It will mask the remote bit in the idr register.
+ * zynqmp_ipi_config_table_init() - Initialize ZynqMP IPI configuration data
  *
  */
-void ipi_mb_enable_irq(uint32_t local, uint32_t remote)
+void zynqmp_ipi_config_table_init(void)
 {
-	mmio_write_32(IPI_REG_BASE(local) + IPI_IER_OFFSET,
-		      IPI_BIT_MASK(remote));
+	ipi_config_table_init(zynqmp_ipi_table, ARRAY_SIZE(zynqmp_ipi_table));
 }
diff --git a/readme.rst b/readme.rst
index e7fbfb4..5404e74 100644
--- a/readme.rst
+++ b/readme.rst
@@ -9,7 +9,7 @@
 -  The `Power State Coordination Interface (PSCI)`_
 -  Trusted Board Boot Requirements (TBBR, Arm DEN0006C-1)
 -  `SMC Calling Convention`_
--  `System Control and Management Interface`_
+-  `System Control and Management Interface (SCMI)`_
 -  `Software Delegated Exception Interface (SDEI)`_
 
 Where possible, the code is designed for reuse or porting to other Armv7-A and
@@ -58,7 +58,7 @@
 
 This release provides a suitable starting point for productization of secure
 world boot and runtime firmware, in either the AArch32 or AArch64 execution
-state.
+states.
 
 Users are encouraged to do their own security validation, including penetration
 testing, on any secure world code derived from TF-A.
@@ -95,13 +95,13 @@
 -  Secure Monitor library code such as world switching, EL1 context management
    and interrupt routing.
    When a Secure-EL1 Payload (SP) is present, for example a Secure OS, the
-   AArch64 EL3 Runtime Software must be integrated with a dispatcher component
-   (SPD) to customize the interaction with the SP.
+   AArch64 EL3 Runtime Software must be integrated with a Secure Payload
+   Dispatcher (SPD) component to customize the interaction with the SP.
 
--  A Test SP/SPD to demonstrate AArch64 Secure Monitor functionality and SP
+-  A Test SP and SPD to demonstrate AArch64 Secure Monitor functionality and SP
    interaction with PSCI.
 
--  SPDs for the `OP-TEE Secure OS`_, `NVidia Trusted Little Kernel`_
+-  SPDs for the `OP-TEE Secure OS`_, `NVIDIA Trusted Little Kernel`_
    and `Trusty Secure OS`_.
 
 -  A Trusted Board Boot implementation, conforming to all mandatory TBBR
@@ -136,8 +136,8 @@
 
 -  Support for the GCC, LLVM and Arm Compiler 6 toolchains.
 
--  Support combining several libraries into a self-called "romlib" image, that
-   may be shared across images to reduce memory footprint. The romlib image
+-  Support for combining several libraries into a self-called "romlib" image
+   that may be shared across images to reduce memory footprint. The romlib image
    is stored in ROM but is accessed through a jump-table that may be stored
    in read-write memory, allowing for the library code to be patched.
 
@@ -148,8 +148,8 @@
 Platforms
 ~~~~~~~~~
 
-Various AArch32 and AArch64 builds of this release has been tested on variants
-r0, r1 and r2 of the `Juno Arm Development Platform`_.
+Various AArch32 and AArch64 builds of this release have been tested on r0, r1
+and r2 variants of the `Juno Arm Development Platform`_.
 
 Various AArch64 builds of this release have been tested on the following Arm
 Fixed Virtual Platforms (`FVP`_) without shifted affinities that do not
@@ -194,19 +194,21 @@
 
 -  Allwinner sun50i_64 and sun50i_h6
 -  Amlogic Meson S905 (GXBB)
--  ARM SGI-575 and SGM-775
+-  Arm SGI-575, SGI Clark.A, SGI Clark.H and SGM-775
+-  Arm NeoVerse N1 System Development Platform
 -  HiKey, HiKey960 and Poplar boards
--  Marvell Armada 8K
+-  Marvell Armada 3700 and 8K
 -  MediaTek MT6795 and MT8173 SoCs
--  NVidia T132, T186 and T210 SoCs
--  NXP QorIQ LS1043A, i.MX8QX, i.MX8QM and i.MX7Solo WaRP7
--  QEMU emulator
--  Raspberry Pi 3 board
+-  NVIDIA T132, T186 and T210 SoCs
+-  NXP QorIQ LS1043A, i.MX8MQ, i.MX8QX, i.MX8QM and i.MX7Solo WaRP7
+-  QEMU
+-  Raspberry Pi 3
+-  R-Car Generation 3
 -  RockChip RK3328, RK3368 and RK3399 SoCs
 -  Socionext UniPhier SoC family and SynQuacer SC2A11 SoCs
 -  STMicroelectronics STM32MP1
 -  Texas Instruments K3 SoCs
--  Xilinx Zynq UltraScale + MPSoC
+-  Xilinx Versal and Zynq UltraScale + MPSoC
 
 Still to come
 ~~~~~~~~~~~~~
@@ -229,10 +231,10 @@
 
 Get the TF-A source code from `GitHub`_.
 
-See the `User Guide`_ for instructions on how to install, build and use
-the TF-A with the Arm `FVP`_\ s.
+See the `User Guide`_ for instructions on how to install, build and use TF-A
+with the Arm `FVP`_\ s.
 
-See the `Firmware Design`_ for information on how the TF-A works.
+See the `Firmware Design`_ for information on how TF-A works.
 
 See the `Porting Guide`_ as well for information about how to use this
 software on another Armv7-A or Armv8-A platform.
@@ -260,14 +262,14 @@
 
 --------------
 
-*Copyright (c) 2013-2018, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.*
 
 .. _Armv7-A and Armv8-A: https://developer.arm.com/products/architecture/a-profile
 .. _Secure Monitor: http://www.arm.com/products/processors/technologies/trustzone/tee-smc.php
 .. _Power State Coordination Interface (PSCI): PSCI_
 .. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
 .. _SMC Calling Convention: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf
-.. _System Control and Management Interface: SCMI_
+.. _System Control and Management Interface (SCMI): SCMI_
 .. _SCMI: http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/DEN0056A_System_Control_and_Management_Interface.pdf
 .. _Software Delegated Exception Interface (SDEI): SDEI_
 .. _SDEI: http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf
@@ -276,7 +278,7 @@
 .. _FVP: https://developer.arm.com/products/system-design/fixed-virtual-platforms
 .. _Linaro Release 18.04: https://community.arm.com/dev-platforms/b/documents/posts/linaro-release-notes-deprecated#LinaroRelease18.04
 .. _OP-TEE Secure OS: https://github.com/OP-TEE/optee_os
-.. _NVidia Trusted Little Kernel: http://nv-tegra.nvidia.com/gitweb/?p=3rdparty/ote_partner/tlk.git;a=summary
+.. _NVIDIA Trusted Little Kernel: http://nv-tegra.nvidia.com/gitweb/?p=3rdparty/ote_partner/tlk.git;a=summary
 .. _Trusty Secure OS: https://source.android.com/security/trusty
 .. _GitHub: https://www.github.com/ARM-software/arm-trusted-firmware
 .. _GitHub issue tracker: https://github.com/ARM-software/tf-issues/issues
diff --git a/services/spd/opteed/teesmc_opteed.h b/services/spd/opteed/teesmc_opteed.h
index 71b8d71..ec821ba 100644
--- a/services/spd/opteed/teesmc_opteed.h
+++ b/services/spd/opteed/teesmc_opteed.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
  */
@@ -10,13 +10,13 @@
 #define TEESMC_OPTEED_H
 
 /*
- * This file specify SMC function IDs used when returning from TEE to the
+ * This file specifies SMC function IDs used when returning from TEE to the
  * secure monitor.
  *
  * All SMC Function IDs indicates SMC32 Calling Convention but will carry
  * full 64 bit values in the argument registers if invoked from Aarch64
  * mode. This violates the SMC Calling Convention, but since this
- * convention only coveres API towards Normwal World it's something that
+ * convention only coveres API towards Normal World it's something that
  * only concerns the OP-TEE Dispatcher in ARM Trusted Firmware and OP-TEE
  * OS at Secure EL1.
  */
diff --git a/services/spd/tlkd/tlkd_main.c b/services/spd/tlkd/tlkd_main.c
index ffe3319..b1a0477 100644
--- a/services/spd/tlkd/tlkd_main.c
+++ b/services/spd/tlkd/tlkd_main.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
  */
@@ -341,7 +341,7 @@
 
 		/*
 		 * SP has been successfully initialized. Register power
-		 * managemnt hooks with PSCI
+		 * management hooks with PSCI
 		 */
 		psci_register_spd_pm_hook(&tlkd_pm_ops);
 
diff --git a/services/spd/trusty/smcall.h b/services/spd/trusty/smcall.h
index 742c8c4..9c1c38c 100644
--- a/services/spd/trusty/smcall.h
+++ b/services/spd/trusty/smcall.h
@@ -7,69 +7,68 @@
 #ifndef SMCALL_H
 #define SMCALL_H
 
-#define SMC_NUM_ENTITIES	64
-#define SMC_NUM_ARGS		4
-#define SMC_NUM_PARAMS		(SMC_NUM_ARGS - 1)
+#define SMC_NUM_ENTITIES	64U
+#define SMC_NUM_ARGS		4U
+#define SMC_NUM_PARAMS		(SMC_NUM_ARGS - 1U)
 
-#define SMC_IS_FASTCALL(smc_nr)	((smc_nr) & 0x80000000)
-#define SMC_IS_SMC64(smc_nr)	((smc_nr) & 0x40000000)
-#define SMC_ENTITY(smc_nr)	(((smc_nr) & 0x3F000000) >> 24)
-#define SMC_FUNCTION(smc_nr)	((smc_nr) & 0x0000FFFF)
+#define SMC_IS_FASTCALL(smc_nr)	((smc_nr) & 0x80000000U)
+#define SMC_IS_SMC64(smc_nr)	((smc_nr) & 0x40000000U)
+#define SMC_ENTITY(smc_nr)	(((smc_nr) & 0x3F000000U) >> 24U)
+#define SMC_FUNCTION(smc_nr)	((smc_nr) & 0x0000FFFFU)
 
 #define SMC_NR(entity, fn, fastcall, smc64)			\
-		(((((unsigned int) (fastcall)) & 0x1) << 31) |	\
-		(((smc64) & 0x1) << 30) |			\
-		(((entity) & 0x3F) << 24) |			\
-		((fn) & 0xFFFF)					\
-		)
+		(((((uint32_t)(fastcall)) & 0x1U) << 31U) |	\
+		(((smc64) & 0x1U) << 30U) |			\
+		(((entity) & 0x3FU) << 24U) |			\
+		((fn) & 0xFFFFU))
 
-#define SMC_FASTCALL_NR(entity, fn)	SMC_NR((entity), (fn), 1, 0)
-#define SMC_FASTCALL64_NR(entity, fn)	SMC_NR((entity), (fn), 1, 1)
-#define SMC_YIELDCALL_NR(entity, fn)	SMC_NR((entity), (fn), 0, 0)
-#define SMC_YIELDCALL64_NR(entity, fn)	SMC_NR((entity), (fn), 0, 1)
+#define SMC_FASTCALL_NR(entity, fn)	SMC_NR((entity), (fn), 1U, 0U)
+#define SMC_FASTCALL64_NR(entity, fn)	SMC_NR((entity), (fn), 1U, 1U)
+#define SMC_YIELDCALL_NR(entity, fn)	SMC_NR((entity), (fn), 0U, 0U)
+#define SMC_YIELDCALL64_NR(entity, fn)	SMC_NR((entity), (fn), 0U, 1U)
 
-#define	SMC_ENTITY_ARCH			0	/* ARM Architecture calls */
-#define	SMC_ENTITY_CPU			1	/* CPU Service calls */
-#define	SMC_ENTITY_SIP			2	/* SIP Service calls */
-#define	SMC_ENTITY_OEM			3	/* OEM Service calls */
-#define	SMC_ENTITY_STD			4	/* Standard Service calls */
-#define	SMC_ENTITY_RESERVED		5	/* Reserved for future use */
-#define	SMC_ENTITY_TRUSTED_APP		48	/* Trusted Application calls */
-#define	SMC_ENTITY_TRUSTED_OS		50	/* Trusted OS calls */
-#define SMC_ENTITY_LOGGING              51	/* Used for secure -> nonsecure logging */
-#define	SMC_ENTITY_SECURE_MONITOR	60	/* Trusted OS calls internal to secure monitor */
+#define	SMC_ENTITY_ARCH			0U	/* ARM Architecture calls */
+#define	SMC_ENTITY_CPU			1U	/* CPU Service calls */
+#define	SMC_ENTITY_SIP			2U	/* SIP Service calls */
+#define	SMC_ENTITY_OEM			3U	/* OEM Service calls */
+#define	SMC_ENTITY_STD			4U	/* Standard Service calls */
+#define	SMC_ENTITY_RESERVED		5U	/* Reserved for future use */
+#define	SMC_ENTITY_TRUSTED_APP		48U	/* Trusted Application calls */
+#define	SMC_ENTITY_TRUSTED_OS		50U	/* Trusted OS calls */
+#define SMC_ENTITY_LOGGING              51U	/* Used for secure -> nonsecure logging */
+#define	SMC_ENTITY_SECURE_MONITOR	60U	/* Trusted OS calls internal to secure monitor */
 
 /* FC = Fast call, YC = Yielding call */
-#define SMC_YC_RESTART_LAST	SMC_YIELDCALL_NR  (SMC_ENTITY_SECURE_MONITOR, 0)
-#define SMC_YC_NOP		SMC_YIELDCALL_NR  (SMC_ENTITY_SECURE_MONITOR, 1)
+#define SMC_YC_RESTART_LAST	SMC_YIELDCALL_NR  (SMC_ENTITY_SECURE_MONITOR, 0U)
+#define SMC_YC_NOP		SMC_YIELDCALL_NR  (SMC_ENTITY_SECURE_MONITOR, 1U)
 
 /*
  * Return from secure os to non-secure os with return value in r1
  */
-#define SMC_YC_NS_RETURN	SMC_YIELDCALL_NR  (SMC_ENTITY_SECURE_MONITOR, 0)
+#define SMC_YC_NS_RETURN	SMC_YIELDCALL_NR  (SMC_ENTITY_SECURE_MONITOR, 0U)
 
-#define SMC_FC_RESERVED		SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 0)
-#define SMC_FC_FIQ_EXIT		SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 1)
-#define SMC_FC_REQUEST_FIQ	SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 2)
-#define SMC_FC_GET_NEXT_IRQ	SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 3)
-#define SMC_FC_FIQ_ENTER	SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 4)
+#define SMC_FC_RESERVED		SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 0U)
+#define SMC_FC_FIQ_EXIT		SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 1U)
+#define SMC_FC_REQUEST_FIQ	SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 2U)
+#define SMC_FC_GET_NEXT_IRQ	SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 3U)
+#define SMC_FC_FIQ_ENTER	SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 4U)
 
-#define SMC_FC64_SET_FIQ_HANDLER SMC_FASTCALL64_NR(SMC_ENTITY_SECURE_MONITOR, 5)
-#define SMC_FC64_GET_FIQ_REGS	SMC_FASTCALL64_NR (SMC_ENTITY_SECURE_MONITOR, 6)
+#define SMC_FC64_SET_FIQ_HANDLER SMC_FASTCALL64_NR(SMC_ENTITY_SECURE_MONITOR, 5U)
+#define SMC_FC64_GET_FIQ_REGS	SMC_FASTCALL64_NR (SMC_ENTITY_SECURE_MONITOR, 6U)
 
-#define SMC_FC_CPU_SUSPEND	SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 7)
-#define SMC_FC_CPU_RESUME	SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 8)
+#define SMC_FC_CPU_SUSPEND	SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 7U)
+#define SMC_FC_CPU_RESUME	SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 8U)
 
-#define SMC_FC_AARCH_SWITCH	SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 9)
-#define SMC_FC_GET_VERSION_STR	SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 10)
+#define SMC_FC_AARCH_SWITCH	SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 9U)
+#define SMC_FC_GET_VERSION_STR	SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 10U)
 
 /* Trusted OS entity calls */
-#define SMC_YC_VIRTIO_GET_DESCR	  SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 20)
-#define SMC_YC_VIRTIO_START	  SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 21)
-#define SMC_YC_VIRTIO_STOP	  SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 22)
+#define SMC_YC_VIRTIO_GET_DESCR	  SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 20U)
+#define SMC_YC_VIRTIO_START	  SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 21U)
+#define SMC_YC_VIRTIO_STOP	  SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 22U)
 
-#define SMC_YC_VDEV_RESET	  SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 23)
-#define SMC_YC_VDEV_KICK_VQ	  SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 24)
-#define SMC_YC_SET_ROT_PARAMS	  SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 65535)
+#define SMC_YC_VDEV_RESET	  SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 23U)
+#define SMC_YC_VDEV_KICK_VQ	  SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 24U)
+#define SMC_YC_SET_ROT_PARAMS	  SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 65535U)
 
 #endif /* SMCALL_H */
diff --git a/services/spd/trusty/trusty.c b/services/spd/trusty/trusty.c
index b6ebeeb..83c14b4 100644
--- a/services/spd/trusty/trusty.c
+++ b/services/spd/trusty/trusty.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
  */
@@ -21,7 +21,10 @@
 #include "smcall.h"
 
 /* macro to check if Hypervisor is enabled in the HCR_EL2 register */
-#define HYP_ENABLE_FLAG		0x286001
+#define HYP_ENABLE_FLAG		0x286001U
+
+/* length of Trusty's input parameters (in bytes) */
+#define TRUSTY_PARAMS_LEN_BYTES	(4096U * 2)
 
 struct trusty_stack {
 	uint8_t space[PLATFORM_STACK_SIZE] __aligned(16);
@@ -32,7 +35,7 @@
 	cpu_context_t	cpu_ctx;
 	void		*saved_sp;
 	uint32_t	saved_security_state;
-	int		fiq_handler_active;
+	int32_t		fiq_handler_active;
 	uint64_t	fiq_handler_pc;
 	uint64_t	fiq_handler_cpsr;
 	uint64_t	fiq_handler_sp;
@@ -43,7 +46,7 @@
 	struct trusty_stack	secure_stack;
 };
 
-struct args {
+struct smc_args {
 	uint64_t	r0;
 	uint64_t	r1;
 	uint64_t	r2;
@@ -56,8 +59,8 @@
 
 static struct trusty_cpu_ctx trusty_cpu_ctx[PLATFORM_CORE_COUNT];
 
-struct args trusty_init_context_stack(void **sp, void *new_stack);
-struct args trusty_context_switch_helper(void **sp, void *smc_params);
+struct smc_args trusty_init_context_stack(void **sp, void *new_stack);
+struct smc_args trusty_context_switch_helper(void **sp, void *smc_params);
 
 static uint32_t current_vmid;
 
@@ -66,41 +69,41 @@
 	return &trusty_cpu_ctx[plat_my_core_pos()];
 }
 
-static uint32_t is_hypervisor_mode(void)
+static bool is_hypervisor_mode(void)
 {
 	uint64_t hcr = read_hcr();
 
-	return !!(hcr & HYP_ENABLE_FLAG);
+	return ((hcr & HYP_ENABLE_FLAG) != 0U) ? true : false;
 }
 
-static struct args trusty_context_switch(uint32_t security_state, uint64_t r0,
+static struct smc_args trusty_context_switch(uint32_t security_state, uint64_t r0,
 					 uint64_t r1, uint64_t r2, uint64_t r3)
 {
-	struct args ret;
+	struct smc_args args, ret_args;
 	struct trusty_cpu_ctx *ctx = get_trusty_ctx();
 	struct trusty_cpu_ctx *ctx_smc;
 
 	assert(ctx->saved_security_state != security_state);
 
-	ret.r7 = 0;
+	args.r7 = 0;
 	if (is_hypervisor_mode()) {
 		/* According to the ARM DEN0028A spec, VMID is stored in x7 */
 		ctx_smc = cm_get_context(NON_SECURE);
-		assert(ctx_smc);
-		ret.r7 = SMC_GET_GP(ctx_smc, CTX_GPREG_X7);
+		assert(ctx_smc != NULL);
+		args.r7 = SMC_GET_GP(ctx_smc, CTX_GPREG_X7);
 	}
 	/* r4, r5, r6 reserved for future use. */
-	ret.r6 = 0;
-	ret.r5 = 0;
-	ret.r4 = 0;
-	ret.r3 = r3;
-	ret.r2 = r2;
-	ret.r1 = r1;
-	ret.r0 = r0;
+	args.r6 = 0;
+	args.r5 = 0;
+	args.r4 = 0;
+	args.r3 = r3;
+	args.r2 = r2;
+	args.r1 = r1;
+	args.r0 = r0;
 
 	/*
 	 * To avoid the additional overhead in PSCI flow, skip FP context
-	 * saving/restoring in case of CPU suspend and resume, asssuming that
+	 * saving/restoring in case of CPU suspend and resume, assuming that
 	 * when it's needed the PSCI caller has preserved FP context before
 	 * going here.
 	 */
@@ -109,9 +112,9 @@
 	cm_el1_sysregs_context_save(security_state);
 
 	ctx->saved_security_state = security_state;
-	ret = trusty_context_switch_helper(&ctx->saved_sp, &ret);
+	ret_args = trusty_context_switch_helper(&ctx->saved_sp, &args);
 
-	assert(ctx->saved_security_state == !security_state);
+	assert(ctx->saved_security_state == ((security_state == 0U) ? 1U : 0U));
 
 	cm_el1_sysregs_context_restore(security_state);
 	if (r0 != SMC_FC_CPU_SUSPEND && r0 != SMC_FC_CPU_RESUME)
@@ -119,7 +122,7 @@
 
 	cm_set_next_eret_context(security_state);
 
-	return ret;
+	return ret_args;
 }
 
 static uint64_t trusty_fiq_handler(uint32_t id,
@@ -127,29 +130,29 @@
 				   void *handle,
 				   void *cookie)
 {
-	struct args ret;
+	struct smc_args ret;
 	struct trusty_cpu_ctx *ctx = get_trusty_ctx();
 
 	assert(!is_caller_secure(flags));
 
 	ret = trusty_context_switch(NON_SECURE, SMC_FC_FIQ_ENTER, 0, 0, 0);
-	if (ret.r0) {
+	if (ret.r0 != 0U) {
 		SMC_RET0(handle);
 	}
 
-	if (ctx->fiq_handler_active) {
+	if (ctx->fiq_handler_active != 0) {
 		INFO("%s: fiq handler already active\n", __func__);
 		SMC_RET0(handle);
 	}
 
 	ctx->fiq_handler_active = 1;
-	memcpy(&ctx->fiq_gpregs, get_gpregs_ctx(handle), sizeof(ctx->fiq_gpregs));
+	(void)memcpy(&ctx->fiq_gpregs, get_gpregs_ctx(handle), sizeof(ctx->fiq_gpregs));
 	ctx->fiq_pc = SMC_GET_EL3(handle, CTX_ELR_EL3);
 	ctx->fiq_cpsr = SMC_GET_EL3(handle, CTX_SPSR_EL3);
 	ctx->fiq_sp_el1 = read_ctx_reg(get_sysregs_ctx(handle), CTX_SP_EL1);
 
 	write_ctx_reg(get_sysregs_ctx(handle), CTX_SP_EL1, ctx->fiq_handler_sp);
-	cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_handler_pc, ctx->fiq_handler_cpsr);
+	cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_handler_pc, (uint32_t)ctx->fiq_handler_cpsr);
 
 	SMC_RET0(handle);
 }
@@ -159,9 +162,9 @@
 {
 	struct trusty_cpu_ctx *ctx;
 
-	if (cpu >= PLATFORM_CORE_COUNT) {
+	if (cpu >= (uint64_t)PLATFORM_CORE_COUNT) {
 		ERROR("%s: cpu %lld >= %d\n", __func__, cpu, PLATFORM_CORE_COUNT);
-		return SM_ERR_INVALID_PARAMETERS;
+		return (uint64_t)SM_ERR_INVALID_PARAMETERS;
 	}
 
 	ctx = &trusty_cpu_ctx[cpu];
@@ -182,16 +185,16 @@
 
 static uint64_t trusty_fiq_exit(void *handle, uint64_t x1, uint64_t x2, uint64_t x3)
 {
-	struct args ret;
+	struct smc_args ret;
 	struct trusty_cpu_ctx *ctx = get_trusty_ctx();
 
-	if (!ctx->fiq_handler_active) {
+	if (ctx->fiq_handler_active == 0) {
 		NOTICE("%s: fiq handler not active\n", __func__);
-		SMC_RET1(handle, SM_ERR_INVALID_PARAMETERS);
+		SMC_RET1(handle, (uint64_t)SM_ERR_INVALID_PARAMETERS);
 	}
 
 	ret = trusty_context_switch(NON_SECURE, SMC_FC_FIQ_EXIT, 0, 0, 0);
-	if (ret.r0 != 1) {
+	if (ret.r0 != 1U) {
 		INFO("%s(%p) SMC_FC_FIQ_EXIT returned unexpected value, %lld\n",
 		       __func__, handle, ret.r0);
 	}
@@ -205,10 +208,10 @@
 	 * x1-x4 and x8-x17 need to be restored here because smc_handler64
 	 * corrupts them (el1 code also restored them).
 	 */
-	memcpy(get_gpregs_ctx(handle), &ctx->fiq_gpregs, sizeof(ctx->fiq_gpregs));
+	(void)memcpy(get_gpregs_ctx(handle), &ctx->fiq_gpregs, sizeof(ctx->fiq_gpregs));
 	ctx->fiq_handler_active = 0;
 	write_ctx_reg(get_sysregs_ctx(handle), CTX_SP_EL1, ctx->fiq_sp_el1);
-	cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_pc, ctx->fiq_cpsr);
+	cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_pc, (uint32_t)ctx->fiq_cpsr);
 
 	SMC_RET0(handle);
 }
@@ -222,8 +225,8 @@
 			 void *handle,
 			 u_register_t flags)
 {
-	struct args ret;
-	uint32_t vmid = 0;
+	struct smc_args ret;
+	uint32_t vmid = 0U;
 	entry_point_info_t *ep_info = bl31_plat_get_next_image_ep_info(SECURE);
 
 	/*
@@ -231,10 +234,12 @@
 	 * Verified Boot is not even supported and returning success here
 	 * would not compromise the boot process.
 	 */
-	if (!ep_info && (smc_fid == SMC_YC_SET_ROT_PARAMS)) {
+	if ((ep_info == NULL) && (smc_fid == SMC_YC_SET_ROT_PARAMS)) {
 		SMC_RET1(handle, 0);
-	} else if (!ep_info) {
+	} else if (ep_info == NULL) {
 		SMC_RET1(handle, SMC_UNK);
+	} else {
+		; /* do nothing */
 	}
 
 	if (is_caller_secure(flags)) {
@@ -279,12 +284,11 @@
 
 static int32_t trusty_init(void)
 {
-	void el3_exit(void);
 	entry_point_info_t *ep_info;
-	struct args zero_args = {0};
+	struct smc_args zero_args = {0};
 	struct trusty_cpu_ctx *ctx = get_trusty_ctx();
 	uint32_t cpu = plat_my_core_pos();
-	int reg_width = GET_RW(read_ctx_reg(get_el3state_ctx(&ctx->cpu_ctx),
+	uint64_t reg_width = GET_RW(read_ctx_reg(get_el3state_ctx(&ctx->cpu_ctx),
 			       CTX_SPSR_EL3));
 
 	/*
@@ -292,7 +296,7 @@
 	 * failure.
 	 */
 	ep_info = bl31_plat_get_next_image_ep_info(SECURE);
-	assert(ep_info);
+	assert(ep_info != NULL);
 
 	fpregs_context_save(get_fpregs_ctx(cm_get_context(NON_SECURE)));
 	cm_el1_sysregs_context_save(NON_SECURE);
@@ -302,9 +306,9 @@
 
 	/*
 	 * Adjust secondary cpu entry point for 32 bit images to the
-	 * end of exeption vectors
+	 * end of exception vectors
 	 */
-	if ((cpu != 0) && (reg_width == MODE_RW_32)) {
+	if ((cpu != 0U) && (reg_width == MODE_RW_32)) {
 		INFO("trusty: cpu %d, adjust entry point to 0x%lx\n",
 		     cpu, ep_info->pc + (1U << 5));
 		cm_set_elr_el3(SECURE, ep_info->pc + (1U << 5));
@@ -314,10 +318,10 @@
 	fpregs_context_restore(get_fpregs_ctx(cm_get_context(SECURE)));
 	cm_set_next_eret_context(SECURE);
 
-	ctx->saved_security_state = ~0; /* initial saved state is invalid */
-	trusty_init_context_stack(&ctx->saved_sp, &ctx->secure_stack.end);
+	ctx->saved_security_state = ~0U; /* initial saved state is invalid */
+	(void)trusty_init_context_stack(&ctx->saved_sp, &ctx->secure_stack.end);
 
-	trusty_context_switch_helper(&ctx->saved_sp, &zero_args);
+	(void)trusty_context_switch_helper(&ctx->saved_sp, &zero_args);
 
 	cm_el1_sysregs_context_restore(NON_SECURE);
 	fpregs_context_restore(get_fpregs_ctx(cm_get_context(NON_SECURE)));
@@ -328,10 +332,10 @@
 
 static void trusty_cpu_suspend(uint32_t off)
 {
-	struct args ret;
+	struct smc_args ret;
 
 	ret = trusty_context_switch(NON_SECURE, SMC_FC_CPU_SUSPEND, off, 0, 0);
-	if (ret.r0 != 0) {
+	if (ret.r0 != 0U) {
 		INFO("%s: cpu %d, SMC_FC_CPU_SUSPEND returned unexpected value, %lld\n",
 		     __func__, plat_my_core_pos(), ret.r0);
 	}
@@ -339,10 +343,10 @@
 
 static void trusty_cpu_resume(uint32_t on)
 {
-	struct args ret;
+	struct smc_args ret;
 
 	ret = trusty_context_switch(NON_SECURE, SMC_FC_CPU_RESUME, on, 0, 0);
-	if (ret.r0 != 0) {
+	if (ret.r0 != 0U) {
 		INFO("%s: cpu %d, SMC_FC_CPU_RESUME returned unexpected value, %lld\n",
 		     __func__, plat_my_core_pos(), ret.r0);
 	}
@@ -359,8 +363,8 @@
 {
 	struct trusty_cpu_ctx *ctx = get_trusty_ctx();
 
-	if (!ctx->saved_sp) {
-		trusty_init();
+	if (ctx->saved_sp == NULL) {
+		(void)trusty_init();
 	} else {
 		trusty_cpu_resume(1);
 	}
@@ -398,12 +402,12 @@
 	entry_point_info_t *ep_info;
 	uint32_t instr;
 	uint32_t flags;
-	int ret;
+	int32_t ret;
 	bool aarch32 = false;
 
 	/* Get trusty's entry point info */
 	ep_info = bl31_plat_get_next_image_ep_info(SECURE);
-	if (!ep_info) {
+	if (ep_info == NULL) {
 		INFO("Trusty image missing.\n");
 		return -1;
 	}
@@ -416,7 +420,8 @@
 	} else if (instr >> 8 == 0xd53810U || instr >> 16 == 0x9400U) {
 		INFO("trusty: Found 64 bit image\n");
 	} else {
-		NOTICE("trusty: Found unknown image, 0x%x\n", instr);
+		ERROR("trusty: Found unknown image, 0x%x\n", instr);
+		return -1;
 	}
 
 	SET_PARAM_HEAD(ep_info, PARAM_EP, VERSION_1, SECURE | EP_ST_ENABLE);
@@ -444,8 +449,9 @@
 	ret = register_interrupt_type_handler(INTR_TYPE_S_EL1,
 					      trusty_fiq_handler,
 					      flags);
-	if (ret)
+	if (ret != 0) {
 		ERROR("trusty: failed to register fiq handler, ret = %d\n", ret);
+	}
 
 	if (aarch32) {
 		entry_point_info_t *ns_ep_info;
diff --git a/services/spd/tspd/tspd_main.c b/services/spd/tspd/tspd_main.c
index d2bd43f..f206724 100644
--- a/services/spd/tspd/tspd_main.c
+++ b/services/spd/tspd/tspd_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
  */
@@ -375,7 +375,7 @@
 
 			/*
 			 * TSP has been successfully initialized. Register power
-			 * managemnt hooks with PSCI
+			 * management hooks with PSCI
 			 */
 			psci_register_spd_pm_hook(&tspd_pm);
 
diff --git a/services/std_svc/sdei/sdei_private.h b/services/std_svc/sdei/sdei_private.h
index b945394..1486431 100644
--- a/services/std_svc/sdei/sdei_private.h
+++ b/services/std_svc/sdei/sdei_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
  */
@@ -54,7 +54,7 @@
 /*
  * 'info' parameter to SDEI_EVENT_GET_INFO SMC.
  *
- * Note that the SDEI v1.0 speification mistakenly enumerates the
+ * Note that the SDEI v1.0 specification mistakenly enumerates the
  * SDEI_INFO_EV_SIGNALED as SDEI_INFO_SIGNALED. This will be corrected in a
  * future version.
  */
diff --git a/services/std_svc/spm_deprecated/aarch64/spm_helpers.S b/services/std_svc/spm_mm/aarch64/spm_helpers.S
similarity index 100%
rename from services/std_svc/spm_deprecated/aarch64/spm_helpers.S
rename to services/std_svc/spm_mm/aarch64/spm_helpers.S
diff --git a/services/std_svc/spm_deprecated/aarch64/spm_shim_exceptions.S b/services/std_svc/spm_mm/aarch64/spm_shim_exceptions.S
similarity index 100%
rename from services/std_svc/spm_deprecated/aarch64/spm_shim_exceptions.S
rename to services/std_svc/spm_mm/aarch64/spm_shim_exceptions.S
diff --git a/services/std_svc/spm_deprecated/spm.mk b/services/std_svc/spm_mm/spm.mk
similarity index 76%
rename from services/std_svc/spm_deprecated/spm.mk
rename to services/std_svc/spm_mm/spm.mk
index ed36812..3aa10ee 100644
--- a/services/std_svc/spm_deprecated/spm.mk
+++ b/services/std_svc/spm_mm/spm.mk
@@ -11,7 +11,7 @@
         $(error "Error: SPM is only supported on aarch64.")
 endif
 
-SPM_SOURCES	:=	$(addprefix services/std_svc/spm_deprecated/, \
+SPM_SOURCES	:=	$(addprefix services/std_svc/spm_mm/,	\
 			${ARCH}/spm_helpers.S			\
 			${ARCH}/spm_shim_exceptions.S		\
 			spm_main.c				\
@@ -21,3 +21,6 @@
 
 # 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_deprecated/spm_main.c b/services/std_svc/spm_mm/spm_main.c
similarity index 99%
rename from services/std_svc/spm_deprecated/spm_main.c
rename to services/std_svc/spm_mm/spm_main.c
index 540f257..7525763 100644
--- a/services/std_svc/spm_deprecated/spm_main.c
+++ b/services/std_svc/spm_mm/spm_main.c
@@ -151,7 +151,7 @@
 
 	INFO("Secure Partition initialized.\n");
 
-	return rc;
+	return !rc;
 }
 
 /*******************************************************************************
diff --git a/services/std_svc/spm_deprecated/spm_private.h b/services/std_svc/spm_mm/spm_private.h
similarity index 100%
rename from services/std_svc/spm_deprecated/spm_private.h
rename to services/std_svc/spm_mm/spm_private.h
diff --git a/services/std_svc/spm_deprecated/spm_setup.c b/services/std_svc/spm_mm/spm_setup.c
similarity index 94%
rename from services/std_svc/spm_deprecated/spm_setup.c
rename to services/std_svc/spm_mm/spm_setup.c
index d458f4a..aae6cd5 100644
--- a/services/std_svc/spm_deprecated/spm_setup.c
+++ b/services/std_svc/spm_mm/spm_setup.c
@@ -84,10 +84,10 @@
 	unsigned int max_granule_mask = max_granule - 1U;
 
 	/* Base must be aligned to the max granularity */
-	assert((ARM_SP_IMAGE_NS_BUF_BASE & max_granule_mask) == 0);
+	assert((PLAT_SP_IMAGE_NS_BUF_BASE & max_granule_mask) == 0);
 
 	/* Size must be a multiple of the max granularity */
-	assert((ARM_SP_IMAGE_NS_BUF_SIZE & max_granule_mask) == 0);
+	assert((PLAT_SP_IMAGE_NS_BUF_SIZE & max_granule_mask) == 0);
 
 #endif /* ENABLE_ASSERTIONS */
 
@@ -144,8 +144,6 @@
 		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
 	;
@@ -153,6 +151,11 @@
 	sctlr_el1 &= ~(
 		/* Explicit data accesses at EL0 are little-endian. */
 		SCTLR_E0E_BIT							|
+		/*
+		 * Alignment fault checking disabled when at EL1 and EL0 as
+		 * the UEFI spec permits unaligned accesses.
+		 */
+		SCTLR_A_BIT							|
 		/* Accesses to DAIF from EL0 are trapped to EL1. */
 		SCTLR_UMA_BIT
 	);
@@ -168,6 +171,9 @@
 	write_ctx_reg(get_sysregs_ctx(ctx), CTX_VBAR_EL1,
 			SPM_SHIM_EXCEPTIONS_PTR);
 
+	write_ctx_reg(get_sysregs_ctx(ctx), CTX_CNTKCTL_EL1,
+		      EL0PTEN_BIT | EL0VTEN_BIT | EL0PCTEN_BIT | EL0VCTEN_BIT);
+
 	/*
 	 * FPEN: Allow the Secure Partition to access FP/SIMD registers.
 	 * Note that SPM will not do any saving/restoring of these registers on
diff --git a/services/std_svc/spm_deprecated/spm_shim_private.h b/services/std_svc/spm_mm/spm_shim_private.h
similarity index 100%
rename from services/std_svc/spm_deprecated/spm_shim_private.h
rename to services/std_svc/spm_mm/spm_shim_private.h
diff --git a/services/std_svc/spm_deprecated/spm_xlat.c b/services/std_svc/spm_mm/spm_xlat.c
similarity index 100%
rename from services/std_svc/spm_deprecated/spm_xlat.c
rename to services/std_svc/spm_mm/spm_xlat.c
diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c
index 7a34655..1d80fa3 100644
--- a/services/std_svc/std_svc_setup.c
+++ b/services/std_svc/std_svc_setup.c
@@ -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
  */
@@ -103,7 +103,7 @@
 		SMC_RET1(handle, ret);
 	}
 
-#if ENABLE_SPM && SPM_DEPRECATED
+#if ENABLE_SPM && SPM_MM
 	/*
 	 * Dispatch SPM calls to SPM SMC handler and return its return
 	 * value
diff --git a/tools/fiptool/fiptool.c b/tools/fiptool/fiptool.c
index 0d4f929..80b498e 100644
--- a/tools/fiptool/fiptool.c
+++ b/tools/fiptool/fiptool.c
@@ -271,10 +271,10 @@
 	    &u->node[2], &u->node[3],
 	    &u->node[4], &u->node[5]);
 	/*
-	 * Given the format specifier above, we expect 11 items to be scanned
+	 * Given the format specifier above, we expect 16 items to be scanned
 	 * for a properly formatted UUID.
 	 */
-	if (n != 11)
+	if (n != 16)
 		log_errx("Invalid UUID: %s", s);
 }