Merge pull request #1781 from dtwlin/m2

spd: trusty: trusty_setup should bail on unknown image
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/plat/imx/common/imx_sip_handler.c b/plat/imx/common/imx_sip_handler.c
index 22a7f2b..55639cd 100644
--- a/plat/imx/common/imx_sip_handler.c
+++ b/plat/imx/common/imx_sip_handler.c
@@ -7,6 +7,7 @@
 #include <stdlib.h>
 #include <stdint.h>
 #include <std_svc.h>
+#include <string.h>
 #include <platform_def.h>
 #include <common/debug.h>
 #include <common/runtime_svc.h>
@@ -76,3 +77,107 @@
 
 	return 0;
 }
+
+static bool wakeup_src_irqsteer;
+
+bool imx_is_wakeup_src_irqsteer(void)
+{
+	return wakeup_src_irqsteer;
+}
+
+int imx_wakeup_src_handler(uint32_t smc_fid,
+		    u_register_t x1,
+		    u_register_t x2,
+		    u_register_t x3)
+{
+	switch (x1) {
+	case IMX_SIP_WAKEUP_SRC_IRQSTEER:
+		wakeup_src_irqsteer = true;
+		break;
+	case IMX_SIP_WAKEUP_SRC_SCU:
+		wakeup_src_irqsteer = false;
+		break;
+	default:
+		return SMC_UNK;
+	}
+
+	return SMC_OK;
+}
+
+int imx_otp_handler(uint32_t smc_fid,
+		void *handle,
+		u_register_t x1,
+		u_register_t x2)
+{
+	int ret;
+	uint32_t fuse;
+
+	switch (smc_fid) {
+	case IMX_SIP_OTP_READ:
+		ret = sc_misc_otp_fuse_read(ipc_handle, x1, &fuse);
+		SMC_RET2(handle, ret, fuse);
+		break;
+	case IMX_SIP_OTP_WRITE:
+		ret = sc_misc_otp_fuse_write(ipc_handle, x1, x2);
+		SMC_RET1(handle, ret);
+		break;
+	default:
+		ret = SMC_UNK;
+		SMC_RET1(handle, ret);
+		break;
+	}
+
+	return ret;
+}
+
+int imx_misc_set_temp_handler(uint32_t smc_fid,
+		    u_register_t x1,
+		    u_register_t x2,
+		    u_register_t x3,
+		    u_register_t x4)
+{
+	return sc_misc_set_temp(ipc_handle, x1, x2, x3, x4);
+}
+
+static uint64_t imx_get_commit_hash(u_register_t x2,
+		    u_register_t x3,
+		    u_register_t x4)
+{
+	/* Parse the version_string */
+	char *parse = (char *)version_string;
+	uint64_t hash = 0;
+
+	do {
+		parse = strchr(parse, '-');
+		if (parse) {
+			parse += 1;
+			if (*(parse) == 'g') {
+				/* Default is 7 hexadecimal digits */
+				memcpy((void *)&hash, (void *)(parse + 1), 7);
+				break;
+			}
+		}
+
+	} while (parse != NULL);
+
+	return hash;
+}
+
+uint64_t imx_buildinfo_handler(uint32_t smc_fid,
+		    u_register_t x1,
+		    u_register_t x2,
+		    u_register_t x3,
+		    u_register_t x4)
+{
+	uint64_t ret;
+
+	switch (x1) {
+	case IMX_SIP_BUILDINFO_GET_COMMITHASH:
+		ret = imx_get_commit_hash(x2, x3, x4);
+		break;
+	default:
+		return SMC_UNK;
+	}
+
+	return ret;
+}
diff --git a/plat/imx/common/imx_sip_svc.c b/plat/imx/common/imx_sip_svc.c
index 89b9df8..c27fbf2 100644
--- a/plat/imx/common/imx_sip_svc.c
+++ b/plat/imx/common/imx_sip_svc.c
@@ -32,7 +32,16 @@
 	case  IMX_SIP_CPUFREQ:
 		SMC_RET1(handle, imx_cpufreq_handler(smc_fid, x1, x2, x3));
 		break;
+	case  IMX_SIP_WAKEUP_SRC:
+		SMC_RET1(handle, imx_wakeup_src_handler(smc_fid, x1, x2, x3));
+	case IMX_SIP_OTP_READ:
+	case IMX_SIP_OTP_WRITE:
+		return imx_otp_handler(smc_fid, handle, x1, x2);
+	case IMX_SIP_MISC_SET_TEMP:
+		SMC_RET1(handle, imx_misc_set_temp_handler(smc_fid, x1, x2, x3, x4));
 #endif
+	case  IMX_SIP_BUILDINFO:
+		SMC_RET1(handle, imx_buildinfo_handler(smc_fid, x1, x2, x3, x4));
 	default:
 		WARN("Unimplemented i.MX SiP Service Call: 0x%x\n", smc_fid);
 		SMC_RET1(handle, SMC_UNK);
diff --git a/plat/imx/common/include/imx_sip_svc.h b/plat/imx/common/include/imx_sip_svc.h
index 4ba7b87..648be37 100644
--- a/plat/imx/common/include/imx_sip_svc.h
+++ b/plat/imx/common/include/imx_sip_svc.h
@@ -14,11 +14,33 @@
 #define IMX_SIP_SRTC			0xC2000002
 #define IMX_SIP_SRTC_SET_TIME		0x00
 
+#define IMX_SIP_BUILDINFO			0xC2000003
+#define IMX_SIP_BUILDINFO_GET_COMMITHASH	0x00
+
+#define IMX_SIP_WAKEUP_SRC		0xC2000009
+#define IMX_SIP_WAKEUP_SRC_SCU		0x1
+#define IMX_SIP_WAKEUP_SRC_IRQSTEER	0x2
+
+#define IMX_SIP_OTP_READ		0xC200000A
+#define IMX_SIP_OTP_WRITE		0xC200000B
+
+#define IMX_SIP_MISC_SET_TEMP		0xC200000C
+
 #if (defined(PLAT_IMX8QM) || defined(PLAT_IMX8QX))
 int imx_cpufreq_handler(uint32_t smc_fid, u_register_t x1,
 			u_register_t x2, u_register_t x3);
 int imx_srtc_handler(uint32_t smc_fid, void *handle, u_register_t x1,
 		     u_register_t x2, u_register_t x3, u_register_t x4);
+int imx_wakeup_src_handler(uint32_t smc_fid, u_register_t x1,
+			   u_register_t x2, u_register_t x3);
+int imx_otp_handler(uint32_t smc_fid, void *handle,
+		    u_register_t x1, u_register_t x2);
+int imx_misc_set_temp_handler(uint32_t smc_fid, u_register_t x1,
+			      u_register_t x2, u_register_t x3,
+			      u_register_t x4);
+uint64_t imx_buildinfo_handler(uint32_t smc_fid, u_register_t x1,
+			       u_register_t x2, u_register_t x3,
+			       u_register_t x4);
 #endif
 
 #endif /* __IMX_SIP_SVC_H__ */
diff --git a/plat/imx/common/include/plat_imx8.h b/plat/imx/common/include/plat_imx8.h
index 8d83173..952ad53 100644
--- a/plat/imx/common/include/plat_imx8.h
+++ b/plat/imx/common/include/plat_imx8.h
@@ -23,5 +23,6 @@
 int imx_validate_power_state(unsigned int power_state,
 			psci_power_state_t *req_state);
 void imx_get_sys_suspend_power_state(psci_power_state_t *req_state);
+bool imx_is_wakeup_src_irqsteer(void);
 
 #endif /* PLAT_IMX8_H */
diff --git a/plat/imx/common/include/sci/sci.h b/plat/imx/common/include/sci/sci.h
index 1b2f699..2c45bb8 100644
--- a/plat/imx/common/include/sci/sci.h
+++ b/plat/imx/common/include/sci/sci.h
@@ -16,5 +16,6 @@
 #include <sci/svc/pm/sci_pm_api.h>
 #include <sci/svc/rm/sci_rm_api.h>
 #include <sci/svc/timer/sci_timer_api.h>
+#include <sci/svc/misc/sci_misc_api.h>
 
 #endif /* SCI_H */
diff --git a/plat/imx/common/include/sci/svc/misc/sci_misc_api.h b/plat/imx/common/include/sci/svc/misc/sci_misc_api.h
new file mode 100644
index 0000000..d9dd49d
--- /dev/null
+++ b/plat/imx/common/include/sci/svc/misc/sci_misc_api.h
@@ -0,0 +1,539 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ * Header file containing the public API for the System Controller (SC)
+ * Miscellaneous (MISC) function.
+ *
+ * @addtogroup MISC_SVC (SVC) Miscellaneous Service
+ *
+ * Module for the Miscellaneous (MISC) service.
+ *
+ * @{
+ */
+
+#ifndef SC_MISC_API_H
+#define SC_MISC_API_H
+
+/* Includes */
+
+#include <sci/svc/rm/sci_rm_api.h>
+#include <sci/sci_types.h>
+
+/* Defines */
+
+/*!
+ * @name Defines for type widths
+ */
+/*@{*/
+#define SC_MISC_DMA_GRP_W       5U	/* Width of sc_misc_dma_group_t */
+/*@}*/
+
+/*! Max DMA channel priority group */
+#define SC_MISC_DMA_GRP_MAX     31U
+
+/*!
+ * @name Defines for sc_misc_boot_status_t
+ */
+/*@{*/
+#define SC_MISC_BOOT_STATUS_SUCCESS     0U	/* Success */
+#define SC_MISC_BOOT_STATUS_SECURITY    1U	/* Security violation */
+/*@}*/
+
+/*!
+ * @name Defines for sc_misc_seco_auth_cmd_t
+ */
+/*@{*/
+#define SC_MISC_SECO_AUTH_SECO_FW       0U	/* SECO Firmware */
+#define SC_MISC_SECO_AUTH_HDMI_TX_FW    1U	/* HDMI TX Firmware */
+#define SC_MISC_SECO_AUTH_HDMI_RX_FW    2U	/* HDMI RX Firmware */
+/*@}*/
+
+/*!
+ * @name Defines for sc_misc_temp_t
+ */
+/*@{*/
+#define SC_MISC_TEMP                    0U	/* Temp sensor */
+#define SC_MISC_TEMP_HIGH               1U	/* Temp high alarm */
+#define SC_MISC_TEMP_LOW                2U	/* Temp low alarm */
+/*@}*/
+
+/*!
+ * @name Defines for sc_misc_seco_auth_cmd_t
+ */
+/*@{*/
+#define SC_MISC_AUTH_CONTAINER          0U	/* Authenticate container */
+#define SC_MISC_VERIFY_IMAGE            1U	/* Verify image */
+#define SC_MISC_REL_CONTAINER           2U	/* Release container */
+/*@}*/
+
+/* Types */
+
+/*!
+ * This type is used to store a DMA channel priority group.
+ */
+typedef uint8_t sc_misc_dma_group_t;
+
+/*!
+ * This type is used report boot status.
+ */
+typedef uint8_t sc_misc_boot_status_t;
+
+/*!
+ * This type is used to issue SECO authenticate commands.
+ */
+typedef uint8_t sc_misc_seco_auth_cmd_t;
+
+/*!
+ * This type is used report boot status.
+ */
+typedef uint8_t sc_misc_temp_t;
+
+/* Functions */
+
+/*!
+ * @name Control Functions
+ * @{
+ */
+
+/*!
+ * This function sets a miscellaneous control value.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     resource    resource the control is associated with
+ * @param[in]     ctrl        control to change
+ * @param[in]     val         value to apply to the control
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the resource owner or parent
+ *   of the owner
+ *
+ * Refer to the [Control List](@ref CONTROLS) for valid control values.
+ */
+sc_err_t sc_misc_set_control(sc_ipc_t ipc, sc_rsrc_t resource,
+			     sc_ctrl_t ctrl, uint32_t val);
+
+/*!
+ * This function gets a miscellaneous control value.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     resource    resource the control is associated with
+ * @param[in]     ctrl        control to get
+ * @param[out]    val         pointer to return the control value
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the resource owner or parent
+ *   of the owner
+ *
+ * Refer to the [Control List](@ref CONTROLS) for valid control values.
+ */
+sc_err_t sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource,
+			     sc_ctrl_t ctrl, uint32_t *val);
+
+/* @} */
+
+/*!
+ * @name DMA Functions
+ * @{
+ */
+
+/*!
+ * This function configures the max DMA channel priority group for a
+ * partition.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     pt          handle of partition to assign \a max
+ * @param[in]     max         max priority group (0-31)
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the parent
+ *   of the affected partition
+ *
+ * Valid \a max range is 0-31 with 0 being the lowest and 31 the highest.
+ * Default is the max priority group for the parent partition of \a pt.
+ */
+sc_err_t sc_misc_set_max_dma_group(sc_ipc_t ipc, sc_rm_pt_t pt,
+				   sc_misc_dma_group_t max);
+
+/*!
+ * This function configures the priority group for a DMA channel.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     resource    DMA channel resource
+ * @param[in]     group       priority group (0-31)
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the owner or parent
+ *   of the owner of the DMA channel
+ *
+ * Valid \a group range is 0-31 with 0 being the lowest and 31 the highest.
+ * The max value of \a group is limited by the partition max set using
+ * sc_misc_set_max_dma_group().
+ */
+sc_err_t sc_misc_set_dma_group(sc_ipc_t ipc, sc_rsrc_t resource,
+			       sc_misc_dma_group_t group);
+
+/* @} */
+
+/*!
+ * @name Security Functions
+ * @{
+ */
+
+/*!
+ * This function loads a SECO image.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     addr_src    address of image source
+ * @param[in]     addr_dst    address of image destination
+ * @param[in]     len         length of image to load
+ * @param[in]     fw          SC_TRUE = firmware load
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * This is used to load images via the SECO. Examples include SECO
+ * Firmware and IVT/CSF data used for authentication. These are usually
+ * loaded into SECO TCM. \a addr_src is in secure memory.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_image_load(sc_ipc_t ipc, sc_faddr_t addr_src,
+				 sc_faddr_t addr_dst, uint32_t len,
+				 sc_bool_t fw);
+
+/*!
+ * This function is used to authenticate a SECO image or command.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     cmd         authenticate command
+ * @param[in]     addr        address of/or metadata
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * This is used to authenticate a SECO image or issue a security
+ * command. \a addr often points to an container. It is also
+ * just data (or even unused) for some commands.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_authenticate(sc_ipc_t ipc,
+				   sc_misc_seco_auth_cmd_t cmd,
+				   sc_faddr_t addr);
+
+/*!
+ * This function securely writes a group of fuse words.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     addr        address of message block
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * Note \a addr must be a pointer to a signed message block.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_fuse_write(sc_ipc_t ipc, sc_faddr_t addr);
+
+/*!
+ * This function securely enables debug.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     addr        address of message block
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * Note \a addr must be a pointer to a signed message block.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_enable_debug(sc_ipc_t ipc, sc_faddr_t addr);
+
+/*!
+ * This function updates the lifecycle of the device.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     lifecycle   new lifecycle
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * This message is used for going from Open to NXP Closed to OEM Closed.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_forward_lifecycle(sc_ipc_t ipc, uint32_t lifecycle);
+
+/*!
+ * This function updates the lifecycle to one of the return lifecycles.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     addr        address of message block
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * Note \a addr must be a pointer to a signed message block.
+ *
+ * To switch back to NXP states (Full Field Return), message must be signed
+ * by NXP SRK. For OEM States (Partial Field Return), must be signed by OEM
+ * SRK.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_return_lifecycle(sc_ipc_t ipc, sc_faddr_t addr);
+
+/*!
+ * This function is used to return the SECO FW build info.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[out]    version     pointer to return build number
+ * @param[out]    commit      pointer to return commit ID (git SHA-1)
+ */
+void sc_misc_seco_build_info(sc_ipc_t ipc, uint32_t *version, uint32_t *commit);
+
+/*!
+ * This function is used to return SECO chip info.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[out]    lc          pointer to return lifecycle
+ * @param[out]    monotonic   pointer to return monotonic counter
+ * @param[out]    uid_l       pointer to return UID (lower 32 bits)
+ * @param[out]    uid_h       pointer to return UID (upper 32 bits)
+ */
+sc_err_t sc_misc_seco_chip_info(sc_ipc_t ipc, uint16_t *lc,
+				uint16_t *monotonic, uint32_t *uid_l,
+				uint32_t *uid_h);
+
+/* @} */
+
+/*!
+ * @name Debug Functions
+ * @{
+ */
+
+/*!
+ * This function is used output a debug character from the SCU UART.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     ch          character to output
+ */
+void sc_misc_debug_out(sc_ipc_t ipc, uint8_t ch);
+
+/*!
+ * This function starts/stops emulation waveform capture.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     enable      flag to enable/disable capture
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_UNAVAILABLE if not running on emulation
+ */
+sc_err_t sc_misc_waveform_capture(sc_ipc_t ipc, sc_bool_t enable);
+
+/*!
+ * This function is used to return the SCFW build info.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[out]    build       pointer to return build number
+ * @param[out]    commit      pointer to return commit ID (git SHA-1)
+ */
+void sc_misc_build_info(sc_ipc_t ipc, uint32_t *build, uint32_t *commit);
+
+/*!
+ * This function is used to return the device's unique ID.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[out]    id_l        pointer to return lower 32-bit of ID [31:0]
+ * @param[out]    id_h        pointer to return upper 32-bits of ID [63:32]
+ */
+void sc_misc_unique_id(sc_ipc_t ipc, uint32_t *id_l, uint32_t *id_h);
+
+/* @} */
+
+/*!
+ * @name Other Functions
+ * @{
+ */
+
+/*!
+ * This function configures the ARI match value for PCIe/SATA resources.
+ *
+ * @param[in]     ipc          IPC handle
+ * @param[in]     resource     match resource
+ * @param[in]     resource_mst PCIe/SATA master to match
+ * @param[in]     ari          ARI to match
+ * @param[in]     enable       enable match or not
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the owner or parent
+ *   of the owner of the resource and translation
+ *
+ * For PCIe, the ARI is the 16-bit value that includes the bus number,
+ * device number, and function number. For SATA, this value includes the
+ * FISType and PM_Port.
+ */
+sc_err_t sc_misc_set_ari(sc_ipc_t ipc, sc_rsrc_t resource,
+			 sc_rsrc_t resource_mst, uint16_t ari,
+			 sc_bool_t enable);
+
+/*!
+ * This function reports boot status.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     status      boot status
+ *
+ * This is used by SW partitions to report status of boot. This is
+ * normally used to report a boot failure.
+ */
+void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status);
+
+/*!
+ * This function tells the SCFW that a CPU is done booting.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     cpu         CPU that is done booting
+ *
+ * This is called by early booting CPUs to report they are done with
+ * initialization. After starting early CPUs, the SCFW halts the
+ * booting process until they are done. During this time, early
+ * CPUs can call the SCFW with lower latency as the SCFW is idle.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the CPU owner
+ */
+sc_err_t sc_misc_boot_done(sc_ipc_t ipc, sc_rsrc_t cpu);
+
+/*!
+ * This function reads a given fuse word index.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     word        fuse word index
+ * @param[out]    val         fuse read value
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_NOACCESS if read operation failed
+ * - SC_ERR_LOCKED if read operation is locked
+ */
+sc_err_t sc_misc_otp_fuse_read(sc_ipc_t ipc, uint32_t word, uint32_t *val);
+
+/*!
+ * This function writes a given fuse word index.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     word        fuse word index
+ * @param[in]     val         fuse write value
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_NOACCESS if write operation failed
+ * - SC_ERR_LOCKED if write operation is locked
+ */
+sc_err_t sc_misc_otp_fuse_write(sc_ipc_t ipc, uint32_t word, uint32_t val);
+
+/*!
+ * This function sets a temp sensor alarm.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     resource    resource with sensor
+ * @param[in]     temp        alarm to set
+ * @param[in]     celsius     whole part of temp to set
+ * @param[in]     tenths      fractional part of temp to set
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * This function will enable the alarm interrupt if the temp requested is
+ * not the min/max temp. This enable automatically clears when the alarm
+ * occurs and this function has to be called again to re-enable.
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if parameters invalid
+ */
+sc_err_t sc_misc_set_temp(sc_ipc_t ipc, sc_rsrc_t resource,
+			  sc_misc_temp_t temp, int16_t celsius, int8_t tenths);
+
+/*!
+ * This function gets a temp sensor value.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     resource    resource with sensor
+ * @param[in]     temp        value to get (sensor or alarm)
+ * @param[out]    celsius     whole part of temp to get
+ * @param[out]    tenths      fractional part of temp to get
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if parameters invalid
+ */
+sc_err_t sc_misc_get_temp(sc_ipc_t ipc, sc_rsrc_t resource,
+			  sc_misc_temp_t temp, int16_t *celsius,
+			  int8_t *tenths);
+
+/*!
+ * This function returns the boot device.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[out]    dev         pointer to return boot device
+ */
+void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *dev);
+
+/*!
+ * This function returns the current status of the ON/OFF button.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[out]    status      pointer to return button status
+ */
+void sc_misc_get_button_status(sc_ipc_t ipc, sc_bool_t *status);
+
+/* @} */
+
+#endif				/* SC_MISC_API_H */
+
+/**@}*/
diff --git a/plat/imx/common/sci/sci_api.mk b/plat/imx/common/sci/sci_api.mk
index edaef4d..92c7190 100644
--- a/plat/imx/common/sci/sci_api.mk
+++ b/plat/imx/common/sci/sci_api.mk
@@ -9,4 +9,5 @@
 			plat/imx/common/sci/svc/pad/pad_rpc_clnt.c	\
 			plat/imx/common/sci/svc/pm/pm_rpc_clnt.c	\
 			plat/imx/common/sci/svc/rm/rm_rpc_clnt.c	\
-			plat/imx/common/sci/svc/timer/timer_rpc_clnt.c
+			plat/imx/common/sci/svc/timer/timer_rpc_clnt.c	\
+			plat/imx/common/sci/svc/misc/misc_rpc_clnt.c
diff --git a/plat/imx/common/sci/svc/misc/misc_rpc_clnt.c b/plat/imx/common/sci/svc/misc/misc_rpc_clnt.c
new file mode 100644
index 0000000..080de6a
--- /dev/null
+++ b/plat/imx/common/sci/svc/misc/misc_rpc_clnt.c
@@ -0,0 +1,506 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ * File containing client-side RPC functions for the MISC service. These
+ * functions are ported to clients that communicate to the SC.
+ *
+ * @addtogroup MISC_SVC
+ * @{
+ */
+
+/* Includes */
+
+#include <sci/sci_types.h>
+#include <sci/svc/rm/sci_rm_api.h>
+#include <sci/svc/misc/sci_misc_api.h>
+#include <sci/sci_rpc.h>
+#include <stdlib.h>
+#include "sci_misc_rpc.h"
+
+/* Local Defines */
+
+/* Local Types */
+
+/* Local Functions */
+
+sc_err_t sc_misc_set_control(sc_ipc_t ipc, sc_rsrc_t resource,
+			     sc_ctrl_t ctrl, uint32_t val)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SET_CONTROL;
+	RPC_U32(&msg, 0U) = (uint32_t)ctrl;
+	RPC_U32(&msg, 4U) = (uint32_t)val;
+	RPC_U16(&msg, 8U) = (uint16_t)resource;
+	RPC_SIZE(&msg) = 4U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource,
+			     sc_ctrl_t ctrl, uint32_t *val)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_GET_CONTROL;
+	RPC_U32(&msg, 0U) = (uint32_t)ctrl;
+	RPC_U16(&msg, 4U) = (uint16_t)resource;
+	RPC_SIZE(&msg) = 3U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	if (val != NULL)
+		*val = RPC_U32(&msg, 0U);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_set_max_dma_group(sc_ipc_t ipc, sc_rm_pt_t pt,
+				   sc_misc_dma_group_t max)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SET_MAX_DMA_GROUP;
+	RPC_U8(&msg, 0U) = (uint8_t)pt;
+	RPC_U8(&msg, 1U) = (uint8_t)max;
+	RPC_SIZE(&msg) = 2U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_set_dma_group(sc_ipc_t ipc, sc_rsrc_t resource,
+			       sc_misc_dma_group_t group)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SET_DMA_GROUP;
+	RPC_U16(&msg, 0U) = (uint16_t)resource;
+	RPC_U8(&msg, 2U) = (uint8_t)group;
+	RPC_SIZE(&msg) = 2U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_image_load(sc_ipc_t ipc, sc_faddr_t addr_src,
+				 sc_faddr_t addr_dst, uint32_t len,
+				 sc_bool_t fw)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_IMAGE_LOAD;
+	RPC_U32(&msg, 0U) = (uint32_t)(addr_src >> 32U);
+	RPC_U32(&msg, 4U) = (uint32_t)addr_src;
+	RPC_U32(&msg, 8U) = (uint32_t)(addr_dst >> 32U);
+	RPC_U32(&msg, 12U) = (uint32_t)addr_dst;
+	RPC_U32(&msg, 16U) = (uint32_t)len;
+	RPC_U8(&msg, 20U) = (uint8_t)fw;
+	RPC_SIZE(&msg) = 7U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_authenticate(sc_ipc_t ipc,
+				   sc_misc_seco_auth_cmd_t cmd, sc_faddr_t addr)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_AUTHENTICATE;
+	RPC_U32(&msg, 0U) = (uint32_t)(addr >> 32U);
+	RPC_U32(&msg, 4U) = (uint32_t)addr;
+	RPC_U8(&msg, 8U) = (uint8_t)cmd;
+	RPC_SIZE(&msg) = 4U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_fuse_write(sc_ipc_t ipc, sc_faddr_t addr)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_FUSE_WRITE;
+	RPC_U32(&msg, 0U) = (uint32_t)(addr >> 32U);
+	RPC_U32(&msg, 4U) = (uint32_t)addr;
+	RPC_SIZE(&msg) = 3U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_enable_debug(sc_ipc_t ipc, sc_faddr_t addr)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_ENABLE_DEBUG;
+	RPC_U32(&msg, 0U) = (uint32_t)(addr >> 32U);
+	RPC_U32(&msg, 4U) = (uint32_t)addr;
+	RPC_SIZE(&msg) = 3U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_forward_lifecycle(sc_ipc_t ipc, uint32_t lifecycle)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_FORWARD_LIFECYCLE;
+	RPC_U32(&msg, 0U) = (uint32_t)lifecycle;
+	RPC_SIZE(&msg) = 2U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_return_lifecycle(sc_ipc_t ipc, sc_faddr_t addr)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_RETURN_LIFECYCLE;
+	RPC_U32(&msg, 0U) = (uint32_t)(addr >> 32U);
+	RPC_U32(&msg, 4U) = (uint32_t)addr;
+	RPC_SIZE(&msg) = 3U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+void sc_misc_seco_build_info(sc_ipc_t ipc, uint32_t *version, uint32_t *commit)
+{
+	sc_rpc_msg_t msg;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_BUILD_INFO;
+	RPC_SIZE(&msg) = 1U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	if (version != NULL)
+		*version = RPC_U32(&msg, 0U);
+
+	if (commit != NULL)
+		*commit = RPC_U32(&msg, 4U);
+}
+
+sc_err_t sc_misc_seco_chip_info(sc_ipc_t ipc, uint16_t *lc,
+				uint16_t *monotonic, uint32_t *uid_l,
+				uint32_t *uid_h)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_CHIP_INFO;
+	RPC_SIZE(&msg) = 1U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	if (uid_l != NULL)
+		*uid_l = RPC_U32(&msg, 0U);
+
+	if (uid_h != NULL)
+		*uid_h = RPC_U32(&msg, 4U);
+
+	if (lc != NULL)
+		*lc = RPC_U16(&msg, 8U);
+
+	if (monotonic != NULL)
+		*monotonic = RPC_U16(&msg, 10U);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+void sc_misc_debug_out(sc_ipc_t ipc, uint8_t ch)
+{
+	sc_rpc_msg_t msg;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_DEBUG_OUT;
+	RPC_U8(&msg, 0U) = (uint8_t)ch;
+	RPC_SIZE(&msg) = 2U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+}
+
+sc_err_t sc_misc_waveform_capture(sc_ipc_t ipc, sc_bool_t enable)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_WAVEFORM_CAPTURE;
+	RPC_U8(&msg, 0U) = (uint8_t)enable;
+	RPC_SIZE(&msg) = 2U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+void sc_misc_build_info(sc_ipc_t ipc, uint32_t *build, uint32_t *commit)
+{
+	sc_rpc_msg_t msg;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_BUILD_INFO;
+	RPC_SIZE(&msg) = 1U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	if (build != NULL)
+		*build = RPC_U32(&msg, 0U);
+
+	if (commit != NULL)
+		*commit = RPC_U32(&msg, 4U);
+}
+
+void sc_misc_unique_id(sc_ipc_t ipc, uint32_t *id_l, uint32_t *id_h)
+{
+	sc_rpc_msg_t msg;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_UNIQUE_ID;
+	RPC_SIZE(&msg) = 1U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	if (id_l != NULL)
+		*id_l = RPC_U32(&msg, 0U);
+
+	if (id_h != NULL)
+		*id_h = RPC_U32(&msg, 4U);
+}
+
+sc_err_t sc_misc_set_ari(sc_ipc_t ipc, sc_rsrc_t resource,
+			 sc_rsrc_t resource_mst, uint16_t ari, sc_bool_t enable)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SET_ARI;
+	RPC_U16(&msg, 0U) = (uint16_t)resource;
+	RPC_U16(&msg, 2U) = (uint16_t)resource_mst;
+	RPC_U16(&msg, 4U) = (uint16_t)ari;
+	RPC_U8(&msg, 6U) = (uint8_t)enable;
+	RPC_SIZE(&msg) = 3U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status)
+{
+	sc_rpc_msg_t msg;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_BOOT_STATUS;
+	RPC_U8(&msg, 0U) = (uint8_t)status;
+	RPC_SIZE(&msg) = 2U;
+
+	sc_call_rpc(ipc, &msg, SC_TRUE);
+}
+
+sc_err_t sc_misc_boot_done(sc_ipc_t ipc, sc_rsrc_t cpu)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_BOOT_DONE;
+	RPC_U16(&msg, 0U) = (uint16_t)cpu;
+	RPC_SIZE(&msg) = 2U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_otp_fuse_read(sc_ipc_t ipc, uint32_t word, uint32_t *val)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_OTP_FUSE_READ;
+	RPC_U32(&msg, 0U) = (uint32_t)word;
+	RPC_SIZE(&msg) = 2U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	if (val != NULL)
+		*val = RPC_U32(&msg, 0U);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_otp_fuse_write(sc_ipc_t ipc, uint32_t word, uint32_t val)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_OTP_FUSE_WRITE;
+	RPC_U32(&msg, 0U) = (uint32_t)word;
+	RPC_U32(&msg, 4U) = (uint32_t)val;
+	RPC_SIZE(&msg) = 3U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_set_temp(sc_ipc_t ipc, sc_rsrc_t resource,
+			  sc_misc_temp_t temp, int16_t celsius, int8_t tenths)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SET_TEMP;
+	RPC_U16(&msg, 0U) = (uint16_t)resource;
+	RPC_I16(&msg, 2U) = (int16_t) celsius;
+	RPC_U8(&msg, 4U) = (uint8_t)temp;
+	RPC_I8(&msg, 5U) = (int8_t) tenths;
+	RPC_SIZE(&msg) = 3U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	result = RPC_R8(&msg);
+	return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_get_temp(sc_ipc_t ipc, sc_rsrc_t resource,
+			  sc_misc_temp_t temp, int16_t *celsius,
+			  int8_t *tenths)
+{
+	sc_rpc_msg_t msg;
+	uint8_t result;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_GET_TEMP;
+	RPC_U16(&msg, 0U) = (uint16_t)resource;
+	RPC_U8(&msg, 2U) = (uint8_t)temp;
+	RPC_SIZE(&msg) = 2U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	if (celsius != NULL)
+		*celsius = RPC_I16(&msg, 0U);
+
+	result = RPC_R8(&msg);
+	if (tenths != NULL)
+		*tenths = RPC_I8(&msg, 2U);
+
+	return (sc_err_t)result;
+}
+
+void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *dev)
+{
+	sc_rpc_msg_t msg;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_GET_BOOT_DEV;
+	RPC_SIZE(&msg) = 1U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	if (dev != NULL)
+		*dev = RPC_U16(&msg, 0U);
+}
+
+void sc_misc_get_button_status(sc_ipc_t ipc, sc_bool_t *status)
+{
+	sc_rpc_msg_t msg;
+
+	RPC_VER(&msg) = SC_RPC_VERSION;
+	RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+	RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_GET_BUTTON_STATUS;
+	RPC_SIZE(&msg) = 1U;
+
+	sc_call_rpc(ipc, &msg, SC_FALSE);
+
+	if (status != NULL)
+		*status = RPC_U8(&msg, 0U);
+}
+
+/**@}*/
diff --git a/plat/imx/common/sci/svc/misc/sci_misc_rpc.h b/plat/imx/common/sci/svc/misc/sci_misc_rpc.h
new file mode 100644
index 0000000..03b1a51
--- /dev/null
+++ b/plat/imx/common/sci/svc/misc/sci_misc_rpc.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ * Header file for the MISC RPC implementation.
+ *
+ * @addtogroup MISC_SVC
+ * @{
+ */
+
+#ifndef SC_MISC_RPC_H
+#define SC_MISC_RPC_H
+
+/* Includes */
+
+/* Defines */
+
+/*!
+ * @name Defines for RPC MISC function calls
+ */
+/*@{*/
+#define MISC_FUNC_UNKNOWN 0	/* Unknown function */
+#define MISC_FUNC_SET_CONTROL 1U	/* Index for misc_set_control() RPC call */
+#define MISC_FUNC_GET_CONTROL 2U	/* Index for misc_get_control() RPC call */
+#define MISC_FUNC_SET_MAX_DMA_GROUP 4U	/* Index for misc_set_max_dma_group() RPC call */
+#define MISC_FUNC_SET_DMA_GROUP 5U	/* Index for misc_set_dma_group() RPC call */
+#define MISC_FUNC_SECO_IMAGE_LOAD 8U	/* Index for misc_seco_image_load() RPC call */
+#define MISC_FUNC_SECO_AUTHENTICATE 9U	/* Index for misc_seco_authenticate() RPC call */
+#define MISC_FUNC_SECO_FUSE_WRITE 20U	/* Index for misc_seco_fuse_write() RPC call */
+#define MISC_FUNC_SECO_ENABLE_DEBUG 21U	/* Index for misc_seco_enable_debug() RPC call */
+#define MISC_FUNC_SECO_FORWARD_LIFECYCLE 22U	/* Index for misc_seco_forward_lifecycle() RPC call */
+#define MISC_FUNC_SECO_RETURN_LIFECYCLE 23U	/* Index for misc_seco_return_lifecycle() RPC call */
+#define MISC_FUNC_SECO_BUILD_INFO 24U	/* Index for misc_seco_build_info() RPC call */
+#define MISC_FUNC_SECO_CHIP_INFO 25U	/* Index for misc_seco_chip_info() RPC call */
+#define MISC_FUNC_DEBUG_OUT 10U	/* Index for misc_debug_out() RPC call */
+#define MISC_FUNC_WAVEFORM_CAPTURE 6U	/* Index for misc_waveform_capture() RPC call */
+#define MISC_FUNC_BUILD_INFO 15U	/* Index for misc_build_info() RPC call */
+#define MISC_FUNC_UNIQUE_ID 19U	/* Index for misc_unique_id() RPC call */
+#define MISC_FUNC_SET_ARI 3U	/* Index for misc_set_ari() RPC call */
+#define MISC_FUNC_BOOT_STATUS 7U	/* Index for misc_boot_status() RPC call */
+#define MISC_FUNC_BOOT_DONE 14U	/* Index for misc_boot_done() RPC call */
+#define MISC_FUNC_OTP_FUSE_READ 11U	/* Index for misc_otp_fuse_read() RPC call */
+#define MISC_FUNC_OTP_FUSE_WRITE 17U	/* Index for misc_otp_fuse_write() RPC call */
+#define MISC_FUNC_SET_TEMP 12U	/* Index for misc_set_temp() RPC call */
+#define MISC_FUNC_GET_TEMP 13U	/* Index for misc_get_temp() RPC call */
+#define MISC_FUNC_GET_BOOT_DEV 16U	/* Index for misc_get_boot_dev() RPC call */
+#define MISC_FUNC_GET_BUTTON_STATUS 18U	/* Index for misc_get_button_status() RPC call */
+/*@}*/
+
+/* Types */
+
+/* Functions */
+
+/*!
+ * This function dispatches an incoming MISC RPC request.
+ *
+ * @param[in]     caller_pt   caller partition
+ * @param[in]     msg         pointer to RPC message
+ */
+void misc_dispatch(sc_rm_pt_t caller_pt, sc_rpc_msg_t *msg);
+
+/*!
+ * This function translates and dispatches an MISC RPC request.
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     msg         pointer to RPC message
+ */
+void misc_xlate(sc_ipc_t ipc, sc_rpc_msg_t *msg);
+
+#endif				/* SC_MISC_RPC_H */
+
+/**@}*/
diff --git a/plat/imx/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/drivers/bpmp/bpmp.c b/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c
index 1867511..1c5d2e1 100644
--- a/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c
+++ b/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c
@@ -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 */
@@ -158,8 +158,7 @@
 		}
 
 		/* 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/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
index 1b221c2..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)
 {
-	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);
-		}
-	}
+	; /* do nothing */
 }
 
 /*
@@ -352,10 +51,9 @@
 
 	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 != NULL);
 	mc_streamid_override_regs = plat_mc_settings->streamid_override_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,16 +111,24 @@
  */
 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 != 0ULL) {
@@ -444,42 +154,10 @@
  */
 void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_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 enabled,
-	 * We need setup TZDRAM before CPU to access TZ Carveout,
-	 * otherwise CPU will fetch non-decrypted data.
-	 * So save TZDRAM setting for restore by SC7 resume FW.
-	 * 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;
-	mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV54_HI, val);
-
-	val |= tegra_mc_read_32(MC_SECURITY_CFG0_0) & MC_SECURITY_BOM_MASK;
-	mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV55_LO, val);
-
-	val = tegra_mc_read_32(MC_SECURITY_CFG3_0) & MC_SECURITY_BOM_HI_MASK;
-	mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV55_HI, val);
-
 	/*
-	 * 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);
 }
 
 /*
@@ -501,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);
@@ -534,6 +221,9 @@
 	val = tegra_mc_read_32(MC_TZRAM_CARVEOUT_CFG);
 	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);
 
 	/*
diff --git a/plat/nvidia/tegra/common/drivers/smmu/smmu.c b/plat/nvidia/tegra/common/drivers/smmu/smmu.c
index 789f11c..8c1b899 100644
--- a/plat/nvidia/tegra/common/drivers/smmu/smmu.c
+++ b/plat/nvidia/tegra/common/drivers/smmu/smmu.c
@@ -101,12 +101,13 @@
 	 * 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) {
+		ERROR("SMMU context size mismatch!");
 		panic();
 	}
 
@@ -123,9 +124,9 @@
 			(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));
 }
 
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
index f40244b..d4c3f95 100644
--- a/plat/nvidia/tegra/common/lib/debug/profiler.c
+++ b/plat/nvidia/tegra/common/lib/debug/profiler.c
@@ -26,8 +26,6 @@
 #include <mmio.h>
 #include <profiler.h>
 #include <stdbool.h>
-#include <stdio.h>
-#include <stdint.h>
 #include <string.h>
 #include <utils_def.h>
 #include <xlat_tables_v2.h>
diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c
index afb10fe..908e4f2 100644
--- a/plat/nvidia/tegra/common/tegra_bl31_setup.c
+++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c
@@ -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
@@ -227,6 +233,9 @@
 	 */
 	tegra_delay_timer_init();
 
+	/* Early platform setup for Tegra SoCs */
+	plat_early_platform_setup();
+
 	/*
 	 * Do initial security configuration to allow DRAM/device access.
 	 */
@@ -269,9 +278,6 @@
 		}
 	}
 
-	/* Early platform setup for Tegra SoCs */
-	plat_early_platform_setup();
-
 	/*
 	 * Add timestamp for platform early setup exit.
 	 */
@@ -329,6 +335,13 @@
 	tegra_memctrl_tzram_setup(TEGRA_TZRAM_BASE, TEGRA_TZRAM_SIZE);
 
 	/*
+	 * 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");
diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk
index 9428f43..d9eec4d 100644
--- a/plat/nvidia/tegra/common/tegra_common.mk
+++ b/plat/nvidia/tegra/common/tegra_common.mk
@@ -22,7 +22,6 @@
 
 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			\
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/memctrl_v2.h b/plat/nvidia/tegra/include/drivers/memctrl_v2.h
index 7eb2952..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			0x7FU
-
-/*******************************************************************************
- * 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
-
-/*******************************************************************************
  * Structure to hold the transaction override settings to use to override
  * client inputs
  ******************************************************************************/
@@ -229,6 +54,25 @@
 #define CLIENT_FLAG_NON_SECURE				1U
 #define CLIENT_INPUTS_OVERRIDE				1U
 #define CLIENT_INPUTS_NO_OVERRIDE			0U
+/*******************************************************************************
+ * StreamID to indicate no SMMU translations (requests to be steered on the
+ * SMMU bypass path)
+ ******************************************************************************/
+#define MC_STREAM_ID_MAX			0x7FU
+
+/*******************************************************************************
+ * Memory Controller SMMU Bypass config register
+ ******************************************************************************/
+#define MC_SMMU_BYPASS_CONFIG			0x1820U
+#define MC_SMMU_BYPASS_CTRL_MASK		0x3U
+#define MC_SMMU_BYPASS_CTRL_SHIFT		0U
+#define MC_SMMU_CTRL_TBU_BYPASS_ALL		(0U << MC_SMMU_BYPASS_CTRL_SHIFT)
+#define MC_SMMU_CTRL_TBU_RSVD			(1U << MC_SMMU_BYPASS_CTRL_SHIFT)
+#define MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID	(2U << MC_SMMU_BYPASS_CTRL_SHIFT)
+#define MC_SMMU_CTRL_TBU_BYPASS_NONE		(3U << MC_SMMU_BYPASS_CTRL_SHIFT)
+#define MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT	(1U << 31)
+#define MC_SMMU_BYPASS_CONFIG_SETTINGS		(MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT | \
+						 MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID)
 
 #define mc_make_sec_cfg(off, ns, ovrrd, access) \
 	{ \
@@ -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			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_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		3U
-
-/*******************************************************************************
- * 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
-
-/*******************************************************************************
- * 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);
@@ -410,6 +133,22 @@
 			(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) \
 	{ \
 		tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_##client, \
@@ -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/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 20a7994..231f93a 100644
--- a/plat/nvidia/tegra/include/t186/tegra_def.h
+++ b/plat/nvidia/tegra/include/t186/tegra_def.h
@@ -135,6 +135,7 @@
 #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)
@@ -165,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
@@ -232,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/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h
index f55f5df..68b4624 100644
--- a/plat/nvidia/tegra/include/tegra_private.h
+++ b/plat/nvidia/tegra/include/tegra_private.h
@@ -75,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);
@@ -126,7 +128,6 @@
 /* Declarations for tegra_bl31_setup.c */
 plat_params_from_bl2_t *bl31_get_plat_params(void);
 int32_t bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes);
-void plat_early_platform_setup(void);
 
 /* 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 ac110cc..614d2a2 100644
--- a/plat/nvidia/tegra/platform.mk
+++ b/plat/nvidia/tegra/platform.mk
@@ -40,5 +40,5 @@
 # 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/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 9c4e57c..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--;
@@ -503,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);
@@ -533,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);
 			}
diff --git a/plat/nvidia/tegra/soc/t186/plat_memctrl.c b/plat/nvidia/tegra/soc/t186/plat_memctrl.c
index 1e8d482..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,6 +205,318 @@
 	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
  ******************************************************************************/
@@ -210,7 +526,9 @@
 	.streamid_security_cfg = 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 = (uint32_t)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 a490bcc..09e257d 100644
--- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
@@ -22,15 +22,11 @@
 #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 uint64_t __tegra186_cpu_reset_handler_end,
-		__tegra186_smmu_context;
-
 /* state id mask */
 #define TEGRA186_STATE_ID_MASK		0xFU
 /* constants to get power state's wake time */
@@ -125,12 +121,11 @@
 
 		/* 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 */
@@ -139,6 +134,7 @@
 		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(
@@ -151,6 +147,10 @@
 		/* Instruct the MCE to enter system suspend state */
 		(void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE,
 			(uint64_t)TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0U);
+
+		/* set system suspend state for house-keeping */
+		tegra186_set_system_suspend_entry();
+
 	} else {
 		; /* do nothing */
 	}
@@ -281,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);
 	}
@@ -297,7 +296,7 @@
 	uint64_t target_cluster = (mpidr & MPIDR_CLUSTER_MASK) >>
 			MPIDR_AFFINITY_BITS;
 
-	if (target_cluster > MPIDR_AFFLVL1) {
+	if (target_cluster > ((uint32_t)PLATFORM_CLUSTER_COUNT - 1U)) {
 
 		ERROR("%s: unsupported CPU (0x%lx)\n", __func__, mpidr);
 		ret = PSCI_E_NOT_PRESENT;
diff --git a/plat/nvidia/tegra/soc/t186/plat_secondary.c b/plat/nvidia/tegra/soc/t186/plat_secondary.c
index 577cc38..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,38 +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);
+	/*
+	 * 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_smmu.c b/plat/nvidia/tegra/soc/t186/plat_smmu.c
index b9541e8..95f6def 100644
--- a/plat/nvidia/tegra/soc/t186/plat_smmu.c
+++ b/plat/nvidia/tegra/soc/t186/plat_smmu.c
@@ -8,6 +8,7 @@
 
 #include <smmu.h>
 #include <tegra_def.h>
+#include <tegra_mc_def.h>
 
 #define MAX_NUM_SMMU_DEVICES	U(1)
 
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 9dae8cd..fdeb886 100644
--- a/plat/nvidia/tegra/soc/t186/platform_t186.mk
+++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk
@@ -11,15 +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))
-
 RESET_TO_BL31				:= 1
 
 PROGRAMMABLE_RESET_ADDRESS		:= 1
@@ -45,7 +39,8 @@
 # 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 \
diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
index 958aa92..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)) &&
diff --git a/plat/nvidia/tegra/soc/t210/platform_t210.mk b/plat/nvidia/tegra/soc/t210/platform_t210.mk
index b8dbf18..e23d7e3 100644
--- a/plat/nvidia/tegra/soc/t210/platform_t210.mk
+++ b/plat/nvidia/tegra/soc/t210/platform_t210.mk
@@ -24,9 +24,10 @@
 
 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/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/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 9447f04..f1511c1 100644
--- a/plat/ti/k3/include/platform_def.h
+++ b/plat/ti/k3/include/platform_def.h
@@ -185,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/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 9741916..83c14b4 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;
 	}
@@ -445,8 +449,9 @@
 	ret = register_interrupt_type_handler(INTR_TYPE_S_EL1,
 					      trusty_fiq_handler,
 					      flags);
-	if (ret)
+	if (ret != 0) {
 		ERROR("trusty: failed to register fiq handler, ret = %d\n", ret);
+	}
 
 	if (aarch32) {
 		entry_point_info_t *ns_ep_info;