Merge "TF-A: Fix non-standard frequency issue in udelay" into integration
diff --git a/docs/change-log.rst b/docs/change-log.rst
index a0db2a9..cf5b57a 100644
--- a/docs/change-log.rst
+++ b/docs/change-log.rst
@@ -60,6 +60,10 @@
 
    - Neoverse Zeus: Apply the MSR SSBS instruction
 
+   - cortex-Hercules/HerculesAE: Support added for Cortex-Hercules and
+     Cortex-HerculesAE CPUs
+   - cortex-Hercules/HerculesAE: Enable AMU for Cortex-Hercules and Cortex-HerculesAE
+
    - cortex-a76AE: Support added for Cortex-A76AE CPU
    - cortex-a76: Workaround for erratum 1257314, 1262606, 1262888, 1275112,
      1286807
diff --git a/docs/security_advisories/security-advisory-tfv-5.rst b/docs/security_advisories/security-advisory-tfv-5.rst
index 2214f2d..97f7cd9 100644
--- a/docs/security_advisories/security-advisory-tfv-5.rst
+++ b/docs/security_advisories/security-advisory-tfv-5.rst
@@ -7,9 +7,9 @@
 +================+=============================================================+
 | CVE ID         | `CVE-2017-15031`_                                           |
 +----------------+-------------------------------------------------------------+
-| Date           | 02 Oct 2017                                                 |
+| Date           | 02 Oct 2017, updated on 04 Nov 2019                         |
 +----------------+-------------------------------------------------------------+
-| Versions       | All, up to and including v1.4                               |
+| Versions       | All, up to and including v2.1                               |
 | Affected       |                                                             |
 +----------------+-------------------------------------------------------------+
 | Configurations | All                                                         |
@@ -18,8 +18,12 @@
 | Impact         | Leakage of sensitive secure world timing information        |
 +----------------+-------------------------------------------------------------+
 | Fix Version    | `Pull Request #1127`_ (merged on 18 October 2017)           |
+|                |                                                             |
+|                | `Commit e290a8fcbc`_ (merged on 23 August 2019)             |
+|                |                                                             |
+|                | `Commit c3e8b0be9b`_ (merged on 27 September 2019)          |
 +----------------+-------------------------------------------------------------+
-| Credit         | Arm                                                         |
+| Credit         | Arm, Marek Bykowski                                         |
 +----------------+-------------------------------------------------------------+
 
 The ``PMCR_EL0`` (Performance Monitors Control Register) provides details of the
@@ -28,10 +32,11 @@
 bit is set to zero, the cycle counter (when enabled) counts during secure world
 execution, even when prohibited by the debug signals.
 
-Since Arm TF does not save and restore ``PMCR_EL0`` when switching between the
+Since TF-A does not save and restore ``PMCR_EL0`` when switching between the
 normal and secure worlds, normal world code can set ``PMCR_EL0.DP`` to zero to
 cause leakage of secure world timing information. This register should be added
-to the list of saved/restored registers.
+to the list of saved/restored registers both when entering EL3 and also
+transitioning to S-EL1.
 
 Furthermore, ``PMCR_EL0.DP`` has an architecturally ``UNKNOWN`` reset value.
 Since Arm TF does not initialize this register, it's possible that on at least
@@ -42,5 +47,11 @@
 The same issue exists for the equivalent AArch32 register, ``PMCR``, except that
 here ``PMCR_EL0.DP`` architecturally resets to zero.
 
+NOTE: The original pull request referenced above only fixed the issue for S-EL1
+whereas the EL3 was fixed in the later commits.
+
 .. _CVE-2017-15031: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-15031
 .. _Pull Request #1127: https://github.com/ARM-software/arm-trusted-firmware/pull/1127
+.. _Commit e290a8fcbc: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=e290a8fcbc
+.. _Commit c3e8b0be9b: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=c3e8b0be9b
+
diff --git a/drivers/arm/gic/v3/gic600_multichip.c b/drivers/arm/gic/v3/gic600_multichip.c
new file mode 100644
index 0000000..c62c3f5
--- /dev/null
+++ b/drivers/arm/gic/v3/gic600_multichip.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * GIC-600 driver extension for multichip setup
+ */
+
+#include <assert.h>
+#include <common/debug.h>
+
+#include <drivers/arm/gicv3.h>
+#include <drivers/arm/gic600_multichip.h>
+
+#include "gic600_multichip_private.h"
+#include "../common/gic_common_private.h"
+
+#warning "GIC-600 Multichip driver is currently experimental and the API may change in future."
+
+/*******************************************************************************
+ * GIC-600 multichip operation related helper functions
+ ******************************************************************************/
+static void gicd_dchipr_wait_for_power_update_progress(uintptr_t base)
+{
+	unsigned int retry = GICD_PUP_UPDATE_RETRIES;
+
+	while ((read_gicd_dchipr(base) & GICD_DCHIPR_PUP_BIT) != 0U) {
+		if (retry-- == 0) {
+			ERROR("GIC-600 connection to Routing Table Owner timed "
+					 "out\n");
+			panic();
+		}
+	}
+}
+
+/*******************************************************************************
+ * Sets up the routing table owner.
+ ******************************************************************************/
+static void set_gicd_dchipr_rt_owner(uintptr_t base, unsigned int rt_owner)
+{
+	/*
+	 * Ensure that Group enables in GICD_CTLR are disabled and no pending
+	 * register writes to GICD_CTLR.
+	 */
+	if ((gicd_read_ctlr(base) &
+			(CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1S_BIT |
+			 CTLR_ENABLE_G1NS_BIT | GICD_CTLR_RWP_BIT)) != 0) {
+		ERROR("GICD_CTLR group interrupts are either enabled or have "
+				"pending writes. Cannot set RT owner.\n");
+		panic();
+	}
+
+	/* Poll till PUP is zero before intiating write */
+	gicd_dchipr_wait_for_power_update_progress(base);
+
+	write_gicd_dchipr(base, read_gicd_dchipr(base) |
+			(rt_owner << GICD_DCHIPR_RT_OWNER_SHIFT));
+
+	/* Poll till PUP is zero to ensure write is complete */
+	gicd_dchipr_wait_for_power_update_progress(base);
+}
+
+/*******************************************************************************
+ * Configures the Chip Register to make connections to GICDs on
+ * a multichip platform.
+ ******************************************************************************/
+static void set_gicd_chipr_n(uintptr_t base,
+				unsigned int chip_id,
+				uint64_t chip_addr,
+				unsigned int spi_id_min,
+				unsigned int spi_id_max)
+{
+	unsigned int spi_block_min, spi_blocks;
+	uint64_t chipr_n_val;
+
+	/*
+	 * Ensure that group enables in GICD_CTLR are disabled and no pending
+	 * register writes to GICD_CTLR.
+	 */
+	if ((gicd_read_ctlr(base) &
+			(CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1S_BIT |
+			 CTLR_ENABLE_G1NS_BIT | GICD_CTLR_RWP_BIT)) != 0) {
+		ERROR("GICD_CTLR group interrupts are either enabled or have "
+				"pending writes. Cannot set CHIPR register.\n");
+		panic();
+	}
+
+	/*
+	 * spi_id_min and spi_id_max of value 0 is used to intidicate that the
+	 * chip doesn't own any SPI block. Re-assign min and max values as SPI
+	 * id starts from 32.
+	 */
+	if (spi_id_min == 0 && spi_id_max == 0) {
+		spi_id_min = GIC600_SPI_ID_MIN;
+		spi_id_max = GIC600_SPI_ID_MIN;
+	}
+
+	spi_block_min = SPI_BLOCK_MIN_VALUE(spi_id_min);
+	spi_blocks    = SPI_BLOCKS_VALUE(spi_id_min, spi_id_max);
+
+	chipr_n_val = (GICD_CHIPR_VALUE(chip_addr, spi_block_min, spi_blocks)) |
+		GICD_CHIPRx_SOCKET_STATE;
+
+	/*
+	 * Wait for DCHIPR.PUP to be zero before commencing writes to
+	 * GICD_CHIPRx.
+	 */
+	gicd_dchipr_wait_for_power_update_progress(base);
+
+	/*
+	 * Assign chip addr, spi min block, number of spi blocks and bring chip
+	 * online by setting SocketState.
+	 */
+	write_gicd_chipr_n(base, chip_id, chipr_n_val);
+
+	/*
+	 * Poll until DCHIP.PUP is zero to verify connection to rt_owner chip
+	 * is complete.
+	 */
+	gicd_dchipr_wait_for_power_update_progress(base);
+
+	/*
+	 * Ensure that write to GICD_CHIPRx is successful and the chip_n came
+	 * online.
+	 */
+	if (read_gicd_chipr_n(base, chip_id) != chipr_n_val) {
+		ERROR("GICD_CHIPR%u write failed\n", chip_id);
+		panic();
+	}
+
+	/* Ensure that chip is in consistent state */
+	if (((read_gicd_chipsr(base) & GICD_CHIPSR_RTS_MASK) >>
+				GICD_CHIPSR_RTS_SHIFT) !=
+			GICD_CHIPSR_RTS_STATE_CONSISTENT) {
+		ERROR("Chip %u routing table is not in consistent state\n",
+				chip_id);
+		panic();
+	}
+}
+
+/*******************************************************************************
+ * Validates the GIC-600 Multichip data structure passed by the platform.
+ ******************************************************************************/
+static void gic600_multichip_validate_data(
+		struct gic600_multichip_data *multichip_data)
+{
+	unsigned int i, spi_id_min, spi_id_max, blocks_of_32;
+	unsigned int multichip_spi_blocks = 0;
+
+	assert(multichip_data != NULL);
+
+	if (multichip_data->chip_count > GIC600_MAX_MULTICHIP) {
+		ERROR("GIC-600 Multichip count should not exceed %d\n",
+				GIC600_MAX_MULTICHIP);
+		panic();
+	}
+
+	for (i = 0; i < multichip_data->chip_count; i++) {
+		spi_id_min = multichip_data->spi_ids[i][SPI_MIN_INDEX];
+		spi_id_max = multichip_data->spi_ids[i][SPI_MAX_INDEX];
+
+		if ((spi_id_min != 0) || (spi_id_max != 0)) {
+
+			/* SPI IDs range check */
+			if (!(spi_id_min >= GIC600_SPI_ID_MIN) ||
+			    !(spi_id_max < GIC600_SPI_ID_MAX) ||
+			    !(spi_id_min <= spi_id_max) ||
+			    !((spi_id_max - spi_id_min + 1) % 32 == 0)) {
+				ERROR("Invalid SPI IDs {%u, %u} passed for "
+						"Chip %u\n", spi_id_min,
+						spi_id_max, i);
+				panic();
+			}
+
+			/* SPI IDs overlap check */
+			blocks_of_32 = BLOCKS_OF_32(spi_id_min, spi_id_max);
+			if ((multichip_spi_blocks & blocks_of_32) != 0) {
+				ERROR("SPI IDs of Chip %u overlapping\n", i);
+				panic();
+			}
+			multichip_spi_blocks |= blocks_of_32;
+		}
+	}
+}
+
+/*******************************************************************************
+ * Intialize GIC-600 Multichip operation.
+ ******************************************************************************/
+void gic600_multichip_init(struct gic600_multichip_data *multichip_data)
+{
+	unsigned int i;
+
+	gic600_multichip_validate_data(multichip_data);
+
+	INFO("GIC-600 Multichip driver is experimental\n");
+
+	/*
+	 * Ensure that G0/G1S/G1NS interrupts are disabled. This also ensures
+	 * that GIC-600 Multichip configuration is done first.
+	 */
+	if ((gicd_read_ctlr(multichip_data->rt_owner_base) &
+			(CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1S_BIT |
+			 CTLR_ENABLE_G1NS_BIT | GICD_CTLR_RWP_BIT)) != 0) {
+		ERROR("GICD_CTLR group interrupts are either enabled or have "
+				"pending writes.\n");
+		panic();
+	}
+
+	/* Ensure that the routing table owner is in disconnected state */
+	if (((read_gicd_chipsr(multichip_data->rt_owner_base) &
+		GICD_CHIPSR_RTS_MASK) >> GICD_CHIPSR_RTS_SHIFT) !=
+			GICD_CHIPSR_RTS_STATE_DISCONNECTED) {
+		ERROR("GIC-600 routing table owner is not in disconnected "
+				"state to begin multichip configuration\n");
+		panic();
+	}
+
+	/* Initialize the GICD which is marked as routing table owner first */
+	set_gicd_dchipr_rt_owner(multichip_data->rt_owner_base,
+			multichip_data->rt_owner);
+
+	set_gicd_chipr_n(multichip_data->rt_owner_base, multichip_data->rt_owner,
+			multichip_data->chip_addrs[multichip_data->rt_owner],
+			multichip_data->
+			spi_ids[multichip_data->rt_owner][SPI_MIN_INDEX],
+			multichip_data->
+			spi_ids[multichip_data->rt_owner][SPI_MAX_INDEX]);
+
+	for (i = 0; i < multichip_data->chip_count; i++) {
+		if (i == multichip_data->rt_owner)
+			continue;
+
+		set_gicd_chipr_n(multichip_data->rt_owner_base, i,
+				multichip_data->chip_addrs[i],
+				multichip_data->spi_ids[i][SPI_MIN_INDEX],
+				multichip_data->spi_ids[i][SPI_MAX_INDEX]);
+	}
+}
diff --git a/drivers/arm/gic/v3/gic600_multichip_private.h b/drivers/arm/gic/v3/gic600_multichip_private.h
new file mode 100644
index 0000000..b0217b6
--- /dev/null
+++ b/drivers/arm/gic/v3/gic600_multichip_private.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2019, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef GIC600_MULTICHIP_PRIVATE_H
+#define GIC600_MULTICHIP_PRIVATE_H
+
+#include <drivers/arm/gic600_multichip.h>
+
+#include "gicv3_private.h"
+
+/* GIC600 GICD multichip related offsets */
+#define GICD_CHIPSR			U(0xC000)
+#define GICD_DCHIPR			U(0xC004)
+#define GICD_CHIPR			U(0xC008)
+
+/* GIC600 GICD multichip related masks */
+#define GICD_CHIPRx_PUP_BIT		BIT_64(1)
+#define GICD_CHIPRx_SOCKET_STATE	BIT_64(0)
+#define GICD_DCHIPR_PUP_BIT		BIT_32(0)
+#define GICD_CHIPSR_RTS_MASK		(BIT_32(4) | BIT_32(5))
+
+/* GIC600 GICD multichip related shifts */
+#define GICD_CHIPRx_ADDR_SHIFT		16
+#define GICD_CHIPRx_SPI_BLOCK_MIN_SHIFT	10
+#define GICD_CHIPRx_SPI_BLOCKS_SHIFT	5
+#define GICD_CHIPSR_RTS_SHIFT		4
+#define GICD_DCHIPR_RT_OWNER_SHIFT	4
+
+#define GICD_CHIPSR_RTS_STATE_DISCONNECTED	U(0)
+#define GICD_CHIPSR_RTS_STATE_UPDATING		U(1)
+#define GICD_CHIPSR_RTS_STATE_CONSISTENT	U(2)
+
+/* SPI interrupt id minimum and maximum range */
+#define GIC600_SPI_ID_MIN		32
+#define GIC600_SPI_ID_MAX		960
+
+/* Number of retries for PUP update */
+#define GICD_PUP_UPDATE_RETRIES		10000
+
+#define SPI_MIN_INDEX			0
+#define SPI_MAX_INDEX			1
+
+#define SPI_BLOCK_MIN_VALUE(spi_id_min) \
+			(((spi_id_min) - GIC600_SPI_ID_MIN) / \
+			GIC600_SPI_ID_MIN)
+#define SPI_BLOCKS_VALUE(spi_id_min, spi_id_max) \
+			(((spi_id_max) - (spi_id_min) + 1) / \
+			GIC600_SPI_ID_MIN)
+#define GICD_CHIPR_VALUE(chip_addr, spi_block_min, spi_blocks) \
+			(((chip_addr) << GICD_CHIPRx_ADDR_SHIFT) | \
+			((spi_block_min) << GICD_CHIPRx_SPI_BLOCK_MIN_SHIFT) | \
+			((spi_blocks) << GICD_CHIPRx_SPI_BLOCKS_SHIFT))
+
+/*
+ * Multichip data assertion macros
+ */
+/* Set bits from 0 to ((spi_id_max + 1) / 32) */
+#define SPI_BLOCKS_TILL_MAX(spi_id_max)	((1 << (((spi_id_max) + 1) >> 5)) - 1)
+/* Set bits from 0 to (spi_id_min / 32) */
+#define SPI_BLOCKS_TILL_MIN(spi_id_min)	((1 << ((spi_id_min) >> 5)) - 1)
+/* Set bits from (spi_id_min / 32) to ((spi_id_max + 1) / 32) */
+#define BLOCKS_OF_32(spi_id_min, spi_id_max) \
+					SPI_BLOCKS_TILL_MAX(spi_id_max) ^ \
+					SPI_BLOCKS_TILL_MIN(spi_id_min)
+
+/*******************************************************************************
+ * GIC-600 multichip operation related helper functions
+ ******************************************************************************/
+static inline uint32_t read_gicd_dchipr(uintptr_t base)
+{
+	return mmio_read_32(base + GICD_DCHIPR);
+}
+
+static inline uint64_t read_gicd_chipr_n(uintptr_t base, uint8_t n)
+{
+	return mmio_read_64(base + (GICD_CHIPR + (8U * n)));
+}
+
+static inline uint32_t read_gicd_chipsr(uintptr_t base)
+{
+	return mmio_read_32(base + GICD_CHIPSR);
+}
+
+static inline void write_gicd_dchipr(uintptr_t base, uint32_t val)
+{
+	mmio_write_32(base + GICD_DCHIPR, val);
+}
+
+static inline void write_gicd_chipr_n(uintptr_t base, uint8_t n, uint64_t val)
+{
+	mmio_write_64(base + (GICD_CHIPR + (8U * n)), val);
+}
+
+#endif /* GIC600_MULTICHIP_PRIVATE_H */
diff --git a/drivers/arm/smmu/smmu_v3.c b/drivers/arm/smmu/smmu_v3.c
index 5493b85..a082a81 100644
--- a/drivers/arm/smmu/smmu_v3.c
+++ b/drivers/arm/smmu/smmu_v3.c
@@ -7,23 +7,27 @@
 #include <common/debug.h>
 #include <cdefs.h>
 #include <drivers/arm/smmu_v3.h>
+#include <drivers/delay_timer.h>
 #include <lib/mmio.h>
 
 /* SMMU poll number of retries */
-#define SMMU_POLL_RETRY		1000000
+#define SMMU_POLL_TIMEOUT_US	U(1000)
 
 static int __init smmuv3_poll(uintptr_t smmu_reg, uint32_t mask,
 				uint32_t value)
 {
-	uint32_t reg_val, retries = SMMU_POLL_RETRY;
+	uint32_t reg_val;
+	uint64_t timeout;
 
+	/* Set 1ms timeout value */
+	timeout = timeout_init_us(SMMU_POLL_TIMEOUT_US);
 	do {
 		reg_val = mmio_read_32(smmu_reg);
 		if ((reg_val & mask) == value)
 			return 0;
-	} while (--retries != 0U);
+	} while (!timeout_elapsed(timeout));
 
-	ERROR("Failed to poll SMMUv3 register @%p\n", (void *)smmu_reg);
+	ERROR("Timeout polling SMMUv3 register @%p\n", (void *)smmu_reg);
 	ERROR("Read value 0x%x, expected 0x%x\n", reg_val,
 		value == 0U ? reg_val & ~mask : reg_val | mask);
 	return -1;
diff --git a/include/drivers/arm/gic600_multichip.h b/include/drivers/arm/gic600_multichip.h
new file mode 100644
index 0000000..bda406b
--- /dev/null
+++ b/include/drivers/arm/gic600_multichip.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2019, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef GIC600_MULTICHIP_H
+#define GIC600_MULTICHIP_H
+
+#include <stdint.h>
+
+/*
+ * GIC-600 microarchitecture supports coherent multichip environments containing
+ * up to 16 chips.
+ */
+#define GIC600_MAX_MULTICHIP	16
+
+/* SPI IDs array consist of min and max ids */
+#define GIC600_SPI_IDS_SIZE	2
+
+/*******************************************************************************
+ * GIC-600 multichip data structure describes platform specific attributes
+ * related to GIC-600 multichip. Platform port is expected to define these
+ * attributes to initialize the multichip related registers and create
+ * successful connections between the GIC-600s in a multichip system.
+ *
+ * The 'rt_owner_base' field contains the base address of the GIC Distributor
+ * which owns the routing table.
+ *
+ * The 'rt_owner' field contains the chip number which owns the routing table.
+ * Chip number or chip_id starts from 0.
+ *
+ * The 'chip_count' field contains the total number of chips in a multichip
+ * system. This should match the number of entries in 'chip_addrs' and 'spi_ids'
+ * fields.
+ *
+ * The 'chip_addrs' field contains array of chip addresses. These addresses are
+ * implementation specific values.
+ *
+ * The 'spi_ids' field contains array of minimum and maximum SPI interrupt ids
+ * that each chip owns. Note that SPI interrupt ids can range from 32 to 960 and
+ * it should be group of 32 (i.e., SPI minimum and (SPI maximum + 1) should be
+ * a multiple of 32). If a chip doesn't own any SPI interrupts a value of {0, 0}
+ * should be passed.
+ ******************************************************************************/
+struct gic600_multichip_data {
+	uintptr_t rt_owner_base;
+	unsigned int rt_owner;
+	unsigned int chip_count;
+	uint64_t chip_addrs[GIC600_MAX_MULTICHIP];
+	unsigned int spi_ids[GIC600_MAX_MULTICHIP][GIC600_SPI_IDS_SIZE];
+};
+
+void gic600_multichip_init(struct gic600_multichip_data *multichip_data);
+#endif /* GIC600_MULTICHIP_H */
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 53bd13f..941190f 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -403,21 +403,16 @@
 #define BL31_LIMIT			(ARM_AP_TZC_DRAM1_BASE +	\
 						PLAT_ARM_MAX_BL31_SIZE)
 #elif (RESET_TO_BL31)
-
-# if ENABLE_PIE
+/* Ensure Position Independent support (PIE) is enabled for this config.*/
+# if !ENABLE_PIE
+#  error "BL31 must be a PIE if RESET_TO_BL31=1."
+#endif
 /*
  * Since this is PIE, we can define BL31_BASE to 0x0 since this macro is solely
  * used for building BL31 and not used for loading BL31.
  */
 #  define BL31_BASE			0x0
 #  define BL31_LIMIT			PLAT_ARM_MAX_BL31_SIZE
-# else
-/* Put BL31_BASE in the middle of the Trusted SRAM.*/
-#  define BL31_BASE			(ARM_TRUSTED_SRAM_BASE + \
-					(PLAT_ARM_TRUSTED_SRAM_SIZE >> 1))
-#  define BL31_LIMIT			(ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)
-# endif /* ENABLE_PIE */
-
 #else
 /* Put BL31 below BL2 in the Trusted SRAM.*/
 #define BL31_BASE			((ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)\
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 07a46c5..c00a041 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -254,6 +254,11 @@
 int plat_arm_bl1_fwu_needed(void);
 __dead2 void plat_arm_error_handler(int err);
 
+/*
+ * Optional function in ARM standard platforms
+ */
+void plat_arm_override_gicr_frames(const uintptr_t *plat_gicr_frames);
+
 #if ARM_PLAT_MT
 unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr);
 #endif
diff --git a/lib/cpus/aarch64/neoverse_n1.S b/lib/cpus/aarch64/neoverse_n1.S
index c9bb005..faf53a8 100644
--- a/lib/cpus/aarch64/neoverse_n1.S
+++ b/lib/cpus/aarch64/neoverse_n1.S
@@ -21,9 +21,7 @@
 #error "Neoverse-N1 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
 #endif
 
-#if ERRATA_N1_IC_TRAP
 	.global neoverse_n1_errata_ic_trap_handler
-#endif
 
 /* --------------------------------------------------
  * Errata Workaround for Neoverse N1 Erratum 1043202.
@@ -356,7 +354,7 @@
 	bl	check_errata_1542419
 	cbz	x0, 1f
 
-        /* Apply instruction patching sequence */
+	/* Apply instruction patching sequence */
 	ldr	x0, =0x0
 	msr	CPUPSELR_EL3, x0
 	ldr	x0, =0xEE670D35
@@ -536,10 +534,10 @@
 	tlbi	vae3is, xzr
 	dsb	sy
 
-        # Skip the IC instruction itself
-        mrs     x3, elr_el3
-        add     x3, x3, #4
-        msr     elr_el3, x3
+	# Skip the IC instruction itself
+	mrs     x3, elr_el3
+	add     x3, x3, #4
+	msr     elr_el3, x3
 
 	ldp	x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
 	ldp	x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
diff --git a/lib/stack_protector/stack_protector.mk b/lib/stack_protector/stack_protector.mk
index 94e804b..b5aba15 100644
--- a/lib/stack_protector/stack_protector.mk
+++ b/lib/stack_protector/stack_protector.mk
@@ -11,7 +11,9 @@
   ENABLE_STACK_PROTECTOR := none
 endif
 
-ifneq (${ENABLE_STACK_PROTECTOR},none)
+ifeq (${ENABLE_STACK_PROTECTOR},none)
+  TF_CFLAGS            +=      -fno-stack-protector
+else
   STACK_PROTECTOR_ENABLED := 1
   BL_COMMON_SOURCES	+=	lib/stack_protector/stack_protector.c	\
 				lib/stack_protector/${ARCH}/asm_stack_protector.S
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 317f0ba..3a9972b 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -244,15 +244,10 @@
 # Enable dynamic mitigation support by default
 DYNAMIC_WORKAROUND_CVE_2018_3639	:=	1
 
+# Enable reclaiming of BL31 initialisation code for secondary cores
+# stacks for FVP.
 ifneq (${RESET_TO_BL31},1)
-# Enable reclaiming of BL31 initialisation code for secondary cores stacks for
-# FVP. We cannot enable PIE for this case because the overlayed init section
-# creates some dynamic relocations which cannot be handled by the fixup
-# logic currently.
 RECLAIM_INIT_CODE	:=	1
-else
-# Enable PIE support when RESET_TO_BL31=1
-ENABLE_PIE		:=	1
 endif
 
 ifeq (${ENABLE_AMU},1)
diff --git a/plat/arm/board/n1sdp/aarch64/n1sdp_helper.S b/plat/arm/board/n1sdp/aarch64/n1sdp_helper.S
index c03185a..3da55b6 100644
--- a/plat/arm/board/n1sdp/aarch64/n1sdp_helper.S
+++ b/plat/arm/board/n1sdp/aarch64/n1sdp_helper.S
@@ -17,19 +17,20 @@
 	 * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
 	 *
 	 * Helper function to calculate the core position.
-	 * (ClusterId * N1SDP_MAX_CPUS_PER_CLUSTER * N1SDP_MAX_PE_PER_CPU) +
-	 * (CPUId * N1SDP_MAX_PE_PER_CPU) +
-	 * ThreadId
+	 * ((ChipId * N1SDP_MAX_CLUSTERS_PER_CHIP + ClusterId) *
+	 * N1SDP_MAX_CPUS_PER_CLUSTER * N1SDP_MAX_PE_PER_CPU) +
+	 * (CPUId * N1SDP_MAX_PE_PER_CPU) + ThreadId
 	 *
 	 * which can be simplified as:
 	 *
-	 * ((ClusterId * N1SDP_MAX_CPUS_PER_CLUSTER + CPUId) *
-	 * N1SDP_MAX_PE_PER_CPU) + ThreadId
+	 * (((ChipId * N1SDP_MAX_CLUSTERS_PER_CHIP + ClusterId) *
+	 * N1SDP_MAX_CPUS_PER_CLUSTER + CPUId) * N1SDP_MAX_PE_PER_CPU) +
+	 * ThreadId
 	 * ------------------------------------------------------
 	 */
 
 func plat_arm_calc_core_pos
-	mov	x3, x0
+	mov	x4, x0
 
 	/*
 	 * The MT bit in MPIDR is always set for n1sdp and the
@@ -37,15 +38,18 @@
 	 */
 
 	/* Extract individual affinity fields from MPIDR */
-	ubfx	x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
-	ubfx	x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
-	ubfx	x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
+	ubfx	x0, x4, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
+	ubfx	x1, x4, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
+	ubfx	x2, x4, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
+	ubfx	x3, x4, #MPIDR_AFF3_SHIFT, #MPIDR_AFFINITY_BITS
 
 	/* Compute linear position */
+	mov	x4, #N1SDP_MAX_CLUSTERS_PER_CHIP
+	madd	x2, x3, x4, x2
 	mov	x4, #N1SDP_MAX_CPUS_PER_CLUSTER
 	madd	x1, x2, x4, x1
-	mov	x5, #N1SDP_MAX_PE_PER_CPU
-	madd	x0, x1, x5, x0
+	mov	x4, #N1SDP_MAX_PE_PER_CPU
+	madd	x0, x1, x4, x0
 	ret
 endfunc plat_arm_calc_core_pos
 
diff --git a/plat/arm/board/n1sdp/include/platform_def.h b/plat/arm/board/n1sdp/include/platform_def.h
index 7348bf5..6a309e8 100644
--- a/plat/arm/board/n1sdp/include/platform_def.h
+++ b/plat/arm/board/n1sdp/include/platform_def.h
@@ -27,16 +27,27 @@
 #define PLAT_ARM_DRAM2_BASE			ULL(0x8080000000)
 #define PLAT_ARM_DRAM2_SIZE			ULL(0xF80000000)
 
+/* N1SDP remote chip at 4 TB offset */
+#define PLAT_ARM_REMOTE_CHIP_OFFSET		(ULL(1) << 42)
+
+#define N1SDP_REMOTE_DRAM1_BASE			ARM_DRAM1_BASE + \
+						PLAT_ARM_REMOTE_CHIP_OFFSET
+#define N1SDP_REMOTE_DRAM1_SIZE			ARM_DRAM1_SIZE
+
+#define N1SDP_REMOTE_DRAM2_BASE			PLAT_ARM_DRAM2_BASE + \
+						PLAT_ARM_REMOTE_CHIP_OFFSET
+#define N1SDP_REMOTE_DRAM2_SIZE			PLAT_ARM_DRAM2_SIZE
+
 /*
  * N1SDP platform supports RDIMMs with ECC capability. To use the ECC
  * capability, the entire DDR memory space has to be zeroed out before
- * enabling the ECC bits in DMC620. The access the complete DDR memory
- * space the physical & virtual address space limits are extended to
- * 40-bits.
+ * enabling the ECC bits in DMC620. To access the complete DDR memory
+ * along with remote chip's DDR memory, which is at 4 TB offset, physical
+ * and virtual address space limits are extended to 43-bits.
  */
 #ifdef __aarch64__
-#define PLAT_PHY_ADDR_SPACE_SIZE		(1ULL << 40)
-#define PLAT_VIRT_ADDR_SPACE_SIZE		(1ULL << 40)
+#define PLAT_PHY_ADDR_SPACE_SIZE		(1ULL << 43)
+#define PLAT_VIRT_ADDR_SPACE_SIZE		(1ULL << 43)
 #else
 #define PLAT_PHY_ADDR_SPACE_SIZE		(1ULL << 32)
 #define PLAT_VIRT_ADDR_SPACE_SIZE		(1ULL << 32)
@@ -51,34 +62,36 @@
 #define PLAT_ARM_TRUSTED_SRAM_SIZE		0x00080000	/* 512 KB */
 #define PLAT_ARM_MAX_BL31_SIZE			0X20000
 
-
 /*******************************************************************************
  * N1SDP topology related constants
  ******************************************************************************/
-#define N1SDP_MAX_CPUS_PER_CLUSTER		2
-#define PLAT_ARM_CLUSTER_COUNT			2
-#define N1SDP_MAX_PE_PER_CPU			1
+#define N1SDP_MAX_CPUS_PER_CLUSTER		U(2)
+#define PLAT_ARM_CLUSTER_COUNT			U(2)
+#define PLAT_N1SDP_CHIP_COUNT			U(2)
+#define N1SDP_MAX_CLUSTERS_PER_CHIP		U(2)
+#define N1SDP_MAX_PE_PER_CPU			U(1)
 
-#define PLATFORM_CORE_COUNT			(PLAT_ARM_CLUSTER_COUNT *	\
+#define PLATFORM_CORE_COUNT			(PLAT_N1SDP_CHIP_COUNT *	\
+						PLAT_ARM_CLUSTER_COUNT *	\
 						N1SDP_MAX_CPUS_PER_CLUSTER *	\
 						N1SDP_MAX_PE_PER_CPU)
 
 /* System power domain level */
-#define CSS_SYSTEM_PWR_DMN_LVL			ARM_PWR_LVL2
+#define CSS_SYSTEM_PWR_DMN_LVL			ARM_PWR_LVL3
 
 /*
  * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
  * plat_arm_mmap array defined for each BL stage.
  */
-#define PLAT_ARM_MMAP_ENTRIES			6
-#define MAX_XLAT_TABLES				7
+#define PLAT_ARM_MMAP_ENTRIES			9
+#define MAX_XLAT_TABLES				10
 
 #define PLATFORM_STACK_SIZE			0x400
 
 #define PLAT_ARM_NSTIMER_FRAME_ID		0
 #define PLAT_CSS_MHU_BASE			0x45000000
 #define PLAT_MHUV2_BASE				PLAT_CSS_MHU_BASE
-#define PLAT_MAX_PWR_LVL			1
+#define PLAT_MAX_PWR_LVL			2
 
 #define PLAT_ARM_G1S_IRQS			ARM_G1S_IRQS,			\
 						CSS_IRQ_MHU
@@ -88,17 +101,36 @@
 #define PLAT_ARM_G0_IRQ_PROPS(grp)		ARM_G0_IRQ_PROPS(grp)
 
 
-#define N1SDP_DEVICE_BASE			(0x08000000)
-#define N1SDP_DEVICE_SIZE			(0x48000000)
-#define N1SDP_MAP_DEVICE			MAP_REGION_FLAT(	\
-						N1SDP_DEVICE_BASE,	\
-						N1SDP_DEVICE_SIZE,	\
-						MT_DEVICE | MT_RW | MT_SECURE)
+#define N1SDP_DEVICE_BASE			ULL(0x08000000)
+#define N1SDP_DEVICE_SIZE			ULL(0x48000000)
+#define N1SDP_REMOTE_DEVICE_BASE		N1SDP_DEVICE_BASE + \
+						PLAT_ARM_REMOTE_CHIP_OFFSET
+#define N1SDP_REMOTE_DEVICE_SIZE		N1SDP_DEVICE_SIZE
+
+#define N1SDP_MAP_DEVICE		MAP_REGION_FLAT(	\
+					N1SDP_DEVICE_BASE,	\
+					N1SDP_DEVICE_SIZE,	\
+					MT_DEVICE | MT_RW | MT_SECURE)
+
+#define ARM_MAP_DRAM1			MAP_REGION_FLAT(	\
+					ARM_DRAM1_BASE,		\
+					ARM_DRAM1_SIZE,		\
+					MT_MEMORY | MT_RW | MT_NS)
+
+#define N1SDP_MAP_REMOTE_DEVICE		MAP_REGION_FLAT(		\
+					N1SDP_REMOTE_DEVICE_BASE,	\
+					N1SDP_REMOTE_DEVICE_SIZE,	\
+					MT_DEVICE | MT_RW | MT_SECURE)
+
+#define N1SDP_MAP_REMOTE_DRAM1		MAP_REGION_FLAT(		\
+					N1SDP_REMOTE_DRAM1_BASE,	\
+					N1SDP_REMOTE_DRAM1_SIZE,	\
+					MT_MEMORY | MT_RW | MT_NS)
 
-#define ARM_MAP_DRAM1				MAP_REGION_FLAT(	\
-						ARM_DRAM1_BASE,		\
-						ARM_DRAM1_SIZE,		\
-						MT_MEMORY | MT_RW | MT_NS)
+#define N1SDP_MAP_REMOTE_DRAM2		MAP_REGION_FLAT(		\
+					N1SDP_REMOTE_DRAM2_BASE,	\
+					N1SDP_REMOTE_DRAM2_SIZE,	\
+					MT_MEMORY | MT_RW | MT_NS)
 
 /* GIC related constants */
 #define PLAT_ARM_GICD_BASE			0x30000000
diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
index 632af7b..4f158ee 100644
--- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
+++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +9,7 @@
 #include <drivers/arm/css/css_mhu_doorbell.h>
 #include <drivers/arm/css/scmi.h>
 #include <drivers/arm/css/sds.h>
+#include <drivers/arm/gic600_multichip.h>
 #include <common/debug.h>
 #include <lib/mmio.h>
 #include <lib/utils.h>
@@ -17,14 +18,22 @@
 #include "n1sdp_def.h"
 
 /*
- * Memory information structure stored in SDS.
- * This structure holds the total DDR memory size which will be
- * used when zeroing out the entire DDR memory before enabling
- * the ECC capability in DMCs.
+ * Platform information structure stored in SDS.
+ * This structure holds information about platform's DDR
+ * size which will be used to zero out the memory before
+ * enabling the ECC capability as well as information
+ * about multichip setup
+ * 	- multichip mode
+ * 	- slave_count
+ * 	- Local DDR size in GB, DDR memory in master board
+ * 	- Remote DDR size in GB, DDR memory in slave board
  */
-struct n1sdp_mem_info {
-	uint32_t ddr_size_gb;
-};
+struct n1sdp_plat_info {
+	bool multichip_mode;
+	uint8_t slave_count;
+	uint8_t local_ddr_size;
+	uint8_t remote_ddr_size;
+} __packed;
 
 /*
  * BL33 image information structure stored in SDS.
@@ -38,13 +47,33 @@
 };
 
 static scmi_channel_plat_info_t n1sdp_scmi_plat_info = {
-		.scmi_mbx_mem = N1SDP_SCMI_PAYLOAD_BASE,
-		.db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
-		.db_preserve_mask = 0xfffffffe,
-		.db_modify_mask = 0x1,
-		.ring_doorbell = &mhu_ring_doorbell,
+	.scmi_mbx_mem = N1SDP_SCMI_PAYLOAD_BASE,
+	.db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
+	.db_preserve_mask = 0xfffffffe,
+	.db_modify_mask = 0x1,
+	.ring_doorbell = &mhu_ring_doorbell
+};
+
+static struct gic600_multichip_data n1sdp_multichip_data __init = {
+	.rt_owner_base = PLAT_ARM_GICD_BASE,
+	.rt_owner = 0,
+	.chip_count = 1,
+	.chip_addrs = {
+		PLAT_ARM_GICD_BASE >> 16,
+		PLAT_ARM_GICD_BASE >> 16
+	},
+	.spi_ids = {
+		{32, 255},
+		{0, 0}
+	}
 };
 
+static uintptr_t n1sdp_multichip_gicr_frames[3] = {
+	PLAT_ARM_GICR_BASE,
+	PLAT_ARM_GICR_BASE + PLAT_ARM_REMOTE_CHIP_OFFSET,
+	0
+};
+
 scmi_channel_plat_info_t *plat_css_get_scmi_info()
 {
 	return &n1sdp_scmi_plat_info;
@@ -66,7 +95,7 @@
  * from IOFPGA-DDR3 memory to main DDR4 memory.
  */
 
-void dmc_ecc_setup(uint32_t ddr_size_gb)
+void dmc_ecc_setup(uint8_t ddr_size_gb)
 {
 	uint64_t dram2_size;
 
@@ -93,6 +122,38 @@
 	mmio_write_32(N1SDP_DMC1_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_READY);
 }
 
+void remote_dmc_ecc_setup(uint8_t remote_ddr_size)
+{
+	uint64_t remote_dram2_size;
+
+	remote_dram2_size = (remote_ddr_size * 1024UL * 1024UL * 1024UL) -
+				N1SDP_REMOTE_DRAM1_SIZE;
+	/* multichip setup */
+	INFO("Zeroing remote DDR memories\n");
+	zero_normalmem((void *)N1SDP_REMOTE_DRAM1_BASE,
+			N1SDP_REMOTE_DRAM1_SIZE);
+	flush_dcache_range(N1SDP_REMOTE_DRAM1_BASE, N1SDP_REMOTE_DRAM1_SIZE);
+	zero_normalmem((void *)N1SDP_REMOTE_DRAM2_BASE, remote_dram2_size);
+	flush_dcache_range(N1SDP_REMOTE_DRAM2_BASE, remote_dram2_size);
+
+	INFO("Enabling ECC on remote DMCs\n");
+	/* Set DMCs to CONFIG state before writing ERR0CTLR0 register */
+	mmio_write_32(N1SDP_REMOTE_DMC0_MEMC_CMD_REG,
+			N1SDP_DMC_MEMC_CMD_CONFIG);
+	mmio_write_32(N1SDP_REMOTE_DMC1_MEMC_CMD_REG,
+			N1SDP_DMC_MEMC_CMD_CONFIG);
+
+	/* Enable ECC in DMCs */
+	mmio_setbits_32(N1SDP_REMOTE_DMC0_ERR0CTLR0_REG,
+			N1SDP_DMC_ERR0CTLR0_ECC_EN);
+	mmio_setbits_32(N1SDP_REMOTE_DMC1_ERR0CTLR0_REG,
+			N1SDP_DMC_ERR0CTLR0_ECC_EN);
+
+	/* Set DMCs to READY state */
+	mmio_write_32(N1SDP_REMOTE_DMC0_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_READY);
+	mmio_write_32(N1SDP_REMOTE_DMC1_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_READY);
+}
+
 void copy_bl33(uint32_t src, uint32_t dst, uint32_t size)
 {
 	uint32_t i;
@@ -109,30 +170,53 @@
 	}
 }
 
+void n1sdp_bl31_multichip_setup(void)
+{
+	plat_arm_override_gicr_frames(n1sdp_multichip_gicr_frames);
+	gic600_multichip_init(&n1sdp_multichip_data);
+}
+
 void bl31_platform_setup(void)
 {
 	int ret;
-	struct n1sdp_mem_info mem_info;
+	struct n1sdp_plat_info plat_info;
 	struct n1sdp_bl33_info bl33_info;
 
-	arm_bl31_platform_setup();
-
 	ret = sds_init();
 	if (ret != SDS_OK) {
 		ERROR("SDS initialization failed\n");
 		panic();
 	}
 
-	ret = sds_struct_read(N1SDP_SDS_MEM_INFO_STRUCT_ID,
-				N1SDP_SDS_MEM_INFO_OFFSET,
-				&mem_info,
-				N1SDP_SDS_MEM_INFO_SIZE,
+	ret = sds_struct_read(N1SDP_SDS_PLATFORM_INFO_STRUCT_ID,
+				N1SDP_SDS_PLATFORM_INFO_OFFSET,
+				&plat_info,
+				N1SDP_SDS_PLATFORM_INFO_SIZE,
 				SDS_ACCESS_MODE_NON_CACHED);
 	if (ret != SDS_OK) {
-		ERROR("Error getting memory info from SDS\n");
+		ERROR("Error getting platform info from SDS\n");
 		panic();
 	}
-	dmc_ecc_setup(mem_info.ddr_size_gb);
+	/* Validate plat_info SDS */
+	if ((plat_info.local_ddr_size == 0)
+		|| (plat_info.local_ddr_size > N1SDP_MAX_DDR_CAPACITY_GB)
+		|| (plat_info.remote_ddr_size > N1SDP_MAX_DDR_CAPACITY_GB)
+		|| (plat_info.slave_count > N1SDP_MAX_SLAVE_COUNT)) {
+		ERROR("platform info SDS is corrupted\n");
+		panic();
+	}
+
+	if (plat_info.multichip_mode) {
+		n1sdp_multichip_data.chip_count = plat_info.slave_count + 1;
+		n1sdp_bl31_multichip_setup();
+	}
+	arm_bl31_platform_setup();
+
+	dmc_ecc_setup(plat_info.local_ddr_size);
+
+	/* Check if remote memory is present */
+	if ((plat_info.multichip_mode) && (plat_info.remote_ddr_size != 0))
+		remote_dmc_ecc_setup(plat_info.remote_ddr_size);
 
 	ret = sds_struct_read(N1SDP_SDS_BL33_INFO_STRUCT_ID,
 				N1SDP_SDS_BL33_INFO_OFFSET,
@@ -147,11 +231,11 @@
 			bl33_info.bl33_dst_addr,
 			bl33_info.bl33_size);
 	/*
-	 * Pass DDR memory size info to BL33. This method is followed as
+	 * Pass platform information to BL33. This method is followed as
 	 * currently there is no BL1/BL2 involved in boot flow of N1SDP.
 	 * When TBBR is implemented for N1SDP, this method should be removed
-	 * and DDR memory size shoule be passed to BL33 using NT_FW_CONFIG
+	 * and platform information should be passed to BL33 using NT_FW_CONFIG
 	 * passing mechanism.
 	 */
-	mmio_write_32(N1SDP_DDR_MEM_INFO_BASE, mem_info.ddr_size_gb);
+	mmio_write_32(N1SDP_PLATFORM_INFO_BASE, *(uint32_t *)&plat_info);
 }
diff --git a/plat/arm/board/n1sdp/n1sdp_def.h b/plat/arm/board/n1sdp/n1sdp_def.h
index d43c5a4..30e29a7 100644
--- a/plat/arm/board/n1sdp/n1sdp_def.h
+++ b/plat/arm/board/n1sdp/n1sdp_def.h
@@ -15,10 +15,12 @@
 						N1SDP_NS_SRAM_SIZE,	\
 						MT_DEVICE | MT_RW | MT_SECURE)
 
-/* SDS memory information defines */
-#define N1SDP_SDS_MEM_INFO_STRUCT_ID		8
-#define N1SDP_SDS_MEM_INFO_OFFSET		0
-#define N1SDP_SDS_MEM_INFO_SIZE			4
+/* SDS Platform information defines */
+#define N1SDP_SDS_PLATFORM_INFO_STRUCT_ID	8
+#define N1SDP_SDS_PLATFORM_INFO_OFFSET		0
+#define N1SDP_SDS_PLATFORM_INFO_SIZE		4
+#define N1SDP_MAX_DDR_CAPACITY_GB		64
+#define N1SDP_MAX_SLAVE_COUNT			16
 
 /* SDS BL33 image information defines */
 #define N1SDP_SDS_BL33_INFO_STRUCT_ID		9
@@ -33,6 +35,18 @@
 #define N1SDP_DMC0_ERR0CTLR0_REG		0x4E000708
 #define N1SDP_DMC1_ERR0CTLR0_REG		0x4E100708
 
+/* Remote DMC memory command registers */
+#define N1SDP_REMOTE_DMC0_MEMC_CMD_REG		PLAT_ARM_REMOTE_CHIP_OFFSET +\
+							N1SDP_DMC0_MEMC_CMD_REG
+#define N1SDP_REMOTE_DMC1_MEMC_CMD_REG		PLAT_ARM_REMOTE_CHIP_OFFSET +\
+							N1SDP_DMC1_MEMC_CMD_REG
+
+/* Remote DMC ERR0CTLR0 registers */
+#define N1SDP_REMOTE_DMC0_ERR0CTLR0_REG		PLAT_ARM_REMOTE_CHIP_OFFSET +\
+							N1SDP_DMC0_ERR0CTLR0_REG
+#define N1SDP_REMOTE_DMC1_ERR0CTLR0_REG		PLAT_ARM_REMOTE_CHIP_OFFSET +\
+							N1SDP_DMC1_ERR0CTLR0_REG
+
 /* DMC memory commands */
 #define N1SDP_DMC_MEMC_CMD_CONFIG		0
 #define N1SDP_DMC_MEMC_CMD_READY		3
@@ -40,7 +54,7 @@
 /* DMC ECC enable bit in ERR0CTLR0 register */
 #define N1SDP_DMC_ERR0CTLR0_ECC_EN		0x1
 
-/* Base address of non-secure SRAM where DDR memory size will be filled */
-#define N1SDP_DDR_MEM_INFO_BASE			0x06008000
+/* Base address of non-secure SRAM where Platform information will be filled */
+#define N1SDP_PLATFORM_INFO_BASE		0x06008000
 
 #endif /* N1SDP_DEF_H */
diff --git a/plat/arm/board/n1sdp/n1sdp_plat.c b/plat/arm/board/n1sdp/n1sdp_plat.c
index a32ca72..951a562 100644
--- a/plat/arm/board/n1sdp/n1sdp_plat.c
+++ b/plat/arm/board/n1sdp/n1sdp_plat.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -25,6 +25,9 @@
 	N1SDP_MAP_NS_SRAM,
 	ARM_MAP_DRAM1,
 	ARM_MAP_DRAM2,
+	N1SDP_MAP_REMOTE_DEVICE,
+	N1SDP_MAP_REMOTE_DRAM1,
+	N1SDP_MAP_REMOTE_DRAM2,
 	{0}
 };
 
diff --git a/plat/arm/board/n1sdp/n1sdp_topology.c b/plat/arm/board/n1sdp/n1sdp_topology.c
index edf1170..5c2db71 100644
--- a/plat/arm/board/n1sdp/n1sdp_topology.c
+++ b/plat/arm/board/n1sdp/n1sdp_topology.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,7 +19,11 @@
  * indices returned by plat_core_pos_by_mpidr().
  */
 const unsigned char n1sdp_pd_tree_desc[] = {
+	PLAT_N1SDP_CHIP_COUNT,
 	PLAT_ARM_CLUSTER_COUNT,
+	PLAT_ARM_CLUSTER_COUNT,
+	N1SDP_MAX_CPUS_PER_CLUSTER,
+	N1SDP_MAX_CPUS_PER_CLUSTER,
 	N1SDP_MAX_CPUS_PER_CLUSTER,
 	N1SDP_MAX_CPUS_PER_CLUSTER
 };
@@ -52,4 +56,4 @@
  * to the SCMI power domain ID implemented by SCP.
  ******************************************************************************/
 const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[PLATFORM_CORE_COUNT] = {
-	0, 1, 2, 3};
+	0, 1, 2, 3, 4, 5, 6, 7};
diff --git a/plat/arm/board/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk
index 986bd70..8816670 100644
--- a/plat/arm/board/n1sdp/platform.mk
+++ b/plat/arm/board/n1sdp/platform.mk
@@ -18,6 +18,7 @@
 N1SDP_GIC_SOURCES	:=	drivers/arm/gic/common/gic_common.c	\
 				drivers/arm/gic/v3/gicv3_main.c		\
 				drivers/arm/gic/v3/gicv3_helpers.c	\
+				drivers/arm/gic/v3/gic600_multichip.c	\
 				plat/common/plat_gicv3.c		\
 				plat/arm/common/arm_gicv3.c		\
 				drivers/arm/gic/v3/gic600.c
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index a4a29bf..acc3797 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -130,6 +130,11 @@
 $(eval $(call assert_boolean,ARM_CRYPTOCELL_INTEG))
 $(eval $(call add_define,ARM_CRYPTOCELL_INTEG))
 
+# Enable PIE support for RESET_TO_BL31 case
+ifeq (${RESET_TO_BL31},1)
+    ENABLE_PIE			:=	1
+endif
+
 # CryptoCell integration relies on coherent buffers for passing data from
 # the AP CPU to the CryptoCell
 ifeq (${ARM_CRYPTOCELL_INTEG},1)
diff --git a/plat/arm/common/arm_gicv3.c b/plat/arm/common/arm_gicv3.c
index fef5376..cfc5359 100644
--- a/plat/arm/common/arm_gicv3.c
+++ b/plat/arm/common/arm_gicv3.c
@@ -28,6 +28,15 @@
 /* The GICv3 driver only needs to be initialized in EL3 */
 static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
 
+/* Default GICR base address to be used for GICR probe. */
+static const uintptr_t gicr_base_addrs[2] = {
+	PLAT_ARM_GICR_BASE,	/* GICR Base address of the primary CPU */
+	0U			/* Zero Termination */
+};
+
+/* List of zero terminated GICR frame addresses which CPUs will probe */
+static const uintptr_t *gicr_frames = gicr_base_addrs;
+
 static const interrupt_prop_t arm_interrupt_props[] = {
 	PLAT_ARM_G1S_IRQ_PROPS(INTR_GROUP1S),
 	PLAT_ARM_G0_IRQ_PROPS(INTR_GROUP0)
@@ -76,6 +85,18 @@
 	.mpidr_to_core_pos = arm_gicv3_mpidr_hash
 };
 
+/*
+ * By default, gicr_frames will be pointing to gicr_base_addrs. If
+ * the platform supports a non-contiguous GICR frames (GICR frames located
+ * at uneven offset), plat_arm_override_gicr_frames function can be used by
+ * such platform to override the gicr_frames.
+ */
+void plat_arm_override_gicr_frames(const uintptr_t *plat_gicr_frames)
+{
+	assert(plat_gicr_frames != NULL);
+	gicr_frames = plat_gicr_frames;
+}
+
 void __init plat_arm_gic_driver_init(void)
 {
 	/*
@@ -88,7 +109,7 @@
 	(defined(__aarch64__) && defined(IMAGE_BL31))
 	gicv3_driver_init(&arm_gic_data);
 
-	if (gicv3_rdistif_probe(PLAT_ARM_GICR_BASE) == -1) {
+	if (gicv3_rdistif_probe(gicr_base_addrs[0]) == -1) {
 		ERROR("No GICR base frame found for Primary CPU\n");
 		panic();
 	}
@@ -124,14 +145,23 @@
 /******************************************************************************
  * ARM common helper function to iterate over all GICR frames and discover the
  * corresponding per-cpu redistributor frame as well as initialize the
- * corresponding interface in GICv3. At the moment, Arm platforms do not have
- * non-contiguous GICR frames.
+ * corresponding interface in GICv3.
  *****************************************************************************/
 void plat_arm_gic_pcpu_init(void)
 {
 	int result;
+	const uintptr_t *plat_gicr_frames = gicr_frames;
+
+	do {
+		result = gicv3_rdistif_probe(*plat_gicr_frames);
+
+		/* If the probe is successful, no need to proceed further */
+		if (result == 0)
+			break;
+
+		plat_gicr_frames++;
+	} while (*plat_gicr_frames != 0U);
 
-	result = gicv3_rdistif_probe(PLAT_ARM_GICR_BASE);
 	if (result == -1) {
 		ERROR("No GICR base frame found for CPU 0x%lx\n", read_mpidr());
 		panic();
diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c
index 8ba02d6..a8c70ea 100644
--- a/plat/nvidia/tegra/common/tegra_pm.c
+++ b/plat/nvidia/tegra/common/tegra_pm.c
@@ -28,14 +28,6 @@
 extern uint64_t tegra_sec_entry_point;
 
 /*
- * tegra_fake_system_suspend acts as a boolean var controlling whether
- * we are going to take fake system suspend code or normal system suspend code
- * path. This variable is set inside the sip call handlers,when the kernel
- * requests a SIP call to set the suspend debug flags.
- */
-uint8_t tegra_fake_system_suspend;
-
-/*
  * The following platform setup functions are weakly defined. They
  * provide typical implementations that will be overridden by a SoC.
  */
@@ -233,31 +225,10 @@
 __dead2 void tegra_pwr_domain_power_down_wfi(const psci_power_state_t
 					     *target_state)
 {
-	uint8_t pwr_state = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL];
-	uint64_t rmr_el3 = 0;
-
 	/* call the chip's power down handler */
 	(void)tegra_soc_pwr_domain_power_down_wfi(target_state);
 
-	/*
-	 * If we are in fake system suspend mode, ensure we start doing
-	 * procedures that help in looping back towards system suspend exit
-	 * instead of calling WFI by requesting a warm reset.
-	 * Else, just call WFI to enter low power state.
-	 */
-	if ((tegra_fake_system_suspend != 0U) &&
-	    (pwr_state == (uint8_t)PSTATE_ID_SOC_POWERDN)) {
-
-		/* warm reboot */
-		rmr_el3 = read_rmr_el3();
-		write_rmr_el3(rmr_el3 | RMR_WARM_RESET_CPU);
-
-	} else {
-		/* enter power down state */
-		wfi();
-	}
-
-	/* we can never reach here */
+	wfi();
 	panic();
 }
 
diff --git a/plat/nvidia/tegra/common/tegra_sip_calls.c b/plat/nvidia/tegra/common/tegra_sip_calls.c
index 957300e..b8ba095 100644
--- a/plat/nvidia/tegra/common/tegra_sip_calls.c
+++ b/plat/nvidia/tegra/common/tegra_sip_calls.c
@@ -24,14 +24,8 @@
 #define TEGRA_SIP_NEW_VIDEOMEM_REGION		0x82000003
 #define TEGRA_SIP_FIQ_NS_ENTRYPOINT		0x82000005
 #define TEGRA_SIP_FIQ_NS_GET_CONTEXT		0x82000006
-#define TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND	0xC2000007
 
 /*******************************************************************************
- * Fake system suspend mode control var
- ******************************************************************************/
-extern uint8_t tegra_fake_system_suspend;
-
-/*******************************************************************************
  * SoC specific SiP handler
  ******************************************************************************/
 #pragma weak plat_sip_handler
@@ -162,26 +156,6 @@
 
 			SMC_RET0(handle);
 
-		case TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND:
-			/*
-			 * System suspend fake mode is set if we are on VDK and we make
-			 * a debug SIP call. This mode ensures that we excercise debug
-			 * path instead of the regular code path to suit the pre-silicon
-			 * platform needs. These include replacing the call to WFI by
-			 * a warm reset request.
-			 */
-			if (tegra_platform_is_virt_dev_kit() != false) {
-
-				tegra_fake_system_suspend = 1;
-				SMC_RET1(handle, 0);
-			}
-
-			/*
-			 * We return to the external world as if this SIP is not
-			 * implemented in case, we are not running on VDK.
-			 */
-			break;
-
 		default:
 			ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
 			break;
diff --git a/plat/nvidia/tegra/include/t194/tegra_def.h b/plat/nvidia/tegra/include/t194/tegra_def.h
new file mode 100644
index 0000000..a1b70db
--- /dev/null
+++ b/plat/nvidia/tegra/include/t194/tegra_def.h
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __TEGRA_DEF_H__
+#define __TEGRA_DEF_H__
+
+#include <lib/utils_def.h>
+
+/*******************************************************************************
+ * These values are used by the PSCI implementation during the `CPU_SUSPEND`
+ * and `SYSTEM_SUSPEND` calls as the `state-id` field in the 'power state'
+ * parameter.
+ ******************************************************************************/
+#define PSTATE_ID_CORE_IDLE		6
+#define PSTATE_ID_CORE_POWERDN		7
+#define PSTATE_ID_SOC_POWERDN		2
+
+/*******************************************************************************
+ * Platform power states (used by PSCI framework)
+ *
+ * - PLAT_MAX_RET_STATE should be less than lowest PSTATE_ID
+ * - PLAT_MAX_OFF_STATE should be greater than the highest PSTATE_ID
+ ******************************************************************************/
+#define PLAT_MAX_RET_STATE		1
+#define PLAT_MAX_OFF_STATE		8
+
+/*******************************************************************************
+ * Implementation defined ACTLR_EL3 bit definitions
+ ******************************************************************************/
+#define ACTLR_EL3_L2ACTLR_BIT		(1 << 6)
+#define ACTLR_EL3_L2ECTLR_BIT		(1 << 5)
+#define ACTLR_EL3_L2CTLR_BIT		(1 << 4)
+#define ACTLR_EL3_CPUECTLR_BIT		(1 << 1)
+#define ACTLR_EL3_CPUACTLR_BIT		(1 << 0)
+#define ACTLR_EL3_ENABLE_ALL_ACCESS	(ACTLR_EL3_L2ACTLR_BIT | \
+					 ACTLR_EL3_L2ECTLR_BIT | \
+					 ACTLR_EL3_L2CTLR_BIT | \
+					 ACTLR_EL3_CPUECTLR_BIT | \
+					 ACTLR_EL3_CPUACTLR_BIT)
+
+/*******************************************************************************
+ * Secure IRQ definitions
+ ******************************************************************************/
+#define TEGRA186_MAX_SEC_IRQS		5
+#define TEGRA186_BPMP_WDT_IRQ		46
+#define TEGRA186_SPE_WDT_IRQ		47
+#define TEGRA186_SCE_WDT_IRQ		48
+#define TEGRA186_TOP_WDT_IRQ		49
+#define TEGRA186_AON_WDT_IRQ		50
+
+#define TEGRA186_SEC_IRQ_TARGET_MASK	0xFF /* 8 Carmel */
+
+/*******************************************************************************
+ * Tegra Miscellanous register constants
+ ******************************************************************************/
+#define TEGRA_MISC_BASE			0x00100000
+#define  HARDWARE_REVISION_OFFSET	0x4
+
+#define  MISCREG_PFCFG			0x200C
+
+/*******************************************************************************
+ * Tegra TSA Controller constants
+ ******************************************************************************/
+#define TEGRA_TSA_BASE			0x02000000
+
+#define TSA_CONFIG_STATIC0_CSW_SESWR		0x1010
+#define  TSA_CONFIG_STATIC0_CSW_SESWR_RESET	0x1100
+#define TSA_CONFIG_STATIC0_CSW_ETRW		0xD034
+#define  TSA_CONFIG_STATIC0_CSW_ETRW_RESET	0x1100
+#define TSA_CONFIG_STATIC0_CSW_SDMMCWAB		0x3020
+#define  TSA_CONFIG_STATIC0_CSW_SDMMCWAB_RESET	0x1100
+#define TSA_CONFIG_STATIC0_CSW_AXISW		0x8008
+#define  TSA_CONFIG_STATIC0_CSW_AXISW_RESET	0x1100
+#define TSA_CONFIG_STATIC0_CSW_HDAW		0xD008
+#define  TSA_CONFIG_STATIC0_CSW_HDAW_RESET	0x1100
+#define TSA_CONFIG_STATIC0_CSW_AONDMAW		0xE018
+#define  TSA_CONFIG_STATIC0_CSW_AONDMAW_RESET	0x1100
+#define TSA_CONFIG_STATIC0_CSW_SCEDMAW		0x9008
+#define  TSA_CONFIG_STATIC0_CSW_SCEDMAW_RESET	0x1100
+#define TSA_CONFIG_STATIC0_CSW_BPMPDMAW		0x9028
+#define  TSA_CONFIG_STATIC0_CSW_BPMPDMAW_RESET	0x1100
+#define TSA_CONFIG_STATIC0_CSW_APEDMAW		0xB008
+#define  TSA_CONFIG_STATIC0_CSW_APEDMAW_RESET	0x1100
+#define TSA_CONFIG_STATIC0_CSW_UFSHCW		0x6008
+#define  TSA_CONFIG_STATIC0_CSW_UFSHCW_RESET	0x1100
+#define TSA_CONFIG_STATIC0_CSW_AFIW		0xF008
+#define  TSA_CONFIG_STATIC0_CSW_AFIW_RESET	0x1100
+#define TSA_CONFIG_STATIC0_CSW_SATAW		0x4008
+#define  TSA_CONFIG_STATIC0_CSW_SATAW_RESET	0x1100
+#define TSA_CONFIG_STATIC0_CSW_EQOSW		0x3038
+#define  TSA_CONFIG_STATIC0_CSW_EQOSW_RESET	0x1100
+#define TSA_CONFIG_STATIC0_CSW_XUSB_DEVW	0x6018
+#define  TSA_CONFIG_STATIC0_CSW_XUSB_DEVW_RESET	0x1100
+#define TSA_CONFIG_STATIC0_CSW_XUSB_HOSTW	0x6028
+#define  TSA_CONFIG_STATIC0_CSW_XUSB_HOSTW_RESET 0x1100
+
+#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK	(0x3 << 11)
+#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU	(0 << 11)
+
+/*******************************************************************************
+ * Tegra Memory Controller constants
+ ******************************************************************************/
+#define TEGRA_MC_STREAMID_BASE		0x02C00000
+#define TEGRA_MC_BASE			0x02C10000
+
+/* General Security Carveout register macros */
+#define MC_GSC_CONFIG_REGS_SIZE		0x40
+#define MC_GSC_LOCK_CFG_SETTINGS_BIT	(1 << 1)
+#define MC_GSC_ENABLE_TZ_LOCK_BIT	(1 << 0)
+#define MC_GSC_SIZE_RANGE_4KB_SHIFT	27
+#define MC_GSC_BASE_LO_SHIFT		12
+#define MC_GSC_BASE_LO_MASK		0xFFFFF
+#define MC_GSC_BASE_HI_SHIFT		0
+#define MC_GSC_BASE_HI_MASK		3
+
+/* TZDRAM carveout configuration registers */
+#define MC_SECURITY_CFG0_0		0x70
+#define MC_SECURITY_CFG1_0		0x74
+#define MC_SECURITY_CFG3_0		0x9BC
+
+/* Video Memory carveout configuration registers */
+#define MC_VIDEO_PROTECT_BASE_HI	0x978
+#define MC_VIDEO_PROTECT_BASE_LO	0x648
+#define MC_VIDEO_PROTECT_SIZE_MB	0x64c
+
+/*
+ * Carveout (MC_SECURITY_CARVEOUT24) registers used to clear the
+ * non-overlapping Video memory region
+ */
+#define MC_VIDEO_PROTECT_CLEAR_CFG	0x25A0
+#define MC_VIDEO_PROTECT_CLEAR_BASE_LO	0x25A4
+#define MC_VIDEO_PROTECT_CLEAR_BASE_HI	0x25A8
+#define MC_VIDEO_PROTECT_CLEAR_SIZE	0x25AC
+#define MC_VIDEO_PROTECT_CLEAR_ACCESS_CFG0	0x25B0
+
+/* TZRAM carveout (MC_SECURITY_CARVEOUT11) configuration registers */
+#define MC_TZRAM_CARVEOUT_CFG		0x2190
+#define MC_TZRAM_BASE_LO		0x2194
+#define MC_TZRAM_BASE_HI		0x2198
+#define MC_TZRAM_SIZE			0x219C
+#define MC_TZRAM_CLIENT_ACCESS_CFG0	0x21A0
+
+/* Memory Controller Reset Control registers */
+#define  MC_CLIENT_HOTRESET_CTRL1_VIFAL_FLUSH_ENB	(1 << 27)
+#define  MC_CLIENT_HOTRESET_CTRL1_DLAA_FLUSH_ENB	(1 << 28)
+#define  MC_CLIENT_HOTRESET_CTRL1_DLA1A_FLUSH_ENB	(1 << 29)
+#define  MC_CLIENT_HOTRESET_CTRL1_PVA0A_FLUSH_ENB	(1 << 30)
+#define  MC_CLIENT_HOTRESET_CTRL1_PVA1A_FLUSH_ENB	(1 << 31)
+
+/*******************************************************************************
+ * Tegra UART Controller constants
+ ******************************************************************************/
+#define TEGRA_UARTA_BASE		0x03100000
+#define TEGRA_UARTB_BASE		0x03110000
+#define TEGRA_UARTC_BASE		0x0C280000
+#define TEGRA_UARTD_BASE		0x03130000
+#define TEGRA_UARTE_BASE		0x03140000
+#define TEGRA_UARTF_BASE		0x03150000
+#define TEGRA_UARTG_BASE		0x0C290000
+
+/*******************************************************************************
+ * Tegra Fuse Controller related constants
+ ******************************************************************************/
+#define TEGRA_FUSE_BASE			0x03820000
+#define  OPT_SUBREVISION		0x248
+#define  SUBREVISION_MASK		0xF
+
+/*******************************************************************************
+ * GICv2 & interrupt handling related constants
+ ******************************************************************************/
+#define TEGRA_GICD_BASE			0x03881000
+#define TEGRA_GICC_BASE			0x03882000
+
+/*******************************************************************************
+ * Security Engine related constants
+ ******************************************************************************/
+#define TEGRA_SE0_BASE			0x03AC0000
+#define  SE_MUTEX_WATCHDOG_NS_LIMIT	0x6C
+#define TEGRA_PKA1_BASE			0x03AD0000
+#define  PKA_MUTEX_WATCHDOG_NS_LIMIT	0x8144
+#define TEGRA_RNG1_BASE			0x03AE0000
+#define  RNG_MUTEX_WATCHDOG_NS_LIMIT	0xFE0
+
+/*******************************************************************************
+ * Tegra micro-seconds timer constants
+ ******************************************************************************/
+#define TEGRA_TMRUS_BASE		0x0C2E0000
+#define TEGRA_TMRUS_SIZE		0x10000
+
+/*******************************************************************************
+ * Tegra Power Mgmt Controller constants
+ ******************************************************************************/
+#define TEGRA_PMC_BASE			0x0C360000
+
+/*******************************************************************************
+ * Tegra scratch registers constants
+ ******************************************************************************/
+#define TEGRA_SCRATCH_BASE		0x0C390000
+#define  SECURE_SCRATCH_RSV1_LO		0x06C
+#define  SECURE_SCRATCH_RSV1_HI		0x070
+#define  SECURE_SCRATCH_RSV6		0x094
+#define  SECURE_SCRATCH_RSV11_LO	0x0BC
+#define  SECURE_SCRATCH_RSV11_HI	0x0C0
+#define  SECURE_SCRATCH_RSV53_LO	0x20C
+#define  SECURE_SCRATCH_RSV53_HI	0x210
+#define  SECURE_SCRATCH_RSV54_HI	0x218
+#define  SECURE_SCRATCH_RSV55_LO	0x21C
+#define  SECURE_SCRATCH_RSV55_HI	0x220
+
+/*******************************************************************************
+ * Tegra Memory Mapped Control Register Access Bus constants
+ ******************************************************************************/
+#define TEGRA_MMCRAB_BASE		0x0E000000
+
+/*******************************************************************************
+ * Tegra SMMU Controller constants
+ ******************************************************************************/
+#define TEGRA_SMMU0_BASE		0x12000000
+#define TEGRA_SMMU1_BASE		0x11000000
+#define TEGRA_SMMU2_BASE		0x10000000
+
+/*******************************************************************************
+ * Tegra TZRAM constants
+ ******************************************************************************/
+#define TEGRA_TZRAM_BASE		0x40000000
+#define TEGRA_TZRAM_SIZE		0x40000
+
+/*******************************************************************************
+ * Tegra Clock and Reset Controller constants
+ ******************************************************************************/
+#define TEGRA_CAR_RESET_BASE		0x200000000
+
+#endif /* __TEGRA_DEF_H__ */
diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h
index 34a096c..fab0eaf 100644
--- a/plat/nvidia/tegra/include/tegra_private.h
+++ b/plat/nvidia/tegra/include/tegra_private.h
@@ -97,8 +97,6 @@
 void tegra_security_setup_videomem(uintptr_t base, uint64_t size);
 
 /* Declarations for tegra_pm.c */
-extern uint8_t tegra_fake_system_suspend;
-
 void tegra_pm_system_suspend_entry(void);
 void tegra_pm_system_suspend_exit(void);
 int32_t tegra_system_suspended(void);
diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h b/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h
new file mode 100644
index 0000000..cc32ec4
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __MCE_PRIVATE_H__
+#define __MCE_PRIVATE_H__
+
+#include <mmio.h>
+#include <tegra_def.h>
+
+/*******************************************************************************
+ * Macros to prepare CSTATE info request
+ ******************************************************************************/
+/* Description of the parameters for UPDATE_CSTATE_INFO request */
+#define CLUSTER_CSTATE_MASK				0x7UL
+#define CLUSTER_CSTATE_SHIFT			0X0UL
+#define CLUSTER_CSTATE_UPDATE_BIT		(1UL << 7)
+#define CCPLEX_CSTATE_MASK				0x3UL
+#define CCPLEX_CSTATE_SHIFT				8UL
+#define CCPLEX_CSTATE_UPDATE_BIT		(1UL << 15)
+#define SYSTEM_CSTATE_MASK				0xFUL
+#define SYSTEM_CSTATE_SHIFT				16UL
+#define SYSTEM_CSTATE_UPDATE_BIT		(1UL << 23)
+#define CSTATE_WAKE_MASK_UPDATE_BIT		(1UL << 31)
+#define CSTATE_WAKE_MASK_SHIFT			32UL
+#define CSTATE_WAKE_MASK_CLEAR			0xFFFFFFFFUL
+
+/*******************************************************************************
+ * Auto-CC3 control macros
+ ******************************************************************************/
+#define MCE_AUTO_CC3_FREQ_MASK			0xFFUL
+#define MCE_AUTO_CC3_FREQ_SHIFT			0UL
+#define MCE_AUTO_CC3_ENABLE_BIT			(1UL << 31)
+
+/*******************************************************************************
+ * Core ID mask (bits 3:0 in the online request)
+ ******************************************************************************/
+#define MCE_CORE_ID_MASK				0xFUL
+
+/*******************************************************************************
+ * Cache control macros
+ ******************************************************************************/
+#define CACHE_CLEAN_SET					(1UL << 0)
+#define CACHE_CLEAN_INVAL_SET			(1UL << 1)
+#define CACHE_CLEAN_INVAL_TR_SET		(1UL << 2)
+
+/* declarations for NVG handler functions */
+uint64_t nvg_get_version(void);
+int32_t nvg_enable_power_perf_mode(void);
+int32_t nvg_disable_power_perf_mode(void);
+int32_t nvg_enable_power_saver_modes(void);
+int32_t nvg_disable_power_saver_modes(void);
+void nvg_set_wake_time(uint32_t wake_time);
+void nvg_update_cstate_info(uint32_t cluster, uint32_t ccplex,
+		uint32_t system, uint32_t wake_mask, uint8_t update_wake_mask);
+int32_t nvg_update_crossover_time(uint32_t type, uint32_t time);
+int32_t nvg_set_cstate_stat_query_value(uint64_t data);
+uint64_t nvg_get_cstate_stat_query_value(void);
+int32_t nvg_is_sc7_allowed(void);
+int32_t nvg_online_core(uint32_t core);
+int32_t nvg_cc3_ctrl(uint32_t freq, uint8_t enable);
+int32_t nvg_update_ccplex_gsc(uint32_t gsc_idx);
+int32_t nvg_roc_flush_cache(void);
+int32_t nvg_roc_clean_cache(void);
+int32_t nvg_roc_clean_cache_trbits(void);
+int32_t nvg_enter_cstate(uint32_t state, uint32_t wake_time);
+
+void nvg_set_request_data(uint64_t req, uint64_t data);
+void nvg_set_request(uint64_t req);
+uint64_t nvg_get_result(void);
+
+#endif /* __MCE_PRIVATE_H__ */
diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/memctrl_plat_config.h b/plat/nvidia/tegra/soc/t194/drivers/include/memctrl_plat_config.h
new file mode 100644
index 0000000..8eaae67
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/drivers/include/memctrl_plat_config.h
@@ -0,0 +1,586 @@
+/*
+ * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __MEMCTRL_PLAT_CONFIG_H
+#define __MEMCTRL_PLAT_CONFIG_H
+
+#include <memctrl_v2.h>
+
+/*******************************************************************************
+ * StreamID to indicate no SMMU translations (requests to be steered on the
+ * SMMU bypass path)
+ ******************************************************************************/
+#define MC_STREAM_ID_MAX			0x7F
+
+/*******************************************************************************
+ * Stream ID Override Config registers
+ ******************************************************************************/
+#define MC_STREAMID_OVERRIDE_CFG_PTCR		0x000
+#define MC_STREAMID_OVERRIDE_CFG_HDAR		0x0A8
+#define MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR	0x0B0
+#define MC_STREAMID_OVERRIDE_CFG_NVENCSRD	0x0E0
+#define MC_STREAMID_OVERRIDE_CFG_SATAR		0x0F8
+#define MC_STREAMID_OVERRIDE_CFG_MPCORER	0x138
+#define MC_STREAMID_OVERRIDE_CFG_NVENCSWR	0x158
+#define MC_STREAMID_OVERRIDE_CFG_HDAW		0x1A8
+#define MC_STREAMID_OVERRIDE_CFG_MPCOREW	0x1C8
+#define MC_STREAMID_OVERRIDE_CFG_SATAW		0x1E8
+#define MC_STREAMID_OVERRIDE_CFG_ISPRA		0x220
+#define MC_STREAMID_OVERRIDE_CFG_ISPFALR	0x228
+#define MC_STREAMID_OVERRIDE_CFG_ISPWA		0x230
+#define MC_STREAMID_OVERRIDE_CFG_ISPWB		0x238
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR	0x250
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW	0x258
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR	0x260
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW	0x268
+#define MC_STREAMID_OVERRIDE_CFG_TSECSRD	0x2A0
+#define MC_STREAMID_OVERRIDE_CFG_TSECSWR	0x2A8
+#define MC_STREAMID_OVERRIDE_CFG_GPUSRD		0x2C0	/*TODO: remove it after HW team confirmation */
+#define MC_STREAMID_OVERRIDE_CFG_GPUSWR		0x2C8	/*TODO: remove it after HW team confirmation */
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCRA	0x300
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCR		0x310
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAB	0x318
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCWA	0x320
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCW		0x330
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAB	0x338
+#define MC_STREAMID_OVERRIDE_CFG_VICSRD		0x360
+#define MC_STREAMID_OVERRIDE_CFG_VICSWR		0x368
+#define MC_STREAMID_OVERRIDE_CFG_VIW		0x390
+#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD	0x3C0
+#define MC_STREAMID_OVERRIDE_CFG_NVDECSWR	0x3C8
+#define MC_STREAMID_OVERRIDE_CFG_APER		0x3D0
+#define MC_STREAMID_OVERRIDE_CFG_APEW		0x3D8
+#define MC_STREAMID_OVERRIDE_CFG_NVJPGSRD	0x3F0
+#define MC_STREAMID_OVERRIDE_CFG_NVJPGSWR	0x3F8
+#define MC_STREAMID_OVERRIDE_CFG_SESRD		0x400
+#define MC_STREAMID_OVERRIDE_CFG_SESWR		0x408
+#define MC_STREAMID_OVERRIDE_CFG_AXIAPR		0x410
+#define MC_STREAMID_OVERRIDE_CFG_AXIAPW		0x418
+#define MC_STREAMID_OVERRIDE_CFG_ETRR		0x420
+#define MC_STREAMID_OVERRIDE_CFG_ETRW		0x428
+#define MC_STREAMID_OVERRIDE_CFG_TSECSRDB	0x430
+#define MC_STREAMID_OVERRIDE_CFG_TSECSWRB	0x438
+#define MC_STREAMID_OVERRIDE_CFG_GPUSRD2	0x440	/*TODO: remove it after HW team confirmation */
+#define MC_STREAMID_OVERRIDE_CFG_GPUSWR2	0x448	/*TODO: remove it after HW team confirmation */
+#define MC_STREAMID_OVERRIDE_CFG_AXISR		0x460
+#define MC_STREAMID_OVERRIDE_CFG_AXISW		0x468
+#define MC_STREAMID_OVERRIDE_CFG_EQOSR		0x470
+#define MC_STREAMID_OVERRIDE_CFG_EQOSW		0x478
+#define MC_STREAMID_OVERRIDE_CFG_UFSHCR		0x480
+#define MC_STREAMID_OVERRIDE_CFG_UFSHCW		0x488
+#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR	0x490
+#define MC_STREAMID_OVERRIDE_CFG_BPMPR		0x498
+#define MC_STREAMID_OVERRIDE_CFG_BPMPW		0x4A0
+#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAR	0x4A8
+#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAW	0x4B0
+#define MC_STREAMID_OVERRIDE_CFG_AONR		0x4B8
+#define MC_STREAMID_OVERRIDE_CFG_AONW		0x4C0
+#define MC_STREAMID_OVERRIDE_CFG_AONDMAR	0x4C8
+#define MC_STREAMID_OVERRIDE_CFG_AONDMAW	0x4D0
+#define MC_STREAMID_OVERRIDE_CFG_SCER		0x4D8
+#define MC_STREAMID_OVERRIDE_CFG_SCEW		0x4E0
+#define MC_STREAMID_OVERRIDE_CFG_SCEDMAR	0x4E8
+#define MC_STREAMID_OVERRIDE_CFG_SCEDMAW	0x4F0
+#define MC_STREAMID_OVERRIDE_CFG_APEDMAR	0x4F8
+#define MC_STREAMID_OVERRIDE_CFG_APEDMAW	0x500
+#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1	0x508
+#define MC_STREAMID_OVERRIDE_CFG_VICSRD1	0x510
+#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD1	0x518
+#define MC_STREAMID_OVERRIDE_CFG_MIU0R		0x530
+#define MC_STREAMID_OVERRIDE_CFG_MIU0W		0x538
+#define MC_STREAMID_OVERRIDE_CFG_MIU1R		0x540
+#define MC_STREAMID_OVERRIDE_CFG_MIU1W		0x548
+#define MC_STREAMID_OVERRIDE_CFG_MIU2R		0x570
+#define MC_STREAMID_OVERRIDE_CFG_MIU2W		0x578
+#define MC_STREAMID_OVERRIDE_CFG_MIU3R		0x580
+#define MC_STREAMID_OVERRIDE_CFG_MIU3W		0x588
+#define MC_STREAMID_OVERRIDE_CFG_VIFALR		0x5E0
+#define MC_STREAMID_OVERRIDE_CFG_VIFALW		0x5E8
+#define MC_STREAMID_OVERRIDE_CFG_DLA0RDA	0x5F0
+#define MC_STREAMID_OVERRIDE_CFG_DLA0FALRDB	0x5F8
+#define MC_STREAMID_OVERRIDE_CFG_DLA0WRA	0x600
+#define MC_STREAMID_OVERRIDE_CFG_DLA0FALWRB	0x608
+#define MC_STREAMID_OVERRIDE_CFG_DLA1RDA	0x610
+#define MC_STREAMID_OVERRIDE_CFG_DLA1FALRDB	0x618
+#define MC_STREAMID_OVERRIDE_CFG_DLA1WRA	0x620
+#define MC_STREAMID_OVERRIDE_CFG_DLA1FALWRB	0x628
+#define MC_STREAMID_OVERRIDE_CFG_PVA0RDA	0x630
+#define MC_STREAMID_OVERRIDE_CFG_PVA0RDB	0x638
+#define MC_STREAMID_OVERRIDE_CFG_PVA0RDC	0x640
+#define MC_STREAMID_OVERRIDE_CFG_PVA0WRA	0x648
+#define MC_STREAMID_OVERRIDE_CFG_PVA0WRB	0x650
+#define MC_STREAMID_OVERRIDE_CFG_PVA0WRC	0x658
+#define MC_STREAMID_OVERRIDE_CFG_PVA1RDA	0x660
+#define MC_STREAMID_OVERRIDE_CFG_PVA1RDB	0x668
+#define MC_STREAMID_OVERRIDE_CFG_PVA1RDC	0x670
+#define MC_STREAMID_OVERRIDE_CFG_PVA1WRA	0x678
+#define MC_STREAMID_OVERRIDE_CFG_PVA1WRB	0x680
+#define MC_STREAMID_OVERRIDE_CFG_PVA1WRC	0x688
+#define MC_STREAMID_OVERRIDE_CFG_RCER		0x690
+#define MC_STREAMID_OVERRIDE_CFG_RCEW		0x698
+#define MC_STREAMID_OVERRIDE_CFG_RCEDMAR	0x6A0
+#define MC_STREAMID_OVERRIDE_CFG_RCEDMAW	0x6A8
+#define MC_STREAMID_OVERRIDE_CFG_NVENC1SRD	0x6B0
+#define MC_STREAMID_OVERRIDE_CFG_NVENC1SWR	0x6B8
+#define MC_STREAMID_OVERRIDE_CFG_PCIE0R		0x6C0
+#define MC_STREAMID_OVERRIDE_CFG_PCIE0W		0x6C8
+#define MC_STREAMID_OVERRIDE_CFG_PCIE1R		0x6D0
+#define MC_STREAMID_OVERRIDE_CFG_PCIE1W		0x6D8
+#define MC_STREAMID_OVERRIDE_CFG_PCIE2AR	0x6E0
+#define MC_STREAMID_OVERRIDE_CFG_PCIE2AW	0x6E8
+#define MC_STREAMID_OVERRIDE_CFG_PCIE3R		0x6F0
+#define MC_STREAMID_OVERRIDE_CFG_PCIE3W		0x6F8
+#define MC_STREAMID_OVERRIDE_CFG_PCIE4R		0x700
+#define MC_STREAMID_OVERRIDE_CFG_PCIE4W		0x708
+#define MC_STREAMID_OVERRIDE_CFG_PCIE5R		0x710
+#define MC_STREAMID_OVERRIDE_CFG_PCIE5W		0x718
+#define MC_STREAMID_OVERRIDE_CFG_ISPFALW	0x720
+#define MC_STREAMID_OVERRIDE_CFG_DLA0RDA1	0x748
+#define MC_STREAMID_OVERRIDE_CFG_DLA1RDA1	0x750
+#define MC_STREAMID_OVERRIDE_CFG_PVA0RDA1	0x758
+#define MC_STREAMID_OVERRIDE_CFG_PVA0RDB1	0x760
+#define MC_STREAMID_OVERRIDE_CFG_PVA1RDA1	0x768
+#define MC_STREAMID_OVERRIDE_CFG_PVA1RDB1	0x770
+#define MC_STREAMID_OVERRIDE_CFG_PCIE5R1	0x778
+#define MC_STREAMID_OVERRIDE_CFG_NVENCSRD1	0x780
+#define MC_STREAMID_OVERRIDE_CFG_NVENC1SRD1	0x788
+#define MC_STREAMID_OVERRIDE_CFG_ISPRA1		0x790
+#define MC_STREAMID_OVERRIDE_CFG_PCIE0R1	0x798
+#define MC_STREAMID_OVERRIDE_CFG_NVDEC1SRD	0x7C8
+#define MC_STREAMID_OVERRIDE_CFG_NVDEC1SRD1	0x7D0
+#define MC_STREAMID_OVERRIDE_CFG_NVDEC1SWR	0x7D8
+
+/*******************************************************************************
+ * Macro to calculate Security cfg register addr from StreamID Override register
+ ******************************************************************************/
+#define MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(addr) (addr + sizeof(uint32_t))
+
+/*******************************************************************************
+ * Memory Controller transaction override config registers
+ ******************************************************************************/
+#define MC_TXN_OVERRIDE_CONFIG_HDAR		0x10a8
+#define MC_TXN_OVERRIDE_CONFIG_BPMPW		0x14a0
+#define MC_TXN_OVERRIDE_CONFIG_PTCR		0x1000
+#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR	0x1490
+#define MC_TXN_OVERRIDE_CONFIG_EQOSW		0x1478
+#define MC_TXN_OVERRIDE_CONFIG_NVJPGSWR		0x13f8
+#define MC_TXN_OVERRIDE_CONFIG_ISPRA		0x1220
+#define MC_TXN_OVERRIDE_CONFIG_VICSRD		0x1360
+#define MC_TXN_OVERRIDE_CONFIG_MPCOREW		0x11c8
+#define MC_TXN_OVERRIDE_CONFIG_GPUSRD		0x12c0
+#define MC_TXN_OVERRIDE_CONFIG_AXISR		0x1460
+#define MC_TXN_OVERRIDE_CONFIG_SCEDMAW		0x14f0
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCW		0x1330
+#define MC_TXN_OVERRIDE_CONFIG_EQOSR		0x1470
+#define MC_TXN_OVERRIDE_CONFIG_APEDMAR		0x14f8
+#define MC_TXN_OVERRIDE_CONFIG_NVENCSRD		0x10e0
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAB		0x1318
+#define MC_TXN_OVERRIDE_CONFIG_VICSRD1		0x1510
+#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAR		0x14a8
+#define MC_TXN_OVERRIDE_CONFIG_VIW		0x1390
+#define MC_TXN_OVERRIDE_CONFIG_AXISW		0x1468
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVR	0x1260
+#define MC_TXN_OVERRIDE_CONFIG_UFSHCR		0x1480
+#define MC_TXN_OVERRIDE_CONFIG_TSECSWR		0x12a8
+#define MC_TXN_OVERRIDE_CONFIG_GPUSWR		0x12c8
+#define MC_TXN_OVERRIDE_CONFIG_SATAR		0x10f8
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTW	0x1258
+#define MC_TXN_OVERRIDE_CONFIG_TSECSWRB		0x1438
+#define MC_TXN_OVERRIDE_CONFIG_GPUSRD2		0x1440
+#define MC_TXN_OVERRIDE_CONFIG_SCEDMAR		0x14e8
+#define MC_TXN_OVERRIDE_CONFIG_GPUSWR2		0x1448
+#define MC_TXN_OVERRIDE_CONFIG_AONDMAW		0x14d0
+#define MC_TXN_OVERRIDE_CONFIG_APEDMAW		0x1500
+#define MC_TXN_OVERRIDE_CONFIG_AONW		0x14c0
+#define MC_TXN_OVERRIDE_CONFIG_HOST1XDMAR	0x10b0
+#define MC_TXN_OVERRIDE_CONFIG_ETRR		0x1420
+#define MC_TXN_OVERRIDE_CONFIG_SESWR		0x1408
+#define MC_TXN_OVERRIDE_CONFIG_NVJPGSRD		0x13f0
+#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD		0x13c0
+#define MC_TXN_OVERRIDE_CONFIG_TSECSRDB		0x1430
+#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAW		0x14b0
+#define MC_TXN_OVERRIDE_CONFIG_APER		0x13d0
+#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD1	0x1518
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTR	0x1250
+#define MC_TXN_OVERRIDE_CONFIG_ISPWA		0x1230
+#define MC_TXN_OVERRIDE_CONFIG_SESRD		0x1400
+#define MC_TXN_OVERRIDE_CONFIG_SCER		0x14d8
+#define MC_TXN_OVERRIDE_CONFIG_AONR		0x14b8
+#define MC_TXN_OVERRIDE_CONFIG_MPCORER		0x1138
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCWA		0x1320
+#define MC_TXN_OVERRIDE_CONFIG_HDAW		0x11a8
+#define MC_TXN_OVERRIDE_CONFIG_NVDECSWR		0x13c8
+#define MC_TXN_OVERRIDE_CONFIG_UFSHCW		0x1488
+#define MC_TXN_OVERRIDE_CONFIG_AONDMAR		0x14c8
+#define MC_TXN_OVERRIDE_CONFIG_SATAW		0x11e8
+#define MC_TXN_OVERRIDE_CONFIG_ETRW		0x1428
+#define MC_TXN_OVERRIDE_CONFIG_VICSWR		0x1368
+#define MC_TXN_OVERRIDE_CONFIG_NVENCSWR		0x1158
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAB		0x1338
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCRA		0x1300
+#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR1	0x1508
+#define MC_TXN_OVERRIDE_CONFIG_ISPWB		0x1238
+#define MC_TXN_OVERRIDE_CONFIG_BPMPR		0x1498
+#define MC_TXN_OVERRIDE_CONFIG_APEW		0x13d8
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCR		0x1310
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVW	0x1268
+#define MC_TXN_OVERRIDE_CONFIG_TSECSRD		0x12a0
+#define MC_TXN_OVERRIDE_CONFIG_SCEW		0x14e0
+#define MC_TXN_OVERRIDE_CONFIG_MIU0R		0x1530
+#define MC_TXN_OVERRIDE_CONFIG_MIU0W		0x1538
+#define MC_TXN_OVERRIDE_CONFIG_MIU1R		0x1540
+#define MC_TXN_OVERRIDE_CONFIG_MIU1W		0x1548
+#define MC_TXN_OVERRIDE_CONFIG_MIU2R		0x1570
+#define MC_TXN_OVERRIDE_CONFIG_MIU2W		0x1578
+#define MC_TXN_OVERRIDE_CONFIG_MIU3R		0x1580
+#define MC_TXN_OVERRIDE_CONFIG_MIU3W		0x158C
+#define MC_TXN_OVERRIDE_CONFIG_VIFALR		0x15E4
+#define MC_TXN_OVERRIDE_CONFIG_VIFALW		0x15EC
+#define MC_TXN_OVERRIDE_CONFIG_DLA0RDA		0x15F4
+#define MC_TXN_OVERRIDE_CONFIG_DLA0FALRDB	0x15FC
+#define MC_TXN_OVERRIDE_CONFIG_DLA0WRA		0x1604
+#define MC_TXN_OVERRIDE_CONFIG_DLA0FALWRB	0x160C
+#define MC_TXN_OVERRIDE_CONFIG_DLA1RDA		0x1614
+#define MC_TXN_OVERRIDE_CONFIG_DLA1FALRDB	0x161C
+#define MC_TXN_OVERRIDE_CONFIG_DLA1WRA		0x1624
+#define MC_TXN_OVERRIDE_CONFIG_DLA1FALWRB	0x162C
+#define MC_TXN_OVERRIDE_CONFIG_PVA0RDA		0x1634
+#define MC_TXN_OVERRIDE_CONFIG_PVA0RDB		0x163C
+#define MC_TXN_OVERRIDE_CONFIG_PVA0RDC		0x1644
+#define MC_TXN_OVERRIDE_CONFIG_PVA0WRA		0x164C
+#define MC_TXN_OVERRIDE_CONFIG_PVA0WRB		0x1654
+#define MC_TXN_OVERRIDE_CONFIG_PVA0WRC		0x165C
+#define MC_TXN_OVERRIDE_CONFIG_PVA1RDA		0x1664
+#define MC_TXN_OVERRIDE_CONFIG_PVA1RDB		0x166C
+#define MC_TXN_OVERRIDE_CONFIG_PVA1RDC		0x1674
+#define MC_TXN_OVERRIDE_CONFIG_PVA1WRA		0x167C
+#define MC_TXN_OVERRIDE_CONFIG_PVA1WRB		0x1684
+#define MC_TXN_OVERRIDE_CONFIG_PVA1WRC		0x168C
+#define MC_TXN_OVERRIDE_CONFIG_RCER		0x1694
+#define MC_TXN_OVERRIDE_CONFIG_RCEW		0x169C
+#define MC_TXN_OVERRIDE_CONFIG_RCEDMAR		0x16A4
+#define MC_TXN_OVERRIDE_CONFIG_RCEDMAW		0x16AC
+#define MC_TXN_OVERRIDE_CONFIG_NVENC1SRD	0x16B4
+#define MC_TXN_OVERRIDE_CONFIG_NVENC1SWR	0x16BC
+#define MC_TXN_OVERRIDE_CONFIG_PCIE0R		0x16C4
+#define MC_TXN_OVERRIDE_CONFIG_PCIE0W		0x16CC
+#define MC_TXN_OVERRIDE_CONFIG_PCIE1R		0x16D4
+#define MC_TXN_OVERRIDE_CONFIG_PCIE1W		0x16DC
+#define MC_TXN_OVERRIDE_CONFIG_PCIE2AR		0x16E4
+#define MC_TXN_OVERRIDE_CONFIG_PCIE2AW		0x16EC
+#define MC_TXN_OVERRIDE_CONFIG_PCIE3R		0x16F4
+#define MC_TXN_OVERRIDE_CONFIG_PCIE3W		0x16FC
+#define MC_TXN_OVERRIDE_CONFIG_PCIE4R		0x1704
+#define MC_TXN_OVERRIDE_CONFIG_PCIE4W		0x170C
+#define MC_TXN_OVERRIDE_CONFIG_PCIE5R		0x1714
+#define MC_TXN_OVERRIDE_CONFIG_PCIE5W		0x171C
+#define MC_TXN_OVERRIDE_CONFIG_ISPFALW		0x1724
+#define MC_TXN_OVERRIDE_CONFIG_DLA0RDA1		0x174C
+#define MC_TXN_OVERRIDE_CONFIG_DLA1RDA1		0x1754
+#define MC_TXN_OVERRIDE_CONFIG_PVA0RDA1		0x175C
+#define MC_TXN_OVERRIDE_CONFIG_PVA0RDB1		0x1764
+#define MC_TXN_OVERRIDE_CONFIG_PVA1RDA1		0x176C
+#define MC_TXN_OVERRIDE_CONFIG_PVA1RDB1		0x1774
+#define MC_TXN_OVERRIDE_CONFIG_PCIE5R1		0x177C
+#define MC_TXN_OVERRIDE_CONFIG_NVENCSRD1	0x1784
+#define MC_TXN_OVERRIDE_CONFIG_NVENC1SRD1	0x178C
+#define MC_TXN_OVERRIDE_CONFIG_ISPRA1		0x1794
+#define MC_TXN_OVERRIDE_CONFIG_PCIE0R1		0x179C
+#define MC_TXN_OVERRIDE_CONFIG_NVDEC1SRD	0x17CC
+#define MC_TXN_OVERRIDE_CONFIG_NVDEC1SRD1	0x17D4
+#define MC_TXN_OVERRIDE_CONFIG_NVDEC1SWR	0x17DC
+
+/*******************************************************************************
+ * Array to hold stream_id override config register offsets
+ ******************************************************************************/
+const static uint32_t mc_streamid_override_regs[] = {
+	MC_STREAMID_OVERRIDE_CFG_HDAR,
+	MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR,
+	MC_STREAMID_OVERRIDE_CFG_NVENCSRD,
+	MC_STREAMID_OVERRIDE_CFG_SATAR,
+	MC_STREAMID_OVERRIDE_CFG_NVENCSWR,
+	MC_STREAMID_OVERRIDE_CFG_HDAW,
+	MC_STREAMID_OVERRIDE_CFG_SATAW,
+	MC_STREAMID_OVERRIDE_CFG_ISPRA,
+	MC_STREAMID_OVERRIDE_CFG_ISPFALR,
+	MC_STREAMID_OVERRIDE_CFG_ISPWA,
+	MC_STREAMID_OVERRIDE_CFG_ISPWB,
+	MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR,
+	MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW,
+	MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR,
+	MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW,
+	MC_STREAMID_OVERRIDE_CFG_TSECSRD,
+	MC_STREAMID_OVERRIDE_CFG_TSECSWR,
+	MC_STREAMID_OVERRIDE_CFG_SDMMCRA,
+	MC_STREAMID_OVERRIDE_CFG_SDMMCR,
+	MC_STREAMID_OVERRIDE_CFG_SDMMCRAB,
+	MC_STREAMID_OVERRIDE_CFG_SDMMCWA,
+	MC_STREAMID_OVERRIDE_CFG_SDMMCW,
+	MC_STREAMID_OVERRIDE_CFG_SDMMCWAB,
+	MC_STREAMID_OVERRIDE_CFG_VICSRD,
+	MC_STREAMID_OVERRIDE_CFG_VICSWR,
+	MC_STREAMID_OVERRIDE_CFG_VIW,
+	MC_STREAMID_OVERRIDE_CFG_NVDECSRD,
+	MC_STREAMID_OVERRIDE_CFG_NVDECSWR,
+	MC_STREAMID_OVERRIDE_CFG_APER,
+	MC_STREAMID_OVERRIDE_CFG_APEW,
+	MC_STREAMID_OVERRIDE_CFG_NVJPGSRD,
+	MC_STREAMID_OVERRIDE_CFG_NVJPGSWR,
+	MC_STREAMID_OVERRIDE_CFG_SESRD,
+	MC_STREAMID_OVERRIDE_CFG_SESWR,
+	MC_STREAMID_OVERRIDE_CFG_AXIAPR,
+	MC_STREAMID_OVERRIDE_CFG_AXIAPW,
+	MC_STREAMID_OVERRIDE_CFG_ETRR,
+	MC_STREAMID_OVERRIDE_CFG_ETRW,
+	MC_STREAMID_OVERRIDE_CFG_TSECSRDB,
+	MC_STREAMID_OVERRIDE_CFG_TSECSWRB,
+	MC_STREAMID_OVERRIDE_CFG_AXISR,
+	MC_STREAMID_OVERRIDE_CFG_AXISW,
+	MC_STREAMID_OVERRIDE_CFG_EQOSR,
+	MC_STREAMID_OVERRIDE_CFG_EQOSW,
+	MC_STREAMID_OVERRIDE_CFG_UFSHCR,
+	MC_STREAMID_OVERRIDE_CFG_UFSHCW,
+	MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR,
+	MC_STREAMID_OVERRIDE_CFG_BPMPR,
+	MC_STREAMID_OVERRIDE_CFG_BPMPW,
+	MC_STREAMID_OVERRIDE_CFG_BPMPDMAR,
+	MC_STREAMID_OVERRIDE_CFG_BPMPDMAW,
+	MC_STREAMID_OVERRIDE_CFG_AONR,
+	MC_STREAMID_OVERRIDE_CFG_AONW,
+	MC_STREAMID_OVERRIDE_CFG_AONDMAR,
+	MC_STREAMID_OVERRIDE_CFG_AONDMAW,
+	MC_STREAMID_OVERRIDE_CFG_SCER,
+	MC_STREAMID_OVERRIDE_CFG_SCEW,
+	MC_STREAMID_OVERRIDE_CFG_SCEDMAR,
+	MC_STREAMID_OVERRIDE_CFG_SCEDMAW,
+	MC_STREAMID_OVERRIDE_CFG_APEDMAR,
+	MC_STREAMID_OVERRIDE_CFG_APEDMAW,
+	MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1,
+	MC_STREAMID_OVERRIDE_CFG_VICSRD1,
+	MC_STREAMID_OVERRIDE_CFG_NVDECSRD1,
+	MC_STREAMID_OVERRIDE_CFG_VIFALR,
+	MC_STREAMID_OVERRIDE_CFG_VIFALW,
+	MC_STREAMID_OVERRIDE_CFG_DLA0RDA,
+	MC_STREAMID_OVERRIDE_CFG_DLA0FALRDB,
+	MC_STREAMID_OVERRIDE_CFG_DLA0WRA,
+	MC_STREAMID_OVERRIDE_CFG_DLA0FALWRB,
+	MC_STREAMID_OVERRIDE_CFG_DLA1RDA,
+	MC_STREAMID_OVERRIDE_CFG_DLA1FALRDB,
+	MC_STREAMID_OVERRIDE_CFG_DLA1WRA,
+	MC_STREAMID_OVERRIDE_CFG_DLA1FALWRB,
+	MC_STREAMID_OVERRIDE_CFG_PVA0RDA,
+	MC_STREAMID_OVERRIDE_CFG_PVA0RDB,
+	MC_STREAMID_OVERRIDE_CFG_PVA0RDC,
+	MC_STREAMID_OVERRIDE_CFG_PVA0WRA,
+	MC_STREAMID_OVERRIDE_CFG_PVA0WRB,
+	MC_STREAMID_OVERRIDE_CFG_PVA0WRC,
+	MC_STREAMID_OVERRIDE_CFG_PVA1RDA,
+	MC_STREAMID_OVERRIDE_CFG_PVA1RDB,
+	MC_STREAMID_OVERRIDE_CFG_PVA1RDC,
+	MC_STREAMID_OVERRIDE_CFG_PVA1WRA,
+	MC_STREAMID_OVERRIDE_CFG_PVA1WRB,
+	MC_STREAMID_OVERRIDE_CFG_PVA1WRC,
+	MC_STREAMID_OVERRIDE_CFG_RCER,
+	MC_STREAMID_OVERRIDE_CFG_RCEW,
+	MC_STREAMID_OVERRIDE_CFG_RCEDMAR,
+	MC_STREAMID_OVERRIDE_CFG_RCEDMAW,
+	MC_STREAMID_OVERRIDE_CFG_NVENC1SRD,
+	MC_STREAMID_OVERRIDE_CFG_NVENC1SWR,
+	MC_STREAMID_OVERRIDE_CFG_PCIE0R,
+	MC_STREAMID_OVERRIDE_CFG_PCIE0W,
+	MC_STREAMID_OVERRIDE_CFG_PCIE1R,
+	MC_STREAMID_OVERRIDE_CFG_PCIE1W,
+	MC_STREAMID_OVERRIDE_CFG_PCIE2AR,
+	MC_STREAMID_OVERRIDE_CFG_PCIE2AW,
+	MC_STREAMID_OVERRIDE_CFG_PCIE3R,
+	MC_STREAMID_OVERRIDE_CFG_PCIE3W,
+	MC_STREAMID_OVERRIDE_CFG_PCIE4R,
+	MC_STREAMID_OVERRIDE_CFG_PCIE4W,
+	MC_STREAMID_OVERRIDE_CFG_PCIE5R,
+	MC_STREAMID_OVERRIDE_CFG_PCIE5W,
+	MC_STREAMID_OVERRIDE_CFG_ISPFALW,
+	MC_STREAMID_OVERRIDE_CFG_DLA0RDA1,
+	MC_STREAMID_OVERRIDE_CFG_DLA1RDA1,
+	MC_STREAMID_OVERRIDE_CFG_PVA0RDA1,
+	MC_STREAMID_OVERRIDE_CFG_PVA0RDB1,
+	MC_STREAMID_OVERRIDE_CFG_PVA1RDA1,
+	MC_STREAMID_OVERRIDE_CFG_PVA1RDB1,
+	MC_STREAMID_OVERRIDE_CFG_PCIE5R1,
+	MC_STREAMID_OVERRIDE_CFG_NVENCSRD1,
+	MC_STREAMID_OVERRIDE_CFG_NVENC1SRD1,
+	MC_STREAMID_OVERRIDE_CFG_ISPRA1,
+	MC_STREAMID_OVERRIDE_CFG_MIU0R,
+	MC_STREAMID_OVERRIDE_CFG_MIU0W,
+	MC_STREAMID_OVERRIDE_CFG_MIU1R,
+	MC_STREAMID_OVERRIDE_CFG_MIU1W,
+	MC_STREAMID_OVERRIDE_CFG_MIU2R,
+	MC_STREAMID_OVERRIDE_CFG_MIU2W,
+	MC_STREAMID_OVERRIDE_CFG_MIU3R,
+	MC_STREAMID_OVERRIDE_CFG_MIU3W
+};
+
+/*******************************************************************************
+ * Array to hold the security configs for stream IDs
+ ******************************************************************************/
+const static mc_streamid_security_cfg_t mc_streamid_sec_cfgs[] = {
+	mc_make_sec_cfg(HDAR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(HOST1XDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVENCSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SATAR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVENCSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(HDAW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SATAW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(ISPRA, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(ISPFALR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(ISPWA, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(ISPWB, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(XUSB_HOSTR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(XUSB_HOSTW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(XUSB_DEVR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(XUSB_DEVW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(TSECSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(TSECSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SDMMCRA, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SDMMCR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SDMMCRAB, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SDMMCWA, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SDMMCW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SDMMCWAB, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(VICSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(VICSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(VIW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVDECSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVDECSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(APER, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(APEW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVJPGSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVJPGSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SESRD, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SESWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AXIAPR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AXIAPW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(ETRR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(ETRW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(TSECSRDB, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(TSECSWRB, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AXISR, SECURE, NO_OVERRIDE, DISABLE),
+	mc_make_sec_cfg(AXISW, SECURE, NO_OVERRIDE, DISABLE),
+	mc_make_sec_cfg(EQOSR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(EQOSW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(UFSHCR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(UFSHCW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVDISPLAYR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(BPMPR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(BPMPW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(BPMPDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(BPMPDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AONR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AONW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AONDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AONDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SCER, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SCEW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SCEDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SCEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(APEDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(APEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVDISPLAYR1, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(VICSRD1, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVDECSRD1, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(VIFALR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(VIFALW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(DLA0RDA, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(DLA0FALRDB, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(DLA0WRA, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(DLA0FALWRB, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(DLA1RDA, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(DLA1FALRDB, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(DLA1WRA, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(DLA1FALWRB, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA0RDA, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA0RDB, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA0RDC, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA0WRA, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA0WRB, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA0WRC, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA1RDA, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA1RDB, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA1RDC, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA1WRA, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA1WRB, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA1WRC, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(RCER, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(RCEW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(RCEDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(RCEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVENC1SRD, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVENC1SWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PCIE0R, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PCIE0W, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PCIE1R, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PCIE1W, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PCIE2AR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PCIE2AW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PCIE3R, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PCIE3W, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PCIE4R, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PCIE4W, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PCIE5R, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PCIE5W, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(ISPFALW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(DLA0RDA1, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(DLA1RDA1, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA0RDA1, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA0RDB1, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA1RDA1, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PVA1RDB1, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PCIE5R1, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVENCSRD1, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVENC1SRD1, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(ISPRA1, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(MIU0R, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(MIU0W, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(MIU1R, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(MIU1W, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(MIU2R, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(MIU2W, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(MIU3R, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(MIU3W, NON_SECURE, OVERRIDE, ENABLE),
+};
+
+/*******************************************************************************
+ * Array to hold the transaction override configs
+ ******************************************************************************/
+const static mc_txn_override_cfg_t mc_txn_override_cfgs[] = {
+	mc_make_txn_override_cfg(NVENCSWR, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(HDAW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(SATAW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(ISPWB, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(XUSB_HOSTW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(XUSB_DEVW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(TSECSWR, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(SDMMCWA, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(SDMMCW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(SDMMCWAB, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(VICSWR, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(NVDECSWR, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(APEW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(NVJPGSWR, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(SESWR, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(ETRW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(TSECSWRB, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(AXISW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(EQOSW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(UFSHCW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(BPMPW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(BPMPDMAW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(AONW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(AONDMAW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(SCEW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(SCEDMAW, CGID_TAG_ADR),
+};
+
+#endif //__MEMCTRL_PLAT_CONFIG_H
diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/smmu_plat_config.h b/plat/nvidia/tegra/soc/t194/drivers/include/smmu_plat_config.h
new file mode 100644
index 0000000..fc8669a
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/drivers/include/smmu_plat_config.h
@@ -0,0 +1,428 @@
+/*
+ * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SMMU_PLAT_CONFIG_H
+#define __SMMU_PLAT_CONFIG_H
+
+#include <mmio.h>
+#include <tegra_def.h>
+#include <smmu.h>
+
+static __attribute__((aligned(16))) smmu_regs_t smmu_ctx_regs[] = {
+	_START_OF_TABLE_,
+	mc_make_sid_security_cfg(HDAR),
+	mc_make_sid_security_cfg(HOST1XDMAR),
+	mc_make_sid_security_cfg(NVENCSRD),
+	mc_make_sid_security_cfg(SATAR),
+	mc_make_sid_security_cfg(NVENCSWR),
+	mc_make_sid_security_cfg(HDAW),
+	mc_make_sid_security_cfg(SATAW),
+	mc_make_sid_security_cfg(ISPRA),
+	mc_make_sid_security_cfg(ISPFALR),
+	mc_make_sid_security_cfg(ISPWA),
+	mc_make_sid_security_cfg(ISPWB),
+	mc_make_sid_security_cfg(XUSB_HOSTR),
+	mc_make_sid_security_cfg(XUSB_HOSTW),
+	mc_make_sid_security_cfg(XUSB_DEVR),
+	mc_make_sid_security_cfg(XUSB_DEVW),
+	mc_make_sid_security_cfg(TSECSRD),
+	mc_make_sid_security_cfg(TSECSWR),
+	mc_make_sid_security_cfg(SDMMCRA),
+	mc_make_sid_security_cfg(SDMMCR),
+	mc_make_sid_security_cfg(SDMMCRAB),
+	mc_make_sid_security_cfg(SDMMCWA),
+	mc_make_sid_security_cfg(SDMMCW),
+	mc_make_sid_security_cfg(SDMMCWAB),
+	mc_make_sid_security_cfg(VICSRD),
+	mc_make_sid_security_cfg(VICSWR),
+	mc_make_sid_security_cfg(VIW),
+	mc_make_sid_security_cfg(NVDECSRD),
+	mc_make_sid_security_cfg(NVDECSWR),
+	mc_make_sid_security_cfg(APER),
+	mc_make_sid_security_cfg(APEW),
+	mc_make_sid_security_cfg(NVJPGSRD),
+	mc_make_sid_security_cfg(NVJPGSWR),
+	mc_make_sid_security_cfg(SESRD),
+	mc_make_sid_security_cfg(SESWR),
+	mc_make_sid_security_cfg(AXIAPR),
+	mc_make_sid_security_cfg(AXIAPW),
+	mc_make_sid_security_cfg(ETRR),
+	mc_make_sid_security_cfg(ETRW),
+	mc_make_sid_security_cfg(TSECSRDB),
+	mc_make_sid_security_cfg(TSECSWRB),
+	mc_make_sid_security_cfg(AXISR),
+	mc_make_sid_security_cfg(AXISW),
+	mc_make_sid_security_cfg(EQOSR),
+	mc_make_sid_security_cfg(EQOSW),
+	mc_make_sid_security_cfg(UFSHCR),
+	mc_make_sid_security_cfg(UFSHCW),
+	mc_make_sid_security_cfg(NVDISPLAYR),
+	mc_make_sid_security_cfg(BPMPR),
+	mc_make_sid_security_cfg(BPMPW),
+	mc_make_sid_security_cfg(BPMPDMAR),
+	mc_make_sid_security_cfg(BPMPDMAW),
+	mc_make_sid_security_cfg(AONR),
+	mc_make_sid_security_cfg(AONW),
+	mc_make_sid_security_cfg(AONDMAR),
+	mc_make_sid_security_cfg(AONDMAW),
+	mc_make_sid_security_cfg(SCER),
+	mc_make_sid_security_cfg(SCEW),
+	mc_make_sid_security_cfg(SCEDMAR),
+	mc_make_sid_security_cfg(SCEDMAW),
+	mc_make_sid_security_cfg(APEDMAR),
+	mc_make_sid_security_cfg(APEDMAW),
+	mc_make_sid_security_cfg(NVDISPLAYR1),
+	mc_make_sid_security_cfg(VICSRD1),
+	mc_make_sid_security_cfg(NVDECSRD1),
+	mc_make_sid_security_cfg(VIFALR),
+	mc_make_sid_security_cfg(VIFALW),
+	mc_make_sid_security_cfg(DLA0RDA),
+	mc_make_sid_security_cfg(DLA0FALRDB),
+	mc_make_sid_security_cfg(DLA0WRA),
+	mc_make_sid_security_cfg(DLA0FALWRB),
+	mc_make_sid_security_cfg(DLA1RDA),
+	mc_make_sid_security_cfg(DLA1FALRDB),
+	mc_make_sid_security_cfg(DLA1WRA),
+	mc_make_sid_security_cfg(DLA1FALWRB),
+	mc_make_sid_security_cfg(PVA0RDA),
+	mc_make_sid_security_cfg(PVA0RDB),
+	mc_make_sid_security_cfg(PVA0RDC),
+	mc_make_sid_security_cfg(PVA0WRA),
+	mc_make_sid_security_cfg(PVA0WRB),
+	mc_make_sid_security_cfg(PVA0WRC),
+	mc_make_sid_security_cfg(PVA1RDA),
+	mc_make_sid_security_cfg(PVA1RDB),
+	mc_make_sid_security_cfg(PVA1RDC),
+	mc_make_sid_security_cfg(PVA1WRA),
+	mc_make_sid_security_cfg(PVA1WRB),
+	mc_make_sid_security_cfg(PVA1WRC),
+	mc_make_sid_security_cfg(RCER),
+	mc_make_sid_security_cfg(RCEW),
+	mc_make_sid_security_cfg(RCEDMAR),
+	mc_make_sid_security_cfg(RCEDMAW),
+	mc_make_sid_security_cfg(NVENC1SRD),
+	mc_make_sid_security_cfg(NVENC1SWR),
+	mc_make_sid_security_cfg(PCIE0R),
+	mc_make_sid_security_cfg(PCIE0W),
+	mc_make_sid_security_cfg(PCIE1R),
+	mc_make_sid_security_cfg(PCIE1W),
+	mc_make_sid_security_cfg(PCIE2AR),
+	mc_make_sid_security_cfg(PCIE2AW),
+	mc_make_sid_security_cfg(PCIE3R),
+	mc_make_sid_security_cfg(PCIE3W),
+	mc_make_sid_security_cfg(PCIE4R),
+	mc_make_sid_security_cfg(PCIE4W),
+	mc_make_sid_security_cfg(PCIE5R),
+	mc_make_sid_security_cfg(PCIE5W),
+	mc_make_sid_security_cfg(ISPFALW),
+	mc_make_sid_security_cfg(DLA0RDA1),
+	mc_make_sid_security_cfg(DLA1RDA1),
+	mc_make_sid_security_cfg(PVA0RDA1),
+	mc_make_sid_security_cfg(PVA0RDB1),
+	mc_make_sid_security_cfg(PVA1RDA1),
+	mc_make_sid_security_cfg(PVA1RDB1),
+	mc_make_sid_security_cfg(PCIE5R1),
+	mc_make_sid_security_cfg(NVENCSRD1),
+	mc_make_sid_security_cfg(NVENC1SRD1),
+	mc_make_sid_security_cfg(ISPRA1),
+	mc_make_sid_security_cfg(MIU0R),
+	mc_make_sid_security_cfg(MIU0W),
+	mc_make_sid_security_cfg(MIU1R),
+	mc_make_sid_security_cfg(MIU1W),
+	mc_make_sid_security_cfg(MIU2R),
+	mc_make_sid_security_cfg(MIU2W),
+	mc_make_sid_security_cfg(MIU3R),
+	mc_make_sid_security_cfg(MIU3W),
+	mc_make_sid_override_cfg(HDAR),
+	mc_make_sid_override_cfg(HOST1XDMAR),
+	mc_make_sid_override_cfg(NVENCSRD),
+	mc_make_sid_override_cfg(SATAR),
+	mc_make_sid_override_cfg(NVENCSWR),
+	mc_make_sid_override_cfg(HDAW),
+	mc_make_sid_override_cfg(SATAW),
+	mc_make_sid_override_cfg(ISPRA),
+	mc_make_sid_override_cfg(ISPFALR),
+	mc_make_sid_override_cfg(ISPWA),
+	mc_make_sid_override_cfg(ISPWB),
+	mc_make_sid_override_cfg(XUSB_HOSTR),
+	mc_make_sid_override_cfg(XUSB_HOSTW),
+	mc_make_sid_override_cfg(XUSB_DEVR),
+	mc_make_sid_override_cfg(XUSB_DEVW),
+	mc_make_sid_override_cfg(TSECSRD),
+	mc_make_sid_override_cfg(TSECSWR),
+	mc_make_sid_override_cfg(SDMMCRA),
+	mc_make_sid_override_cfg(SDMMCR),
+	mc_make_sid_override_cfg(SDMMCRAB),
+	mc_make_sid_override_cfg(SDMMCWA),
+	mc_make_sid_override_cfg(SDMMCW),
+	mc_make_sid_override_cfg(SDMMCWAB),
+	mc_make_sid_override_cfg(VICSRD),
+	mc_make_sid_override_cfg(VICSWR),
+	mc_make_sid_override_cfg(VIW),
+	mc_make_sid_override_cfg(NVDECSRD),
+	mc_make_sid_override_cfg(NVDECSWR),
+	mc_make_sid_override_cfg(APER),
+	mc_make_sid_override_cfg(APEW),
+	mc_make_sid_override_cfg(NVJPGSRD),
+	mc_make_sid_override_cfg(NVJPGSWR),
+	mc_make_sid_override_cfg(SESRD),
+	mc_make_sid_override_cfg(SESWR),
+	mc_make_sid_override_cfg(AXIAPR),
+	mc_make_sid_override_cfg(AXIAPW),
+	mc_make_sid_override_cfg(ETRR),
+	mc_make_sid_override_cfg(ETRW),
+	mc_make_sid_override_cfg(TSECSRDB),
+	mc_make_sid_override_cfg(TSECSWRB),
+	mc_make_sid_override_cfg(AXISR),
+	mc_make_sid_override_cfg(AXISW),
+	mc_make_sid_override_cfg(EQOSR),
+	mc_make_sid_override_cfg(EQOSW),
+	mc_make_sid_override_cfg(UFSHCR),
+	mc_make_sid_override_cfg(UFSHCW),
+	mc_make_sid_override_cfg(NVDISPLAYR),
+	mc_make_sid_override_cfg(BPMPR),
+	mc_make_sid_override_cfg(BPMPW),
+	mc_make_sid_override_cfg(BPMPDMAR),
+	mc_make_sid_override_cfg(BPMPDMAW),
+	mc_make_sid_override_cfg(AONR),
+	mc_make_sid_override_cfg(AONW),
+	mc_make_sid_override_cfg(AONDMAR),
+	mc_make_sid_override_cfg(AONDMAW),
+	mc_make_sid_override_cfg(SCER),
+	mc_make_sid_override_cfg(SCEW),
+	mc_make_sid_override_cfg(SCEDMAR),
+	mc_make_sid_override_cfg(SCEDMAW),
+	mc_make_sid_override_cfg(APEDMAR),
+	mc_make_sid_override_cfg(APEDMAW),
+	mc_make_sid_override_cfg(NVDISPLAYR1),
+	mc_make_sid_override_cfg(VICSRD1),
+	mc_make_sid_override_cfg(NVDECSRD1),
+	mc_make_sid_override_cfg(VIFALR),
+	mc_make_sid_override_cfg(VIFALW),
+	mc_make_sid_override_cfg(DLA0RDA),
+	mc_make_sid_override_cfg(DLA0FALRDB),
+	mc_make_sid_override_cfg(DLA0WRA),
+	mc_make_sid_override_cfg(DLA0FALWRB),
+	mc_make_sid_override_cfg(DLA1RDA),
+	mc_make_sid_override_cfg(DLA1FALRDB),
+	mc_make_sid_override_cfg(DLA1WRA),
+	mc_make_sid_override_cfg(DLA1FALWRB),
+	mc_make_sid_override_cfg(PVA0RDA),
+	mc_make_sid_override_cfg(PVA0RDB),
+	mc_make_sid_override_cfg(PVA0RDC),
+	mc_make_sid_override_cfg(PVA0WRA),
+	mc_make_sid_override_cfg(PVA0WRB),
+	mc_make_sid_override_cfg(PVA0WRC),
+	mc_make_sid_override_cfg(PVA1RDA),
+	mc_make_sid_override_cfg(PVA1RDB),
+	mc_make_sid_override_cfg(PVA1RDC),
+	mc_make_sid_override_cfg(PVA1WRA),
+	mc_make_sid_override_cfg(PVA1WRB),
+	mc_make_sid_override_cfg(PVA1WRC),
+	mc_make_sid_override_cfg(RCER),
+	mc_make_sid_override_cfg(RCEW),
+	mc_make_sid_override_cfg(RCEDMAR),
+	mc_make_sid_override_cfg(RCEDMAW),
+	mc_make_sid_override_cfg(NVENC1SRD),
+	mc_make_sid_override_cfg(NVENC1SWR),
+	mc_make_sid_override_cfg(PCIE0R),
+	mc_make_sid_override_cfg(PCIE0W),
+	mc_make_sid_override_cfg(PCIE1R),
+	mc_make_sid_override_cfg(PCIE1W),
+	mc_make_sid_override_cfg(PCIE2AR),
+	mc_make_sid_override_cfg(PCIE2AW),
+	mc_make_sid_override_cfg(PCIE3R),
+	mc_make_sid_override_cfg(PCIE3W),
+	mc_make_sid_override_cfg(PCIE4R),
+	mc_make_sid_override_cfg(PCIE4W),
+	mc_make_sid_override_cfg(PCIE5R),
+	mc_make_sid_override_cfg(PCIE5W),
+	mc_make_sid_override_cfg(ISPFALW),
+	mc_make_sid_override_cfg(DLA0RDA1),
+	mc_make_sid_override_cfg(DLA1RDA1),
+	mc_make_sid_override_cfg(PVA0RDA1),
+	mc_make_sid_override_cfg(PVA0RDB1),
+	mc_make_sid_override_cfg(PVA1RDA1),
+	mc_make_sid_override_cfg(PVA1RDB1),
+	mc_make_sid_override_cfg(PCIE5R1),
+	mc_make_sid_override_cfg(NVENCSRD1),
+	mc_make_sid_override_cfg(NVENC1SRD1),
+	mc_make_sid_override_cfg(ISPRA1),
+	mc_make_sid_override_cfg(MIU0R),
+	mc_make_sid_override_cfg(MIU0W),
+	mc_make_sid_override_cfg(MIU1R),
+	mc_make_sid_override_cfg(MIU1W),
+	mc_make_sid_override_cfg(MIU2R),
+	mc_make_sid_override_cfg(MIU2W),
+	mc_make_sid_override_cfg(MIU3R),
+	mc_make_sid_override_cfg(MIU3W),
+	smmu_make_gnsr0_nsec_cfg(CR0),
+	smmu_make_gnsr0_sec_cfg(IDR0),
+	smmu_make_gnsr0_sec_cfg(IDR1),
+	smmu_make_gnsr0_sec_cfg(IDR2),
+	smmu_make_gnsr0_nsec_cfg(GFSR),
+	smmu_make_gnsr0_nsec_cfg(GFSYNR0),
+	smmu_make_gnsr0_nsec_cfg(GFSYNR1),
+	smmu_make_gnsr0_nsec_cfg(TLBGSTATUS),
+	smmu_make_gnsr0_nsec_cfg(PIDR2),
+	smmu_make_smrg_group(0),
+	smmu_make_smrg_group(1),
+	smmu_make_smrg_group(2),
+	smmu_make_smrg_group(3),
+	smmu_make_smrg_group(4),
+	smmu_make_smrg_group(5),
+	smmu_make_smrg_group(6),
+	smmu_make_smrg_group(7),
+	smmu_make_smrg_group(8),
+	smmu_make_smrg_group(9),
+	smmu_make_smrg_group(10),
+	smmu_make_smrg_group(11),
+	smmu_make_smrg_group(12),
+	smmu_make_smrg_group(13),
+	smmu_make_smrg_group(14),
+	smmu_make_smrg_group(15),
+	smmu_make_smrg_group(16),
+	smmu_make_smrg_group(17),
+	smmu_make_smrg_group(18),
+	smmu_make_smrg_group(19),
+	smmu_make_smrg_group(20),
+	smmu_make_smrg_group(21),
+	smmu_make_smrg_group(22),
+	smmu_make_smrg_group(23),
+	smmu_make_smrg_group(24),
+	smmu_make_smrg_group(25),
+	smmu_make_smrg_group(26),
+	smmu_make_smrg_group(27),
+	smmu_make_smrg_group(28),
+	smmu_make_smrg_group(29),
+	smmu_make_smrg_group(30),
+	smmu_make_smrg_group(31),
+	smmu_make_smrg_group(32),
+	smmu_make_smrg_group(33),
+	smmu_make_smrg_group(34),
+	smmu_make_smrg_group(35),
+	smmu_make_smrg_group(36),
+	smmu_make_smrg_group(37),
+	smmu_make_smrg_group(38),
+	smmu_make_smrg_group(39),
+	smmu_make_smrg_group(40),
+	smmu_make_smrg_group(41),
+	smmu_make_smrg_group(42),
+	smmu_make_smrg_group(43),
+	smmu_make_smrg_group(44),
+	smmu_make_smrg_group(45),
+	smmu_make_smrg_group(46),
+	smmu_make_smrg_group(47),
+	smmu_make_smrg_group(48),
+	smmu_make_smrg_group(49),
+	smmu_make_smrg_group(50),
+	smmu_make_smrg_group(51),
+	smmu_make_smrg_group(52),
+	smmu_make_smrg_group(53),
+	smmu_make_smrg_group(54),
+	smmu_make_smrg_group(55),
+	smmu_make_smrg_group(56),
+	smmu_make_smrg_group(57),
+	smmu_make_smrg_group(58),
+	smmu_make_smrg_group(59),
+	smmu_make_smrg_group(60),
+	smmu_make_smrg_group(61),
+	smmu_make_smrg_group(62),
+	smmu_make_smrg_group(63),
+	smmu_make_cb_group(0),
+	smmu_make_cb_group(1),
+	smmu_make_cb_group(2),
+	smmu_make_cb_group(3),
+	smmu_make_cb_group(4),
+	smmu_make_cb_group(5),
+	smmu_make_cb_group(6),
+	smmu_make_cb_group(7),
+	smmu_make_cb_group(8),
+	smmu_make_cb_group(9),
+	smmu_make_cb_group(10),
+	smmu_make_cb_group(11),
+	smmu_make_cb_group(12),
+	smmu_make_cb_group(13),
+	smmu_make_cb_group(14),
+	smmu_make_cb_group(15),
+	smmu_make_cb_group(16),
+	smmu_make_cb_group(17),
+	smmu_make_cb_group(18),
+	smmu_make_cb_group(19),
+	smmu_make_cb_group(20),
+	smmu_make_cb_group(21),
+	smmu_make_cb_group(22),
+	smmu_make_cb_group(23),
+	smmu_make_cb_group(24),
+	smmu_make_cb_group(25),
+	smmu_make_cb_group(26),
+	smmu_make_cb_group(27),
+	smmu_make_cb_group(28),
+	smmu_make_cb_group(29),
+	smmu_make_cb_group(30),
+	smmu_make_cb_group(31),
+	smmu_make_cb_group(32),
+	smmu_make_cb_group(33),
+	smmu_make_cb_group(34),
+	smmu_make_cb_group(35),
+	smmu_make_cb_group(36),
+	smmu_make_cb_group(37),
+	smmu_make_cb_group(38),
+	smmu_make_cb_group(39),
+	smmu_make_cb_group(40),
+	smmu_make_cb_group(41),
+	smmu_make_cb_group(42),
+	smmu_make_cb_group(43),
+	smmu_make_cb_group(44),
+	smmu_make_cb_group(45),
+	smmu_make_cb_group(46),
+	smmu_make_cb_group(47),
+	smmu_make_cb_group(48),
+	smmu_make_cb_group(49),
+	smmu_make_cb_group(50),
+	smmu_make_cb_group(51),
+	smmu_make_cb_group(52),
+	smmu_make_cb_group(53),
+	smmu_make_cb_group(54),
+	smmu_make_cb_group(55),
+	smmu_make_cb_group(56),
+	smmu_make_cb_group(57),
+	smmu_make_cb_group(58),
+	smmu_make_cb_group(59),
+	smmu_make_cb_group(60),
+	smmu_make_cb_group(61),
+	smmu_make_cb_group(62),
+	smmu_make_cb_group(63),
+	smmu_bypass_cfg,	/* TBU settings */
+	_END_OF_TABLE_,
+};
+
+static inline uint32_t tegra_smmu_read_32(uint32_t smmu_id, uint32_t off)
+{
+	if (smmu_id == 0)
+		return mmio_read_32(TEGRA_SMMU0_BASE + off);
+	else if (smmu_id == 1)
+		return mmio_read_32(TEGRA_SMMU1_BASE + off);
+	else if (smmu_id == 2)
+		return mmio_read_32(TEGRA_SMMU2_BASE + off);
+	else
+		panic();
+}
+
+static inline void tegra_smmu_write_32(uint32_t smmu_id,
+			uint32_t off, uint32_t val)
+{
+	if (smmu_id == 0)
+		mmio_write_32(TEGRA_SMMU0_BASE + off, val);
+	else if (smmu_id == 1)
+		mmio_write_32(TEGRA_SMMU1_BASE + off, val);
+	else if (smmu_id == 2)
+		mmio_write_32(TEGRA_SMMU2_BASE + off, val);
+	else
+		panic();
+}
+
+#endif //__SMMU_PLAT_CONFIG_H
diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h b/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h
new file mode 100644
index 0000000..1fe4620
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef T194_NVG_H
+#define T194_NVG_H
+
+/**
+ * t194_nvg.h - Header for the NVIDIA Generic interface (NVG).
+ * Official documentation for this interface is included as part
+ * of the T194 TRM.
+ */
+
+/**
+ * Current version - Major version increments may break backwards
+ * compatiblity and binary compatibility. Minor version increments
+ * occur when there is only new functionality.
+ */
+enum {
+    TEGRA_NVG_VERSION_MAJOR = 6,
+    TEGRA_NVG_VERSION_MINOR = 0,
+};
+
+typedef enum {
+    TEGRA_NVG_CHANNEL_VERSION = 0,
+    TEGRA_NVG_CHANNEL_POWER_PERF = 1,
+    TEGRA_NVG_CHANNEL_POWER_MODES = 2,
+    TEGRA_NVG_CHANNEL_WAKE_TIME = 3,
+    TEGRA_NVG_CHANNEL_CSTATE_INFO = 4,
+    TEGRA_NVG_CHANNEL_CROSSOVER_C6_LOWER_BOUND = 5,
+    TEGRA_NVG_CHANNEL_CROSSOVER_CC6_LOWER_BOUND = 6,
+    // Value 7 reserved
+    TEGRA_NVG_CHANNEL_CROSSOVER_CG7_LOWER_BOUND = 8,
+    // Value 9 reserved
+    TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_REQUEST = 10,
+    TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_VALUE = 11,
+    // Values 12-42 reserved
+    TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED = 43,
+    TEGRA_NVG_CHANNEL_ONLINE_CORE = 44,
+    TEGRA_NVG_CHANNEL_CC3_CTRL = 45,
+    TEGRA_NVG_CHANNEL_UPDATE_CCPLEX_GSC = 50,
+    TEGRA_NVG_CHANNEL_CCPLEX_CACHE_INVAL = 51,
+    // 52 FREQ FEEDBACK
+    TEGRA_NVG_CHANNEL_HSM_ERROR_CTRL = 53,
+    TEGRA_NVG_CHANNEL_SECURITY_CONFIG = 54,
+    TEGRA_NVG_CHANNEL_LAST_INDEX,
+} tegra_nvg_channel_id_t;
+
+
+typedef enum {
+    // Value 0 reserved
+    NVG_STAT_QUERY_SC7_ENTRIES = 1,
+    // Values 2-5 reserved
+    NVG_STAT_QUERY_CC6_ENTRIES = 6,
+    NVG_STAT_QUERY_CG7_ENTRIES = 7,
+    // Values 8-9 reserved
+    NVG_STAT_QUERY_C6_ENTRIES = 10,
+    // Values 11-13 reserved
+    NVG_STAT_QUERY_C7_ENTRIES = 14,
+    // Values 15-31 reserved
+    NVG_STAT_QUERY_SC7_RESIDENCY_SUM = 32,
+    NVG_STAT_QUERY_CC6_RESIDENCY_SUM = 41,
+    NVG_STAT_QUERY_CG7_RESIDENCY_SUM = 46,
+    NVG_STAT_QUERY_C6_RESIDENCY_SUM = 51,
+    NVG_STAT_QUERY_C7_RESIDENCY_SUM = 56,
+} tegra_nvg_stat_query_t;
+
+
+typedef enum {
+    TEGRA_NVG_CORE_C0 = 0,
+    TEGRA_NVG_CORE_C1 = 1,
+    TEGRA_NVG_CORE_C6 = 6,
+    TEGRA_NVG_CORE_C7 = 7,
+    TEGRA_NVG_CORE_WARMRSTREQ = 8,
+} tegra_nvg_core_sleep_state_t;
+
+typedef enum {
+    TEGRA_NVG_CLUSTER_CC0 = 0,
+    TEGRA_NVG_CLUSTER_CC6 = 6,
+} tegra_nvg_cluster_sleep_state_t;
+
+typedef enum {
+    TEGRA_NVG_CCPLEX_CG0 = 0,
+    TEGRA_NVG_CCPLEX_CG7 = 1,
+
+} tegra_nvg_cluster_group_sleep_state_t;
+
+typedef enum {
+    TEGRA_NVG_SYSTEM_SC0 = 0,
+    TEGRA_NVG_SYSTEM_SC7 = 7,
+    TEGRA_NVG_SYSTEM_SC8 = 8,
+} tegra_nvg_system_sleep_state_t;
+
+// ---------------------------------------------------------------------------
+// NVG Data subformats
+// ---------------------------------------------------------------------------
+
+typedef union
+{
+    uint64_t flat;
+    struct nvg_version_channel_t {
+        uint64_t minor_version : 32;
+        uint64_t major_version : 32;
+    } bits;
+} nvg_version_data_t;
+
+typedef union nvg_channel_1_data_u
+{
+    uint64_t flat;
+    struct nvg_channel_1_data_s
+    {
+        uint64_t perf_per_watt_mode : 1;
+        uint64_t reserved_63_1 : 63;
+    } bits;
+} nvg_channel_1_data_t;
+
+typedef union nvg_channel_2_data_u
+{
+    uint64_t flat;
+    struct nvg_channel_2_data_s
+    {
+        uint64_t reserved_1_0 : 2;
+        uint64_t battery_saver_mode : 1;
+        uint64_t reserved_63_3 : 61;
+    } bits;
+} nvg_channel_2_data_t;
+
+typedef union
+{
+    uint64_t flat;
+    struct nvg_wake_time_channel_t {
+        uint64_t wake_time : 32;
+        uint64_t reserved_63_32 : 32;
+    } bits;
+} nvg_wake_time_channel_t;
+
+typedef union
+{
+    uint64_t flat;
+    struct nvg_cstate_info_channel_t {
+        uint64_t cluster_state : 3;
+        uint64_t reserved_6_3 : 4;
+        uint64_t update_cluster : 1;
+        uint64_t cg_cstate : 3;
+        uint64_t reserved_14_11 : 4;
+        uint64_t update_cg : 1;
+        uint64_t system_cstate : 4;
+        uint64_t reserved_22_20 : 3;
+        uint64_t update_system : 1;
+        uint64_t reserved_30_24 : 7;
+        uint64_t update_wake_mask : 1;
+        uint64_t wake_mask : 32;
+    } bits;
+} nvg_cstate_info_channel_t;
+
+typedef union
+{
+    uint64_t flat;
+    struct nvg_lower_bound_channel_t {
+        uint64_t crossover_value : 32;
+        uint64_t reserved_63_32 : 32;
+    } bits;
+} nvg_lower_bound_channel_t;
+
+
+typedef union
+{
+    uint64_t flat;
+    struct nvg_cstate_stat_query_channel_t {
+        uint64_t unit_id : 4;
+        uint64_t reserved_15_4 : 12;
+        uint64_t stat_id : 16;
+        uint64_t reserved_63_32 : 32;
+    } bits;
+} nvg_cstate_stat_query_channel_t;
+
+typedef union
+{
+    uint64_t flat;
+    struct nvg_is_sc7_allowed_channel_t {
+        uint64_t is_sc7_allowed : 1;
+        uint64_t reserved_63_32 : 63;
+    } bits;
+} nvg_is_sc7_allowed_channel_t;
+
+
+typedef union
+{
+    uint64_t flat;
+    struct nvg_core_online_channel_t {
+        uint64_t core_id : 4;
+        uint64_t reserved_63_4 : 60;
+    } bits;
+} nvg_core_online_channel_t;
+
+
+typedef union
+{
+    uint64_t flat;
+    struct nvg_cc3_control_channel_t {
+        uint64_t freq_req : 8;
+        uint64_t reserved_30_8 : 23;
+        uint64_t enable : 1;
+        uint64_t reserved_63_32 : 32;
+    } bits;
+} nvg_cc3_control_channel_t;
+
+
+typedef union
+{
+    uint64_t flat;
+    struct nvg_update_gsc_channel_t {
+        uint64_t gsc_enum : 16;
+        uint64_t reserved_63_16 : 48;
+    } bits;
+} nvg_update_gsc_channel_t;
+
+
+typedef union
+{
+    uint64_t flat;
+    struct nvg_cache_inval_channel_t {
+        uint64_t cache_clean : 1;
+        uint64_t cache_clean_inval : 1;
+        uint64_t cache_clean_inval_tr : 1;
+        uint64_t reserved_63_3 : 61;
+    } bits;
+} nvg_cache_inval_channel_t;
+
+
+/* GSC type define */
+typedef enum {
+    TEGRA_NVG_GSC_ALL=0,
+    TEGRA_NVG_GSC_NVDEC=1,
+    TEGRA_NVG_GSC_WPR1=2,
+    TEGRA_NVG_GSC_WPR2=3,
+    TEGRA_NVG_GSC_TSECA=4,
+    TEGRA_NVG_GSC_TSECB=5,
+
+    TEGRA_NVG_GSC_BPMP=6,
+    TEGRA_NVG_GSC_APE=7,
+    TEGRA_NVG_GSC_SPE=8,
+    TEGRA_NVG_GSC_SCE=9,
+    TEGRA_NVG_GSC_APR=10,
+    TEGRA_NVG_GSC_TZRAM=11,
+    TEGRA_NVG_GSC_SE=12,
+
+    TEGRA_NVG_GSC_DMCE=13,
+    TEGRA_NVG_GSC_BPMP_TO_DMCE=14,
+    TEGRA_NVG_GSC_BPMP_TO_SPE=16,
+    TEGRA_NVG_GSC_CPU_TZ_TO_BPMP=18,
+    TEGRA_NVG_GSC_CPU_NS_TO_BPMP=20,
+    TEGRA_NVG_GSC_IPC_SE_SPE_SCE_BPMP=22,
+    TEGRA_NVG_GSC_SC7_RESUME_FW=23,
+
+    TEGRA_NVG_GSC_VPR_RESIZE=24,
+    TEGRA_NVG_GSC_RCE=25,
+    TEGRA_NVG_GSC_CV=26,
+
+    TEGRA_NVG_GSC_BO_MTS_PACKAGE=28,
+    TEGRA_NVG_GSC_BO_MCE_PREBOOT=29,
+
+    TEGRA_NVG_GSC_TZ_DRAM_IDX=34,
+    TEGRA_NVG_GSC_VPR_IDX=35,
+} tegra_nvg_gsc_index_t;
+
+typedef enum {
+    TEGRA_NVG_CROSSOVER_C6 = 0,
+    TEGRA_NVG_CROSSOVER_CC6 = 1,
+    TEGRA_NVG_CROSSOVER_CG7 = 2,
+} tegra_nvg_crossover_index_t;
+
+#endif // T194_NVG_H
diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/aarch64/nvg_helpers.S b/plat/nvidia/tegra/soc/t194/drivers/mce/aarch64/nvg_helpers.S
new file mode 100644
index 0000000..e6a6a99
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/drivers/mce/aarch64/nvg_helpers.S
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+
+	.globl	nvg_set_request_data
+	.globl	nvg_set_request
+	.globl	nvg_get_result
+
+/* void nvg_set_request_data(uint64_t req, uint64_t data) */
+func nvg_set_request_data
+	msr	s3_0_c15_c1_2, x0
+	msr	s3_0_c15_c1_3, x1
+	ret
+endfunc nvg_set_request_data
+
+/* void nvg_set_request(uint64_t req) */
+func nvg_set_request
+	msr	s3_0_c15_c1_2, x0
+	ret
+endfunc nvg_set_request
+
+/* uint64_t nvg_get_result(void) */
+func nvg_get_result
+	mrs	x0, s3_0_c15_c1_3
+	ret
+endfunc nvg_get_result
diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c
new file mode 100644
index 0000000..f13643f
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <common/bl_common.h>
+#include <context.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <common/debug.h>
+#include <denver.h>
+#include <mce.h>
+#include <mce_private.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <string.h>
+#include <errno.h>
+#include <t194_nvg.h>
+#include <tegra_def.h>
+#include <tegra_platform.h>
+
+/*******************************************************************************
+ * Common handler for all MCE commands
+ ******************************************************************************/
+int32_t mce_command_handler(mce_cmd_t cmd, uint64_t arg0, uint64_t arg1,
+			uint64_t arg2)
+{
+	uint64_t ret64 = 0, arg3, arg4, arg5;
+	int32_t ret = 0;
+	cpu_context_t *ctx = cm_get_context(NON_SECURE);
+	gp_regs_t *gp_regs = get_gpregs_ctx(ctx);
+
+	assert(ctx);
+	assert(gp_regs);
+
+	switch (cmd) {
+	case MCE_CMD_ENTER_CSTATE:
+		ret = nvg_enter_cstate((uint32_t)arg0, (uint32_t)arg1);
+		if (ret < 0) {
+			ERROR("%s: enter_cstate failed(%d)\n", __func__, ret);
+		}
+
+		break;
+
+	case MCE_CMD_UPDATE_CSTATE_INFO:
+		/*
+		 * get the parameters required for the update cstate info
+		 * command
+		 */
+		arg3 = read_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X4));
+		arg4 = read_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X5));
+		arg5 = read_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X6));
+
+		/* arg0 cluster
+		 * arg1 ccplex
+		 * arg2 system
+		 * arg3 sys_state_force => T19x not support
+		 * arg4 wake_mask
+		 * arg5 update_wake_mask
+		 */
+		nvg_update_cstate_info((uint32_t)arg0, (uint32_t)arg1,
+				(uint32_t)arg2, (uint32_t)arg4, (uint8_t)arg5);
+
+		write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X4), (arg3));
+		write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X5), (arg4));
+		write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X6), (arg5));
+
+		break;
+
+	case MCE_CMD_UPDATE_CROSSOVER_TIME:
+		ret = nvg_update_crossover_time((uint32_t)arg0, (uint32_t)arg1);
+		if (ret < 0) {
+			ERROR("%s: update_crossover_time failed(%d)\n",
+				__func__, ret);
+		}
+
+		break;
+
+	case MCE_CMD_READ_CSTATE_STATS:
+		ret64 = nvg_get_cstate_stat_query_value();
+
+		/* update context to return cstate stats value */
+		write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X1), (ret64));
+		write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X2), (ret64));
+
+		break;
+
+	case MCE_CMD_WRITE_CSTATE_STATS:
+		ret = nvg_set_cstate_stat_query_value(arg0);
+
+		break;
+
+	case MCE_CMD_IS_SC7_ALLOWED:
+		ret = nvg_is_sc7_allowed();
+		if (ret < 0) {
+			ERROR("%s: is_sc7_allowed failed(%d)\n", __func__, ret);
+			break;
+		}
+
+		/* update context to return SC7 status value */
+		write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X1), ((uint64_t)ret));
+		write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X3), ((uint64_t)ret));
+
+		break;
+
+	case MCE_CMD_ONLINE_CORE:
+		ret = nvg_online_core((uint32_t)arg0);
+		if (ret < 0) {
+			ERROR("%s: online_core failed(%d)\n", __func__, ret);
+		}
+
+		break;
+
+	case MCE_CMD_CC3_CTRL:
+		ret = nvg_cc3_ctrl((uint32_t)arg0, (uint8_t)arg2);
+		if (ret < 0) {
+			ERROR("%s: cc3_ctrl failed(%d)\n", __func__, ret);
+		}
+
+		break;
+
+	case MCE_CMD_READ_VERSIONS:
+		/* get the MCE firmware version */
+		ret64 = nvg_get_version();
+
+		/*
+		 * version = minor(63:32) | major(31:0). Update context
+		 * to return major and minor version number.
+		 */
+		write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X1), (ret64 & (uint64_t)0xFFFF));
+		write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X2), (ret64 >> 32));
+
+		break;
+
+	case MCE_CMD_ROC_FLUSH_CACHE_TRBITS:
+		ret = nvg_roc_clean_cache_trbits();
+		if (ret < 0) {
+			ERROR("%s: flush cache_trbits failed(%d)\n", __func__,
+				ret);
+		}
+
+		break;
+
+	case MCE_CMD_ROC_FLUSH_CACHE:
+		ret = nvg_roc_flush_cache();
+		if (ret < 0) {
+			ERROR("%s: flush cache failed(%d)\n", __func__, ret);
+		}
+
+		break;
+
+	case MCE_CMD_ROC_CLEAN_CACHE:
+		ret = nvg_roc_clean_cache();
+		if (ret < 0) {
+			ERROR("%s: clean cache failed(%d)\n", __func__, ret);
+		}
+
+		break;
+
+	default:
+		ERROR("unknown MCE command (%lld)\n", cmd);
+		ret = EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/*******************************************************************************
+ * Handler to update carveout values for Video Memory Carveout region
+ ******************************************************************************/
+int32_t mce_update_gsc_videomem(void)
+{
+	return nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_GSC_VPR_IDX);
+}
+
+/*******************************************************************************
+ * Handler to update carveout values for TZDRAM aperture
+ ******************************************************************************/
+int32_t mce_update_gsc_tzdram(void)
+{
+	return nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_GSC_TZ_DRAM_IDX);
+}
+
+/*******************************************************************************
+ * Handler to update carveout values for TZ SysRAM aperture
+ ******************************************************************************/
+int32_t mce_update_gsc_tzram(void)
+{
+	return nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_GSC_TZRAM);
+}
+
+/*******************************************************************************
+ * Handler to issue the UPDATE_CSTATE_INFO request
+ ******************************************************************************/
+void mce_update_cstate_info(mce_cstate_info_t *cstate)
+{
+	/* issue the UPDATE_CSTATE_INFO request */
+	nvg_update_cstate_info(cstate->cluster, cstate->ccplex, cstate->system,
+		cstate->wake_mask, cstate->update_wake_mask);
+}
+
+/*******************************************************************************
+ * Handler to read the MCE firmware version and check if it is compatible
+ * with interface header the BL3-1 was compiled against
+ ******************************************************************************/
+void mce_verify_firmware_version(void)
+{
+	uint64_t version;
+	uint32_t major, minor;
+
+	/*
+	 * MCE firmware is not running on simulation platforms.
+	 */
+	if ((tegra_platform_is_linsim() == 1U) ||
+		(tegra_platform_is_virt_dev_kit() == 1U) ||
+		(tegra_platform_is_qt() == 1U)) {
+		return;
+	}
+
+	/*
+	 * Read the MCE firmware version and extract the major and minor
+	 * version fields
+	 */
+	version = nvg_get_version();
+	minor = (uint32_t)version;
+	major = (uint32_t)(version >> 32);
+
+	INFO("MCE Version - HW=%d:%d, SW=%d:%d\n", major, minor,
+		0, 0);
+
+	/*
+	 * Verify that the MCE firmware version and the interface header
+	 * match
+	 */
+	if (major != (uint32_t)TEGRA_NVG_VERSION_MAJOR) {
+		ERROR("MCE major version mismatch\n");
+		panic();
+	}
+
+	if (minor < (uint32_t)TEGRA_NVG_VERSION_MINOR) {
+		ERROR("MCE minor version mismatch\n");
+		panic();
+	}
+}
diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c
new file mode 100644
index 0000000..12dd6cb
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c
@@ -0,0 +1,363 @@
+/*
+ * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <denver.h>
+#include <errno.h>
+#include <lib/mmio.h>
+#include <mce_private.h>
+#include <platform_def.h>
+#include <t194_nvg.h>
+
+extern void nvg_set_request_data(uint64_t req, uint64_t data);
+extern void nvg_set_request(uint64_t req);
+extern uint64_t nvg_get_result(void);
+
+/*
+ * Reports the major and minor version of this interface.
+ *
+ * NVGDATA[0:31]: SW(R) Minor Version
+ * NVGDATA[32:63]: SW(R) Major Version
+ */
+uint64_t nvg_get_version(void)
+{
+	nvg_set_request(TEGRA_NVG_CHANNEL_VERSION);
+
+	return (uint64_t)nvg_get_result();
+}
+
+/*
+ * Enable the perf per watt mode.
+ *
+ * NVGDATA[0]: SW(RW), 1 = enable perf per watt mode
+ */
+int32_t nvg_enable_power_perf_mode(void)
+{
+	nvg_set_request_data(TEGRA_NVG_CHANNEL_POWER_PERF, 1U);
+
+	return 0;
+}
+
+/*
+ * Disable the perf per watt mode.
+ *
+ * NVGDATA[0]: SW(RW), 0 = disable perf per watt mode
+ */
+int32_t nvg_disable_power_perf_mode(void)
+{
+	nvg_set_request_data(TEGRA_NVG_CHANNEL_POWER_PERF, 0U);
+
+	return 0;
+}
+
+/*
+ * Enable the battery saver mode.
+ *
+ * NVGDATA[2]: SW(RW), 1 = enable battery saver mode
+ */
+int32_t nvg_enable_power_saver_modes(void)
+{
+	nvg_set_request_data(TEGRA_NVG_CHANNEL_POWER_MODES, 1U);
+
+	return 0;
+}
+
+/*
+ * Disable the battery saver mode.
+ *
+ * NVGDATA[2]: SW(RW), 0 = disable battery saver mode
+ */
+int32_t nvg_disable_power_saver_modes(void)
+{
+	nvg_set_request_data(TEGRA_NVG_CHANNEL_POWER_MODES, 0U);
+
+	return 0;
+}
+
+/*
+ * Set the expected wake time in TSC ticks for the next low-power state the
+ * core enters.
+ *
+ * NVGDATA[0:31]: SW(RW), WAKE_TIME
+ */
+void nvg_set_wake_time(uint32_t wake_time)
+{
+	/* time (TSC ticks) until the core is expected to get a wake event */
+	nvg_set_request_data(TEGRA_NVG_CHANNEL_WAKE_TIME, (uint64_t)wake_time);
+}
+
+/*
+ * This request allows updating of CLUSTER_CSTATE, CCPLEX_CSTATE and
+ * SYSTEM_CSTATE values.
+ *
+ * NVGDATA[0:2]: SW(RW), CLUSTER_CSTATE
+ * NVGDATA[7]: SW(W), update cluster flag
+ * NVGDATA[8:9]: SW(RW), CG_CSTATE
+ * NVGDATA[15]: SW(W), update ccplex flag
+ * NVGDATA[16:19]: SW(RW), SYSTEM_CSTATE
+ * NVGDATA[23]: SW(W), update system flag
+ * NVGDATA[31]: SW(W), update wake mask flag
+ * NVGDATA[32:63]: SW(RW), WAKE_MASK
+ */
+void nvg_update_cstate_info(uint32_t cluster, uint32_t ccplex,
+		uint32_t system, uint32_t wake_mask, uint8_t update_wake_mask)
+{
+	uint64_t val = 0;
+
+	/* update CLUSTER_CSTATE? */
+	if (cluster != 0U) {
+		val |= ((uint64_t)cluster & CLUSTER_CSTATE_MASK) |
+				CLUSTER_CSTATE_UPDATE_BIT;
+	}
+
+	/* update CCPLEX_CSTATE? */
+	if (ccplex != 0U) {
+		val |= (((uint64_t)ccplex & CCPLEX_CSTATE_MASK) << CCPLEX_CSTATE_SHIFT) |
+				CCPLEX_CSTATE_UPDATE_BIT;
+	}
+
+	/* update SYSTEM_CSTATE? */
+	if (system != 0U) {
+		val |= (((uint64_t)system & SYSTEM_CSTATE_MASK) << SYSTEM_CSTATE_SHIFT) |
+				SYSTEM_CSTATE_UPDATE_BIT;
+	}
+
+	/* update wake mask value? */
+	if (update_wake_mask != 0U) {
+		val |= CSTATE_WAKE_MASK_UPDATE_BIT;
+	}
+
+	/* set the wake mask */
+	val |= ((uint64_t)wake_mask & CSTATE_WAKE_MASK_CLEAR) << CSTATE_WAKE_MASK_SHIFT;
+
+	/* set the updated cstate info */
+	nvg_set_request_data(TEGRA_NVG_CHANNEL_CSTATE_INFO, val);
+}
+
+/*
+ * Indices gives MTS the crossover point in TSC ticks for when it becomes
+ * no longer viable to enter the named state
+ *
+ * Type 0 : NVGDATA[0:31]: C6 Lower bound
+ * Type 1 : NVGDATA[0:31]: CC6 Lower bound
+ * Type 2 : NVGDATA[0:31]: CG7 Lower bound
+ */
+int32_t nvg_update_crossover_time(uint32_t type, uint32_t time)
+{
+	int32_t ret = 0;
+
+	switch (type) {
+	case TEGRA_NVG_CROSSOVER_C6:
+		nvg_set_request_data(TEGRA_NVG_CHANNEL_CROSSOVER_C6_LOWER_BOUND,
+			(uint64_t)time);
+		break;
+
+	case TEGRA_NVG_CROSSOVER_CC6:
+		nvg_set_request_data(TEGRA_NVG_CHANNEL_CROSSOVER_CC6_LOWER_BOUND,
+			(uint64_t)time);
+		break;
+
+	case TEGRA_NVG_CROSSOVER_CG7:
+		nvg_set_request_data(TEGRA_NVG_CHANNEL_CROSSOVER_CG7_LOWER_BOUND,
+			(uint64_t)time);
+		break;
+
+	default:
+		ERROR("%s: unknown crossover type (%d)\n", __func__, type);
+		ret = EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/*
+ * These NVG calls allow ARM SW to access CSTATE statistical information
+ *
+ * NVGDATA[0:3]: SW(RW) Core/cluster/cg id
+ * NVGDATA[16:31]: SW(RW) Stat id
+ */
+int32_t nvg_set_cstate_stat_query_value(uint64_t data)
+{
+	int32_t ret = 0;
+
+	/* sanity check stat id */
+	if (data > (uint64_t)NVG_STAT_QUERY_C7_RESIDENCY_SUM) {
+		ERROR("%s: unknown stat id (%d)\n", __func__, (uint32_t)data);
+		ret = EINVAL;
+	} else {
+		nvg_set_request_data(TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_REQUEST, data);
+	}
+
+	return ret;
+}
+
+/*
+ * The read-only value associated with the CSTATE_STAT_QUERY_REQUEST
+ *
+ * NVGDATA[0:63]: SW(R) Stat count
+ */
+uint64_t nvg_get_cstate_stat_query_value(void)
+{
+	nvg_set_request(TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_VALUE);
+
+	return (uint64_t)nvg_get_result();
+}
+
+/*
+ * Return a non-zero value if the CCPLEX is able to enter SC7
+ *
+ * NVGDATA[0]: SW(R), Is allowed result
+ */
+int32_t nvg_is_sc7_allowed(void)
+{
+	/* issue command to check if SC7 is allowed */
+	nvg_set_request(TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED);
+
+	/* 1 = SC7 allowed, 0 = SC7 not allowed */
+	return (int32_t)nvg_get_result();
+}
+
+/*
+ * Wake an offlined logical core. Note that a core is offlined by entering
+ * a C-state where the WAKE_MASK is all 0.
+ *
+ * NVGDATA[0:3]: SW(W) logical core to online
+ */
+int32_t nvg_online_core(uint32_t core)
+{
+	int32_t ret = 0;
+
+	/* sanity check the core ID value */
+	if (core > (uint32_t)PLATFORM_CORE_COUNT) {
+		ERROR("%s: unknown core id (%d)\n", __func__, core);
+		ret = EINVAL;
+	} else {
+		/* get a core online */
+		nvg_set_request_data(TEGRA_NVG_CHANNEL_ONLINE_CORE,
+								(uint64_t)core & MCE_CORE_ID_MASK);
+	}
+
+	return ret;
+}
+
+/*
+ * Enables and controls the voltage/frequency hint for CC3. CC3 is disabled
+ * by default.
+ *
+ * NVGDATA[7:0] SW(RW) frequency request
+ * NVGDATA[31:31] SW(RW) enable bit
+ */
+int32_t nvg_cc3_ctrl(uint32_t freq, uint8_t enable)
+{
+	uint64_t val = 0;
+
+	/*
+	 * If the enable bit is cleared, Auto-CC3 will be disabled by setting
+	 * the SW visible frequency request registers for all non
+	 * floorswept cores valid independent of StandbyWFI and disabling
+	 * the IDLE frequency request register. If set, Auto-CC3
+	 * will be enabled by setting the ARM SW visible frequency
+	 * request registers for all non floorswept cores to be enabled by
+	 * StandbyWFI or the equivalent signal, and always keeping the IDLE
+	 * frequency request register enabled.
+	 */
+	if (enable != 0U) {
+		val = ((uint64_t)freq & MCE_AUTO_CC3_FREQ_MASK) | MCE_AUTO_CC3_ENABLE_BIT;
+	}
+	nvg_set_request_data(TEGRA_NVG_CHANNEL_CC3_CTRL, val);
+
+	return 0;
+}
+
+/*
+ * MC GSC (General Security Carveout) register values are expected to be
+ * changed by TrustZone ARM code after boot.
+ *
+ * NVGDATA[0:15] SW(R) GSC enun
+ */
+int32_t nvg_update_ccplex_gsc(uint32_t gsc_idx)
+{
+	int32_t ret = 0;
+
+	/* sanity check GSC ID */
+	if (gsc_idx > (uint32_t)TEGRA_NVG_GSC_VPR_IDX) {
+		ERROR("%s: unknown gsc_idx (%d)\n", __func__, gsc_idx);
+		ret = EINVAL;
+	} else {
+		nvg_set_request_data(TEGRA_NVG_CHANNEL_UPDATE_CCPLEX_GSC,
+								(uint64_t)gsc_idx);
+	}
+
+	return ret;
+}
+
+/*
+ * Cache clean operation for all CCPLEX caches.
+ *
+ * NVGDATA[0] cache_clean
+ */
+int32_t nvg_roc_clean_cache(void)
+{
+	nvg_set_request_data(TEGRA_NVG_CHANNEL_CCPLEX_CACHE_INVAL,
+							(uint64_t)CACHE_CLEAN_SET);
+
+	return 0;
+}
+
+/*
+ * Cache clean and invalidate operation for all CCPLEX caches.
+ *
+ * NVGDATA[1] cache_clean_inval
+ */
+int32_t nvg_roc_flush_cache(void)
+{
+	nvg_set_request_data(TEGRA_NVG_CHANNEL_CCPLEX_CACHE_INVAL,
+							(uint64_t)CACHE_CLEAN_INVAL_SET);
+
+	return 0;
+}
+
+/*
+ * Cache clean and invalidate, clear TR-bit operation for all CCPLEX caches.
+ *
+ * NVGDATA[2] cache_clean_inval_tr
+ */
+int32_t nvg_roc_clean_cache_trbits(void)
+{
+	nvg_set_request_data(TEGRA_NVG_CHANNEL_CCPLEX_CACHE_INVAL,
+							(uint64_t)CACHE_CLEAN_INVAL_TR_SET);
+
+	return 0;
+}
+
+/*
+ * Set the power state for a core
+ */
+int32_t nvg_enter_cstate(uint32_t state, uint32_t wake_time)
+{
+	int32_t ret = 0;
+
+	/* check for allowed power state */
+	if ((state != (uint32_t)TEGRA_NVG_CORE_C0) &&
+		(state != (uint32_t)TEGRA_NVG_CORE_C1) &&
+	    (state != (uint32_t)TEGRA_NVG_CORE_C6) &&
+		(state != (uint32_t)TEGRA_NVG_CORE_C7))
+	{
+		ERROR("%s: unknown cstate (%d)\n", __func__, state);
+		ret = EINVAL;
+	} else {
+		/* time (TSC ticks) until the core is expected to get a wake event */
+		nvg_set_wake_time(wake_time);
+
+		/* set the core cstate */
+		write_actlr_el1(state);
+	}
+
+	return ret;
+}
diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
new file mode 100644
index 0000000..b7a6c4f
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <common/bl_common.h>
+#include <context.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <common/debug.h>
+#include <denver.h>
+#include <mce.h>
+#include <plat/common/platform.h>
+#include <lib/psci/psci.h>
+#include <smmu.h>
+#include <string.h>
+#include <tegra_private.h>
+
+extern void prepare_core_pwr_dwn(void);
+
+#if ENABLE_SYSTEM_SUSPEND_CTX_SAVE_TZDRAM
+extern void tegra186_cpu_reset_handler(void);
+extern uint32_t __tegra186_cpu_reset_handler_data,
+		__tegra186_cpu_reset_handler_end;
+
+/* TZDRAM offset for saving SMMU context */
+#define TEGRA186_SMMU_CTX_OFFSET	16
+#endif
+
+/* state id mask */
+#define TEGRA186_STATE_ID_MASK		0xF
+/* constants to get power state's wake time */
+#define TEGRA186_WAKE_TIME_MASK		0x0FFFFFF0
+#define TEGRA186_WAKE_TIME_SHIFT	4
+/* default core wake mask for CPU_SUSPEND */
+#define TEGRA186_CORE_WAKE_MASK		0x180c
+/* context size to save during system suspend */
+#define TEGRA186_SE_CONTEXT_SIZE	3
+
+static uint32_t se_regs[TEGRA186_SE_CONTEXT_SIZE];
+static struct t18x_psci_percpu_data {
+	unsigned int wake_time;
+} __aligned(CACHE_WRITEBACK_GRANULE) percpu_data[PLATFORM_CORE_COUNT];
+
+int32_t tegra_soc_validate_power_state(unsigned int power_state,
+					psci_power_state_t *req_state)
+{
+	int state_id = psci_get_pstate_id(power_state) & TEGRA186_STATE_ID_MASK;
+	int cpu = plat_my_core_pos();
+
+	/* save the core wake time (in TSC ticks)*/
+	percpu_data[cpu].wake_time = (power_state & TEGRA186_WAKE_TIME_MASK)
+			<< TEGRA186_WAKE_TIME_SHIFT;
+
+	/*
+	 * Clean percpu_data[cpu] to DRAM. This needs to be done to ensure that
+	 * the correct value is read in tegra_soc_pwr_domain_suspend(), which
+	 * is called with caches disabled. It is possible to read a stale value
+	 * from DRAM in that function, because the L2 cache is not flushed
+	 * unless the cluster is entering CC6/CC7.
+	 */
+	clean_dcache_range((uint64_t)&percpu_data[cpu],
+			sizeof(percpu_data[cpu]));
+
+	/* Sanity check the requested state id */
+	switch (state_id) {
+	case PSTATE_ID_CORE_IDLE:
+	case PSTATE_ID_CORE_POWERDN:
+
+		/* Core powerdown request */
+		req_state->pwr_domain_state[MPIDR_AFFLVL0] = state_id;
+		req_state->pwr_domain_state[MPIDR_AFFLVL1] = state_id;
+
+		break;
+
+	default:
+		ERROR("%s: unsupported state id (%d)\n", __func__, state_id);
+		return PSCI_E_INVALID_PARAMS;
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
+int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
+{
+	const plat_local_state_t *pwr_domain_state;
+	unsigned int stateid_afflvl0, stateid_afflvl2;
+#if ENABLE_SYSTEM_SUSPEND_CTX_SAVE_TZDRAM
+	plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+	uint64_t smmu_ctx_base;
+#endif
+	uint32_t val;
+
+	/* get the state ID */
+	pwr_domain_state = target_state->pwr_domain_state;
+	stateid_afflvl0 = pwr_domain_state[MPIDR_AFFLVL0] &
+		TEGRA186_STATE_ID_MASK;
+	stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] &
+		TEGRA186_STATE_ID_MASK;
+
+	if ((stateid_afflvl0 == PSTATE_ID_CORE_IDLE) ||
+	    (stateid_afflvl0 == PSTATE_ID_CORE_POWERDN)) {
+
+		/* Enter CPU idle/powerdown */
+
+	} else if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
+
+		/* save SE registers */
+		se_regs[0] = mmio_read_32(TEGRA_SE0_BASE +
+				SE_MUTEX_WATCHDOG_NS_LIMIT);
+		se_regs[1] = mmio_read_32(TEGRA_RNG1_BASE +
+				RNG_MUTEX_WATCHDOG_NS_LIMIT);
+		se_regs[2] = mmio_read_32(TEGRA_PKA1_BASE +
+				PKA_MUTEX_WATCHDOG_NS_LIMIT);
+
+		/* 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);
+
+#if ENABLE_SYSTEM_SUSPEND_CTX_SAVE_TZDRAM
+		/* save SMMU context */
+		smmu_ctx_base = params_from_bl2->tzdram_base +
+			((uintptr_t)&__tegra186_cpu_reset_handler_data -
+			 (uintptr_t)tegra186_cpu_reset_handler) +
+			TEGRA186_SMMU_CTX_OFFSET;
+		tegra_smmu_save_context((uintptr_t)smmu_ctx_base);
+#else
+		tegra_smmu_save_context(0);
+#endif
+
+		/* Instruct the MCE to enter system suspend state */
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
+/*******************************************************************************
+ * Platform handler to calculate the proper target power level at the
+ * specified affinity level
+ ******************************************************************************/
+plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl,
+					     const plat_local_state_t *states,
+					     unsigned int ncpu)
+{
+	plat_local_state_t target = *states;
+	int cluster_powerdn = 1;
+	int core_pos = read_mpidr() & MPIDR_CPU_MASK;
+
+	/* get the current core's power state */
+	target = *(states + core_pos);
+
+	/* CPU suspend */
+	if (lvl == MPIDR_AFFLVL1 && target == PSTATE_ID_CORE_POWERDN) {
+
+		/* Program default wake mask */
+
+		/* Check if CCx state is allowed. */
+	}
+
+	/* CPU off */
+	if (lvl == MPIDR_AFFLVL1 && target == PLAT_MAX_OFF_STATE) {
+
+		/* find out the number of ON cpus in the cluster */
+		do {
+			target = *states++;
+			if (target != PLAT_MAX_OFF_STATE)
+				cluster_powerdn = 0;
+		} while (--ncpu);
+
+		/* Enable cluster powerdn from last CPU in the cluster */
+		if (cluster_powerdn) {
+
+			/* Enable CC7 state and turn off wake mask */
+
+		} else {
+
+			/* Turn off wake_mask */
+		}
+	}
+
+	/* System Suspend */
+	if ((lvl == MPIDR_AFFLVL2) || (target == PSTATE_ID_SOC_POWERDN))
+		return PSTATE_ID_SOC_POWERDN;
+
+	/* default state */
+	return PSCI_LOCAL_STATE_RUN;
+}
+
+#if ENABLE_SYSTEM_SUSPEND_CTX_SAVE_TZDRAM
+int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
+{
+	const plat_local_state_t *pwr_domain_state =
+		target_state->pwr_domain_state;
+	plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+	unsigned int stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] &
+		TEGRA186_STATE_ID_MASK;
+	uint64_t val;
+
+	if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
+		/*
+		 * The TZRAM loses power when we enter system suspend. To
+		 * allow graceful exit from system suspend, we need to copy
+		 * BL3-1 over to TZDRAM.
+		 */
+		val = params_from_bl2->tzdram_base +
+			((uintptr_t)&__tegra186_cpu_reset_handler_end -
+			 (uintptr_t)tegra186_cpu_reset_handler);
+		memcpy((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE,
+		       (uintptr_t)&__BL31_END__ - (uintptr_t)BL31_BASE);
+	}
+
+	return PSCI_E_SUCCESS;
+}
+#endif
+
+int tegra_soc_pwr_domain_on(u_register_t mpidr)
+{
+	int target_cpu = mpidr & MPIDR_CPU_MASK;
+	int target_cluster = (mpidr & MPIDR_CLUSTER_MASK) >>
+			MPIDR_AFFINITY_BITS;
+
+	if (target_cluster > MPIDR_AFFLVL1) {
+		ERROR("%s: unsupported CPU (0x%lx)\n", __func__ , mpidr);
+		return PSCI_E_NOT_PRESENT;
+	}
+
+	/* construct the target CPU # */
+	target_cpu |= (target_cluster << 2);
+
+	mce_command_handler(MCE_CMD_ONLINE_CORE, target_cpu, 0, 0);
+
+	return PSCI_E_SUCCESS;
+}
+
+int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+	int stateid_afflvl2 = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL];
+
+	/*
+	 * Reset power state info for CPUs when onlining, we set
+	 * deepest power when offlining a core but that may not be
+	 * requested by non-secure sw which controls idle states. It
+	 * will re-init this info from non-secure software when the
+	 * core come online.
+	 */
+
+	/*
+	 * Check if we are exiting from deep sleep and restore SE
+	 * context if we are.
+	 */
+	if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
+
+		mmio_write_32(TEGRA_SE0_BASE + SE_MUTEX_WATCHDOG_NS_LIMIT,
+			se_regs[0]);
+		mmio_write_32(TEGRA_RNG1_BASE + RNG_MUTEX_WATCHDOG_NS_LIMIT,
+			se_regs[1]);
+		mmio_write_32(TEGRA_PKA1_BASE + PKA_MUTEX_WATCHDOG_NS_LIMIT,
+			se_regs[2]);
+
+		/* Init SMMU */
+
+		/*
+		 * Reset power state info for the last core doing SC7
+		 * entry and exit, we set deepest power state as CC7
+		 * and SC7 for SC7 entry which may not be requested by
+		 * non-secure SW which controls idle states.
+		 */
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
+int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
+{
+	int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
+
+	/* Disable Denver's DCO operations */
+	if (impl == DENVER_IMPL)
+		denver_disable_dco();
+
+	/* Turn off CPU */
+
+	return PSCI_E_SUCCESS;
+}
+
+__dead2 void tegra_soc_prepare_system_off(void)
+{
+	/* System power off */
+
+	/* SC8 */
+
+	wfi();
+
+	/* wait for the system to power down */
+	for (;;) {
+		;
+	}
+}
+
+int tegra_soc_prepare_system_reset(void)
+{
+	return PSCI_E_SUCCESS;
+}
diff --git a/plat/nvidia/tegra/soc/t194/plat_secondary.c b/plat/nvidia/tegra/soc/t194/plat_secondary.c
new file mode 100644
index 0000000..f5e56b9
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/plat_secondary.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <mce.h>
+#include <string.h>
+#include <tegra_def.h>
+#include <tegra_private.h>
+
+#define MISCREG_CPU_RESET_VECTOR	0x2000
+#define MISCREG_AA64_RST_LOW		0x2004
+#define MISCREG_AA64_RST_HIGH		0x2008
+
+#define CPU_RESET_MODE_AA64		1
+
+extern void tegra_secure_entrypoint(void);
+
+#if ENABLE_SYSTEM_SUSPEND_CTX_SAVE_TZDRAM
+extern void tegra186_cpu_reset_handler(void);
+extern uint64_t __tegra186_smmu_ctx_start;
+#endif
+
+/*******************************************************************************
+ * Setup secondary CPU vectors
+ ******************************************************************************/
+void plat_secondary_setup(void)
+{
+	uint32_t addr_low, addr_high;
+#if ENABLE_SYSTEM_SUSPEND_CTX_SAVE_TZDRAM
+	plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+	uint64_t cpu_reset_handler_base = params_from_bl2->tzdram_base;
+#else
+	uint64_t cpu_reset_handler_base = (uintptr_t)tegra_secure_entrypoint;
+#endif
+
+	INFO("Setting up secondary CPU boot\n");
+
+#if ENABLE_SYSTEM_SUSPEND_CTX_SAVE_TZDRAM
+	memcpy((void *)((uintptr_t)cpu_reset_handler_base),
+		 (void *)(uintptr_t)tegra186_cpu_reset_handler,
+		 (uintptr_t)&__tegra186_smmu_ctx_start -
+		 (uintptr_t)tegra186_cpu_reset_handler);
+#endif
+
+	addr_low = (uint32_t)cpu_reset_handler_base | CPU_RESET_MODE_AA64;
+	addr_high = (uint32_t)((cpu_reset_handler_base >> 32) & 0x7ff);
+
+	/* 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 + SECURE_SCRATCH_RSV1_LO,
+			addr_low);
+	mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV1_HI,
+			addr_high);
+}
diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c
new file mode 100644
index 0000000..3424d19
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/plat_setup.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl31/bl31.h>
+#include <common/bl_common.h>
+#include <common/interrupt_props.h>
+#include <drivers/console.h>
+#include <context.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <cortex_a57.h>
+#include <common/debug.h>
+#include <denver.h>
+#include <drivers/arm/gic_common.h>
+#include <drivers/arm/gicv2.h>
+#include <bl31/interrupt_mgmt.h>
+#include <mce.h>
+#include <plat/common/platform.h>
+#include <tegra_def.h>
+#include <tegra_platform.h>
+#include <tegra_private.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+DEFINE_RENAME_SYSREG_RW_FUNCS(l2ctlr_el1, L2CTLR_EL1)
+extern uint64_t tegra_enable_l2_ecc_parity_prot;
+
+/*******************************************************************************
+ * The Tegra power domain tree has a single system level power domain i.e. a
+ * single root node. The first entry in the power domain descriptor specifies
+ * the number of power domains at the highest power level.
+ *******************************************************************************
+ */
+const unsigned char tegra_power_domain_tree_desc[] = {
+	/* No of root nodes */
+	1,
+	/* No of clusters */
+	PLATFORM_CLUSTER_COUNT,
+	/* No of CPU cores - cluster0 */
+	PLATFORM_MAX_CPUS_PER_CLUSTER,
+	/* No of CPU cores - cluster1 */
+	PLATFORM_MAX_CPUS_PER_CLUSTER
+};
+
+/*
+ * Table of regions to map using the MMU.
+ */
+static const mmap_region_t tegra_mmap[] = {
+	MAP_REGION_FLAT(TEGRA_MISC_BASE, 0x10000, /* 64KB */
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_TSA_BASE, 0x20000, /* 128KB */
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_MC_STREAMID_BASE, 0x10000, /* 64KB */
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_MC_BASE, 0x10000, /* 64KB */
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_UARTA_BASE, 0x20000, /* 128KB - UART A, B*/
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_UARTC_BASE, 0x20000, /* 128KB - UART C, G */
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_UARTD_BASE, 0x30000, /* 192KB - UART D, E, F */
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_FUSE_BASE, 0x10000, /* 64KB */
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_GICD_BASE, 0x20000, /* 128KB */
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_SE0_BASE, 0x10000, /* 64KB */
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_PKA1_BASE, 0x10000, /* 64KB */
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_RNG1_BASE, 0x10000, /* 64KB */
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_CAR_RESET_BASE, 0x10000, /* 64KB */
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_PMC_BASE, 0x40000, /* 256KB */
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_SCRATCH_BASE, 0x10000, /* 64KB */
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_MMCRAB_BASE, 0x60000, /* 384KB */
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_SMMU0_BASE, 0x1000000, /* 64KB */
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_SMMU1_BASE, 0x1000000, /* 64KB */
+			MT_DEVICE | MT_RW | MT_SECURE),
+	MAP_REGION_FLAT(TEGRA_SMMU2_BASE, 0x1000000, /* 64KB */
+			MT_DEVICE | MT_RW | MT_SECURE),
+	{0}
+};
+
+/*******************************************************************************
+ * Set up the pagetables as per the platform memory map & initialize the MMU
+ ******************************************************************************/
+const mmap_region_t *plat_get_mmio_map(void)
+{
+	/* MMIO space */
+	return tegra_mmap;
+}
+
+/*******************************************************************************
+ * Handler to get the System Counter Frequency
+ ******************************************************************************/
+unsigned int plat_get_syscnt_freq2(void)
+{
+	return 31250000;
+}
+
+/*******************************************************************************
+ * Maximum supported UART controllers
+ ******************************************************************************/
+#define TEGRA186_MAX_UART_PORTS		7
+
+/*******************************************************************************
+ * This variable holds the UART port base addresses
+ ******************************************************************************/
+static uint32_t tegra186_uart_addresses[TEGRA186_MAX_UART_PORTS + 1] = {
+	0,	/* undefined - treated as an error case */
+	TEGRA_UARTA_BASE,
+	TEGRA_UARTB_BASE,
+	TEGRA_UARTC_BASE,
+	TEGRA_UARTD_BASE,
+	TEGRA_UARTE_BASE,
+	TEGRA_UARTF_BASE,
+	TEGRA_UARTG_BASE,
+};
+
+/*******************************************************************************
+ * Retrieve the UART controller base to be used as the console
+ ******************************************************************************/
+uint32_t plat_get_console_from_id(int id)
+{
+	if (id > TEGRA186_MAX_UART_PORTS)
+		return 0;
+
+	return tegra186_uart_addresses[id];
+}
+
+/* represent chip-version as concatenation of major (15:12), minor (11:8) and subrev (7:0) */
+#define TEGRA186_VER_A02P	0x1201
+
+/*******************************************************************************
+ * Handler for early platform setup
+ ******************************************************************************/
+void plat_early_platform_setup(void)
+{
+	int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
+	uint32_t chip_subrev, val;
+
+	/* sanity check MCE firmware compatibility */
+	mce_verify_firmware_version();
+
+	/*
+	 * Enable ECC and Parity Protection for Cortex-A57 CPUs
+	 * for Tegra A02p SKUs
+	 */
+	if (impl != DENVER_IMPL) {
+
+		/* get the major, minor and sub-version values */
+		chip_subrev = mmio_read_32(TEGRA_FUSE_BASE + OPT_SUBREVISION) &
+			      SUBREVISION_MASK;
+
+		/* prepare chip version number */
+		val = (tegra_get_chipid_major() << 12) |
+		      (tegra_get_chipid_minor() << 8) |
+		       chip_subrev;
+
+		/* enable L2 ECC for Tegra186 A02P and beyond */
+		if (val >= TEGRA186_VER_A02P) {
+
+			val = read_l2ctlr_el1();
+			val |= L2_ECC_PARITY_PROTECTION_BIT;
+			write_l2ctlr_el1(val);
+
+			/*
+			 * Set the flag to enable ECC/Parity Protection
+			 * when we exit System Suspend or Cluster Powerdn
+			 */
+			tegra_enable_l2_ecc_parity_prot = 1;
+		}
+	}
+}
+
+/* Secure IRQs for Tegra186 */
+static const irq_sec_cfg_t tegra186_sec_irqs[] = {
+	[0] = {
+		TEGRA186_BPMP_WDT_IRQ,
+		TEGRA186_SEC_IRQ_TARGET_MASK,
+		INTR_TYPE_EL3,
+	},
+	[1] = {
+		TEGRA186_BPMP_WDT_IRQ,
+		TEGRA186_SEC_IRQ_TARGET_MASK,
+		INTR_TYPE_EL3,
+	},
+	[2] = {
+		TEGRA186_SPE_WDT_IRQ,
+		TEGRA186_SEC_IRQ_TARGET_MASK,
+		INTR_TYPE_EL3,
+	},
+	[3] = {
+		TEGRA186_SCE_WDT_IRQ,
+		TEGRA186_SEC_IRQ_TARGET_MASK,
+		INTR_TYPE_EL3,
+	},
+	[4] = {
+		TEGRA186_TOP_WDT_IRQ,
+		TEGRA186_SEC_IRQ_TARGET_MASK,
+		INTR_TYPE_EL3,
+	},
+	[5] = {
+		TEGRA186_AON_WDT_IRQ,
+		TEGRA186_SEC_IRQ_TARGET_MASK,
+		INTR_TYPE_EL3,
+	},
+};
+
+/*******************************************************************************
+ * Initialize the GIC and SGIs
+ ******************************************************************************/
+void plat_gic_setup(void)
+{
+	tegra_gic_setup(tegra186_sec_irqs,
+		sizeof(tegra186_sec_irqs) / sizeof(tegra186_sec_irqs[0]));
+
+	/*
+	 * Initialize the FIQ handler only if the platform supports any
+	 * FIQ interrupt sources.
+	 */
+	if (sizeof(tegra186_sec_irqs) > 0)
+		tegra_fiq_handler_setup();
+}
+
+/*******************************************************************************
+ * Return pointer to the BL31 params from previous bootloader
+ ******************************************************************************/
+struct tegra_bl31_params *plat_get_bl31_params(void)
+{
+	uint32_t val;
+
+	val = mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV53_LO);
+
+	return (struct tegra_bl31_params *)(uintptr_t)val;
+}
+
+/*******************************************************************************
+ * Return pointer to the BL31 platform params from previous bootloader
+ ******************************************************************************/
+plat_params_from_bl2_t *plat_get_bl31_plat_params(void)
+{
+	uint32_t val;
+
+	val = mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV53_HI);
+
+	return (plat_params_from_bl2_t *)(uintptr_t)val;
+}
diff --git a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
new file mode 100644
index 0000000..cb57c9b
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <common/bl_common.h>
+#include <lib/el3_runtime/context_mgmt.h>
+#include <common/debug.h>
+#include <errno.h>
+#include <mce.h>
+#include <memctrl.h>
+#include <common/runtime_svc.h>
+#include <tegra_private.h>
+
+extern uint32_t tegra186_system_powerdn_state;
+
+/*******************************************************************************
+ * Tegra186 SiP SMCs
+ ******************************************************************************/
+#define TEGRA_SIP_SYSTEM_SHUTDOWN_STATE			0xC2FFFE01
+#define TEGRA_SIP_GET_ACTMON_CLK_COUNTERS		0xC2FFFE02
+#define TEGRA_SIP_MCE_CMD_ENTER_CSTATE			0xC2FFFF00
+#define TEGRA_SIP_MCE_CMD_UPDATE_CSTATE_INFO		0xC2FFFF01
+#define TEGRA_SIP_MCE_CMD_UPDATE_CROSSOVER_TIME		0xC2FFFF02
+#define TEGRA_SIP_MCE_CMD_READ_CSTATE_STATS		0xC2FFFF03
+#define TEGRA_SIP_MCE_CMD_WRITE_CSTATE_STATS		0xC2FFFF04
+#define TEGRA_SIP_MCE_CMD_IS_SC7_ALLOWED		0xC2FFFF05
+#define TEGRA_SIP_MCE_CMD_ONLINE_CORE			0xC2FFFF06
+#define TEGRA_SIP_MCE_CMD_CC3_CTRL			0xC2FFFF07
+#define TEGRA_SIP_MCE_CMD_ECHO_DATA			0xC2FFFF08
+#define TEGRA_SIP_MCE_CMD_READ_VERSIONS			0xC2FFFF09
+#define TEGRA_SIP_MCE_CMD_ENUM_FEATURES			0xC2FFFF0A
+#define TEGRA_SIP_MCE_CMD_ROC_FLUSH_CACHE_TRBITS	0xC2FFFF0B
+#define TEGRA_SIP_MCE_CMD_ENUM_READ_MCA			0xC2FFFF0C
+#define TEGRA_SIP_MCE_CMD_ENUM_WRITE_MCA		0xC2FFFF0D
+#define TEGRA_SIP_MCE_CMD_ROC_FLUSH_CACHE		0xC2FFFF0E
+#define TEGRA_SIP_MCE_CMD_ROC_CLEAN_CACHE		0xC2FFFF0F
+#define TEGRA_SIP_MCE_CMD_ENABLE_LATIC			0xC2FFFF10
+#define TEGRA_SIP_MCE_CMD_UNCORE_PERFMON_REQ		0xC2FFFF11
+#define TEGRA_SIP_MCE_CMD_MISC_CCPLEX			0xC2FFFF12
+
+/*******************************************************************************
+ * This function is responsible for handling all T186 SiP calls
+ ******************************************************************************/
+int plat_sip_handler(uint32_t smc_fid,
+		     uint64_t x1,
+		     uint64_t x2,
+		     uint64_t x3,
+		     uint64_t x4,
+		     void *cookie,
+		     void *handle,
+		     uint64_t flags)
+{
+	int mce_ret;
+
+	/*
+	 * Convert SMC FID to SMC64 until the linux driver uses
+	 * SMC64 encoding.
+	 */
+	smc_fid |= (SMC_64 << FUNCID_CC_SHIFT);
+
+	switch (smc_fid) {
+
+	/*
+	 * Micro Coded Engine (MCE) commands reside in the 0x82FFFF00 -
+	 * 0x82FFFFFF SiP SMC space
+	 */
+	case TEGRA_SIP_MCE_CMD_ENTER_CSTATE:
+	case TEGRA_SIP_MCE_CMD_UPDATE_CSTATE_INFO:
+	case TEGRA_SIP_MCE_CMD_UPDATE_CROSSOVER_TIME:
+	case TEGRA_SIP_MCE_CMD_READ_CSTATE_STATS:
+	case TEGRA_SIP_MCE_CMD_WRITE_CSTATE_STATS:
+	case TEGRA_SIP_MCE_CMD_IS_SC7_ALLOWED:
+	case TEGRA_SIP_MCE_CMD_CC3_CTRL:
+	case TEGRA_SIP_MCE_CMD_ECHO_DATA:
+	case TEGRA_SIP_MCE_CMD_READ_VERSIONS:
+	case TEGRA_SIP_MCE_CMD_ENUM_FEATURES:
+	case TEGRA_SIP_MCE_CMD_ROC_FLUSH_CACHE_TRBITS:
+	case TEGRA_SIP_MCE_CMD_ENUM_READ_MCA:
+	case TEGRA_SIP_MCE_CMD_ENUM_WRITE_MCA:
+	case TEGRA_SIP_MCE_CMD_ROC_FLUSH_CACHE:
+	case TEGRA_SIP_MCE_CMD_ROC_CLEAN_CACHE:
+	case TEGRA_SIP_MCE_CMD_ENABLE_LATIC:
+	case TEGRA_SIP_MCE_CMD_UNCORE_PERFMON_REQ:
+	case TEGRA_SIP_MCE_CMD_MISC_CCPLEX:
+
+		/* clean up the high bits */
+		smc_fid &= MCE_CMD_MASK;
+
+		/* execute the command and store the result */
+		mce_ret = mce_command_handler(smc_fid, x1, x2, x3);
+		write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X0, mce_ret);
+
+		return 0;
+
+	case TEGRA_SIP_SYSTEM_SHUTDOWN_STATE:
+
+		/* clean up the high bits */
+		x1 = (uint32_t)x1;
+
+		/*
+		 * SC8 is a special Tegra186 system state where the CPUs and
+		 * DRAM are powered down but the other subsystem is still
+		 * alive.
+		 */
+
+		return 0;
+
+	default:
+		break;
+	}
+
+	return -ENOTSUP;
+}
diff --git a/plat/nvidia/tegra/soc/t194/plat_trampoline.S b/plat/nvidia/tegra/soc/t194/plat_trampoline.S
new file mode 100644
index 0000000..e3ee5e5
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/plat_trampoline.S
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <plat/common/common_def.h>
+#include <memctrl_v2.h>
+#include <tegra_def.h>
+
+#define TEGRA186_SMMU_CTX_SIZE		0x490
+
+	.align 4
+	.globl	tegra186_cpu_reset_handler
+
+/* CPU reset handler routine */
+func tegra186_cpu_reset_handler
+	/*
+	 * 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
+
+	/* resume from system suspend */
+	mov	x0, #BL31_BASE
+	adr	x1, __tegra186_cpu_reset_handler_end
+	adr	x2, __tegra186_cpu_reset_handler_data
+	ldr	x2, [x2, #8]
+
+	/* memcpy16 */
+m_loop16:
+	cmp	x2, #16
+	b.lt	m_loop1
+	ldp	x3, x4, [x1], #16
+	stp	x3, x4, [x0], #16
+	sub	x2, x2, #16
+	b	m_loop16
+	/* copy byte per byte */
+m_loop1:
+	cbz	x2, boot_cpu
+	ldrb	w3, [x1], #1
+	strb	w3, [x0], #1
+	subs	x2, x2, #1
+	b.ne	m_loop1
+
+boot_cpu:
+	adr	x0, __tegra186_cpu_reset_handler_data
+	ldr	x0, [x0]
+	br	x0
+endfunc tegra186_cpu_reset_handler
+
+	/*
+	 * Tegra186 reset data (offset 0x0 - 0x2490)
+	 *
+	 * 0x0000: secure world's entrypoint
+	 * 0x0008: BL31 size (RO + RW)
+	 * 0x0010: SMMU context start
+	 * 0x2490: SMMU context end
+	 */
+
+	.align 4
+	.type	__tegra186_cpu_reset_handler_data, %object
+	.globl	__tegra186_cpu_reset_handler_data
+__tegra186_cpu_reset_handler_data:
+	.quad	tegra_secure_entrypoint
+	.quad	__BL31_END__ - BL31_BASE
+	.globl	__tegra186_smmu_ctx_start
+__tegra186_smmu_ctx_start:
+	.rept	TEGRA186_SMMU_CTX_SIZE
+	.quad	0
+	.endr
+	.size	__tegra186_cpu_reset_handler_data, \
+		. - __tegra186_cpu_reset_handler_data
+
+	.align 4
+	.globl	__tegra186_cpu_reset_handler_end
+__tegra186_cpu_reset_handler_end:
diff --git a/plat/nvidia/tegra/soc/t194/platform_t194.mk b/plat/nvidia/tegra/soc/t194/platform_t194.mk
new file mode 100644
index 0000000..b6bc442
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t194/platform_t194.mk
@@ -0,0 +1,67 @@
+#
+# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# platform configs
+ENABLE_AFI_DEVICE			:= 0
+$(eval $(call add_define,ENABLE_AFI_DEVICE))
+
+ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS	:= 0
+$(eval $(call add_define,ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS))
+
+ENABLE_SYSTEM_SUSPEND_CTX_SAVE_TZDRAM	:= 1
+$(eval $(call add_define,ENABLE_SYSTEM_SUSPEND_CTX_SAVE_TZDRAM))
+
+RELOCATE_TO_BL31_BASE			:= 1
+$(eval $(call add_define,RELOCATE_TO_BL31_BASE))
+
+ENABLE_CHIP_VERIFICATION_HARNESS	:= 0
+$(eval $(call add_define,ENABLE_CHIP_VERIFICATION_HARNESS))
+
+ENABLE_SMMU_DEVICE			:= 1
+$(eval $(call add_define,ENABLE_SMMU_DEVICE))
+
+NUM_SMMU_DEVICES			:= 3
+$(eval $(call add_define,NUM_SMMU_DEVICES))
+
+RESET_TO_BL31				:= 1
+
+PROGRAMMABLE_RESET_ADDRESS		:= 1
+
+COLD_BOOT_SINGLE_CPU			:= 1
+
+# platform settings
+TZDRAM_BASE				:= 0x40000000
+$(eval $(call add_define,TZDRAM_BASE))
+
+PLATFORM_CLUSTER_COUNT			:= 2
+$(eval $(call add_define,PLATFORM_CLUSTER_COUNT))
+
+PLATFORM_MAX_CPUS_PER_CLUSTER		:= 4
+$(eval $(call add_define,PLATFORM_MAX_CPUS_PER_CLUSTER))
+
+MAX_XLAT_TABLES				:= 24
+$(eval $(call add_define,MAX_XLAT_TABLES))
+
+MAX_MMAP_REGIONS			:= 24
+$(eval $(call add_define,MAX_MMAP_REGIONS))
+
+# platform files
+PLAT_INCLUDES		+=	-I${SOC_DIR}/drivers/include
+
+BL31_SOURCES		+=	lib/cpus/aarch64/denver.S		\
+				${COMMON_DIR}/drivers/memctrl/memctrl_v2.c	\
+				${COMMON_DIR}/drivers/smmu/smmu.c	\
+				${SOC_DIR}/drivers/mce/mce.c		\
+				${SOC_DIR}/drivers/mce/nvg.c		\
+				${SOC_DIR}/drivers/mce/aarch64/nvg_helpers.S \
+				${SOC_DIR}/plat_psci_handlers.c		\
+				${SOC_DIR}/plat_setup.c			\
+				${SOC_DIR}/plat_secondary.c		\
+				${SOC_DIR}/plat_sip_calls.c
+
+ifeq (${ENABLE_SYSTEM_SUSPEND_CTX_SAVE_TZDRAM}, 1)
+BL31_SOURCES		+=	${SOC_DIR}/plat_trampoline.S
+endif