Merge pull request #1766 from Anson-Huang/master

Add more SIP runtime service for i.MX8
diff --git a/Makefile b/Makefile
index 3de7b3f..ad1ba15 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
 #
@@ -584,7 +584,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 +612,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 +666,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/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/docs/plat/nvidia-tegra.rst b/docs/plat/nvidia-tegra.rst
index e244c1c..90d2ae1 100644
--- a/docs/plat/nvidia-tegra.rst
+++ b/docs/plat/nvidia-tegra.rst
@@ -82,6 +82,8 @@
 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/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/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/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index d3f0df7..4e459bb 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -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)
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/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/plat/arm/common/arm_spm_def.h b/include/plat/arm/common/arm_spm_def.h
index 997e156..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
  */
@@ -32,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
@@ -121,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 d1c03be..b5edc74 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},					\
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/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/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index 4da807a..fdf82f4 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
  */
@@ -95,10 +95,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
@@ -126,16 +126,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,				\
@@ -189,7 +189,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.
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 31f06a9..8c0daf1 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
  */
@@ -13,7 +13,7 @@
 #  define PLAT_XLAT_TABLES_DYNAMIC     1
 # endif
 #else
-# if defined(IMAGE_BL31) && (RESET_TO_BL31 || (ENABLE_SPM && !SPM_DEPRECATED))
+# if defined(IMAGE_BL31) && (RESET_TO_BL31 || (ENABLE_SPM && !SPM_MM))
 #  define PLAT_XLAT_TABLES_DYNAMIC     1
 # endif
 #endif /* AARCH32 */
@@ -125,7 +125,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)
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index a8ac286..9ad7bd7 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
 #
@@ -240,7 +240,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		\
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/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/platform.mk b/plat/imx/imx8qm/platform.mk
index 9113d33..ed6108d 100644
--- a/plat/imx/imx8qm/platform.mk
+++ b/plat/imx/imx8qm/platform.mk
@@ -38,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/nvidia/tegra/common/aarch64/tegra_helpers.S b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
index 2bf9a22..b47be6d 100644
--- a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
+++ b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
@@ -18,16 +18,21 @@
 /*******************************************************************************
  * 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
@@ -87,8 +92,17 @@
 	 * 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
 
@@ -130,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
 
@@ -162,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
 
@@ -400,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
 	 * --------------------------------------------------
diff --git a/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c b/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c
index 96e3667..1c5d2e1 100644
--- a/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c
+++ b/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c
@@ -16,7 +16,7 @@
 #include <string.h>
 #include <tegra_def.h>
 
-#define BPMP_TIMEOUT_10US	10
+#define BPMP_TIMEOUT	2
 
 static uint32_t channel_base[NR_CHANNELS];
 static uint32_t bpmp_init_state = BPMP_INIT_PENDING;
@@ -58,15 +58,15 @@
 	if (bpmp_init_state == BPMP_INIT_COMPLETE) {
 
 		/* loop until BPMP is free */
-		for (timeout = 0; timeout < BPMP_TIMEOUT_10US; timeout++) {
+		for (timeout = 0; timeout < BPMP_TIMEOUT; timeout++) {
 			if (master_free(ch) == true) {
 				break;
 			}
 
-			udelay(1);
+			mdelay(1);
 		}
 
-		if (timeout != BPMP_TIMEOUT_10US) {
+		if (timeout != BPMP_TIMEOUT) {
 
 			/* generate the command struct */
 			p->code = mrq;
@@ -76,18 +76,18 @@
 			/* signal command ready to the BPMP */
 			signal_slave(ch);
 			mmio_write_32(TEGRA_PRI_ICTLR_BASE + CPU_IEP_FIR_SET,
-				      (1UL << INT_SHR_SEM_OUTBOX_FULL));
+				      (1U << INT_SHR_SEM_OUTBOX_FULL));
 
 			/* loop until the command is executed */
-			for (timeout = 0; timeout < BPMP_TIMEOUT_10US; timeout++) {
+			for (timeout = 0; timeout < BPMP_TIMEOUT; timeout++) {
 				if (master_acked(ch) == true) {
 					break;
 				}
 
-				udelay(1);
+				mdelay(1);
 			}
 
-			if (timeout != BPMP_TIMEOUT_10US) {
+			if (timeout != BPMP_TIMEOUT) {
 
 				/* get the command response */
 				(void)memcpy(ib_data, (const void *)p->data,
@@ -106,8 +106,8 @@
 		ret = -EINVAL;
 	}
 
-	if (timeout == BPMP_TIMEOUT_10US) {
-		ERROR("Timed out waiting for bpmp's response");
+	if (timeout == BPMP_TIMEOUT) {
+		ERROR("Timed out waiting for bpmp's response\n");
 	}
 
 	return ret;
@@ -125,7 +125,7 @@
 		val = mmio_read_32(TEGRA_RES_SEMA_BASE + STA_OFFSET);
 		if (val != SIGN_OF_LIFE) {
 			ERROR("BPMP precessor not available\n");
-			ret = -ENOTSUP;
+			return -ENOTSUP;
 		}
 
 		/* check if clock for the atomics block is enabled */
@@ -154,12 +154,11 @@
 			channel_base[ch] = mmio_read_32(base);
 
 			/* increment result register offset */
-			base += 4UL;
+			base += 4U;
 		}
 
 		/* mark state as "initialized" */
-		if (ret == 0)
-			bpmp_init_state = BPMP_INIT_COMPLETE;
+		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));
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 de431b7..a3ef5e1 100644
--- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
+++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
@@ -25,316 +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.
-	 *
-	 * 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
-}
+/*
+ * 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 */
 }
 
 /*
@@ -347,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;
@@ -398,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();
+	}
 }
 
 /*
@@ -409,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,
@@ -445,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.
-	 */
-
-	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.
+	 * Perform platform specific steps.
 	 */
-	mce_update_gsc_tzdram();
+	plat_memctrl_tzdram_setup(phys_base, size_in_bytes);
 }
 
 /*
@@ -494,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);
@@ -525,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);
 
 	/*
@@ -600,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);
 }
 
@@ -658,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);
 		}
 	}
 
@@ -700,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 0806307..908e4f2 100644
--- a/plat/nvidia/tegra/common/tegra_bl31_setup.c
+++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c
@@ -26,6 +26,7 @@
 #include <plat/common/platform.h>
 
 #include <memctrl.h>
+#include <profiler.h>
 #include <tegra_def.h>
 #include <tegra_platform.h>
 #include <tegra_private.h>
@@ -40,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;
@@ -70,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)
 {
@@ -86,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
@@ -93,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;
 }
 
 /*******************************************************************************
@@ -124,6 +132,7 @@
 	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
@@ -131,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;
@@ -153,7 +164,7 @@
 	/*
 	 * 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;
@@ -163,14 +174,15 @@
 	 * 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() == 1U) {
+	if (tegra_platform_is_fpga()) {
 		console_clock = TEGRA_BOOT_UART_CLK_13_MHZ;
 	} else {
 		console_clock = TEGRA_BOOT_UART_CLK_408_MHZ;
@@ -182,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, console_clock,
+		(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;
 
@@ -223,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);
 
@@ -237,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)
@@ -256,6 +299,9 @@
 	if (args->arg4 != 0U) {
 		args->arg2 = args->arg4;
 	}
+
+	/* Profiler Carveout Base */
+	args->arg3 = args->arg5;
 }
 #endif
 
@@ -264,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();
@@ -285,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");
 }
@@ -298,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
@@ -307,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();
 }
 
 /*******************************************************************************
@@ -315,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,
@@ -352,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();
@@ -374,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 9a43f76..cab2e5e 100644
--- a/plat/nvidia/tegra/common/tegra_fiq_glue.c
+++ b/plat/nvidia/tegra/common/tegra_fiq_glue.c
@@ -65,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 72da126..c1e4209 100644
--- a/plat/nvidia/tegra/common/tegra_platform.c
+++ b/plat/nvidia/tegra/common/tegra_platform.c
@@ -15,7 +15,7 @@
  * Tegra platforms
  ******************************************************************************/
 typedef enum tegra_platform {
-	TEGRA_PLATFORM_SILICON = 0,
+	TEGRA_PLATFORM_SILICON = 0U,
 	TEGRA_PLATFORM_QT,
 	TEGRA_PLATFORM_FPGA,
 	TEGRA_PLATFORM_EMULATION,
@@ -83,7 +83,7 @@
 {
 	uint32_t chip_id = ((tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK);
 
-	return (chip_id == (uint32_t)TEGRA_CHIPID_TEGRA13);
+	return (chip_id == TEGRA_CHIPID_TEGRA13);
 }
 
 bool tegra_chipid_is_t186(void)
@@ -97,12 +97,12 @@
 {
 	uint32_t chip_id = (tegra_get_chipid() >> CHIP_ID_SHIFT) & CHIP_ID_MASK;
 
-	return (chip_id == (uint32_t)TEGRA_CHIPID_TEGRA21);
+	return (chip_id == TEGRA_CHIPID_TEGRA21);
 }
 
 bool tegra_chipid_is_t210_b01(void)
 {
-	return (tegra_chipid_is_t210() && (tegra_get_chipid_major() == 0x2UL));
+	return (tegra_chipid_is_t210() && (tegra_get_chipid_major() == 0x2U));
 }
 
 /*
diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c
index ce44983..2805272 100644
--- a/plat/nvidia/tegra/common/tegra_pm.c
+++ b/plat/nvidia/tegra/common/tegra_pm.c
@@ -50,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;
 }
@@ -91,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;
 }
@@ -117,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;
+	}
 }
 
 /*******************************************************************************
@@ -126,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
@@ -138,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);
 }
@@ -149,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);
 }
 
 /*******************************************************************************
@@ -169,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();
@@ -191,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
@@ -222,7 +238,7 @@
  ******************************************************************************/
 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;
 
 	/*
@@ -239,15 +255,15 @@
 		/*
 		 * Reference clock used by the FPGAs is a lot slower.
 		 */
-		if (tegra_platform_is_fpga() == 1U) {
+		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, console_clock,
+		if (tegra_console_base != 0ULL) {
+			(void)console_init(tegra_console_base, console_clock,
 				     TEGRA_CONSOLE_BAUDRATE);
 		}
 
@@ -262,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
@@ -274,7 +290,7 @@
 	/*
 	 * Reset hardware settings.
 	 */
-	tegra_soc_pwr_domain_on_finish(target_state);
+	(void)tegra_soc_pwr_domain_on_finish(target_state);
 }
 
 /*******************************************************************************
@@ -305,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.
@@ -316,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);
 }
@@ -327,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;
 }
 
 /*******************************************************************************
@@ -376,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 e7acece..4955b2f 100644
--- a/plat/nvidia/tegra/common/tegra_sip_calls.c
+++ b/plat/nvidia/tegra/common/tegra_sip_calls.c
@@ -69,7 +69,7 @@
 			    void *handle,
 			    u_register_t flags)
 {
-	uint32_t regval;
+	uint32_t regval, local_x2_32 = (uint32_t)x2;
 	int32_t err;
 
 	/* Check if this is a SoC specific SiP */
@@ -84,14 +84,11 @@
 
 		case TEGRA_SIP_NEW_VIDEOMEM_REGION:
 
-			/* clean up the high bits */
-			x2 = (uint32_t)x2;
-
 			/*
 			 * Check if Video Memory overlaps TZDRAM (contains bl31/bl32)
 			 * or falls outside of the valid DRAM range
 			*/
-			err = bl31_check_ns_address(x1, x2);
+			err = bl31_check_ns_address(x1, local_x2_32);
 			if (err != 0) {
 				SMC_RET1(handle, (uint64_t)err);
 			}
@@ -99,9 +96,9 @@
 			/*
 			 * Check if Video Memory is aligned to 1MB.
 			 */
-			if (((x1 & 0xFFFFFU) != 0U) || ((x2 & 0xFFFFFU) != 0U)) {
+			if (((x1 & 0xFFFFFU) != 0U) || ((local_x2_32 & 0xFFFFFU) != 0U)) {
 				ERROR("Unaligned Video Memory base address!\n");
-				SMC_RET1(handle, -ENOTSUP);
+				SMC_RET1(handle, (uint64_t)-ENOTSUP);
 			}
 
 			/*
@@ -111,13 +108,13 @@
 			 */
 			regval = mmio_read_32(TEGRA_CAR_RESET_BASE +
 					      TEGRA_GPU_RESET_REG_OFFSET);
-			if ((regval & GPU_RESET_BIT) == 0UL) {
+			if ((regval & GPU_RESET_BIT) == 0U) {
 				ERROR("GPU not in reset! Video Memory setup failed\n");
-				SMC_RET1(handle, -ENOTSUP);
+				SMC_RET1(handle, (uint64_t)-ENOTSUP);
 			}
 
 			/* new video memory carveout settings */
-			tegra_memctrl_videomem_setup(x1, (uint32_t)x2);
+			tegra_memctrl_videomem_setup(x1, local_x2_32);
 
 			SMC_RET1(handle, 0);
 
diff --git a/plat/nvidia/tegra/common/tegra_topology.c b/plat/nvidia/tegra/common/tegra_topology.c
index 4f6cf93..14631a7 100644
--- a/plat/nvidia/tegra/common/tegra_topology.c
+++ b/plat/nvidia/tegra/common/tegra_topology.c
@@ -23,10 +23,14 @@
 	u_register_t cluster_id, cpu_id;
 	int32_t result;
 
-	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;
+	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;
 
-	result = (int32_t)cpu_id + ((int32_t)cluster_id * 4);
+	/* 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;
diff --git a/plat/nvidia/tegra/include/drivers/bpmp.h b/plat/nvidia/tegra/include/drivers/bpmp.h
index 27f57df..03da6f6 100644
--- a/plat/nvidia/tegra/include/drivers/bpmp.h
+++ b/plat/nvidia/tegra/include/drivers/bpmp.h
@@ -10,25 +10,25 @@
 #include <stdint.h>
 
 /* macro to enable clock to the Atomics block */
-#define CAR_ENABLE_ATOMICS	(1UL << 16)
+#define CAR_ENABLE_ATOMICS	(1U << 16)
 
 /* command to get the channel base addresses from bpmp */
-#define ATOMIC_CMD_GET		4UL
+#define ATOMIC_CMD_GET		4U
 
 /* Hardware IRQ # used to signal bpmp of an incoming command */
-#define INT_SHR_SEM_OUTBOX_FULL	6UL
+#define INT_SHR_SEM_OUTBOX_FULL	6U
 
 /* macros to decode the bpmp's state */
-#define CH_MASK(ch)		(0x3UL << ((ch) * 2UL))
-#define MA_FREE(ch)		(0x2UL << ((ch) * 2UL))
-#define MA_ACKD(ch)		(0x3UL << ((ch) * 2UL))
+#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		0xAAAAAAAAUL
+#define SIGN_OF_LIFE		0xAAAAAAAAU
 
 /* flags to indicate bpmp driver's state */
-#define BPMP_INIT_COMPLETE	0xBEEFF00DUL
-#define BPMP_INIT_PENDING	0xDEADBEEFUL
+#define BPMP_INIT_COMPLETE	0xBEEFF00DU
+#define BPMP_INIT_PENDING	0xDEADBEEFU
 
 /* requests serviced by the bpmp */
 #define MRQ_PING		0
@@ -64,14 +64,14 @@
 #define TEGRA_PM_SC7		23
 
 /* flag to indicate if entry into a CCx power state is allowed */
-#define BPMP_CCx_ALLOWED	0UL
+#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			(0UL << 0UL)
-#define DO_ACK			(1UL << 0UL)
+#define NO_ACK			(0U << 0U)
+#define DO_ACK			(1U << 0U)
 
 /* size of the command/response data */
 #define MSG_DATA_MAX_SZ		120U
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 ffe5269..f5b0ed4 100644
--- a/plat/nvidia/tegra/include/drivers/memctrl_v2.h
+++ b/plat/nvidia/tegra/include/drivers/memctrl_v2.h
@@ -11,185 +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))
-
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_SO_DEV		(0UL << 4)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_SO_DEV	(1UL << 4)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SO_DEV		(2UL << 4)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_SO_DEV	(3UL << 4)
-
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_NORMAL		(0UL << 8)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_NORMAL	(1UL << 8)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_NORMAL		(2UL << 8)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_NORMAL	(3UL << 8)
-
-#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_ZERO				(0UL << 12)
-#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_CLIENT_AXI_ID		(1UL << 12)
-
-/*******************************************************************************
- * 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
  ******************************************************************************/
@@ -223,12 +48,31 @@
 	int override_client_ns_flag;
 } mc_streamid_security_cfg_t;
 
+#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
+
-#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
+/*******************************************************************************
+ * 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) \
 	{ \
@@ -250,131 +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				0xdd4UL
-#define  MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL			0x20000UL
-#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_UNORDERED		(0UL << 17)
-#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_MASK		(1UL << 17)
-#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_UNORDERED		(0UL << 21)
-#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_MASK		(1UL << 21)
-#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_UNORDERED	(0UL << 29)
-#define  MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_MASK		(1UL << 29)
-
-#define MC_PCFIFO_CLIENT_CONFIG2				0xdd8UL
-#define  MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL			0x20000UL
-#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_UNORDERED	(0UL << 11)
-#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_MASK	(1UL << 11)
-#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_UNORDERED	(0UL << 13)
-#define  MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_MASK		(1UL << 13)
-
-#define MC_PCFIFO_CLIENT_CONFIG3				0xddcUL
-#define  MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL			0UL
-#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_UNORDERED	(0UL << 7)
-#define  MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_MASK		(1UL << 7)
-
-#define MC_PCFIFO_CLIENT_CONFIG4				0xde0UL
-#define  MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL			0UL
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_UNORDERED	(0UL << 1)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_MASK		(1UL << 1)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_UNORDERED		(0UL << 5)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_MASK		(1UL << 5)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_UNORDERED	(0UL << 13)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_MASK		(1UL << 13)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_UNORDERED	(0UL << 15)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_ORDERED		(1UL << 15)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_MASK		(1UL << 15)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_UNORDERED	(0UL << 17)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_MASK		(1UL << 17)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_UNORDERED	(0UL << 22)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_MASK		(1UL << 22)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_UNORDERED	(0UL << 26)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_MASK		(1UL << 26)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_UNORDERED	(0UL << 30)
-#define  MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_MASK		(1UL << 30)
-
-#define MC_PCFIFO_CLIENT_CONFIG5				0xbf4UL
-#define  MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL			0UL
-#define  MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_UNORDERED	(0UL << 0)
-#define  MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_MASK		(1UL << 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);
@@ -396,7 +119,7 @@
 }
 
 #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_pcfifo_ordered_boot_so_mss(id, client) \
@@ -406,8 +129,24 @@
 	{ \
 		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_tsa_w_passthrough(client) \
+	{ \
+		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_tsa_r_passthrough(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_txn_override(client, normal_axi_id, so_dev_axi_id, normal_override, so_dev_override) \
@@ -426,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
index abfb217..4ab2f9a 100644
--- a/plat/nvidia/tegra/include/drivers/security_engine.h
+++ b/plat/nvidia/tegra/include/drivers/security_engine.h
@@ -38,8 +38,16 @@
 	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
  ******************************************************************************/
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/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 8d71cae..75919e1 100644
--- a/plat/nvidia/tegra/include/t210/tegra_def.h
+++ b/plat/nvidia/tegra/include/t210/tegra_def.h
@@ -89,6 +89,16 @@
 #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
  ******************************************************************************/
@@ -125,6 +135,16 @@
 #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)
@@ -143,6 +163,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)
@@ -153,6 +176,10 @@
 #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
  ******************************************************************************/
@@ -168,4 +195,10 @@
 #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 1e7ba16..13c92e0 100644
--- a/plat/nvidia/tegra/include/tegra_platform.h
+++ b/plat/nvidia/tegra/include/tegra_platform.h
@@ -46,7 +46,6 @@
 bool tegra_chipid_is_t210(void);
 bool tegra_chipid_is_t210_b01(void);
 
-
 /*
  * Tegra platform identifiers
  */
diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h
index 1682927..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,9 +41,11 @@
 	/* TZ memory base */
 	uint64_t tzdram_base;
 	/* UART port ID */
-	int uart_id;
+	int32_t uart_id;
 	/* L2 ECC parity protection disable flag */
-	int l2_ecc_parity_prot_dis;
+	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;
 
 /*******************************************************************************
@@ -63,6 +75,8 @@
 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);
@@ -82,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);
@@ -90,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);
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/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 599e46e..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;
 
@@ -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;
@@ -191,7 +191,7 @@
 	}
 
 	/* set the updated cstate info */
-	return ari_request_wait(ari_base, 0U, TEGRA_ARI_UPDATE_CSTATE_INFO,
+	return ari_request_wait(ari_base, 0U, (uint32_t)TEGRA_ARI_UPDATE_CSTATE_INFO,
 				(uint32_t)val, wake_mask);
 }
 
@@ -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;
@@ -307,8 +308,8 @@
 		/* 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;
@@ -346,7 +347,8 @@
 		} 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);
 		}
 	}
 
@@ -374,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)
@@ -386,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;
 }
@@ -396,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)
@@ -405,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)
@@ -414,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)
@@ -432,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) {
@@ -473,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;
@@ -487,7 +492,8 @@
 	/*
 	 * 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,
@@ -497,7 +503,7 @@
 	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);
@@ -514,8 +520,8 @@
 		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 {
@@ -527,7 +533,7 @@
 			 * 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);
 			}
@@ -552,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 e948e99..9e42b2b 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
@@ -170,12 +170,12 @@
 	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);
 
 		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
@@ -194,12 +194,12 @@
 
 		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);
 
 		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 */
@@ -208,12 +208,12 @@
 
 		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);
 
 		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);
 
 		/* update context to return CCx status value */
@@ -221,7 +221,7 @@
 
 		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);
 
 		/* update context to return SC7 status value */
@@ -230,17 +230,17 @@
 
 		break;
 
-	case MCE_CMD_ONLINE_CORE:
+	case (uint64_t)MCE_CMD_ONLINE_CORE:
 		ret = ops->online_core(cpu_ari_base, arg0);
 
 		break;
 
-	case MCE_CMD_CC3_CTRL:
+	case (uint64_t)MCE_CMD_CC3_CTRL:
 		ret = ops->cc3_ctrl(cpu_ari_base, arg0, arg1, arg2);
 
 		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);
 
@@ -252,7 +252,7 @@
 
 		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);
 
@@ -265,7 +265,7 @@
 
 		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);
 
@@ -274,22 +274,22 @@
 
 		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);
 
 		break;
 
-	case MCE_CMD_ROC_FLUSH_CACHE:
+	case (uint64_t)MCE_CMD_ROC_FLUSH_CACHE:
 		ret = ops->roc_flush_cache(cpu_ari_base);
 
 		break;
 
-	case MCE_CMD_ROC_CLEAN_CACHE:
+	case (uint64_t)MCE_CMD_ROC_CLEAN_CACHE:
 		ret = ops->roc_clean_cache(cpu_ari_base);
 
 		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 */
@@ -299,7 +299,7 @@
 
 		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 */
@@ -309,7 +309,7 @@
 		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
@@ -327,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, 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 44ee8fb..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;
@@ -219,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));
 		}
 	}
@@ -247,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 7a9ce28..09e257d 100644
--- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
@@ -20,19 +20,13 @@
 
 #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;
-
-/* TZDRAM offset for saving SMMU context */
-#define TEGRA186_SMMU_CTX_OFFSET	16UL
-
 /* state id mask */
 #define TEGRA186_STATE_ID_MASK		0xFU
 /* constants to get power state's wake time */
@@ -111,7 +105,7 @@
 
 		/* Enter CPU idle/powerdown */
 		val = (stateid_afflvl0 == PSTATE_ID_CORE_IDLE) ?
-			TEGRA_ARI_CORE_C6 : TEGRA_ARI_CORE_C7;
+			(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);
 
@@ -127,32 +121,36 @@
 
 		/* 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 = (uint32_t)mce_command_handler(
 					(uint64_t)MCE_CMD_IS_SC7_ALLOWED,
-					TEGRA_ARI_CORE_C7,
+					(uint64_t)TEGRA_ARI_CORE_C7,
 					MCE_CORE_SLEEP_TIME_INFINITE,
 					0U);
 		} while (val == 0U);
 
 		/* Instruct the MCE to enter system suspend state */
 		(void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE,
-			TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0U);
+			(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 */
 	}
@@ -161,32 +159,41 @@
 }
 
 /*******************************************************************************
- * 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(uint32_t lvl,
-					     const plat_local_state_t *states,
-					     uint32_t ncpu)
+static bool tegra_last_cpu_in_cluster(const plat_local_state_t *states,
+			uint32_t ncpu)
 {
-	plat_local_state_t target = *states;
-	uint32_t pos = 0;
-	plat_local_state_t result = PSCI_LOCAL_STATE_RUN;
-	uint32_t cpu = plat_my_core_pos(), num_cpu = ncpu;
-	int32_t ret, cluster_powerdn = 1;
-	uint64_t core_pos = read_mpidr() & (uint64_t)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 == (uint32_t)MPIDR_AFFLVL1) {
-		target = states[core_pos];
-	}
-	if (lvl == (uint32_t)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 == (uint32_t)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;
@@ -194,41 +201,30 @@
 
 		/* Check if CCx state is allowed. */
 		ret = mce_command_handler((uint64_t)MCE_CMD_IS_CCX_ALLOWED,
-				TEGRA_ARI_CORE_C7, tegra_percpu_data[cpu].wake_time,
+				(uint64_t)TEGRA_ARI_CORE_C7,
+				tegra_percpu_data[cpu].wake_time,
 				0U);
-		if (ret != 0) {
-			result = PSTATE_ID_CORE_POWERDN;
+		if (ret == 0) {
+			target = PSCI_LOCAL_STATE_RUN;
 		}
 	}
 
 	/* CPU off */
-	if ((lvl == (uint32_t)MPIDR_AFFLVL1) && (target == PLAT_MAX_OFF_STATE)) {
-
-		/* find out the number of ON cpus in the cluster */
-		do {
-			target = states[pos];
-			if (target != PLAT_MAX_OFF_STATE) {
-				cluster_powerdn = 0;
-			}
-			--num_cpu;
-			pos++;
-		} while (num_cpu != 0U);
-
+	if (target == PLAT_MAX_OFF_STATE) {
 		/* Enable cluster powerdn from last CPU in the cluster */
-		if (cluster_powerdn != 0) {
-
+		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((uint64_t)MCE_CMD_IS_CCX_ALLOWED,
-						  TEGRA_ARI_CORE_C7,
+						  (uint64_t)TEGRA_ARI_CORE_C7,
 						  MCE_CORE_SLEEP_TIME_INFINITE,
 						  0U);
-			if (ret != 0) {
-				result = PSTATE_ID_CORE_POWERDN;
+			if (ret == 0) {
+				target = PSCI_LOCAL_STATE_RUN;
 			}
 
 		} else {
@@ -236,17 +232,37 @@
 			/* 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 == (uint32_t)MPIDR_AFFLVL2) || (lvl == (uint32_t)MPIDR_AFFLVL1)) &&
-	    (target == PSTATE_ID_SOC_POWERDN)) {
-		result = PSTATE_ID_SOC_POWERDN;
+	if ((lvl == (uint32_t)MPIDR_AFFLVL2) &&
+	    (states[cpu] == PSTATE_ID_SOC_POWERDN)) {
+		target = PSTATE_ID_SOC_POWERDN;
+	}
+
+	/* CPU off, CPU suspend */
+	if (lvl == (uint32_t)MPIDR_AFFLVL1) {
+		target = tegra_get_afflvl1_pwr_state(states, ncpu);
 	}
 
-	/* default state */
-	return result;
+	/* target cluster/system state */
+	return target;
 }
 
 int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
@@ -265,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);
 	}
@@ -276,12 +291,12 @@
 
 int32_t tegra_soc_pwr_domain_on(u_register_t mpidr)
 {
-	uint32_t target_cpu = mpidr & (uint64_t)MPIDR_CPU_MASK;
-	uint32_t target_cluster = (mpidr & MPIDR_CLUSTER_MASK) >>
-			(uint64_t)MPIDR_AFFINITY_BITS;
 	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 > (uint64_t)MPIDR_AFFLVL1) {
+	if (target_cluster > ((uint32_t)PLATFORM_CLUSTER_COUNT - 1U)) {
 
 		ERROR("%s: unsupported CPU (0x%lx)\n", __func__, mpidr);
 		ret = PSCI_E_NOT_PRESENT;
@@ -304,14 +319,13 @@
 	uint64_t impl, val;
 	const plat_params_from_bl2_t *plat_params = bl31_get_plat_params();
 
-	impl = (read_midr() >> MIDR_IMPL_SHIFT) & (uint64_t)MIDR_IMPL_MASK;
+	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 != (uint64_t)DENVER_IMPL)) {
+	if ((plat_params->l2_ecc_parity_prot_dis != 1) && (impl != DENVER_IMPL)) {
 
 		val = read_l2ctlr_el1();
 		val |= CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT;
@@ -327,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);
 	}
@@ -354,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);
 	}
@@ -375,8 +389,8 @@
 	}
 
 	/* Turn off CPU */
-	(void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE, TEGRA_ARI_CORE_C7,
-			MCE_CORE_SLEEP_TIME_INFINITE, 0U);
+	(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;
 }
@@ -384,7 +398,7 @@
 __dead2 void tegra_soc_prepare_system_off(void)
 {
 	/* power off the entire system */
-	mce_enter_ccplex_state(TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF);
+	mce_enter_ccplex_state((uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF);
 
 	wfi();
 
@@ -396,7 +410,7 @@
 
 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 35a403b..1650809 100644
--- a/plat/nvidia/tegra/soc/t186/plat_secondary.c
+++ b/plat/nvidia/tegra/soc/t186/plat_secondary.c
@@ -11,6 +11,7 @@
 #include <lib/mmio.h>
 
 #include <mce.h>
+#include <tegra186_private.h>
 #include <tegra_def.h>
 #include <tegra_private.h>
 
@@ -24,9 +25,6 @@
 
 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
  ******************************************************************************/
@@ -34,39 +32,33 @@
 {
 	uint32_t addr_low, addr_high;
 	const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
-	uint64_t cpu_reset_handler_base;
+	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 >> 32U) & 0x7ffU);
+	/* 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 */
diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c
index bbd19c1..fd109e5 100644
--- a/plat/nvidia/tegra/soc/t186/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t186/plat_setup.c
@@ -40,7 +40,7 @@
  * the number of power domains at the highest power level.
  *******************************************************************************
  */
-const uint8_t tegra_power_domain_tree_desc[] = {
+static const uint8_t tegra_power_domain_tree_desc[] = {
 	/* No of root nodes */
 	1,
 	/* No of clusters */
@@ -211,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;
 }
@@ -223,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;
 }
diff --git a/plat/nvidia/tegra/soc/t186/plat_sip_calls.c b/plat/nvidia/tegra/soc/t186/plat_sip_calls.c
index 955029e..4de8a9e 100644
--- a/plat/nvidia/tegra/soc/t186/plat_sip_calls.c
+++ b/plat/nvidia/tegra/soc/t186/plat_sip_calls.c
@@ -23,7 +23,7 @@
 /*******************************************************************************
  * Offset to read the ref_clk counter value
  ******************************************************************************/
-#define REF_CLK_OFFSET		4
+#define REF_CLK_OFFSET		4ULL
 
 /*******************************************************************************
  * Tegra186 SiP SMCs
@@ -35,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
@@ -52,7 +52,7 @@
 /*******************************************************************************
  * 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,
@@ -61,24 +61,30 @@
 		     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
@@ -103,14 +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;
+		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
@@ -125,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;
+		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;
 
-		/* 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 + (8ULL * cpu));
+			ref_clk_ctr = mmio_read_32(base + (8ULL * cpu) + REF_CLK_OFFSET);
 
-		/* 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);
+			/* 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 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 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
index 0157747..be1f9cc 100644
--- a/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h
+++ b/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h
@@ -16,14 +16,16 @@
  */
 
 /* 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_SCRATCH120_OFFSET    	0xB38U
-#define PMC_SECURE_SCRATCH121_OFFSET    	0xB3CU
-#define PMC_SECURE_SCRATCH122_OFFSET    	0xB40U
-#define PMC_SECURE_SCRATCH123_OFFSET    	0xB44U
+#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
@@ -32,6 +34,12 @@
 #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
@@ -42,8 +50,24 @@
 #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_REG_OFFSET			0x14U
 #define SE_CONFIG_ENC_ALG_SHIFT 		12
 #define SE_CONFIG_ENC_ALG_AES_ENC	\
 		((1U) << SE_CONFIG_ENC_ALG_SHIFT)
@@ -66,7 +90,7 @@
 #define SE_CONFIG_DEC_ALG(x)	\
 		((x) & ((0xFU) << SE_CONFIG_DEC_ALG_SHIFT))
 
-#define SE_CONFIG_DST_SHIFT     		2
+#define SE_CONFIG_DST_SHIFT	 		2
 #define SE_CONFIG_DST_MEMORY	\
 		((0U) << SE_CONFIG_DST_SHIFT)
 #define SE_CONFIG_DST_HASHREG	\
@@ -80,33 +104,75 @@
 #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		\
-		((0UL) << DRBG_MODE_SHIFT)
+		((0U) << DRBG_MODE_SHIFT)
 #define DRBG_MODE_FORCE_INSTANTION  \
-		((1UL) << DRBG_MODE_SHIFT)
+		((1U) << DRBG_MODE_SHIFT)
 #define DRBG_MODE_FORCE_RESEED	  \
-		((2UL) << DRBG_MODE_SHIFT)
+		((2U) << DRBG_MODE_SHIFT)
 #define SE_RNG_CONFIG_MODE(x)   \
-		((x) & ((0x3UL) << DRBG_MODE_SHIFT))
+		((x) & ((0x3U) << DRBG_MODE_SHIFT))
 
 #define DRBG_SRC_SHIFT				2
 #define DRBG_SRC_NONE	   \
-		((0UL) << DRBG_SRC_SHIFT)
+		((0U) << DRBG_SRC_SHIFT)
 #define DRBG_SRC_ENTROPY	\
-		((1UL) << DRBG_SRC_SHIFT)
+		((1U) << DRBG_SRC_SHIFT)
 #define DRBG_SRC_LFSR	   \
-		((2UL) << DRBG_SRC_SHIFT)
+		((2U) << DRBG_SRC_SHIFT)
 #define SE_RNG_SRC_CONFIG_MODE(x)   \
-		((x) & ((0x3UL) << DRBG_SRC_SHIFT))
+		((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_SHIFT			1
 #define DRBG_RO_ENT_SRC_ENABLE	\
 		((1U) << DRBG_RO_ENT_SRC_SHIFT)
 #define DRBG_RO_ENT_SRC_DISABLE	\
@@ -114,7 +180,7 @@
 #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_SHIFT		0
 #define DRBG_RO_ENT_SRC_LOCK_ENABLE	\
 		((1U) << DRBG_RO_ENT_SRC_LOCK_SHIFT)
 #define DRBG_RO_ENT_SRC_LOCK_DISABLE	\
@@ -130,9 +196,97 @@
 #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_OPERATION_SHIFT			0
 #define SE_OP_ABORT	\
 		((0x0U) << SE_OPERATION_SHIFT)
 #define SE_OP_START	\
@@ -146,11 +300,85 @@
 #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_ENABLE_SHIFT		0
 #define SE_CTX_SAVE_AUTO_DIS	\
 		((0U) << SE_CTX_SAVE_AUTO_ENABLE_SHIFT)
 #define SE_CTX_SAVE_AUTO_EN	\
@@ -167,20 +395,22 @@
 #define SE_CTX_SAVE_AUTO_LOCK(x)	\
 		((x) & ((0x1U) << SE_CTX_SAVE_AUTO_LOCK_SHIFT))
 
-/* Current context save number of blocks  */
+/* 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
+#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_OPERATION			0x540U
 
-#define SE_TZRAM_OP_MODE_SHIFT  		1
+#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	\
@@ -188,7 +418,7 @@
 #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_SHIFT			2
 #define SE_TZRAM_OP_BUSY_OFF	\
 		((0U) << SE_TZRAM_OP_BUSY_SHIFT)
 #define SE_TZRAM_OP_BUSY_ON	\
@@ -196,7 +426,7 @@
 #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_SHIFT			0
 #define SE_TZRAM_OP_REQ_IDLE	\
 		((0U) << SE_TZRAM_OP_REQ_SHIFT)
 #define SE_TZRAM_OP_REQ_INIT	\
@@ -206,7 +436,7 @@
 
 /* SE Interrupt */
 #define SE_INT_STATUS_REG_OFFSET		0x10U
-#define SE_INT_OP_DONE_SHIFT    		4
+#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	\
@@ -214,21 +444,188 @@
 #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
+#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_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
  ******************************************************************************/
 
@@ -242,8 +639,21 @@
 	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
index fa99db6..e0a0d6c 100644
--- a/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c
+++ b/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c
@@ -20,7 +20,8 @@
  * Constants and Macros
  ******************************************************************************/
 
-#define TIMEOUT_100MS	100UL	// Timeout in 100ms
+#define TIMEOUT_100MS	100U	// Timeout in 100ms
+#define RNG_AES_KEY_INDEX   1
 
 /*******************************************************************************
  * Data structure and global variables
@@ -67,6 +68,15 @@
  * #--------------------------------#
  */
 
+/* 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;
@@ -78,7 +88,7 @@
 /* SE1 security engine device handle */
 static tegra_se_dev_t se_dev_1 = {
 	.se_num = 1,
-	/* setup base address for se */
+	/* 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,
@@ -86,12 +96,14 @@
 	.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 */
+	/* 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,
@@ -99,8 +111,12 @@
 	.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
  ******************************************************************************/
@@ -186,35 +202,15 @@
 }
 
 /*
- * Verify the SE context save auto has been enabled.
- * SE_CTX_SAVE_AUTO.ENABLE == ENABLE
- * If the SE context save auto is not enabled, then set
- * the context save auto enable and lock the setting.
- * If the SE context save auto is not enabled and the
- * enable setting is locked, then return an error.
+ * Returns true if the SE engine is configured to perform SE context save in
+ * hardware.
  */
-static inline int32_t tegra_se_ctx_save_auto_enable(const tegra_se_dev_t *se_dev)
+static inline bool tegra_se_atomic_save_enabled(const tegra_se_dev_t *se_dev)
 {
 	uint32_t val;
-	int32_t ret = 0;
 
 	val = tegra_se_read_32(se_dev, SE_CTX_SAVE_AUTO_REG_OFFSET);
-	if (SE_CTX_SAVE_AUTO_ENABLE(val) == SE_CTX_SAVE_AUTO_DIS) {
-		if (SE_CTX_SAVE_AUTO_LOCK(val) == SE_CTX_SAVE_AUTO_LOCK_EN) {
-			ERROR("%s: ERR: Cannot enable atomic. Write locked!\n",
-					__func__);
-			ret = -EACCES;
-		}
-
-		/* Program SE_CTX_SAVE_AUTO */
-		if (ret == 0) {
-			tegra_se_write_32(se_dev, SE_CTX_SAVE_AUTO_REG_OFFSET,
-					SE_CTX_SAVE_AUTO_LOCK_EN |
-					SE_CTX_SAVE_AUTO_EN);
-		}
-	}
-
-	return ret;
+	return (SE_CTX_SAVE_AUTO_ENABLE(val) == SE_CTX_SAVE_AUTO_EN);
 }
 
 /*
@@ -259,14 +255,6 @@
 	/* Check that previous operation is finalized */
 	ret = tegra_se_operation_prepare(se_dev);
 
-	/* Ensure HW atomic context save has been enabled
-	 * This should have been done at boot time.
-	 * SE_CTX_SAVE_AUTO.ENABLE == ENABLE
-	 */
-	if (ret == 0) {
-		ret = tegra_se_ctx_save_auto_enable(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
@@ -325,7 +313,8 @@
  * 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)
+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;
@@ -351,7 +340,10 @@
 	tegra_se_make_data_coherent(se_dev);
 
 	/* Start hardware operation */
-	tegra_se_write_32(se_dev, SE_OPERATION_REG_OFFSET, SE_OP_START);
+	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);
@@ -361,6 +353,22 @@
 }
 
 /*
+ * 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.
@@ -381,7 +389,10 @@
 	se_dev->dst_ll_buf->last_buff_num = 0;
 
 	/* Configure random number generator */
-	val = (DRBG_MODE_FORCE_RESEED | DRBG_SRC_ENTROPY);
+	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 */
@@ -391,25 +402,562 @@
 	tegra_se_write_32(se_dev, SE_CONFIG_REG_OFFSET, val);
 
 	/* Perform hardware operation */
-	ret = tegra_se_perform_operation(se_dev, 0);
+	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.
@@ -417,21 +965,57 @@
 int32_t tegra_se_suspend(void)
 {
 	int32_t ret = 0;
+	uint32_t val = 0;
 
-	/* Atomic context save se2 and pka1 */
-	INFO("%s: SE2/PKA1 atomic context save\n", __func__);
-	ret = tegra_se_context_save_atomic(&se_dev_2);
+	/* 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);
 
-	/* Atomic context save se */
-	if (ret == 0) {
-		INFO("%s: SE1 atomic context save\n", __func__);
-		ret = tegra_se_context_save_atomic(&se_dev_1);
-	}
+	tegra_se_enable_clocks();
 
-	if (ret == 0) {
-		INFO("%s: SE atomic context save done\n", __func__);
+	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;
 }
 
@@ -445,6 +1029,7 @@
 	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);
@@ -465,6 +1050,8 @@
 		INFO("%s: SE TZRAM save done!\n", __func__);
 	}
 
+	tegra_se_disable_clocks();
+
 	return ret;
 }
 
@@ -483,12 +1070,6 @@
 		DRBG_RO_ENT_SRC_ENABLE;
 	tegra_se_write_32(se_dev, SE_RNG_SRC_CONFIG_REG_OFFSET, val);
 
-	/* Enable and lock the SE atomic context save setting */
-	if (tegra_se_ctx_save_auto_enable(se_dev) != 0) {
-		ERROR("%s: ERR: enable SE%d context save auto failed!\n",
-			__func__, se_dev->se_num);
-	}
-
 	/* Set a random value to SRK to initialize DRBG */
 	tegra_se_generate_srk(se_dev);
 }
diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
index ed30ff4..f52d975 100644
--- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
@@ -104,41 +104,55 @@
 	if ((lvl == MPIDR_AFFLVL1) && (target == PSTATE_ID_CLUSTER_IDLE)) {
 
 		/* initialize the bpmp interface */
-		(void)tegra_bpmp_init();
-
-		/* 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)) {
+		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;
+			}
 		}
 
 	} else if ((lvl == MPIDR_AFFLVL1) && (target == PSTATE_ID_CLUSTER_POWERDN)) {
 
 		/* initialize the bpmp interface */
-		(void)tegra_bpmp_init();
-
-		/* 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)) {
+		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)) &&
@@ -177,18 +191,8 @@
 			if (tegra_se_suspend() != 0) {
 				ret = PSCI_E_INTERN_FAIL;
 			}
-
-			/* Save tzram contents */
-			if (tegra_se_save_tzram() != 0) {
-				ret = PSCI_E_INTERN_FAIL;
-			}
 		}
 
-		/* enter system suspend */
-		if (ret == PSCI_E_SUCCESS) {
-			tegra_fc_soc_powerdn(mpidr);
-		}
-
 	} else if (stateid_afflvl1 == PSTATE_ID_CLUSTER_IDLE) {
 
 		assert(stateid_afflvl0 == PSTATE_ID_CORE_POWERDN);
@@ -217,6 +221,27 @@
 	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;
+}
+
 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();
diff --git a/plat/nvidia/tegra/soc/t210/platform_t210.mk b/plat/nvidia/tegra/soc/t210/platform_t210.mk
index a9ab0d8..e23d7e3 100644
--- a/plat/nvidia/tegra/soc/t210/platform_t210.mk
+++ b/plat/nvidia/tegra/soc/t210/platform_t210.mk
@@ -19,14 +19,15 @@
 MAX_XLAT_TABLES				:= 10
 $(eval $(call add_define,MAX_XLAT_TABLES))
 
-MAX_MMAP_REGIONS			:= 10
+MAX_MMAP_REGIONS			:= 15
 $(eval $(call add_define,MAX_MMAP_REGIONS))
 
 PLAT_INCLUDES		+=	-I${SOC_DIR}/drivers/se
 
-BL31_SOURCES		+=	lib/cpus/aarch64/cortex_a53.S			\
+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/bpmp/bpmp.c		\
 				${COMMON_DIR}/drivers/flowctrl/flowctrl.c	\
 				${COMMON_DIR}/drivers/memctrl/memctrl_v1.c	\
 				${SOC_DIR}/plat_psci_handlers.c			\
diff --git a/plat/socionext/synquacer/sq_bl31_setup.c b/plat/socionext/synquacer/sq_bl31_setup.c
index 2fac80f..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
  */
@@ -160,7 +160,7 @@
 void bl31_plat_arch_setup(void)
 {
 	static const mmap_region_t secure_partition_mmap[] = {
-#if ENABLE_SPM && SPM_DEPRECATED
+#if ENABLE_SPM && SPM_MM
 		MAP_REGION_FLAT(PLAT_SPM_BUF_BASE,
 				PLAT_SPM_BUF_SIZE,
 				MT_RW_DATA | MT_SECURE),
@@ -174,7 +174,7 @@
 	sq_mmap_setup(BL31_BASE, BL31_SIZE, secure_partition_mmap);
 	enable_mmu_el3(XLAT_TABLE_NC);
 
-#if ENABLE_SPM && SPM_DEPRECATED
+#if ENABLE_SPM && SPM_MM
 	memcpy((void *)SPM_SHIM_EXCEPTIONS_START,
 	       (void *)SPM_SHIM_EXCEPTIONS_LMA,
 	       (uintptr_t)SPM_SHIM_EXCEPTIONS_END -
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/readme.rst b/readme.rst
index 1f02bf1..5404e74 100644
--- a/readme.rst
+++ b/readme.rst
@@ -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
 ~~~~~~~~~~~~~
@@ -260,7 +262,7 @@
 
 --------------
 
-*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
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 c9d73f0..0305143 100644
--- a/services/spd/trusty/trusty.c
+++ b/services/spd/trusty/trusty.c
@@ -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,37 +69,37 @@
 	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
@@ -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);
@@ -304,7 +308,7 @@
 	 * Adjust secondary cpu entry point for 32 bit images to the
 	 * 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;
 	}
@@ -444,8 +448,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/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 90%
rename from services/std_svc/spm_deprecated/spm.mk
rename to services/std_svc/spm_mm/spm.mk
index 3503020..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				\
diff --git a/services/std_svc/spm_deprecated/spm_main.c b/services/std_svc/spm_mm/spm_main.c
similarity index 100%
rename from services/std_svc/spm_deprecated/spm_main.c
rename to services/std_svc/spm_mm/spm_main.c
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 100%
rename from services/std_svc/spm_deprecated/spm_setup.c
rename to services/std_svc/spm_mm/spm_setup.c
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