Merge pull request #872 from dp-arm/dp/fix-typo

firmware-design: Fix typo in ToC header flags specification
diff --git a/docs/cpu-specific-build-macros.md b/docs/cpu-specific-build-macros.md
index 0a575f7..eb23bcd 100644
--- a/docs/cpu-specific-build-macros.md
+++ b/docs/cpu-specific-build-macros.md
@@ -60,6 +60,13 @@
      CPU. This needs to be enabled only for revision <= r0p3 of the CPU. From
      r0p4 and onwards, this errata is enabled by default in hardware.
 
+*   `ERRATA_A53_855873`: This applies errata 855873 workaround to Cortex-A53
+     CPUs. Though the erratum is present in every revision of the CPU,
+     this workaround is only applied to CPUs from r0p3 onwards, which feature
+     a chicken bit in CPUACTLR_EL1 to enable a hardware workaround.
+     Earlier revisions of the CPU have other errata which require the same
+     workaround in software, so they should be covered anyway.
+
 For Cortex-A57, following errata build flags are defined :
 
 *   `ERRATA_A57_806969`: This applies errata 806969 workaround to Cortex-A57
diff --git a/include/lib/cpus/aarch64/cortex_a53.h b/include/lib/cpus/aarch64/cortex_a53.h
index 6976b80..484eb63 100644
--- a/include/lib/cpus/aarch64/cortex_a53.h
+++ b/include/lib/cpus/aarch64/cortex_a53.h
@@ -67,6 +67,7 @@
 #define CPUACTLR_EL1			S3_1_C15_C2_0	/* Instruction def. */
 
 #define CPUACTLR_DTAH			(1 << 24)
+#define CPUACTLR_ENDCCASCI		(1 << 44)
 
 /*******************************************************************************
  * L2 Auxiliary Control register specific definitions.
diff --git a/lib/cpus/aarch64/cortex_a53.S b/lib/cpus/aarch64/cortex_a53.S
index 1dd8a86..a36666b 100644
--- a/lib/cpus/aarch64/cortex_a53.S
+++ b/lib/cpus/aarch64/cortex_a53.S
@@ -129,6 +129,39 @@
 	b	cpu_rev_var_ls
 endfunc check_errata_disable_non_temporal_hint
 
+	/* --------------------------------------------------
+	 * Errata Workaround for Cortex A53 Errata #855873.
+	 *
+	 * This applies only to revisions >= r0p3 of Cortex A53.
+	 * Earlier revisions of the core are affected as well, but don't
+	 * have the chicken bit in the CPUACTLR register. It is expected that
+	 * the rich OS takes care of that, especially as the workaround is
+	 * shared with other erratas in those revisions of the CPU.
+	 * Inputs:
+	 * x0: variant[4:7] and revision[0:3] of current cpu.
+	 * Shall clobber: x0-x17
+	 * --------------------------------------------------
+	 */
+func errata_a53_855873_wa
+	/*
+	 * Compare x0 against revision r0p3 and higher
+	 */
+        mov     x17, x30
+        bl      check_errata_855873
+        cbz     x0, 1f
+
+	mrs	x1, CPUACTLR_EL1
+	orr	x1, x1, #CPUACTLR_ENDCCASCI
+	msr	CPUACTLR_EL1, x1
+1:
+	ret	x17
+endfunc errata_a53_855873_wa
+
+func check_errata_855873
+	mov	x1, #0x03
+	b	cpu_rev_var_hs
+endfunc check_errata_855873
+
 	/* -------------------------------------------------
 	 * The CPU Ops reset function for Cortex-A53.
 	 * Shall clobber: x0-x19
@@ -150,6 +183,11 @@
 	bl	a53_disable_non_temporal_hint
 #endif
 
+#if ERRATA_A53_855873
+	mov	x0, x18
+	bl	errata_a53_855873_wa
+#endif
+
 	/* ---------------------------------------------
 	 * Enable the SMP bit.
 	 * ---------------------------------------------
@@ -238,6 +276,7 @@
 	 */
 	report_errata ERRATA_A53_826319, cortex_a53, 826319
 	report_errata ERRATA_A53_836870, cortex_a53, disable_non_temporal_hint
+	report_errata ERRATA_A53_855873, cortex_a53, 855873
 
 	ldp	x8, x30, [sp], #16
 	ret
@@ -255,13 +294,15 @@
 	 */
 .section .rodata.cortex_a53_regs, "aS"
 cortex_a53_regs:  /* The ascii list of register names to be reported */
-	.asciz	"cpuectlr_el1", "cpumerrsr_el1", "l2merrsr_el1", ""
+	.asciz	"cpuectlr_el1", "cpumerrsr_el1", "l2merrsr_el1", \
+		"cpuactlr_el1", ""
 
 func cortex_a53_cpu_reg_dump
 	adr	x6, cortex_a53_regs
 	mrs	x8, CPUECTLR_EL1
 	mrs	x9, CPUMERRSR_EL1
 	mrs	x10, L2MERRSR_EL1
+	mrs	x11, CPUACTLR_EL1
 	ret
 endfunc cortex_a53_cpu_reg_dump
 
diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S
index 6a3669d..47cb6a2 100644
--- a/lib/cpus/aarch64/cpu_helpers.S
+++ b/lib/cpus/aarch64/cpu_helpers.S
@@ -234,6 +234,20 @@
 	ret
 endfunc cpu_rev_var_ls
 
+/*
+ * Compare the CPU's revision-variant (x0) with a given value (x1), for errata
+ * application purposes. If the revision-variant is higher than or same as a
+ * given value, indicates that errata applies; otherwise not.
+ */
+	.globl	cpu_rev_var_hs
+func cpu_rev_var_hs
+	mov	x2, #ERRATA_APPLIES
+	mov	x3, #ERRATA_NOT_APPLIES
+	cmp	x0, x1
+	csel	x0, x2, x3, hs
+	ret
+endfunc cpu_rev_var_hs
+
 #if REPORT_ERRATA
 /*
  * void print_errata_status(void);
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 7d7db20..132ab6f 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -66,6 +66,12 @@
 # erratum workaround is enabled by default in hardware.
 ERRATA_A53_836870	?=0
 
+# Flag to apply errata 855873 during reset. This errata applies to all
+# revisions of the Cortex A53 CPU, but this firmware workaround only works
+# for revisions r0p3 and higher. Earlier revisions are taken care
+# of by the rich OS.
+ERRATA_A53_855873	?=0
+
 # Flag to apply erratum 806969 workaround during reset. This erratum applies
 # only to revision r0p0 of the Cortex A57 cpu.
 ERRATA_A57_806969	?=0
@@ -106,6 +112,10 @@
 $(eval $(call assert_boolean,ERRATA_A53_836870))
 $(eval $(call add_define,ERRATA_A53_836870))
 
+# Process ERRATA_A53_855873 flag
+$(eval $(call assert_boolean,ERRATA_A53_855873))
+$(eval $(call add_define,ERRATA_A53_855873))
+
 # Process ERRATA_A57_806969 flag
 $(eval $(call assert_boolean,ERRATA_A57_806969))
 $(eval $(call add_define,ERRATA_A57_806969))
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index 5ba1698..7571582 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -67,7 +67,8 @@
 				${JUNO_INTERCONNECT_SOURCES}		\
 				${JUNO_SECURITY_SOURCES}
 
-# Enable workarounds for selected Cortex-A57 erratas.
+# Enable workarounds for selected Cortex-A53 and A57 erratas.
+ERRATA_A53_855873		:=	1
 ERRATA_A57_806969		:=	0
 ERRATA_A57_813419		:=	1
 ERRATA_A57_813420		:=	1
diff --git a/plat/mediatek/mt8173/platform.mk b/plat/mediatek/mt8173/platform.mk
index e59125a..9583efe 100644
--- a/plat/mediatek/mt8173/platform.mk
+++ b/plat/mediatek/mt8173/platform.mk
@@ -90,6 +90,7 @@
 # Enable workarounds for selected Cortex-A53 erratas.
 ERRATA_A53_826319	:=	1
 ERRATA_A53_836870	:=	1
+ERRATA_A53_855873	:=	1
 
 # indicate the reset vector address can be programmed
 PROGRAMMABLE_RESET_ADDRESS	:=	1
diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
new file mode 100644
index 0000000..e11b8ad
--- /dev/null
+++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
@@ -0,0 +1,450 @@
+/*
+ * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <debug.h>
+#include <mce.h>
+#include <memctrl.h>
+#include <memctrl_v2.h>
+#include <mmio.h>
+#include <smmu.h>
+#include <string.h>
+#include <tegra_def.h>
+#include <xlat_tables.h>
+
+#define TEGRA_GPU_RESET_REG_OFFSET	0x30
+#define  GPU_RESET_BIT			(1 << 0)
+
+/* Video Memory base and size (live values) */
+static uint64_t video_mem_base;
+static uint64_t video_mem_size;
+
+/* array to hold stream_id override config register offsets */
+const static uint32_t streamid_overrides[] = {
+	MC_STREAMID_OVERRIDE_CFG_PTCR,
+	MC_STREAMID_OVERRIDE_CFG_AFIR,
+	MC_STREAMID_OVERRIDE_CFG_HDAR,
+	MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR,
+	MC_STREAMID_OVERRIDE_CFG_NVENCSRD,
+	MC_STREAMID_OVERRIDE_CFG_SATAR,
+	MC_STREAMID_OVERRIDE_CFG_MPCORER,
+	MC_STREAMID_OVERRIDE_CFG_NVENCSWR,
+	MC_STREAMID_OVERRIDE_CFG_AFIW,
+	MC_STREAMID_OVERRIDE_CFG_SATAW,
+	MC_STREAMID_OVERRIDE_CFG_MPCOREW,
+	MC_STREAMID_OVERRIDE_CFG_SATAW,
+	MC_STREAMID_OVERRIDE_CFG_HDAW,
+	MC_STREAMID_OVERRIDE_CFG_ISPRA,
+	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_GPUSRD,
+	MC_STREAMID_OVERRIDE_CFG_GPUSWR,
+	MC_STREAMID_OVERRIDE_CFG_SDMMCRA,
+	MC_STREAMID_OVERRIDE_CFG_SDMMCRAA,
+	MC_STREAMID_OVERRIDE_CFG_SDMMCR,
+	MC_STREAMID_OVERRIDE_CFG_SDMMCRAB,
+	MC_STREAMID_OVERRIDE_CFG_SDMMCWA,
+	MC_STREAMID_OVERRIDE_CFG_SDMMCWAA,
+	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_ETRR,
+	MC_STREAMID_OVERRIDE_CFG_ETRW,
+	MC_STREAMID_OVERRIDE_CFG_TSECSRDB,
+	MC_STREAMID_OVERRIDE_CFG_TSECSWRB,
+	MC_STREAMID_OVERRIDE_CFG_GPUSRD2,
+	MC_STREAMID_OVERRIDE_CFG_GPUSWR2,
+	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
+};
+
+/* array to hold the security configs for stream IDs */
+const static mc_streamid_security_cfg_t sec_cfgs[] = {
+	mc_make_sec_cfg(SCEW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AFIR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVDISPLAYR1, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(XUSB_DEVR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(VICSRD1, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVENCSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(TSECSRDB, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AXISW, SECURE, NO_OVERRIDE, DISABLE),
+	mc_make_sec_cfg(SDMMCWAB, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AONDMAW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(GPUSWR2, SECURE, NO_OVERRIDE, DISABLE),
+	mc_make_sec_cfg(SATAW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(UFSHCW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AFIW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SDMMCR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SCEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(UFSHCR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SDMMCWAA, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(APEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SESWR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(MPCORER, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(PTCR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(BPMPW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(ETRW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(GPUSRD, SECURE, NO_OVERRIDE, DISABLE),
+	mc_make_sec_cfg(VICSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SCEDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(HDAW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(ISPWA, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(EQOSW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(XUSB_HOSTW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(TSECSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SDMMCRAA, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(APER, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(VIW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(APEW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AXISR, SECURE, NO_OVERRIDE, DISABLE),
+	mc_make_sec_cfg(SDMMCW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(BPMPDMAW, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(ISPRA, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVDECSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(XUSB_DEVW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVDECSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(MPCOREW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVDISPLAYR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(BPMPDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVJPGSWR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVDECSRD1, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(TSECSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVJPGSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SDMMCWA, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SCER, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(XUSB_HOSTR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(VICSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AONDMAR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AONW, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SDMMCRA, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(HOST1XDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(EQOSR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SATAR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(BPMPR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(HDAR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SDMMCRAB, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(ETRR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(AONR, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(APEDMAR, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(SESRD, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(NVENCSRD, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(GPUSWR, SECURE, NO_OVERRIDE, DISABLE),
+	mc_make_sec_cfg(TSECSWRB, NON_SECURE, NO_OVERRIDE, ENABLE),
+	mc_make_sec_cfg(ISPWB, NON_SECURE, OVERRIDE, ENABLE),
+	mc_make_sec_cfg(GPUSRD2, SECURE, NO_OVERRIDE, DISABLE),
+};
+
+const static mc_txn_override_cfg_t mc_override_cfgs[] = {
+	mc_make_txn_override_cfg(BPMPW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(EQOSW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(NVJPGSWR, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(SDMMCWAA, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(MPCOREW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(SCEDMAW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(SDMMCW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(AXISW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(TSECSWR, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(GPUSWR, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(XUSB_HOSTW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(TSECSWRB, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(GPUSWR2, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(AONDMAW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(AONW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(SESWR, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(BPMPDMAW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(SDMMCWA, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(HDAW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(NVDECSWR, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(UFSHCW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(SATAW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(ETRW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(VICSWR, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(NVENCSWR, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(SDMMCWAB, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(ISPWB, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(APEW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(XUSB_DEVW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(AFIW, CGID_TAG_ADR),
+	mc_make_txn_override_cfg(SCEW, CGID_TAG_ADR),
+};
+
+/*
+ * Init Memory controller during boot.
+ */
+void tegra_memctrl_setup(void)
+{
+	uint32_t val;
+	uint32_t num_overrides = sizeof(streamid_overrides) / sizeof(uint32_t);
+	uint32_t num_sec_cfgs = sizeof(sec_cfgs) / sizeof(mc_streamid_security_cfg_t);
+	uint32_t num_txn_overrides = sizeof(mc_override_cfgs) / sizeof(mc_txn_override_cfg_t);
+	uint32_t tegra_rev;
+	int i;
+
+	INFO("Tegra Memory Controller (v2)\n");
+
+	/* Program the SMMU pagesize */
+	tegra_smmu_init();
+
+	/* Program all the Stream ID overrides */
+	for (i = 0; i < num_overrides; i++)
+		tegra_mc_streamid_write_32(streamid_overrides[i],
+			MC_STREAM_ID_MAX);
+
+	/* Program the security config settings for all Stream IDs */
+	for (i = 0; i < num_sec_cfgs; i++) {
+		val = sec_cfgs[i].override_enable << 16 |
+		      sec_cfgs[i].override_client_inputs << 8 |
+		      sec_cfgs[i].override_client_ns_flag << 0;
+		tegra_mc_streamid_write_32(sec_cfgs[i].offset, val);
+	}
+
+	/*
+	 * All requests at boot time, and certain requests during
+	 * normal run time, are physically addressed and must bypass
+	 * the SMMU. The client hub logic implements a hardware bypass
+	 * path around the Translation Buffer Units (TBU). During
+	 * boot-time, the SMMU_BYPASS_CTRL register (which defaults to
+	 * TBU_BYPASS mode) will be used to steer all requests around
+	 * the uninitialized TBUs. During normal operation, this register
+	 * is locked into TBU_BYPASS_SID config, which routes requests
+	 * with special StreamID 0x7f on the bypass path and all others
+	 * through the selected TBU. This is done to disable SMMU Bypass
+	 * mode, as it could be used to circumvent SMMU security checks.
+	 */
+	tegra_mc_write_32(MC_SMMU_BYPASS_CONFIG,
+		MC_SMMU_BYPASS_CONFIG_SETTINGS);
+
+	/*
+	 * Set the MC_TXN_OVERRIDE registers for write clients.
+	 */
+	tegra_rev = (mmio_read_32(TEGRA_MISC_BASE + HARDWARE_REVISION_OFFSET) &
+			HARDWARE_MINOR_REVISION_MASK) >> HARDWARE_MINOR_REVISION_SHIFT;
+
+	if (tegra_rev == HARDWARE_REVISION_A01) {
+
+		/* GPU and NVENC settings for rev. A01 */
+		val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR);
+		val &= ~MC_TXN_OVERRIDE_CGID_TAG_MASK;
+		tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR,
+			val | MC_TXN_OVERRIDE_CGID_TAG_ZERO);
+
+		val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR2);
+		val &= ~MC_TXN_OVERRIDE_CGID_TAG_MASK;
+		tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR2,
+			val | MC_TXN_OVERRIDE_CGID_TAG_ZERO);
+
+		val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_NVENCSWR);
+		val &= ~MC_TXN_OVERRIDE_CGID_TAG_MASK;
+		tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_NVENCSWR,
+			val | MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID);
+
+	} else {
+
+		/* settings for rev. A02 */
+		for (i = 0; i < num_txn_overrides; i++) {
+			val = tegra_mc_read_32(mc_override_cfgs[i].offset);
+			val &= ~MC_TXN_OVERRIDE_CGID_TAG_MASK;
+			tegra_mc_write_32(mc_override_cfgs[i].offset,
+				val | mc_override_cfgs[i].cgid_tag);
+		}
+
+	}
+}
+
+/*
+ * Restore Memory Controller settings after "System Suspend"
+ */
+void tegra_memctrl_restore_settings(void)
+{
+	/* video memory carveout region */
+	if (video_mem_base) {
+		tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO,
+				  (uint32_t)video_mem_base);
+		tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI,
+				  (uint32_t)(video_mem_base >> 32));
+		tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size);
+
+		/*
+		 * MCE propogates the VideoMem configuration values across the
+		 * CCPLEX.
+		 */
+		mce_update_gsc_videomem();
+	}
+}
+
+/*
+ * Secure the BL31 DRAM aperture.
+ *
+ * phys_base = physical base of TZDRAM aperture
+ * size_in_bytes = size of aperture in bytes
+ */
+void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes)
+{
+	/*
+	 * Setup the Memory controller to allow only secure accesses to
+	 * the TZDRAM carveout
+	 */
+	INFO("Configuring TrustZone DRAM Memory Carveout\n");
+
+	tegra_mc_write_32(MC_SECURITY_CFG0_0, (uint32_t)phys_base);
+	tegra_mc_write_32(MC_SECURITY_CFG3_0, (uint32_t)(phys_base >> 32));
+	tegra_mc_write_32(MC_SECURITY_CFG1_0, size_in_bytes >> 20);
+
+	/*
+	 * MCE propogates the security configuration values across the
+	 * CCPLEX.
+	 */
+	mce_update_gsc_tzdram();
+}
+
+/*
+ * Secure the BL31 TZRAM aperture.
+ *
+ * phys_base = physical base of TZRAM aperture
+ * size_in_bytes = size of aperture in bytes
+ */
+void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes)
+{
+	uint64_t tzram_end = phys_base + size_in_bytes - 1;
+	uint32_t val;
+
+	/*
+	 * Check if the TZRAM is locked already.
+	 */
+	if (tegra_mc_read_32(MC_TZRAM_REG_CTRL) == DISABLE_TZRAM_ACCESS)
+		return;
+
+	/*
+	 * Setup the Memory controller to allow only secure accesses to
+	 * the TZRAM carveout
+	 */
+	INFO("Configuring TrustZone RAM (SysRAM) Memory Carveout\n");
+
+	/* Program the base and end values */
+	tegra_mc_write_32(MC_TZRAM_BASE, (uint32_t)phys_base);
+	tegra_mc_write_32(MC_TZRAM_END, (uint32_t)tzram_end);
+
+	/* Extract the high address bits from the base/end values */
+	val = (uint32_t)(phys_base >> 32) & TZRAM_ADDR_HI_BITS_MASK;
+	val |= (((uint32_t)(tzram_end >> 32) << TZRAM_END_HI_BITS_SHIFT) &
+		TZRAM_ADDR_HI_BITS_MASK);
+	tegra_mc_write_32(MC_TZRAM_HI_ADDR_BITS, val);
+
+	/* Disable further writes to the TZRAM setup registers */
+	tegra_mc_write_32(MC_TZRAM_REG_CTRL, DISABLE_TZRAM_ACCESS);
+
+	/*
+	 * MCE propogates the security configuration values across the
+	 * CCPLEX.
+	 */
+	mce_update_gsc_tzram();
+}
+
+/*
+ * Program the Video Memory carveout region
+ *
+ * phys_base = physical base of aperture
+ * size_in_bytes = size of aperture in bytes
+ */
+void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes)
+{
+	uint32_t regval;
+
+	/*
+	 * The GPU is the user of the Video Memory region. In order to
+	 * transition to the new memory region smoothly, we program the
+	 * new base/size ONLY if the GPU is in reset mode.
+	 */
+	regval = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_GPU_RESET_REG_OFFSET);
+	if ((regval & GPU_RESET_BIT) == 0) {
+		ERROR("GPU not in reset! Video Memory setup failed\n");
+		return;
+	}
+
+	/*
+	 * Setup the Memory controller to restrict CPU accesses to the Video
+	 * Memory region
+	 */
+	INFO("Configuring Video Memory Carveout\n");
+
+	tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)phys_base);
+	tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI,
+			  (uint32_t)(phys_base >> 32));
+	tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, size_in_bytes);
+
+	/* store new values */
+	video_mem_base = phys_base;
+	video_mem_size = size_in_bytes >> 20;
+
+	/*
+	 * MCE propogates the VideoMem configuration values across the
+	 * CCPLEX.
+	 */
+	mce_update_gsc_videomem();
+}
diff --git a/plat/nvidia/tegra/common/tegra_platform.c b/plat/nvidia/tegra/common/tegra_platform.c
index 5b96459..0724b18 100644
--- a/plat/nvidia/tegra/common/tegra_platform.c
+++ b/plat/nvidia/tegra/common/tegra_platform.c
@@ -82,7 +82,7 @@
 /*
  * Read the chip's major version from chip ID value
  */
-static uint32_t tegra_get_chipid_major(void)
+uint32_t tegra_get_chipid_major(void)
 {
 	return (tegra_get_chipid() >> MAJOR_VERSION_SHIFT) & MAJOR_VERSION_MASK;
 }
@@ -90,7 +90,7 @@
 /*
  * Read the chip's minor version from the chip ID value
  */
-static uint32_t tegra_get_chipid_minor(void)
+uint32_t tegra_get_chipid_minor(void)
 {
 	return (tegra_get_chipid() >> MINOR_VERSION_SHIFT) & MINOR_VERSION_MASK;
 }
diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v2.h b/plat/nvidia/tegra/include/drivers/memctrl_v2.h
new file mode 100644
index 0000000..9623e25
--- /dev/null
+++ b/plat/nvidia/tegra/include/drivers/memctrl_v2.h
@@ -0,0 +1,391 @@
+/*
+ * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MEMCTRLV2_H__
+#define __MEMCTRLV2_H__
+
+#include <mmio.h>
+#include <tegra_def.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		0x0
+#define MC_STREAMID_OVERRIDE_CFG_AFIR		0x70
+#define MC_STREAMID_OVERRIDE_CFG_HDAR		0xA8
+#define MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR	0xB0
+#define MC_STREAMID_OVERRIDE_CFG_NVENCSRD	0xE0
+#define MC_STREAMID_OVERRIDE_CFG_SATAR		0xF8
+#define MC_STREAMID_OVERRIDE_CFG_MPCORER	0x138
+#define MC_STREAMID_OVERRIDE_CFG_NVENCSWR	0x158
+#define MC_STREAMID_OVERRIDE_CFG_AFIW		0x188
+#define MC_STREAMID_OVERRIDE_CFG_SATAW		0x1E8
+#define MC_STREAMID_OVERRIDE_CFG_MPCOREW	0x1C8
+#define MC_STREAMID_OVERRIDE_CFG_SATAW		0x1E8
+#define MC_STREAMID_OVERRIDE_CFG_HDAW		0x1A8
+#define MC_STREAMID_OVERRIDE_CFG_ISPRA		0x220
+#define MC_STREAMID_OVERRIDE_CFG_ISPWA		0x230
+#define MC_STREAMID_OVERRIDE_CFG_ISPWB		0x238
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR	0x250
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW	0x258
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR	0x260
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW	0x268
+#define MC_STREAMID_OVERRIDE_CFG_TSECSRD	0x2A0
+#define MC_STREAMID_OVERRIDE_CFG_TSECSWR	0x2A8
+#define MC_STREAMID_OVERRIDE_CFG_GPUSRD		0x2C0
+#define MC_STREAMID_OVERRIDE_CFG_GPUSWR		0x2C8
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCRA	0x300
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAA	0x308
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCR		0x310
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAB	0x318
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCWA	0x320
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAA	0x328
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCW		0x330
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAB	0x338
+#define MC_STREAMID_OVERRIDE_CFG_VICSRD		0x360
+#define MC_STREAMID_OVERRIDE_CFG_VICSWR		0x368
+#define MC_STREAMID_OVERRIDE_CFG_VIW		0x390
+#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD	0x3C0
+#define MC_STREAMID_OVERRIDE_CFG_NVDECSWR	0x3C8
+#define MC_STREAMID_OVERRIDE_CFG_APER		0x3D0
+#define MC_STREAMID_OVERRIDE_CFG_APEW		0x3D8
+#define MC_STREAMID_OVERRIDE_CFG_NVJPGSRD	0x3F0
+#define MC_STREAMID_OVERRIDE_CFG_NVJPGSWR	0x3F8
+#define MC_STREAMID_OVERRIDE_CFG_SESRD		0x400
+#define MC_STREAMID_OVERRIDE_CFG_SESWR		0x408
+#define MC_STREAMID_OVERRIDE_CFG_ETRR		0x420
+#define MC_STREAMID_OVERRIDE_CFG_ETRW		0x428
+#define MC_STREAMID_OVERRIDE_CFG_TSECSRDB	0x430
+#define MC_STREAMID_OVERRIDE_CFG_TSECSWRB	0x438
+#define MC_STREAMID_OVERRIDE_CFG_GPUSRD2	0x440
+#define MC_STREAMID_OVERRIDE_CFG_GPUSWR2	0x448
+#define MC_STREAMID_OVERRIDE_CFG_AXISR		0x460
+#define MC_STREAMID_OVERRIDE_CFG_AXISW		0x468
+#define MC_STREAMID_OVERRIDE_CFG_EQOSR		0x470
+#define MC_STREAMID_OVERRIDE_CFG_EQOSW		0x478
+#define MC_STREAMID_OVERRIDE_CFG_UFSHCR		0x480
+#define MC_STREAMID_OVERRIDE_CFG_UFSHCW		0x488
+#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR	0x490
+#define MC_STREAMID_OVERRIDE_CFG_BPMPR		0x498
+#define MC_STREAMID_OVERRIDE_CFG_BPMPW		0x4A0
+#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAR	0x4A8
+#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAW	0x4B0
+#define MC_STREAMID_OVERRIDE_CFG_AONR		0x4B8
+#define MC_STREAMID_OVERRIDE_CFG_AONW		0x4C0
+#define MC_STREAMID_OVERRIDE_CFG_AONDMAR	0x4C8
+#define MC_STREAMID_OVERRIDE_CFG_AONDMAW	0x4D0
+#define MC_STREAMID_OVERRIDE_CFG_SCER		0x4D8
+#define MC_STREAMID_OVERRIDE_CFG_SCEW		0x4E0
+#define MC_STREAMID_OVERRIDE_CFG_SCEDMAR	0x4E8
+#define MC_STREAMID_OVERRIDE_CFG_SCEDMAW	0x4F0
+#define MC_STREAMID_OVERRIDE_CFG_APEDMAR	0x4F8
+#define MC_STREAMID_OVERRIDE_CFG_APEDMAW	0x500
+#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1	0x508
+#define MC_STREAMID_OVERRIDE_CFG_VICSRD1	0x510
+#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD1	0x518
+
+/*******************************************************************************
+ * Stream ID Security Config registers
+ ******************************************************************************/
+#define MC_STREAMID_SECURITY_CFG_PTCR		0x4
+#define MC_STREAMID_SECURITY_CFG_AFIR		0x74
+#define MC_STREAMID_SECURITY_CFG_HDAR		0xAC
+#define MC_STREAMID_SECURITY_CFG_HOST1XDMAR	0xB4
+#define MC_STREAMID_SECURITY_CFG_NVENCSRD	0xE4
+#define MC_STREAMID_SECURITY_CFG_SATAR		0xFC
+#define MC_STREAMID_SECURITY_CFG_HDAW		0x1AC
+#define MC_STREAMID_SECURITY_CFG_MPCORER	0x13C
+#define MC_STREAMID_SECURITY_CFG_NVENCSWR	0x15C
+#define MC_STREAMID_SECURITY_CFG_AFIW		0x18C
+#define MC_STREAMID_SECURITY_CFG_MPCOREW	0x1CC
+#define MC_STREAMID_SECURITY_CFG_SATAW		0x1EC
+#define MC_STREAMID_SECURITY_CFG_ISPRA		0x224
+#define MC_STREAMID_SECURITY_CFG_ISPWA		0x234
+#define MC_STREAMID_SECURITY_CFG_ISPWB		0x23C
+#define MC_STREAMID_SECURITY_CFG_XUSB_HOSTR	0x254
+#define MC_STREAMID_SECURITY_CFG_XUSB_HOSTW	0x25C
+#define MC_STREAMID_SECURITY_CFG_XUSB_DEVR	0x264
+#define MC_STREAMID_SECURITY_CFG_XUSB_DEVW	0x26C
+#define MC_STREAMID_SECURITY_CFG_TSECSRD	0x2A4
+#define MC_STREAMID_SECURITY_CFG_TSECSWR	0x2AC
+#define MC_STREAMID_SECURITY_CFG_GPUSRD		0x2C4
+#define MC_STREAMID_SECURITY_CFG_GPUSWR		0x2CC
+#define MC_STREAMID_SECURITY_CFG_SDMMCRA	0x304
+#define MC_STREAMID_SECURITY_CFG_SDMMCRAA	0x30C
+#define MC_STREAMID_SECURITY_CFG_SDMMCR		0x314
+#define MC_STREAMID_SECURITY_CFG_SDMMCRAB	0x31C
+#define MC_STREAMID_SECURITY_CFG_SDMMCWA	0x324
+#define MC_STREAMID_SECURITY_CFG_SDMMCWAA	0x32C
+#define MC_STREAMID_SECURITY_CFG_SDMMCW		0x334
+#define MC_STREAMID_SECURITY_CFG_SDMMCWAB	0x33C
+#define MC_STREAMID_SECURITY_CFG_VICSRD		0x364
+#define MC_STREAMID_SECURITY_CFG_VICSWR		0x36C
+#define MC_STREAMID_SECURITY_CFG_VIW		0x394
+#define MC_STREAMID_SECURITY_CFG_NVDECSRD	0x3C4
+#define MC_STREAMID_SECURITY_CFG_NVDECSWR	0x3CC
+#define MC_STREAMID_SECURITY_CFG_APER		0x3D4
+#define MC_STREAMID_SECURITY_CFG_APEW		0x3DC
+#define MC_STREAMID_SECURITY_CFG_NVJPGSRD	0x3F4
+#define MC_STREAMID_SECURITY_CFG_NVJPGSWR	0x3FC
+#define MC_STREAMID_SECURITY_CFG_SESRD		0x404
+#define MC_STREAMID_SECURITY_CFG_SESWR		0x40C
+#define MC_STREAMID_SECURITY_CFG_ETRR		0x424
+#define MC_STREAMID_SECURITY_CFG_ETRW		0x42C
+#define MC_STREAMID_SECURITY_CFG_TSECSRDB	0x434
+#define MC_STREAMID_SECURITY_CFG_TSECSWRB	0x43C
+#define MC_STREAMID_SECURITY_CFG_GPUSRD2	0x444
+#define MC_STREAMID_SECURITY_CFG_GPUSWR2	0x44C
+#define MC_STREAMID_SECURITY_CFG_AXISR		0x464
+#define MC_STREAMID_SECURITY_CFG_AXISW		0x46C
+#define MC_STREAMID_SECURITY_CFG_EQOSR		0x474
+#define MC_STREAMID_SECURITY_CFG_EQOSW		0x47C
+#define MC_STREAMID_SECURITY_CFG_UFSHCR		0x484
+#define MC_STREAMID_SECURITY_CFG_UFSHCW		0x48C
+#define MC_STREAMID_SECURITY_CFG_NVDISPLAYR	0x494
+#define MC_STREAMID_SECURITY_CFG_BPMPR		0x49C
+#define MC_STREAMID_SECURITY_CFG_BPMPW		0x4A4
+#define MC_STREAMID_SECURITY_CFG_BPMPDMAR	0x4AC
+#define MC_STREAMID_SECURITY_CFG_BPMPDMAW	0x4B4
+#define MC_STREAMID_SECURITY_CFG_AONR		0x4BC
+#define MC_STREAMID_SECURITY_CFG_AONW		0x4C4
+#define MC_STREAMID_SECURITY_CFG_AONDMAR	0x4CC
+#define MC_STREAMID_SECURITY_CFG_AONDMAW	0x4D4
+#define MC_STREAMID_SECURITY_CFG_SCER		0x4DC
+#define MC_STREAMID_SECURITY_CFG_SCEW		0x4E4
+#define MC_STREAMID_SECURITY_CFG_SCEDMAR	0x4EC
+#define MC_STREAMID_SECURITY_CFG_SCEDMAW	0x4F4
+#define MC_STREAMID_SECURITY_CFG_APEDMAR	0x4FC
+#define MC_STREAMID_SECURITY_CFG_APEDMAW	0x504
+#define MC_STREAMID_SECURITY_CFG_NVDISPLAYR1	0x50C
+#define MC_STREAMID_SECURITY_CFG_VICSRD1	0x514
+#define MC_STREAMID_SECURITY_CFG_NVDECSRD1	0x51C
+
+/*******************************************************************************
+ * Memory Controller SMMU Bypass config register
+ ******************************************************************************/
+#define MC_SMMU_BYPASS_CONFIG			0x1820
+#define MC_SMMU_BYPASS_CTRL_MASK		0x3
+#define MC_SMMU_BYPASS_CTRL_SHIFT		0
+#define MC_SMMU_CTRL_TBU_BYPASS_ALL		(0 << MC_SMMU_BYPASS_CTRL_SHIFT)
+#define MC_SMMU_CTRL_TBU_RSVD			(1 << MC_SMMU_BYPASS_CTRL_SHIFT)
+#define MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID	(2 << MC_SMMU_BYPASS_CTRL_SHIFT)
+#define MC_SMMU_CTRL_TBU_BYPASS_NONE		(3 << MC_SMMU_BYPASS_CTRL_SHIFT)
+#define MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT	(1 << 31)
+#define MC_SMMU_BYPASS_CONFIG_SETTINGS		(MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT | \
+						 MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID)
+
+/*******************************************************************************
+ * Memory Controller transaction override config registers
+ ******************************************************************************/
+#define MC_TXN_OVERRIDE_CONFIG_HDAR		0x10a8
+#define MC_TXN_OVERRIDE_CONFIG_BPMPW		0x14a0
+#define MC_TXN_OVERRIDE_CONFIG_PTCR		0x1000
+#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR	0x1490
+#define MC_TXN_OVERRIDE_CONFIG_EQOSW		0x1478
+#define MC_TXN_OVERRIDE_CONFIG_NVJPGSWR		0x13f8
+#define MC_TXN_OVERRIDE_CONFIG_ISPRA		0x1220
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAA		0x1328
+#define MC_TXN_OVERRIDE_CONFIG_VICSRD		0x1360
+#define MC_TXN_OVERRIDE_CONFIG_MPCOREW		0x11c8
+#define MC_TXN_OVERRIDE_CONFIG_GPUSRD		0x12c0
+#define MC_TXN_OVERRIDE_CONFIG_AXISR		0x1460
+#define MC_TXN_OVERRIDE_CONFIG_SCEDMAW		0x14f0
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCW		0x1330
+#define MC_TXN_OVERRIDE_CONFIG_EQOSR		0x1470
+#define MC_TXN_OVERRIDE_CONFIG_APEDMAR		0x14f8
+#define MC_TXN_OVERRIDE_CONFIG_NVENCSRD		0x10e0
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAB		0x1318
+#define MC_TXN_OVERRIDE_CONFIG_VICSRD1		0x1510
+#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAR		0x14a8
+#define MC_TXN_OVERRIDE_CONFIG_VIW		0x1390
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAA		0x1308
+#define MC_TXN_OVERRIDE_CONFIG_AXISW		0x1468
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVR	0x1260
+#define MC_TXN_OVERRIDE_CONFIG_UFSHCR		0x1480
+#define MC_TXN_OVERRIDE_CONFIG_TSECSWR		0x12a8
+#define MC_TXN_OVERRIDE_CONFIG_GPUSWR		0x12c8
+#define MC_TXN_OVERRIDE_CONFIG_SATAR		0x10f8
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTW	0x1258
+#define MC_TXN_OVERRIDE_CONFIG_TSECSWRB		0x1438
+#define MC_TXN_OVERRIDE_CONFIG_GPUSRD2		0x1440
+#define MC_TXN_OVERRIDE_CONFIG_SCEDMAR		0x14e8
+#define MC_TXN_OVERRIDE_CONFIG_GPUSWR2		0x1448
+#define MC_TXN_OVERRIDE_CONFIG_AONDMAW		0x14d0
+#define MC_TXN_OVERRIDE_CONFIG_APEDMAW		0x1500
+#define MC_TXN_OVERRIDE_CONFIG_AONW		0x14c0
+#define MC_TXN_OVERRIDE_CONFIG_HOST1XDMAR	0x10b0
+#define MC_TXN_OVERRIDE_CONFIG_ETRR		0x1420
+#define MC_TXN_OVERRIDE_CONFIG_SESWR		0x1408
+#define MC_TXN_OVERRIDE_CONFIG_NVJPGSRD		0x13f0
+#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD		0x13c0
+#define MC_TXN_OVERRIDE_CONFIG_TSECSRDB		0x1430
+#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAW		0x14b0
+#define MC_TXN_OVERRIDE_CONFIG_APER		0x13d0
+#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD1	0x1518
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTR	0x1250
+#define MC_TXN_OVERRIDE_CONFIG_ISPWA		0x1230
+#define MC_TXN_OVERRIDE_CONFIG_SESRD		0x1400
+#define MC_TXN_OVERRIDE_CONFIG_SCER		0x14d8
+#define MC_TXN_OVERRIDE_CONFIG_AONR		0x14b8
+#define MC_TXN_OVERRIDE_CONFIG_MPCORER		0x1138
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCWA		0x1320
+#define MC_TXN_OVERRIDE_CONFIG_HDAW		0x11a8
+#define MC_TXN_OVERRIDE_CONFIG_NVDECSWR		0x13c8
+#define MC_TXN_OVERRIDE_CONFIG_UFSHCW		0x1488
+#define MC_TXN_OVERRIDE_CONFIG_AONDMAR		0x14c8
+#define MC_TXN_OVERRIDE_CONFIG_SATAW		0x11e8
+#define MC_TXN_OVERRIDE_CONFIG_ETRW		0x1428
+#define MC_TXN_OVERRIDE_CONFIG_VICSWR		0x1368
+#define MC_TXN_OVERRIDE_CONFIG_NVENCSWR		0x1158
+#define MC_TXN_OVERRIDE_CONFIG_AFIR		0x1070
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAB		0x1338
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCRA		0x1300
+#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR1	0x1508
+#define MC_TXN_OVERRIDE_CONFIG_ISPWB		0x1238
+#define MC_TXN_OVERRIDE_CONFIG_BPMPR		0x1498
+#define MC_TXN_OVERRIDE_CONFIG_APEW		0x13d8
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCR		0x1310
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVW	0x1268
+#define MC_TXN_OVERRIDE_CONFIG_TSECSRD		0x12a0
+#define MC_TXN_OVERRIDE_CONFIG_AFIW		0x1188
+#define MC_TXN_OVERRIDE_CONFIG_SCEW		0x14e0
+
+/*******************************************************************************
+ * Non-SO_DEV transactions override values for CGID_TAG bitfield for the
+ * MC_TXN_OVERRIDE_CONFIG_{module} registers
+ ******************************************************************************/
+#define MC_TXN_OVERRIDE_CGID_TAG_DEFAULT	0
+#define MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID	1
+#define MC_TXN_OVERRIDE_CGID_TAG_ZERO		2
+#define MC_TXN_OVERRIDE_CGID_TAG_ADR		3
+#define MC_TXN_OVERRIDE_CGID_TAG_MASK		3
+
+/*******************************************************************************
+ * Structure to hold the transaction override settings to use to override
+ * client inputs
+ ******************************************************************************/
+typedef struct mc_txn_override_cfg {
+	uint32_t offset;
+	uint8_t cgid_tag;
+} mc_txn_override_cfg_t;
+
+#define mc_make_txn_override_cfg(off, val) \
+	{ \
+		.offset = MC_TXN_OVERRIDE_CONFIG_ ## off, \
+		.cgid_tag = MC_TXN_OVERRIDE_ ## val \
+	}
+
+/*******************************************************************************
+ * Structure to hold the Stream ID to use to override client inputs
+ ******************************************************************************/
+typedef struct mc_streamid_override_cfg {
+	uint32_t offset;
+	uint8_t stream_id;
+} mc_streamid_override_cfg_t;
+
+/*******************************************************************************
+ * Structure to hold the Stream ID Security Configuration settings
+ ******************************************************************************/
+typedef struct mc_streamid_security_cfg {
+	char *name;
+	uint32_t offset;
+	int override_enable;
+	int override_client_inputs;
+	int override_client_ns_flag;
+} mc_streamid_security_cfg_t;
+
+#define OVERRIDE_DISABLE			1
+#define OVERRIDE_ENABLE				0
+#define CLIENT_FLAG_SECURE			0
+#define CLIENT_FLAG_NON_SECURE			1
+#define CLIENT_INPUTS_OVERRIDE			1
+#define CLIENT_INPUTS_NO_OVERRIDE		0
+
+#define mc_make_sec_cfg(off, ns, ovrrd, access) \
+		{ \
+			.name = # off, \
+			.offset = MC_STREAMID_SECURITY_CFG_ ## off, \
+			.override_client_ns_flag = CLIENT_FLAG_ ## ns, \
+			.override_client_inputs = CLIENT_INPUTS_ ## ovrrd, \
+			.override_enable = OVERRIDE_ ## access \
+		}
+
+/*******************************************************************************
+ * 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
+
+/*******************************************************************************
+ * TZRAM carveout configuration registers
+ ******************************************************************************/
+#define MC_TZRAM_BASE				0x1850
+#define MC_TZRAM_END				0x1854
+#define MC_TZRAM_HI_ADDR_BITS			0x1588
+ #define TZRAM_ADDR_HI_BITS_MASK		0x3
+ #define TZRAM_END_HI_BITS_SHIFT		8
+#define MC_TZRAM_REG_CTRL			0x185c
+ #define DISABLE_TZRAM_ACCESS			1
+
+static inline uint32_t tegra_mc_read_32(uint32_t off)
+{
+	return mmio_read_32(TEGRA_MC_BASE + off);
+}
+
+static inline void tegra_mc_write_32(uint32_t off, uint32_t val)
+{
+	mmio_write_32(TEGRA_MC_BASE + off, val);
+}
+
+static inline uint32_t tegra_mc_streamid_read_32(uint32_t off)
+{
+	return mmio_read_32(TEGRA_MC_STREAMID_BASE + off);
+}
+
+static inline void tegra_mc_streamid_write_32(uint32_t off, uint32_t val)
+{
+	mmio_write_32(TEGRA_MC_STREAMID_BASE + off, val);
+}
+
+#endif /* __MEMCTRLV2_H__ */
diff --git a/plat/nvidia/tegra/include/drivers/smmu.h b/plat/nvidia/tegra/include/drivers/smmu.h
new file mode 100644
index 0000000..bb08a55
--- /dev/null
+++ b/plat/nvidia/tegra/include/drivers/smmu.h
@@ -0,0 +1,632 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __SMMU_H
+#define __SMMU_H
+
+#include <mmio.h>
+#include <tegra_def.h>
+
+/*******************************************************************************
+ * SMMU Register constants
+ ******************************************************************************/
+#define SMMU_CBn_SCTLR				(0x0)
+#define SMMU_CBn_SCTLR_STAGE2			(0x0)
+#define SMMU_CBn_ACTLR				(0x4)
+#define SMMU_CBn_RESUME				(0x8)
+#define SMMU_CBn_TCR2				(0x10)
+#define SMMU_CBn_TTBR0_LO			(0x20)
+#define SMMU_CBn_TTBR0_HI			(0x24)
+#define SMMU_CBn_TTBR1_LO			(0x28)
+#define SMMU_CBn_TTBR1_HI			(0x2c)
+#define SMMU_CBn_TCR_LPAE			(0x30)
+#define SMMU_CBn_TCR				(0x30)
+#define SMMU_CBn_TCR_EAE_1			(0x30)
+#define SMMU_CBn_TCR				(0x30)
+#define SMMU_CBn_CONTEXTIDR			(0x34)
+#define SMMU_CBn_CONTEXTIDR_EAE_1		(0x34)
+#define SMMU_CBn_PRRR_MAIR0			(0x38)
+#define SMMU_CBn_NMRR_MAIR1			(0x3c)
+#define SMMU_CBn_SMMU_CBn_PAR			(0x50)
+#define SMMU_CBn_SMMU_CBn_PAR0			(0x50)
+#define SMMU_CBn_SMMU_CBn_PAR1			(0x54)
+/*      SMMU_CBn_SMMU_CBn_PAR0_Fault		(0x50) */
+/*      SMMU_CBn_SMMU_CBn_PAR0_Fault		(0x54) */
+#define SMMU_CBn_FSR				(0x58)
+#define SMMU_CBn_FSRRESTORE			(0x5c)
+#define SMMU_CBn_FAR_LO				(0x60)
+#define SMMU_CBn_FAR_HI				(0x64)
+#define SMMU_CBn_FSYNR0				(0x68)
+#define SMMU_CBn_IPAFAR_LO			(0x70)
+#define SMMU_CBn_IPAFAR_HI			(0x74)
+#define SMMU_CBn_TLBIVA_LO			(0x600)
+#define SMMU_CBn_TLBIVA_HI			(0x604)
+#define SMMU_CBn_TLBIVA_AARCH_32		(0x600)
+#define SMMU_CBn_TLBIVAA_LO			(0x608)
+#define SMMU_CBn_TLBIVAA_HI			(0x60c)
+#define SMMU_CBn_TLBIVAA_AARCH_32		(0x608)
+#define SMMU_CBn_TLBIASID			(0x610)
+#define SMMU_CBn_TLBIALL			(0x618)
+#define SMMU_CBn_TLBIVAL_LO			(0x620)
+#define SMMU_CBn_TLBIVAL_HI			(0x624)
+#define SMMU_CBn_TLBIVAL_AARCH_32		(0x618)
+#define SMMU_CBn_TLBIVAAL_LO			(0x628)
+#define SMMU_CBn_TLBIVAAL_HI			(0x62c)
+#define SMMU_CBn_TLBIVAAL_AARCH_32		(0x628)
+#define SMMU_CBn_TLBIIPAS2_LO			(0x630)
+#define SMMU_CBn_TLBIIPAS2_HI			(0x634)
+#define SMMU_CBn_TLBIIPAS2L_LO			(0x638)
+#define SMMU_CBn_TLBIIPAS2L_HI			(0x63c)
+#define SMMU_CBn_TLBSYNC			(0x7f0)
+#define SMMU_CBn_TLBSTATUS			(0x7f4)
+#define SMMU_CBn_ATSR				(0x800)
+#define SMMU_CBn_PMEVCNTR0			(0xe00)
+#define SMMU_CBn_PMEVCNTR1			(0xe04)
+#define SMMU_CBn_PMEVCNTR2			(0xe08)
+#define SMMU_CBn_PMEVCNTR3			(0xe0c)
+#define SMMU_CBn_PMEVTYPER0			(0xe80)
+#define SMMU_CBn_PMEVTYPER1			(0xe84)
+#define SMMU_CBn_PMEVTYPER2			(0xe88)
+#define SMMU_CBn_PMEVTYPER3			(0xe8c)
+#define SMMU_CBn_PMCFGR				(0xf00)
+#define SMMU_CBn_PMCR				(0xf04)
+#define SMMU_CBn_PMCEID				(0xf20)
+#define SMMU_CBn_PMCNTENSE			(0xf40)
+#define SMMU_CBn_PMCNTENCLR			(0xf44)
+#define SMMU_CBn_PMCNTENSET			(0xf48)
+#define SMMU_CBn_PMINTENCLR			(0xf4c)
+#define SMMU_CBn_PMOVSCLR			(0xf50)
+#define SMMU_CBn_PMOVSSET			(0xf58)
+#define SMMU_CBn_PMAUTHSTATUS			(0xfb8)
+#define SMMU_GNSR0_CR0				(0x0)
+#define SMMU_GNSR0_CR2				(0x8)
+#define SMMU_GNSR0_ACR				(0x10)
+#define SMMU_GNSR0_IDR0				(0x20)
+#define SMMU_GNSR0_IDR1				(0x24)
+#define SMMU_GNSR0_IDR2				(0x28)
+#define SMMU_GNSR0_IDR7				(0x3c)
+#define SMMU_GNSR0_GFAR_LO			(0x40)
+#define SMMU_GNSR0_GFAR_HI			(0x44)
+#define SMMU_GNSR0_GFSR				(0x48)
+#define SMMU_GNSR0_GFSRRESTORE			(0x4c)
+#define SMMU_GNSR0_GFSYNR0			(0x50)
+#define SMMU_GNSR0_GFSYNR1			(0x54)
+#define SMMU_GNSR0_GFSYNR1_v2			(0x54)
+#define SMMU_GNSR0_TLBIVMID			(0x64)
+#define SMMU_GNSR0_TLBIALLNSNH			(0x68)
+#define SMMU_GNSR0_TLBIALLH			(0x6c)
+#define SMMU_GNSR0_TLBGSYNC			(0x70)
+#define SMMU_GNSR0_TLBGSTATUS			(0x74)
+#define SMMU_GNSR0_TLBIVAH_LO			(0x78)
+#define SMMU_GNSR0_TLBIVALH64_LO		(0xb0)
+#define SMMU_GNSR0_TLBIVALH64_HI		(0xb4)
+#define SMMU_GNSR0_TLBIVMIDS1			(0xb8)
+#define SMMU_GNSR0_TLBIVAH64_LO			(0xc0)
+#define SMMU_GNSR0_TLBIVAH64_HI			(0xc4)
+#define SMMU_GNSR0_SMR0				(0x800)
+#define SMMU_GNSR0_SMRn				(0x800)
+#define SMMU_GNSR0_SMR1				(0x804)
+#define SMMU_GNSR0_SMR2				(0x808)
+#define SMMU_GNSR0_SMR3				(0x80c)
+#define SMMU_GNSR0_SMR4				(0x810)
+#define SMMU_GNSR0_SMR5				(0x814)
+#define SMMU_GNSR0_SMR6				(0x818)
+#define SMMU_GNSR0_SMR7				(0x81c)
+#define SMMU_GNSR0_SMR8				(0x820)
+#define SMMU_GNSR0_SMR9				(0x824)
+#define SMMU_GNSR0_SMR10			(0x828)
+#define SMMU_GNSR0_SMR11			(0x82c)
+#define SMMU_GNSR0_SMR12			(0x830)
+#define SMMU_GNSR0_SMR13			(0x834)
+#define SMMU_GNSR0_SMR14			(0x838)
+#define SMMU_GNSR0_SMR15			(0x83c)
+#define SMMU_GNSR0_SMR16			(0x840)
+#define SMMU_GNSR0_SMR17			(0x844)
+#define SMMU_GNSR0_SMR18			(0x848)
+#define SMMU_GNSR0_SMR19			(0x84c)
+#define SMMU_GNSR0_SMR20			(0x850)
+#define SMMU_GNSR0_SMR21			(0x854)
+#define SMMU_GNSR0_SMR22			(0x858)
+#define SMMU_GNSR0_SMR23			(0x85c)
+#define SMMU_GNSR0_SMR24			(0x860)
+#define SMMU_GNSR0_SMR25			(0x864)
+#define SMMU_GNSR0_SMR26			(0x868)
+#define SMMU_GNSR0_SMR27			(0x86c)
+#define SMMU_GNSR0_SMR28			(0x870)
+#define SMMU_GNSR0_SMR29			(0x874)
+#define SMMU_GNSR0_SMR30			(0x878)
+#define SMMU_GNSR0_SMR31			(0x87c)
+#define SMMU_GNSR0_SMR32			(0x880)
+#define SMMU_GNSR0_SMR33			(0x884)
+#define SMMU_GNSR0_SMR34			(0x888)
+#define SMMU_GNSR0_SMR35			(0x88c)
+#define SMMU_GNSR0_SMR36			(0x890)
+#define SMMU_GNSR0_SMR37			(0x894)
+#define SMMU_GNSR0_SMR38			(0x898)
+#define SMMU_GNSR0_SMR39			(0x89c)
+#define SMMU_GNSR0_SMR40			(0x8a0)
+#define SMMU_GNSR0_SMR41			(0x8a4)
+#define SMMU_GNSR0_SMR42			(0x8a8)
+#define SMMU_GNSR0_SMR43			(0x8ac)
+#define SMMU_GNSR0_SMR44			(0x8b0)
+#define SMMU_GNSR0_SMR45			(0x8b4)
+#define SMMU_GNSR0_SMR46			(0x8b8)
+#define SMMU_GNSR0_SMR47			(0x8bc)
+#define SMMU_GNSR0_SMR48			(0x8c0)
+#define SMMU_GNSR0_SMR49			(0x8c4)
+#define SMMU_GNSR0_SMR50			(0x8c8)
+#define SMMU_GNSR0_SMR51			(0x8cc)
+#define SMMU_GNSR0_SMR52			(0x8d0)
+#define SMMU_GNSR0_SMR53			(0x8d4)
+#define SMMU_GNSR0_SMR54			(0x8d8)
+#define SMMU_GNSR0_SMR55			(0x8dc)
+#define SMMU_GNSR0_SMR56			(0x8e0)
+#define SMMU_GNSR0_SMR57			(0x8e4)
+#define SMMU_GNSR0_SMR58			(0x8e8)
+#define SMMU_GNSR0_SMR59			(0x8ec)
+#define SMMU_GNSR0_SMR60			(0x8f0)
+#define SMMU_GNSR0_SMR61			(0x8f4)
+#define SMMU_GNSR0_SMR62			(0x8f8)
+#define SMMU_GNSR0_SMR63			(0x8fc)
+#define SMMU_GNSR0_SMR64			(0x900)
+#define SMMU_GNSR0_SMR65			(0x904)
+#define SMMU_GNSR0_SMR66			(0x908)
+#define SMMU_GNSR0_SMR67			(0x90c)
+#define SMMU_GNSR0_SMR68			(0x910)
+#define SMMU_GNSR0_SMR69			(0x914)
+#define SMMU_GNSR0_SMR70			(0x918)
+#define SMMU_GNSR0_SMR71			(0x91c)
+#define SMMU_GNSR0_SMR72			(0x920)
+#define SMMU_GNSR0_SMR73			(0x924)
+#define SMMU_GNSR0_SMR74			(0x928)
+#define SMMU_GNSR0_SMR75			(0x92c)
+#define SMMU_GNSR0_SMR76			(0x930)
+#define SMMU_GNSR0_SMR77			(0x934)
+#define SMMU_GNSR0_SMR78			(0x938)
+#define SMMU_GNSR0_SMR79			(0x93c)
+#define SMMU_GNSR0_SMR80			(0x940)
+#define SMMU_GNSR0_SMR81			(0x944)
+#define SMMU_GNSR0_SMR82			(0x948)
+#define SMMU_GNSR0_SMR83			(0x94c)
+#define SMMU_GNSR0_SMR84			(0x950)
+#define SMMU_GNSR0_SMR85			(0x954)
+#define SMMU_GNSR0_SMR86			(0x958)
+#define SMMU_GNSR0_SMR87			(0x95c)
+#define SMMU_GNSR0_SMR88			(0x960)
+#define SMMU_GNSR0_SMR89			(0x964)
+#define SMMU_GNSR0_SMR90			(0x968)
+#define SMMU_GNSR0_SMR91			(0x96c)
+#define SMMU_GNSR0_SMR92			(0x970)
+#define SMMU_GNSR0_SMR93			(0x974)
+#define SMMU_GNSR0_SMR94			(0x978)
+#define SMMU_GNSR0_SMR95			(0x97c)
+#define SMMU_GNSR0_SMR96			(0x980)
+#define SMMU_GNSR0_SMR97			(0x984)
+#define SMMU_GNSR0_SMR98			(0x988)
+#define SMMU_GNSR0_SMR99			(0x98c)
+#define SMMU_GNSR0_SMR100			(0x990)
+#define SMMU_GNSR0_SMR101			(0x994)
+#define SMMU_GNSR0_SMR102			(0x998)
+#define SMMU_GNSR0_SMR103			(0x99c)
+#define SMMU_GNSR0_SMR104			(0x9a0)
+#define SMMU_GNSR0_SMR105			(0x9a4)
+#define SMMU_GNSR0_SMR106			(0x9a8)
+#define SMMU_GNSR0_SMR107			(0x9ac)
+#define SMMU_GNSR0_SMR108			(0x9b0)
+#define SMMU_GNSR0_SMR109			(0x9b4)
+#define SMMU_GNSR0_SMR110			(0x9b8)
+#define SMMU_GNSR0_SMR111			(0x9bc)
+#define SMMU_GNSR0_SMR112			(0x9c0)
+#define SMMU_GNSR0_SMR113			(0x9c4)
+#define SMMU_GNSR0_SMR114			(0x9c8)
+#define SMMU_GNSR0_SMR115			(0x9cc)
+#define SMMU_GNSR0_SMR116			(0x9d0)
+#define SMMU_GNSR0_SMR117			(0x9d4)
+#define SMMU_GNSR0_SMR118			(0x9d8)
+#define SMMU_GNSR0_SMR119			(0x9dc)
+#define SMMU_GNSR0_SMR120			(0x9e0)
+#define SMMU_GNSR0_SMR121			(0x9e4)
+#define SMMU_GNSR0_SMR122			(0x9e8)
+#define SMMU_GNSR0_SMR123			(0x9ec)
+#define SMMU_GNSR0_SMR124			(0x9f0)
+#define SMMU_GNSR0_SMR125			(0x9f4)
+#define SMMU_GNSR0_SMR126			(0x9f8)
+#define SMMU_GNSR0_SMR127			(0x9fc)
+#define SMMU_GNSR0_S2CR0			(0xc00)
+#define SMMU_GNSR0_S2CRn			(0xc00)
+#define SMMU_GNSR0_S2CRn			(0xc00)
+#define SMMU_GNSR0_S2CR1			(0xc04)
+#define SMMU_GNSR0_S2CR2			(0xc08)
+#define SMMU_GNSR0_S2CR3			(0xc0c)
+#define SMMU_GNSR0_S2CR4			(0xc10)
+#define SMMU_GNSR0_S2CR5			(0xc14)
+#define SMMU_GNSR0_S2CR6			(0xc18)
+#define SMMU_GNSR0_S2CR7			(0xc1c)
+#define SMMU_GNSR0_S2CR8			(0xc20)
+#define SMMU_GNSR0_S2CR9			(0xc24)
+#define SMMU_GNSR0_S2CR10			(0xc28)
+#define SMMU_GNSR0_S2CR11			(0xc2c)
+#define SMMU_GNSR0_S2CR12			(0xc30)
+#define SMMU_GNSR0_S2CR13			(0xc34)
+#define SMMU_GNSR0_S2CR14			(0xc38)
+#define SMMU_GNSR0_S2CR15			(0xc3c)
+#define SMMU_GNSR0_S2CR16			(0xc40)
+#define SMMU_GNSR0_S2CR17			(0xc44)
+#define SMMU_GNSR0_S2CR18			(0xc48)
+#define SMMU_GNSR0_S2CR19			(0xc4c)
+#define SMMU_GNSR0_S2CR20			(0xc50)
+#define SMMU_GNSR0_S2CR21			(0xc54)
+#define SMMU_GNSR0_S2CR22			(0xc58)
+#define SMMU_GNSR0_S2CR23			(0xc5c)
+#define SMMU_GNSR0_S2CR24			(0xc60)
+#define SMMU_GNSR0_S2CR25			(0xc64)
+#define SMMU_GNSR0_S2CR26			(0xc68)
+#define SMMU_GNSR0_S2CR27			(0xc6c)
+#define SMMU_GNSR0_S2CR28			(0xc70)
+#define SMMU_GNSR0_S2CR29			(0xc74)
+#define SMMU_GNSR0_S2CR30			(0xc78)
+#define SMMU_GNSR0_S2CR31			(0xc7c)
+#define SMMU_GNSR0_S2CR32			(0xc80)
+#define SMMU_GNSR0_S2CR33			(0xc84)
+#define SMMU_GNSR0_S2CR34			(0xc88)
+#define SMMU_GNSR0_S2CR35			(0xc8c)
+#define SMMU_GNSR0_S2CR36			(0xc90)
+#define SMMU_GNSR0_S2CR37			(0xc94)
+#define SMMU_GNSR0_S2CR38			(0xc98)
+#define SMMU_GNSR0_S2CR39			(0xc9c)
+#define SMMU_GNSR0_S2CR40			(0xca0)
+#define SMMU_GNSR0_S2CR41			(0xca4)
+#define SMMU_GNSR0_S2CR42			(0xca8)
+#define SMMU_GNSR0_S2CR43			(0xcac)
+#define SMMU_GNSR0_S2CR44			(0xcb0)
+#define SMMU_GNSR0_S2CR45			(0xcb4)
+#define SMMU_GNSR0_S2CR46			(0xcb8)
+#define SMMU_GNSR0_S2CR47			(0xcbc)
+#define SMMU_GNSR0_S2CR48			(0xcc0)
+#define SMMU_GNSR0_S2CR49			(0xcc4)
+#define SMMU_GNSR0_S2CR50			(0xcc8)
+#define SMMU_GNSR0_S2CR51			(0xccc)
+#define SMMU_GNSR0_S2CR52			(0xcd0)
+#define SMMU_GNSR0_S2CR53			(0xcd4)
+#define SMMU_GNSR0_S2CR54			(0xcd8)
+#define SMMU_GNSR0_S2CR55			(0xcdc)
+#define SMMU_GNSR0_S2CR56			(0xce0)
+#define SMMU_GNSR0_S2CR57			(0xce4)
+#define SMMU_GNSR0_S2CR58			(0xce8)
+#define SMMU_GNSR0_S2CR59			(0xcec)
+#define SMMU_GNSR0_S2CR60			(0xcf0)
+#define SMMU_GNSR0_S2CR61			(0xcf4)
+#define SMMU_GNSR0_S2CR62			(0xcf8)
+#define SMMU_GNSR0_S2CR63			(0xcfc)
+#define SMMU_GNSR0_S2CR64			(0xd00)
+#define SMMU_GNSR0_S2CR65			(0xd04)
+#define SMMU_GNSR0_S2CR66			(0xd08)
+#define SMMU_GNSR0_S2CR67			(0xd0c)
+#define SMMU_GNSR0_S2CR68			(0xd10)
+#define SMMU_GNSR0_S2CR69			(0xd14)
+#define SMMU_GNSR0_S2CR70			(0xd18)
+#define SMMU_GNSR0_S2CR71			(0xd1c)
+#define SMMU_GNSR0_S2CR72			(0xd20)
+#define SMMU_GNSR0_S2CR73			(0xd24)
+#define SMMU_GNSR0_S2CR74			(0xd28)
+#define SMMU_GNSR0_S2CR75			(0xd2c)
+#define SMMU_GNSR0_S2CR76			(0xd30)
+#define SMMU_GNSR0_S2CR77			(0xd34)
+#define SMMU_GNSR0_S2CR78			(0xd38)
+#define SMMU_GNSR0_S2CR79			(0xd3c)
+#define SMMU_GNSR0_S2CR80			(0xd40)
+#define SMMU_GNSR0_S2CR81			(0xd44)
+#define SMMU_GNSR0_S2CR82			(0xd48)
+#define SMMU_GNSR0_S2CR83			(0xd4c)
+#define SMMU_GNSR0_S2CR84			(0xd50)
+#define SMMU_GNSR0_S2CR85			(0xd54)
+#define SMMU_GNSR0_S2CR86			(0xd58)
+#define SMMU_GNSR0_S2CR87			(0xd5c)
+#define SMMU_GNSR0_S2CR88			(0xd60)
+#define SMMU_GNSR0_S2CR89			(0xd64)
+#define SMMU_GNSR0_S2CR90			(0xd68)
+#define SMMU_GNSR0_S2CR91			(0xd6c)
+#define SMMU_GNSR0_S2CR92			(0xd70)
+#define SMMU_GNSR0_S2CR93			(0xd74)
+#define SMMU_GNSR0_S2CR94			(0xd78)
+#define SMMU_GNSR0_S2CR95			(0xd7c)
+#define SMMU_GNSR0_S2CR96			(0xd80)
+#define SMMU_GNSR0_S2CR97			(0xd84)
+#define SMMU_GNSR0_S2CR98			(0xd88)
+#define SMMU_GNSR0_S2CR99			(0xd8c)
+#define SMMU_GNSR0_S2CR100			(0xd90)
+#define SMMU_GNSR0_S2CR101			(0xd94)
+#define SMMU_GNSR0_S2CR102			(0xd98)
+#define SMMU_GNSR0_S2CR103			(0xd9c)
+#define SMMU_GNSR0_S2CR104			(0xda0)
+#define SMMU_GNSR0_S2CR105			(0xda4)
+#define SMMU_GNSR0_S2CR106			(0xda8)
+#define SMMU_GNSR0_S2CR107			(0xdac)
+#define SMMU_GNSR0_S2CR108			(0xdb0)
+#define SMMU_GNSR0_S2CR109			(0xdb4)
+#define SMMU_GNSR0_S2CR110			(0xdb8)
+#define SMMU_GNSR0_S2CR111			(0xdbc)
+#define SMMU_GNSR0_S2CR112			(0xdc0)
+#define SMMU_GNSR0_S2CR113			(0xdc4)
+#define SMMU_GNSR0_S2CR114			(0xdc8)
+#define SMMU_GNSR0_S2CR115			(0xdcc)
+#define SMMU_GNSR0_S2CR116			(0xdd0)
+#define SMMU_GNSR0_S2CR117			(0xdd4)
+#define SMMU_GNSR0_S2CR118			(0xdd8)
+#define SMMU_GNSR0_S2CR119			(0xddc)
+#define SMMU_GNSR0_S2CR120			(0xde0)
+#define SMMU_GNSR0_S2CR121			(0xde4)
+#define SMMU_GNSR0_S2CR122			(0xde8)
+#define SMMU_GNSR0_S2CR123			(0xdec)
+#define SMMU_GNSR0_S2CR124			(0xdf0)
+#define SMMU_GNSR0_S2CR125			(0xdf4)
+#define SMMU_GNSR0_S2CR126			(0xdf8)
+#define SMMU_GNSR0_S2CR127			(0xdfc)
+#define SMMU_GNSR0_PIDR0			(0xfe0)
+#define SMMU_GNSR0_PIDR1			(0xfe4)
+#define SMMU_GNSR0_PIDR2			(0xfe8)
+#define SMMU_GNSR0_PIDR3			(0xfec)
+#define SMMU_GNSR0_PIDR4			(0xfd0)
+#define SMMU_GNSR0_PIDR5			(0xfd4)
+#define SMMU_GNSR0_PIDR6			(0xfd8)
+#define SMMU_GNSR0_PIDR7			(0xfdc)
+#define SMMU_GNSR0_CIDR0			(0xff0)
+#define SMMU_GNSR0_CIDR1			(0xff4)
+#define SMMU_GNSR0_CIDR2			(0xff8)
+#define SMMU_GNSR0_CIDR3			(0xffc)
+#define SMMU_GNSR1_CBAR0			(0x0)
+#define SMMU_GNSR1_CBARn			(0x0)
+#define SMMU_GNSR1_CBFRSYNRA0			(0x400)
+#define SMMU_GNSR1_CBA2R0			(0x800)
+#define SMMU_GNSR1_CBAR1			(0x4)
+#define SMMU_GNSR1_CBFRSYNRA1			(0x404)
+#define SMMU_GNSR1_CBA2R1			(0x804)
+#define SMMU_GNSR1_CBAR2			(0x8)
+#define SMMU_GNSR1_CBFRSYNRA2			(0x408)
+#define SMMU_GNSR1_CBA2R2			(0x808)
+#define SMMU_GNSR1_CBAR3			(0xc)
+#define SMMU_GNSR1_CBFRSYNRA3			(0x40c)
+#define SMMU_GNSR1_CBA2R3			(0x80c)
+#define SMMU_GNSR1_CBAR4			(0x10)
+#define SMMU_GNSR1_CBFRSYNRA4			(0x410)
+#define SMMU_GNSR1_CBA2R4			(0x810)
+#define SMMU_GNSR1_CBAR5			(0x14)
+#define SMMU_GNSR1_CBFRSYNRA5			(0x414)
+#define SMMU_GNSR1_CBA2R5			(0x814)
+#define SMMU_GNSR1_CBAR6			(0x18)
+#define SMMU_GNSR1_CBFRSYNRA6			(0x418)
+#define SMMU_GNSR1_CBA2R6			(0x818)
+#define SMMU_GNSR1_CBAR7			(0x1c)
+#define SMMU_GNSR1_CBFRSYNRA7			(0x41c)
+#define SMMU_GNSR1_CBA2R7			(0x81c)
+#define SMMU_GNSR1_CBAR8			(0x20)
+#define SMMU_GNSR1_CBFRSYNRA8			(0x420)
+#define SMMU_GNSR1_CBA2R8			(0x820)
+#define SMMU_GNSR1_CBAR9			(0x24)
+#define SMMU_GNSR1_CBFRSYNRA9			(0x424)
+#define SMMU_GNSR1_CBA2R9			(0x824)
+#define SMMU_GNSR1_CBAR10			(0x28)
+#define SMMU_GNSR1_CBFRSYNRA10			(0x428)
+#define SMMU_GNSR1_CBA2R10			(0x828)
+#define SMMU_GNSR1_CBAR11			(0x2c)
+#define SMMU_GNSR1_CBFRSYNRA11			(0x42c)
+#define SMMU_GNSR1_CBA2R11			(0x82c)
+#define SMMU_GNSR1_CBAR12			(0x30)
+#define SMMU_GNSR1_CBFRSYNRA12			(0x430)
+#define SMMU_GNSR1_CBA2R12			(0x830)
+#define SMMU_GNSR1_CBAR13			(0x34)
+#define SMMU_GNSR1_CBFRSYNRA13			(0x434)
+#define SMMU_GNSR1_CBA2R13			(0x834)
+#define SMMU_GNSR1_CBAR14			(0x38)
+#define SMMU_GNSR1_CBFRSYNRA14			(0x438)
+#define SMMU_GNSR1_CBA2R14			(0x838)
+#define SMMU_GNSR1_CBAR15			(0x3c)
+#define SMMU_GNSR1_CBFRSYNRA15			(0x43c)
+#define SMMU_GNSR1_CBA2R15			(0x83c)
+#define SMMU_GNSR1_CBAR16			(0x40)
+#define SMMU_GNSR1_CBFRSYNRA16			(0x440)
+#define SMMU_GNSR1_CBA2R16			(0x840)
+#define SMMU_GNSR1_CBAR17			(0x44)
+#define SMMU_GNSR1_CBFRSYNRA17			(0x444)
+#define SMMU_GNSR1_CBA2R17			(0x844)
+#define SMMU_GNSR1_CBAR18			(0x48)
+#define SMMU_GNSR1_CBFRSYNRA18			(0x448)
+#define SMMU_GNSR1_CBA2R18			(0x848)
+#define SMMU_GNSR1_CBAR19			(0x4c)
+#define SMMU_GNSR1_CBFRSYNRA19			(0x44c)
+#define SMMU_GNSR1_CBA2R19			(0x84c)
+#define SMMU_GNSR1_CBAR20			(0x50)
+#define SMMU_GNSR1_CBFRSYNRA20			(0x450)
+#define SMMU_GNSR1_CBA2R20			(0x850)
+#define SMMU_GNSR1_CBAR21			(0x54)
+#define SMMU_GNSR1_CBFRSYNRA21			(0x454)
+#define SMMU_GNSR1_CBA2R21			(0x854)
+#define SMMU_GNSR1_CBAR22			(0x58)
+#define SMMU_GNSR1_CBFRSYNRA22			(0x458)
+#define SMMU_GNSR1_CBA2R22			(0x858)
+#define SMMU_GNSR1_CBAR23			(0x5c)
+#define SMMU_GNSR1_CBFRSYNRA23			(0x45c)
+#define SMMU_GNSR1_CBA2R23			(0x85c)
+#define SMMU_GNSR1_CBAR24			(0x60)
+#define SMMU_GNSR1_CBFRSYNRA24			(0x460)
+#define SMMU_GNSR1_CBA2R24			(0x860)
+#define SMMU_GNSR1_CBAR25			(0x64)
+#define SMMU_GNSR1_CBFRSYNRA25			(0x464)
+#define SMMU_GNSR1_CBA2R25			(0x864)
+#define SMMU_GNSR1_CBAR26			(0x68)
+#define SMMU_GNSR1_CBFRSYNRA26			(0x468)
+#define SMMU_GNSR1_CBA2R26			(0x868)
+#define SMMU_GNSR1_CBAR27			(0x6c)
+#define SMMU_GNSR1_CBFRSYNRA27			(0x46c)
+#define SMMU_GNSR1_CBA2R27			(0x86c)
+#define SMMU_GNSR1_CBAR28			(0x70)
+#define SMMU_GNSR1_CBFRSYNRA28			(0x470)
+#define SMMU_GNSR1_CBA2R28			(0x870)
+#define SMMU_GNSR1_CBAR29			(0x74)
+#define SMMU_GNSR1_CBFRSYNRA29			(0x474)
+#define SMMU_GNSR1_CBA2R29			(0x874)
+#define SMMU_GNSR1_CBAR30			(0x78)
+#define SMMU_GNSR1_CBFRSYNRA30			(0x478)
+#define SMMU_GNSR1_CBA2R30			(0x878)
+#define SMMU_GNSR1_CBAR31			(0x7c)
+#define SMMU_GNSR1_CBFRSYNRA31			(0x47c)
+#define SMMU_GNSR1_CBA2R31			(0x87c)
+#define SMMU_GNSR1_CBAR32			(0x80)
+#define SMMU_GNSR1_CBFRSYNRA32			(0x480)
+#define SMMU_GNSR1_CBA2R32			(0x880)
+#define SMMU_GNSR1_CBAR33			(0x84)
+#define SMMU_GNSR1_CBFRSYNRA33			(0x484)
+#define SMMU_GNSR1_CBA2R33			(0x884)
+#define SMMU_GNSR1_CBAR34			(0x88)
+#define SMMU_GNSR1_CBFRSYNRA34			(0x488)
+#define SMMU_GNSR1_CBA2R34			(0x888)
+#define SMMU_GNSR1_CBAR35			(0x8c)
+#define SMMU_GNSR1_CBFRSYNRA35			(0x48c)
+#define SMMU_GNSR1_CBA2R35			(0x88c)
+#define SMMU_GNSR1_CBAR36			(0x90)
+#define SMMU_GNSR1_CBFRSYNRA36			(0x490)
+#define SMMU_GNSR1_CBA2R36			(0x890)
+#define SMMU_GNSR1_CBAR37			(0x94)
+#define SMMU_GNSR1_CBFRSYNRA37			(0x494)
+#define SMMU_GNSR1_CBA2R37			(0x894)
+#define SMMU_GNSR1_CBAR38			(0x98)
+#define SMMU_GNSR1_CBFRSYNRA38			(0x498)
+#define SMMU_GNSR1_CBA2R38			(0x898)
+#define SMMU_GNSR1_CBAR39			(0x9c)
+#define SMMU_GNSR1_CBFRSYNRA39			(0x49c)
+#define SMMU_GNSR1_CBA2R39			(0x89c)
+#define SMMU_GNSR1_CBAR40			(0xa0)
+#define SMMU_GNSR1_CBFRSYNRA40			(0x4a0)
+#define SMMU_GNSR1_CBA2R40			(0x8a0)
+#define SMMU_GNSR1_CBAR41			(0xa4)
+#define SMMU_GNSR1_CBFRSYNRA41			(0x4a4)
+#define SMMU_GNSR1_CBA2R41			(0x8a4)
+#define SMMU_GNSR1_CBAR42			(0xa8)
+#define SMMU_GNSR1_CBFRSYNRA42			(0x4a8)
+#define SMMU_GNSR1_CBA2R42			(0x8a8)
+#define SMMU_GNSR1_CBAR43			(0xac)
+#define SMMU_GNSR1_CBFRSYNRA43			(0x4ac)
+#define SMMU_GNSR1_CBA2R43			(0x8ac)
+#define SMMU_GNSR1_CBAR44			(0xb0)
+#define SMMU_GNSR1_CBFRSYNRA44			(0x4b0)
+#define SMMU_GNSR1_CBA2R44			(0x8b0)
+#define SMMU_GNSR1_CBAR45			(0xb4)
+#define SMMU_GNSR1_CBFRSYNRA45			(0x4b4)
+#define SMMU_GNSR1_CBA2R45			(0x8b4)
+#define SMMU_GNSR1_CBAR46			(0xb8)
+#define SMMU_GNSR1_CBFRSYNRA46			(0x4b8)
+#define SMMU_GNSR1_CBA2R46			(0x8b8)
+#define SMMU_GNSR1_CBAR47			(0xbc)
+#define SMMU_GNSR1_CBFRSYNRA47			(0x4bc)
+#define SMMU_GNSR1_CBA2R47			(0x8bc)
+#define SMMU_GNSR1_CBAR48			(0xc0)
+#define SMMU_GNSR1_CBFRSYNRA48			(0x4c0)
+#define SMMU_GNSR1_CBA2R48			(0x8c0)
+#define SMMU_GNSR1_CBAR49			(0xc4)
+#define SMMU_GNSR1_CBFRSYNRA49			(0x4c4)
+#define SMMU_GNSR1_CBA2R49			(0x8c4)
+#define SMMU_GNSR1_CBAR50			(0xc8)
+#define SMMU_GNSR1_CBFRSYNRA50			(0x4c8)
+#define SMMU_GNSR1_CBA2R50			(0x8c8)
+#define SMMU_GNSR1_CBAR51			(0xcc)
+#define SMMU_GNSR1_CBFRSYNRA51			(0x4cc)
+#define SMMU_GNSR1_CBA2R51			(0x8cc)
+#define SMMU_GNSR1_CBAR52			(0xd0)
+#define SMMU_GNSR1_CBFRSYNRA52			(0x4d0)
+#define SMMU_GNSR1_CBA2R52			(0x8d0)
+#define SMMU_GNSR1_CBAR53			(0xd4)
+#define SMMU_GNSR1_CBFRSYNRA53			(0x4d4)
+#define SMMU_GNSR1_CBA2R53			(0x8d4)
+#define SMMU_GNSR1_CBAR54			(0xd8)
+#define SMMU_GNSR1_CBFRSYNRA54			(0x4d8)
+#define SMMU_GNSR1_CBA2R54			(0x8d8)
+#define SMMU_GNSR1_CBAR55			(0xdc)
+#define SMMU_GNSR1_CBFRSYNRA55			(0x4dc)
+#define SMMU_GNSR1_CBA2R55			(0x8dc)
+#define SMMU_GNSR1_CBAR56			(0xe0)
+#define SMMU_GNSR1_CBFRSYNRA56			(0x4e0)
+#define SMMU_GNSR1_CBA2R56			(0x8e0)
+#define SMMU_GNSR1_CBAR57			(0xe4)
+#define SMMU_GNSR1_CBFRSYNRA57			(0x4e4)
+#define SMMU_GNSR1_CBA2R57			(0x8e4)
+#define SMMU_GNSR1_CBAR58			(0xe8)
+#define SMMU_GNSR1_CBFRSYNRA58			(0x4e8)
+#define SMMU_GNSR1_CBA2R58			(0x8e8)
+#define SMMU_GNSR1_CBAR59			(0xec)
+#define SMMU_GNSR1_CBFRSYNRA59			(0x4ec)
+#define SMMU_GNSR1_CBA2R59			(0x8ec)
+#define SMMU_GNSR1_CBAR60			(0xf0)
+#define SMMU_GNSR1_CBFRSYNRA60			(0x4f0)
+#define SMMU_GNSR1_CBA2R60			(0x8f0)
+#define SMMU_GNSR1_CBAR61			(0xf4)
+#define SMMU_GNSR1_CBFRSYNRA61			(0x4f4)
+#define SMMU_GNSR1_CBA2R61			(0x8f4)
+#define SMMU_GNSR1_CBAR62			(0xf8)
+#define SMMU_GNSR1_CBFRSYNRA62			(0x4f8)
+#define SMMU_GNSR1_CBA2R62			(0x8f8)
+#define SMMU_GNSR1_CBAR63			(0xfc)
+#define SMMU_GNSR1_CBFRSYNRA63			(0x4fc)
+#define SMMU_GNSR1_CBA2R63			(0x8fc)
+
+/*******************************************************************************
+ * SMMU Global Secure Aux. Configuration Register
+ ******************************************************************************/
+#define SMMU_GSR0_SECURE_ACR			0x10
+#define SMMU_GSR0_PGSIZE_SHIFT			16
+#define SMMU_GSR0_PGSIZE_4K			(0 << SMMU_GSR0_PGSIZE_SHIFT)
+#define SMMU_GSR0_PGSIZE_64K			(1 << SMMU_GSR0_PGSIZE_SHIFT)
+
+/*******************************************************************************
+ * SMMU configuration constants
+ ******************************************************************************/
+#define ID1_PAGESIZE				(1 << 31)
+#define ID1_NUMPAGENDXB_SHIFT			28
+#define ID1_NUMPAGENDXB_MASK			7
+#define ID1_NUMS2CB_SHIFT			16
+#define ID1_NUMS2CB_MASK			0xff
+#define ID1_NUMCB_SHIFT				0
+#define ID1_NUMCB_MASK				0xff
+#define PGSHIFT					16
+#define CB_SIZE					0x800000
+
+static inline uint32_t tegra_smmu_read_32(uint32_t off)
+{
+	return mmio_read_32(TEGRA_SMMU_BASE + off);
+}
+
+static inline void tegra_smmu_write_32(uint32_t off, uint32_t val)
+{
+	mmio_write_32(TEGRA_SMMU_BASE + off, val);
+}
+
+void tegra_smmu_init(void);
+void tegra_smmu_save_context(void);
+
+#endif /*__SMMU_H */
diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h
new file mode 100644
index 0000000..f3fbb89
--- /dev/null
+++ b/plat/nvidia/tegra/include/t186/tegra_def.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __TEGRA_DEF_H__
+#define __TEGRA_DEF_H__
+
+#include <platform_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_TOP_WDT_IRQ		49
+#define TEGRA186_AON_WDT_IRQ		50
+
+#define TEGRA186_SEC_IRQ_TARGET_MASK	0xF3 /* 4 A57 - 2 Denver */
+
+/*******************************************************************************
+ * Tegra Miscellanous register constants
+ ******************************************************************************/
+#define TEGRA_MISC_BASE			0x00100000
+#define  HARDWARE_REVISION_OFFSET	0x4
+#define  HARDWARE_MINOR_REVISION_MASK	0xf0000
+#define  HARDWARE_MINOR_REVISION_SHIFT	0x10
+#define  HARDWARE_REVISION_A01		1
+#define  MISCREG_PFCFG			0x200C
+
+/*******************************************************************************
+ * Tegra Memory Controller constants
+ ******************************************************************************/
+#define TEGRA_MC_STREAMID_BASE		0x02C00000
+#define TEGRA_MC_BASE			0x02C10000
+
+/*******************************************************************************
+ * 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
+
+/*******************************************************************************
+ * 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 Clock and Reset Controller constants
+ ******************************************************************************/
+#define TEGRA_CAR_RESET_BASE		0x05000000
+
+/*******************************************************************************
+ * Tegra micro-seconds timer constants
+ ******************************************************************************/
+#define TEGRA_TMRUS_BASE		0x0C2E0000
+
+/*******************************************************************************
+ * Tegra Power Mgmt Controller constants
+ ******************************************************************************/
+#define TEGRA_PMC_BASE			0x0C360000
+
+/*******************************************************************************
+ * Tegra scratch registers constants
+ ******************************************************************************/
+#define TEGRA_SCRATCH_BASE		0x0C390000
+#define  SECURE_SCRATCH_RSV6		0x680
+#define  SECURE_SCRATCH_RSV11_LO	0x6A8
+#define  SECURE_SCRATCH_RSV11_HI	0x6AC
+
+/*******************************************************************************
+ * Tegra Memory Mapped Control Register Access Bus constants
+ ******************************************************************************/
+#define TEGRA_MMCRAB_BASE		0x0E000000
+
+/*******************************************************************************
+ * Tegra SMMU Controller constants
+ ******************************************************************************/
+#define TEGRA_SMMU_BASE			0x12000000
+
+/*******************************************************************************
+ * Tegra TZRAM constants
+ ******************************************************************************/
+#define TEGRA_TZRAM_BASE		0x30000000
+#define TEGRA_TZRAM_SIZE		0x50000
+
+#endif /* __TEGRA_DEF_H__ */
diff --git a/plat/nvidia/tegra/include/tegra_platform.h b/plat/nvidia/tegra/include/tegra_platform.h
index f9d7b60..a2813a8 100644
--- a/plat/nvidia/tegra/include/tegra_platform.h
+++ b/plat/nvidia/tegra/include/tegra_platform.h
@@ -34,6 +34,12 @@
 #include <sys/cdefs.h>
 
 /*
+ * Tegra chip major/minor version
+ */
+uint32_t tegra_get_chipid_major(void);
+uint32_t tegra_get_chipid_minor(void);
+
+/*
  * Tegra chip identifiers
  */
 uint8_t tegra_is_t132(void);
diff --git a/plat/nvidia/tegra/soc/t186/drivers/include/mce.h b/plat/nvidia/tegra/soc/t186/drivers/include/mce.h
new file mode 100644
index 0000000..7078b8b
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t186/drivers/include/mce.h
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MCE_H__
+#define __MCE_H__
+
+#include <mmio.h>
+#include <tegra_def.h>
+
+/*******************************************************************************
+ * MCE apertures used by the ARI interface
+ *
+ * Aperture 0 - Cpu0 (ARM Cortex A-57)
+ * Aperture 1 - Cpu1 (ARM Cortex A-57)
+ * Aperture 2 - Cpu2 (ARM Cortex A-57)
+ * Aperture 3 - Cpu3 (ARM Cortex A-57)
+ * Aperture 4 - Cpu4 (Denver15)
+ * Aperture 5 - Cpu5 (Denver15)
+ ******************************************************************************/
+#define MCE_ARI_APERTURE_0_OFFSET	0x0
+#define MCE_ARI_APERTURE_1_OFFSET	0x10000
+#define MCE_ARI_APERTURE_2_OFFSET	0x20000
+#define MCE_ARI_APERTURE_3_OFFSET	0x30000
+#define MCE_ARI_APERTURE_4_OFFSET	0x40000
+#define MCE_ARI_APERTURE_5_OFFSET	0x50000
+#define MCE_ARI_APERTURE_OFFSET_MAX	MCE_APERTURE_5_OFFSET
+
+/* number of apertures */
+#define MCE_ARI_APERTURES_MAX		6
+
+/* each ARI aperture is 64KB */
+#define MCE_ARI_APERTURE_SIZE		0x10000
+
+/*******************************************************************************
+ * CPU core ids - used by the MCE_ONLINE_CORE ARI
+ ******************************************************************************/
+typedef enum mce_core_id {
+	MCE_CORE_ID_DENVER_15_0,
+	MCE_CORE_ID_DENVER_15_1,
+	/* 2 and 3 are reserved */
+	MCE_CORE_ID_A57_0 = 4,
+	MCE_CORE_ID_A57_1,
+	MCE_CORE_ID_A57_2,
+	MCE_CORE_ID_A57_3,
+	MCE_CORE_ID_MAX
+} mce_core_id_t;
+
+#define MCE_CORE_ID_MASK			0x7
+
+/*******************************************************************************
+ * MCE commands
+ ******************************************************************************/
+typedef enum mce_cmd {
+	MCE_CMD_ENTER_CSTATE = 0,
+	MCE_CMD_UPDATE_CSTATE_INFO,
+	MCE_CMD_UPDATE_CROSSOVER_TIME,
+	MCE_CMD_READ_CSTATE_STATS,
+	MCE_CMD_WRITE_CSTATE_STATS,
+	MCE_CMD_IS_SC7_ALLOWED,
+	MCE_CMD_ONLINE_CORE,
+	MCE_CMD_CC3_CTRL,
+	MCE_CMD_ECHO_DATA,
+	MCE_CMD_READ_VERSIONS,
+	MCE_CMD_ENUM_FEATURES,
+	MCE_CMD_ROC_FLUSH_CACHE_TRBITS,
+	MCE_CMD_ENUM_READ_MCA,
+	MCE_CMD_ENUM_WRITE_MCA,
+	MCE_CMD_ROC_FLUSH_CACHE,
+	MCE_CMD_ROC_CLEAN_CACHE,
+	MCE_CMD_IS_CCX_ALLOWED = 0xFE,
+	MCE_CMD_MAX = 0xFF,
+} mce_cmd_t;
+
+#define MCE_CMD_MASK				0xFF
+
+/*******************************************************************************
+ * Macros to prepare CSTATE info request
+ ******************************************************************************/
+/* Description of the parameters for UPDATE_CSTATE_INFO request */
+#define CLUSTER_CSTATE_MASK			0x7
+#define CLUSTER_CSTATE_SHIFT			0
+#define CLUSTER_CSTATE_UPDATE_BIT		(1 << 7)
+#define CCPLEX_CSTATE_MASK			0x3
+#define CCPLEX_CSTATE_SHIFT			8
+#define CCPLEX_CSTATE_UPDATE_BIT		(1 << 15)
+#define SYSTEM_CSTATE_MASK			0xF
+#define SYSTEM_CSTATE_SHIFT			16
+#define SYSTEM_CSTATE_FORCE_UPDATE_SHIFT	22
+#define SYSTEM_CSTATE_FORCE_UPDATE_BIT		(1 << 22)
+#define SYSTEM_CSTATE_UPDATE_BIT		(1 << 23)
+#define CSTATE_WAKE_MASK_UPDATE_BIT		(1 << 31)
+#define CSTATE_WAKE_MASK_SHIFT			32
+#define CSTATE_WAKE_MASK_CLEAR			0xFFFFFFFF
+
+/*******************************************************************************
+ * Auto-CC3 control macros
+ ******************************************************************************/
+#define MCE_AUTO_CC3_FREQ_MASK			0x1FF
+#define MCE_AUTO_CC3_FREQ_SHIFT			0
+#define MCE_AUTO_CC3_VTG_MASK			0x7F
+#define MCE_AUTO_CC3_VTG_SHIFT			16
+#define MCE_AUTO_CC3_ENABLE_BIT			(1 << 31)
+
+/*******************************************************************************
+ * Macros for the 'IS_SC7_ALLOWED' command
+ ******************************************************************************/
+#define MCE_SC7_ALLOWED_MASK			0x7
+#define MCE_SC7_WAKE_TIME_SHIFT			32
+
+/*******************************************************************************
+ * Macros for 'read/write ctats' commands
+ ******************************************************************************/
+#define MCE_CSTATE_STATS_TYPE_SHIFT		32
+#define MCE_CSTATE_WRITE_DATA_LO_MASK		0xF
+
+/*******************************************************************************
+ * Macros for 'update crossover threshold' command
+ ******************************************************************************/
+#define MCE_CROSSOVER_THRESHOLD_TIME_SHIFT	32
+
+/*******************************************************************************
+ * Timeout value used to powerdown a core
+ ******************************************************************************/
+#define MCE_CORE_SLEEP_TIME_INFINITE		0xFFFFFFFF
+
+/*******************************************************************************
+ * MCA command struct
+ ******************************************************************************/
+typedef union mca_cmd {
+	struct command {
+		uint8_t cmd;
+		uint8_t idx;
+		uint8_t subidx;
+	} command;
+	struct input {
+		uint32_t low;
+		uint32_t high;
+	} input;
+	uint64_t data;
+} mca_cmd_t;
+
+/*******************************************************************************
+ * MCA argument struct
+ ******************************************************************************/
+typedef union mca_arg {
+	struct err {
+		uint64_t error:8;
+		uint64_t unused:48;
+		uint64_t finish:8;
+	} err;
+	struct arg {
+		uint32_t low;
+		uint32_t high;
+	} arg;
+	uint64_t data;
+} mca_arg_t;
+
+/*******************************************************************************
+ * Structure populated by arch specific code to export routines which perform
+ * common low level MCE functions
+ ******************************************************************************/
+typedef struct arch_mce_ops {
+	/*
+	 * This ARI request sets up the MCE to start execution on assertion
+	 * of STANDBYWFI, update the core power state and expected wake time,
+	 * then determine the proper power state to enter.
+	 */
+	int (*enter_cstate)(uint32_t ari_base, uint32_t state,
+			    uint32_t wake_time);
+	/*
+	 * This ARI request allows updating of the CLUSTER_CSTATE,
+	 * CCPLEX_CSTATE, and SYSTEM_CSTATE register values.
+	 */
+	int (*update_cstate_info)(uint32_t ari_base,
+				  uint32_t cluster,
+				  uint32_t ccplex,
+				  uint32_t system,
+				  uint8_t sys_state_force,
+				  uint32_t wake_mask,
+				  uint8_t update_wake_mask);
+	/*
+	 * This ARI request allows updating of power state crossover
+	 * threshold times. An index value specifies which crossover
+	 * state is being updated.
+	 */
+	int (*update_crossover_time)(uint32_t ari_base,
+				     uint32_t type,
+				     uint32_t time);
+	/*
+	 * This ARI request allows read access to statistical information
+	 * related to power states.
+	 */
+	uint64_t (*read_cstate_stats)(uint32_t ari_base,
+				     uint32_t state);
+	/*
+	 * This ARI request allows write access to statistical information
+	 * related to power states.
+	 */
+	int (*write_cstate_stats)(uint32_t ari_base,
+				  uint32_t state,
+				  uint32_t stats);
+	/*
+	 * This ARI request allows the CPU to understand the features
+	 * supported by the MCE firmware.
+	 */
+	uint64_t (*call_enum_misc)(uint32_t ari_base, uint32_t cmd,
+				   uint32_t data);
+	/*
+	 * This ARI request allows querying the CCPLEX to determine if
+	 * the CCx state is allowed given a target core C-state and wake
+	 * time. If the CCx state is allowed, the response indicates CCx
+	 * must be entered. If the CCx state is not allowed, the response
+	 * indicates CC6/CC7 can't be entered
+	 */
+	int (*is_ccx_allowed)(uint32_t ari_base, uint32_t state,
+			      uint32_t wake_time);
+	/*
+	 * This ARI request allows querying the CCPLEX to determine if
+	 * the SC7 state is allowed given a target core C-state and wake
+	 * time. If the SC7 state is allowed, all cores but the associated
+	 * core are offlined (WAKE_EVENTS are set to 0) and the response
+	 * indicates SC7 must be entered. If the SC7 state is not allowed,
+	 * the response indicates SC7 can't be entered
+	 */
+	int (*is_sc7_allowed)(uint32_t ari_base, uint32_t state,
+			      uint32_t wake_time);
+	/*
+	 * This ARI request allows a core to bring another offlined core
+	 * back online to the C0 state. Note that a core is offlined by
+	 * entering a C-state where the WAKE_MASK is all 0.
+	 */
+	int (*online_core)(uint32_t ari_base, uint32_t cpuid);
+	/*
+	 * This ARI request allows the CPU to enable/disable Auto-CC3 idle
+	 * state.
+	 */
+	int (*cc3_ctrl)(uint32_t ari_base,
+			uint32_t freq,
+			uint32_t volt,
+			uint8_t enable);
+	/*
+	 * This ARI request allows updating the reset vector register for
+	 * D15 and A57 CPUs.
+	 */
+	int (*update_reset_vector)(uint32_t ari_base,
+				   uint32_t addr_low,
+				   uint32_t addr_high);
+	/*
+	 * This ARI request instructs the ROC to flush A57 data caches in
+	 * order to maintain coherency with the Denver cluster.
+	 */
+	int (*roc_flush_cache)(uint32_t ari_base);
+	/*
+	 * This ARI request instructs the ROC to flush A57 data caches along
+	 * with the caches covering ARM code in order to maintain coherency
+	 * with the Denver cluster.
+	 */
+	int (*roc_flush_cache_trbits)(uint32_t ari_base);
+	/*
+	 * This ARI request instructs the ROC to clean A57 data caches along
+	 * with the caches covering ARM code in order to maintain coherency
+	 * with the Denver cluster.
+	 */
+	int (*roc_clean_cache)(uint32_t ari_base);
+	/*
+	 * This ARI request reads/writes the Machine Check Arch. (MCA)
+	 * registers.
+	 */
+	uint64_t (*read_write_mca)(uint32_t ari_base,
+			      mca_cmd_t cmd,
+			      uint64_t *data);
+	/*
+	 * Some MC GSC (General Security Carveout) register values are
+	 * expected to be changed by TrustZone secure ARM code after boot.
+	 * Since there is no hardware mechanism for the CCPLEX to know
+	 * that an MC GSC register has changed to allow it to update its
+	 * own internal GSC register, there needs to be a mechanism that
+	 * can be used by ARM code to cause the CCPLEX to update its GSC
+	 * register value. This ARI request allows updating the GSC register
+	 * value for a certain carveout in the CCPLEX.
+	 */
+	int (*update_ccplex_gsc)(uint32_t ari_base, uint32_t gsc_idx);
+	/*
+	 * This ARI request instructs the CCPLEX to either shutdown or
+	 * reset the entire system
+	 */
+	void (*enter_ccplex_state)(uint32_t ari_base, uint32_t state_idx);
+} arch_mce_ops_t;
+
+int mce_command_handler(mce_cmd_t cmd, uint64_t arg0, uint64_t arg1,
+		uint64_t arg2);
+int mce_update_reset_vector(uint32_t addr_lo, uint32_t addr_hi);
+int mce_update_gsc_videomem(void);
+int mce_update_gsc_tzdram(void);
+int mce_update_gsc_tzram(void);
+__dead2 void mce_enter_ccplex_state(uint32_t state_idx);
+
+/* declarations for ARI/NVG handler functions */
+int ari_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time);
+int ari_update_cstate_info(uint32_t ari_base, uint32_t cluster, uint32_t ccplex,
+	uint32_t system, uint8_t sys_state_force, uint32_t wake_mask,
+	uint8_t update_wake_mask);
+int ari_update_crossover_time(uint32_t ari_base, uint32_t type, uint32_t time);
+uint64_t ari_read_cstate_stats(uint32_t ari_base, uint32_t state);
+int ari_write_cstate_stats(uint32_t ari_base, uint32_t state, uint32_t stats);
+uint64_t ari_enumeration_misc(uint32_t ari_base, uint32_t cmd, uint32_t data);
+int ari_is_ccx_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time);
+int ari_is_sc7_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time);
+int ari_online_core(uint32_t ari_base, uint32_t core);
+int ari_cc3_ctrl(uint32_t ari_base, uint32_t freq, uint32_t volt, uint8_t enable);
+int ari_reset_vector_update(uint32_t ari_base, uint32_t lo, uint32_t hi);
+int ari_roc_flush_cache_trbits(uint32_t ari_base);
+int ari_roc_flush_cache(uint32_t ari_base);
+int ari_roc_clean_cache(uint32_t ari_base);
+uint64_t ari_read_write_mca(uint32_t ari_base, mca_cmd_t cmd, uint64_t *data);
+int ari_update_ccplex_gsc(uint32_t ari_base, uint32_t gsc_idx);
+void ari_enter_ccplex_state(uint32_t ari_base, uint32_t state_idx);
+
+int nvg_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time);
+int nvg_update_cstate_info(uint32_t ari_base, uint32_t cluster, uint32_t ccplex,
+		uint32_t system, uint8_t sys_state_force, uint32_t wake_mask,
+		uint8_t update_wake_mask);
+int nvg_update_crossover_time(uint32_t ari_base, uint32_t type, uint32_t time);
+uint64_t nvg_read_cstate_stats(uint32_t ari_base, uint32_t state);
+int nvg_write_cstate_stats(uint32_t ari_base, uint32_t state, uint32_t val);
+int nvg_is_ccx_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time);
+int nvg_is_sc7_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time);
+int nvg_online_core(uint32_t ari_base, uint32_t core);
+int nvg_cc3_ctrl(uint32_t ari_base, uint32_t freq, uint32_t volt, uint8_t enable);
+
+#endif /* __MCE_H__ */
diff --git a/plat/nvidia/tegra/soc/t186/drivers/include/t18x_ari.h b/plat/nvidia/tegra/soc/t186/drivers/include/t18x_ari.h
new file mode 100644
index 0000000..3e6054b
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t186/drivers/include/t18x_ari.h
@@ -0,0 +1,450 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef T18X_TEGRA_ARI_H
+#define T18X_TEGRA_ARI_H
+
+/*
+ * ----------------------------------------------------------------------------
+ * t18x_ari.h
+ *
+ * Global ARI definitions.
+ * ----------------------------------------------------------------------------
+ */
+
+enum {
+	TEGRA_ARI_VERSION_MAJOR = 2,
+	TEGRA_ARI_VERSION_MINOR = 19,
+};
+
+typedef enum {
+	/* indexes below get the core lock */
+	TEGRA_ARI_MISC = 0,
+	/* index 1 is deprecated */
+	/* index 2 is deprecated */
+	/* index 3 is deprecated */
+	TEGRA_ARI_ONLINE_CORE = 4,
+
+	/* indexes below need cluster lock */
+	TEGRA_ARI_MISC_CLUSTER = 41,
+	TEGRA_ARI_IS_CCX_ALLOWED = 42,
+	TEGRA_ARI_CC3_CTRL = 43,
+
+	/* indexes below need ccplex lock */
+	TEGRA_ARI_ENTER_CSTATE = 80,
+	TEGRA_ARI_UPDATE_CSTATE_INFO = 81,
+	TEGRA_ARI_IS_SC7_ALLOWED = 82,
+	/* index 83 is deprecated */
+	TEGRA_ARI_PERFMON = 84,
+	TEGRA_ARI_UPDATE_CCPLEX_GSC = 85,
+	/* index 86 is depracated */
+	/* index 87 is deprecated */
+	TEGRA_ARI_ROC_FLUSH_CACHE_ONLY = 88,
+	TEGRA_ARI_ROC_FLUSH_CACHE_TRBITS = 89,
+	TEGRA_ARI_MISC_CCPLEX = 90,
+	TEGRA_ARI_MCA = 91,
+	TEGRA_ARI_UPDATE_CROSSOVER = 92,
+	TEGRA_ARI_CSTATE_STATS = 93,
+	TEGRA_ARI_WRITE_CSTATE_STATS = 94,
+	TEGRA_ARI_COPY_MISCREG_AA64_RST = 95,
+	TEGRA_ARI_ROC_CLEAN_CACHE_ONLY = 96,
+} tegra_ari_req_id_t;
+
+typedef enum {
+	TEGRA_ARI_MISC_ECHO = 0,
+	TEGRA_ARI_MISC_VERSION = 1,
+	TEGRA_ARI_MISC_FEATURE_LEAF_0 = 2,
+} tegra_ari_misc_index_t;
+
+typedef enum {
+	TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF = 0,
+	TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT = 1,
+	TEGRA_ARI_MISC_CCPLEX_CORESIGHT_CG_CTRL = 2,
+} tegra_ari_misc_ccplex_index_t;
+
+typedef enum {
+	TEGRA_ARI_CORE_C0 = 0,
+	TEGRA_ARI_CORE_C1 = 1,
+	TEGRA_ARI_CORE_C6 = 6,
+	TEGRA_ARI_CORE_C7 = 7,
+	TEGRA_ARI_CORE_WARMRSTREQ = 8,
+} tegra_ari_core_sleep_state_t;
+
+typedef enum {
+	TEGRA_ARI_CLUSTER_CC0 = 0,
+	TEGRA_ARI_CLUSTER_CC1 = 1,
+	TEGRA_ARI_CLUSTER_CC6 = 6,
+	TEGRA_ARI_CLUSTER_CC7 = 7,
+} tegra_ari_cluster_sleep_state_t;
+
+typedef enum {
+	TEGRA_ARI_CCPLEX_CCP0 = 0,
+	TEGRA_ARI_CCPLEX_CCP1 = 1,
+	TEGRA_ARI_CCPLEX_CCP3 = 3,
+} tegra_ari_ccplex_sleep_state_t;
+
+typedef enum {
+	TEGRA_ARI_SYSTEM_SC0 = 0,
+	TEGRA_ARI_SYSTEM_SC1 = 1,
+	TEGRA_ARI_SYSTEM_SC2 = 2,
+	TEGRA_ARI_SYSTEM_SC3 = 3,
+	TEGRA_ARI_SYSTEM_SC4 = 4,
+	TEGRA_ARI_SYSTEM_SC7 = 7,
+	TEGRA_ARI_SYSTEM_SC8 = 8,
+} tegra_ari_system_sleep_state_t;
+
+typedef enum {
+	TEGRA_ARI_CROSSOVER_C1_C6 = 0,
+	TEGRA_ARI_CROSSOVER_CC1_CC6 = 1,
+	TEGRA_ARI_CROSSOVER_CC1_CC7 = 2,
+	TEGRA_ARI_CROSSOVER_CCP1_CCP3 = 3,
+	TEGRA_ARI_CROSSOVER_CCP3_SC2 = 4,
+	TEGRA_ARI_CROSSOVER_CCP3_SC3 = 5,
+	TEGRA_ARI_CROSSOVER_CCP3_SC4 = 6,
+	TEGRA_ARI_CROSSOVER_CCP3_SC7 = 7,
+	TEGRA_ARI_CROSSOVER_CCP3_SC1 = 8,
+} tegra_ari_crossover_index_t;
+
+typedef enum {
+	TEGRA_ARI_CSTATE_STATS_CLEAR = 0,
+	TEGRA_ARI_CSTATE_STATS_SC7_ENTRIES = 1,
+	TEGRA_ARI_CSTATE_STATS_SC4_ENTRIES,
+	TEGRA_ARI_CSTATE_STATS_SC3_ENTRIES,
+	TEGRA_ARI_CSTATE_STATS_SC2_ENTRIES,
+	TEGRA_ARI_CSTATE_STATS_CCP3_ENTRIES,
+	TEGRA_ARI_CSTATE_STATS_A57_CC6_ENTRIES,
+	TEGRA_ARI_CSTATE_STATS_A57_CC7_ENTRIES,
+	TEGRA_ARI_CSTATE_STATS_D15_CC6_ENTRIES,
+	TEGRA_ARI_CSTATE_STATS_D15_CC7_ENTRIES,
+	TEGRA_ARI_CSTATE_STATS_D15_0_C6_ENTRIES,
+	TEGRA_ARI_CSTATE_STATS_D15_1_C6_ENTRIES,
+	TEGRA_ARI_CSTATE_STATS_D15_0_C7_ENTRIES = 14,
+	TEGRA_ARI_CSTATE_STATS_D15_1_C7_ENTRIES,
+	TEGRA_ARI_CSTATE_STATS_A57_0_C7_ENTRIES = 18,
+	TEGRA_ARI_CSTATE_STATS_A57_1_C7_ENTRIES,
+	TEGRA_ARI_CSTATE_STATS_A57_2_C7_ENTRIES,
+	TEGRA_ARI_CSTATE_STATS_A57_3_C7_ENTRIES,
+	TEGRA_ARI_CSTATE_STATS_LAST_CSTATE_ENTRY_D15_0,
+	TEGRA_ARI_CSTATE_STATS_LAST_CSTATE_ENTRY_D15_1,
+	TEGRA_ARI_CSTATE_STATS_LAST_CSTATE_ENTRY_A57_0 = 26,
+	TEGRA_ARI_CSTATE_STATS_LAST_CSTATE_ENTRY_A57_1,
+	TEGRA_ARI_CSTATE_STATS_LAST_CSTATE_ENTRY_A57_2,
+	TEGRA_ARI_CSTATE_STATS_LAST_CSTATE_ENTRY_A57_3,
+} tegra_ari_cstate_stats_index_t;
+
+typedef enum {
+	TEGRA_ARI_GSC_ALL = 0,
+
+	TEGRA_ARI_GSC_BPMP = 6,
+	TEGRA_ARI_GSC_APE = 7,
+	TEGRA_ARI_GSC_SPE = 8,
+	TEGRA_ARI_GSC_SCE = 9,
+	TEGRA_ARI_GSC_APR = 10,
+	TEGRA_ARI_GSC_TZRAM = 11,
+	TEGRA_ARI_GSC_SE = 12,
+
+	TEGRA_ARI_GSC_BPMP_TO_SPE = 16,
+	TEGRA_ARI_GSC_SPE_TO_BPMP = 17,
+	TEGRA_ARI_GSC_CPU_TZ_TO_BPMP = 18,
+	TEGRA_ARI_GSC_BPMP_TO_CPU_TZ = 19,
+	TEGRA_ARI_GSC_CPU_NS_TO_BPMP = 20,
+	TEGRA_ARI_GSC_BPMP_TO_CPU_NS = 21,
+	TEGRA_ARI_GSC_IPC_SE_SPE_SCE_BPMP = 22,
+	TEGRA_ARI_GSC_SC7_RESUME_FW = 23,
+
+	TEGRA_ARI_GSC_TZ_DRAM_IDX = 34,
+	TEGRA_ARI_GSC_VPR_IDX = 35,
+} tegra_ari_gsc_index_t;
+
+/* This macro will produce enums for __name##_LSB, __name##_MSB and __name##_MSK */
+#define TEGRA_ARI_ENUM_MASK_LSB_MSB(__name, __lsb, __msb) __name##_LSB = __lsb, __name##_MSB = __msb
+
+typedef enum {
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_UPDATE_CSTATE_INFO__CLUSTER_CSTATE, 0, 2),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_UPDATE_CSTATE_INFO__CLUSTER_CSTATE_PRESENT, 7, 7),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_UPDATE_CSTATE_INFO__CCPLEX_CSTATE, 8, 9),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_UPDATE_CSTATE_INFO__CCPLEX_CSTATE_PRESENT, 15, 15),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_UPDATE_CSTATE_INFO__SYSTEM_CSTATE, 16, 19),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_UPDATE_CSTATE_INFO__IGNORE_CROSSOVERS, 22, 22),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_UPDATE_CSTATE_INFO__SYSTEM_CSTATE_PRESENT, 23, 23),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_UPDATE_CSTATE_INFO__WAKE_MASK_PRESENT, 31, 31),
+} tegra_ari_update_cstate_info_bitmasks_t;
+
+typedef enum {
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MISC_CCPLEX_CORESIGHT_CG_CTRL__EN, 0, 0),
+} tegra_ari_misc_ccplex_bitmasks_t;
+
+typedef enum {
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_CC3_CTRL__IDLE_FREQ, 0, 8),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_CC3_CTRL__IDLE_VOLT, 16, 23),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_CC3_CTRL__ENABLE, 31, 31),
+} tegra_ari_cc3_ctrl_bitmasks_t;
+
+typedef enum {
+	TEGRA_ARI_MCA_NOP = 0,
+	TEGRA_ARI_MCA_READ_SERR = 1,
+	TEGRA_ARI_MCA_WRITE_SERR = 2,
+	TEGRA_ARI_MCA_CLEAR_SERR = 4,
+	TEGRA_ARI_MCA_REPORT_SERR = 5,
+	TEGRA_ARI_MCA_READ_INTSTS = 6,
+	TEGRA_ARI_MCA_WRITE_INTSTS = 7,
+	TEGRA_ARI_MCA_READ_PREBOOT_SERR = 8,
+} tegra_ari_mca_commands_t;
+
+typedef enum {
+	TEGRA_ARI_MCA_RD_WR_DPMU = 0,
+	TEGRA_ARI_MCA_RD_WR_IOB = 1,
+	TEGRA_ARI_MCA_RD_WR_MCB = 2,
+	TEGRA_ARI_MCA_RD_WR_CCE = 3,
+	TEGRA_ARI_MCA_RD_WR_CQX = 4,
+	TEGRA_ARI_MCA_RD_WR_CTU = 5,
+	TEGRA_ARI_MCA_RD_BANK_INFO = 0x0f,
+	TEGRA_ARI_MCA_RD_BANK_TEMPLATE = 0x10,
+	TEGRA_ARI_MCA_RD_WR_SECURE_ACCESS_REGISTER = 0x11,
+	TEGRA_ARI_MCA_RD_WR_GLOBAL_CONFIG_REGISTER = 0x12,
+} tegra_ari_mca_rd_wr_indexes_t;
+
+typedef enum {
+	TEGRA_ARI_MCA_RD_WR_ASERRX_CTRL = 0,
+	TEGRA_ARI_MCA_RD_WR_ASERRX_STATUS = 1,
+	TEGRA_ARI_MCA_RD_WR_ASERRX_ADDR = 2,
+	TEGRA_ARI_MCA_RD_WR_ASERRX_MISC1 = 3,
+	TEGRA_ARI_MCA_RD_WR_ASERRX_MISC2 = 4,
+} tegra_ari_mca_read_asserx_subindexes_t;
+
+typedef enum {
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_SECURE_REGISTER_SETTING_ENABLES_NS_PERMITTED, 0, 0),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_SECURE_REGISTER_READING_STATUS_NS_PERMITTED, 1, 1),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_SECURE_REGISTER_PENDING_MCA_ERRORS_NS_PERMITTED, 2, 2),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_SECURE_REGISTER_CLEARING_MCA_INTERRUPTS_NS_PERMITTED, 3, 3),
+} tegra_ari_mca_secure_register_bitmasks_t;
+
+typedef enum {
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_STAT_SERR_ERR_CODE, 0, 15),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_STAT_PWM_ERR, 16, 16),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_STAT_CRAB_ERR, 17, 17),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_STAT_RD_WR_N, 18, 18),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_STAT_UCODE_ERR, 19, 19),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_STAT_PWM, 20, 23),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_STAT_AV, 58, 58),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_STAT_MV, 59, 59),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_STAT_EN, 60, 60),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_STAT_UC, 61, 61),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_STAT_OVF, 62, 62),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_STAT_VAL, 63, 63),
+
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_ADDR_ADDR, 0, 41),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_ADDR_UCODE_ERRCD, 42, 52),
+
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_CTRL_EN_PWM_ERR, 0, 0),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_CTRL_EN_CRAB_ERR, 1, 1),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR0_CTRL_EN_UCODE_ERR, 3, 3),
+} tegra_ari_mca_aserr0_bitmasks_t;
+
+typedef enum {
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_SERR_ERR_CODE, 0, 15),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_MSI_ERR, 16, 16),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_IHI_ERR, 17, 17),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_CRI_ERR, 18, 18),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_MMCRAB_ERR, 19, 19),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_CSI_ERR, 20, 20),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_RD_WR_N, 21, 21),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_REQ_ERRT, 22, 23),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_RESP_ERRT, 24, 25),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_AV, 58, 58),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_MV, 59, 59),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_EN, 60, 60),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_UC, 61, 61),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_OVF, 62, 62),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_VAL, 63, 63),
+
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_AXI_ID, 0, 7),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_CQX_ID, 8, 27),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_CQX_CID, 28, 31),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_STAT_CQX_CMD, 32, 35),
+
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_CTRL_EN_MSI_ERR, 0, 0),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_CTRL_EN_IHI_ERR, 1, 1),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_CTRL_EN_CRI_ERR, 2, 2),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_CTRL_EN_MMCRAB_ERR, 3, 3),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_CTRL_EN_CSI_ERR, 4, 4),
+
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR1_MISC_ADDR, 0, 41),
+} tegra_ari_mca_aserr1_bitmasks_t;
+
+typedef enum {
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_STAT_SERR_ERR_CODE, 0, 15),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_STAT_MC_ERR, 16, 16),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_STAT_SYSRAM_ERR, 17, 17),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_STAT_CLIENT_ID, 18, 19),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_STAT_AV, 58, 58),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_STAT_MV, 59, 59),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_STAT_EN, 60, 60),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_STAT_UC, 61, 61),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_STAT_OVF, 62, 62),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_STAT_VAL, 63, 63),
+
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_ADDR_ID, 0, 17),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_ADDR_CMD, 18, 21),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_ADDR_ADDR, 22, 53),
+
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR2_CTRL_EN_MC_ERR, 0, 0),
+} tegra_ari_mca_aserr2_bitmasks_t;
+
+typedef enum {
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_SERR_ERR_CODE, 0, 15),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_TO_ERR, 16, 16),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_STAT_ERR, 17, 17),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_DST_ERR, 18, 18),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_UNC_ERR, 19, 19),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_MH_ERR, 20, 20),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_PERR, 21, 21),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_PSN_ERR, 22, 22),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_AV, 58, 58),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_MV, 59, 59),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_EN, 60, 60),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_UC, 61, 61),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_OVF, 62, 62),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_STAT_VAL, 63, 63),
+
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_ADDR_CMD, 0, 5),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_ADDR_ADDR, 6, 47),
+
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_MISC1_TO, 0, 0),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_MISC1_DIV4, 1, 1),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_MISC1_TLIMIT, 2, 11),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_MISC1_PSN_ERR_CORR_MSK, 12, 25),
+
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_MISC2_MORE_INFO, 0, 17),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_MISC2_TO_INFO, 18, 43),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_MISC2_SRC, 44, 45),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_MISC2_TID, 46, 52),
+
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_CTRL_EN_TO_ERR, 0, 0),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_CTRL_EN_STAT_ERR, 1, 1),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_CTRL_EN_DST_ERR, 2, 2),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_CTRL_EN_UNC_ERR, 3, 3),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_CTRL_EN_MH_ERR, 4, 4),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_CTRL_EN_PERR, 5, 5),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR3_CTRL_EN_PSN_ERR, 6, 19),
+} tegra_ari_mca_aserr3_bitmasks_t;
+
+typedef enum {
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR4_STAT_SERR_ERR_CODE, 0, 15),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR4_STAT_SRC_ERR, 16, 16),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR4_STAT_DST_ERR, 17, 17),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR4_STAT_REQ_ERR, 18, 18),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR4_STAT_RSP_ERR, 19, 19),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR4_STAT_AV, 58, 58),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR4_STAT_MV, 59, 59),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR4_STAT_EN, 60, 60),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR4_STAT_UC, 61, 61),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR4_STAT_OVF, 62, 62),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR4_STAT_VAL, 63, 63),
+
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR4_CTRL_EN_CPE_ERR, 0, 0),
+} tegra_ari_mca_aserr4_bitmasks_t;
+
+typedef enum {
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_STAT_SERR_ERR_CODE, 0, 15),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_STAT_CTUPAR, 16, 16),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_STAT_MULTI, 17, 17),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_STAT_AV, 58, 58),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_STAT_MV, 59, 59),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_STAT_EN, 60, 60),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_STAT_UC, 61, 61),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_STAT_OVF, 62, 62),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_STAT_VAL, 63, 63),
+
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_ADDR_SRC, 0, 7),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_ADDR_ID, 8, 15),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_ADDR_DATA, 16, 26),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_ADDR_CMD, 32, 35),
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_ADDR_ADDR, 36, 45),
+
+	TEGRA_ARI_ENUM_MASK_LSB_MSB(TEGRA_ARI_MCA_ASERR5_CTRL_EN_CTUPAR, 0, 0),
+} tegra_ari_mca_aserr5_bitmasks_t;
+
+#undef TEGRA_ARI_ENUM_MASK_LSB_MSB
+
+typedef enum {
+	TEGRA_NVG_CHANNEL_PMIC = 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_C1_C6 = 5,
+	TEGRA_NVG_CHANNEL_CROSSOVER_CC1_CC6 = 6,
+	TEGRA_NVG_CHANNEL_CROSSOVER_CC1_CC7 = 7,
+	TEGRA_NVG_CHANNEL_CROSSOVER_CCP1_CCP3 = 8,
+	TEGRA_NVG_CHANNEL_CROSSOVER_CCP3_SC2 = 9,
+	TEGRA_NVG_CHANNEL_CROSSOVER_CCP3_SC3 = 10,
+	TEGRA_NVG_CHANNEL_CROSSOVER_CCP3_SC4 = 11,
+	TEGRA_NVG_CHANNEL_CROSSOVER_CCP3_SC7 = 12,
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_CLEAR = 13,
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_SC7_ENTRIES = 14,
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_SC4_ENTRIES = 15,
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_SC3_ENTRIES = 16,
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_SC2_ENTRIES = 17,
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_CCP3_ENTRIES = 18,
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_A57_CC6_ENTRIES = 19,
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_A57_CC7_ENTRIES = 20,
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_D15_CC6_ENTRIES = 21,
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_D15_CC7_ENTRIES = 22,
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_D15_0_C6_ENTRIES = 23,
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_D15_1_C6_ENTRIES = 24,
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_D15_2_C6_ENTRIES = 25, /* Reserved (for Denver15 core 2) */
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_D15_3_C6_ENTRIES = 26, /* Reserved (for Denver15 core 3) */
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_D15_0_C7_ENTRIES = 27,
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_D15_1_C7_ENTRIES = 28,
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_D15_2_C7_ENTRIES = 29, /* Reserved (for Denver15 core 2) */
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_D15_3_C7_ENTRIES = 30, /* Reserved (for Denver15 core 3) */
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_A57_0_C7_ENTRIES = 31,
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_A57_1_C7_ENTRIES = 32,
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_A57_2_C7_ENTRIES = 33,
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_A57_3_C7_ENTRIES = 34,
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_LAST_CSTATE_ENTRY_D15_0 = 35,
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_LAST_CSTATE_ENTRY_D15_1 = 36,
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_LAST_CSTATE_ENTRY_D15_2 = 37, /*  Reserved (for Denver15 core 2) */
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_LAST_CSTATE_ENTRY_D15_3 = 38, /* Reserved (for Denver15 core 3) */
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_LAST_CSTATE_ENTRY_A57_0 = 39,
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_LAST_CSTATE_ENTRY_A57_1 = 40,
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_LAST_CSTATE_ENTRY_A57_2 = 41,
+	TEGRA_NVG_CHANNEL_CSTATE_STATS_LAST_CSTATE_ENTRY_A57_3 = 42,
+	TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED = 43,
+	TEGRA_NVG_CHANNEL_ONLINE_CORE = 44,
+	TEGRA_NVG_CHANNEL_CC3_CTRL = 45,
+	TEGRA_NVG_CHANNEL_CROSSOVER_CCP3_SC1 = 46,
+	TEGRA_NVG_CHANNEL_LAST_INDEX,
+} tegra_nvg_channel_id_t;
+
+#endif /* T18X_TEGRA_ARI_H */
+
+
diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/aarch64/nvg_helpers.S b/plat/nvidia/tegra/soc/t186/drivers/mce/aarch64/nvg_helpers.S
new file mode 100644
index 0000000..b6e4b31
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/aarch64/nvg_helpers.S
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#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/t186/drivers/mce/ari.c b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
new file mode 100644
index 0000000..147a358
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
@@ -0,0 +1,391 @@
+/*
+ * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <debug.h>
+#include <denver.h>
+#include <mmio.h>
+#include <mce.h>
+#include <sys/errno.h>
+#include <t18x_ari.h>
+
+/*******************************************************************************
+ * Register offsets for ARI request/results
+ ******************************************************************************/
+#define ARI_REQUEST			0x0
+#define ARI_REQUEST_EVENT_MASK		0x4
+#define ARI_STATUS			0x8
+#define ARI_REQUEST_DATA_LO		0xC
+#define ARI_REQUEST_DATA_HI		0x10
+#define ARI_RESPONSE_DATA_LO		0x14
+#define ARI_RESPONSE_DATA_HI		0x18
+
+/* Status values for the current request */
+#define ARI_REQ_PENDING			1
+#define ARI_REQ_ONGOING			3
+#define ARI_REQUEST_VALID_BIT		(1 << 8)
+#define ARI_EVT_MASK_STANDBYWFI_BIT	(1 << 7)
+
+/*******************************************************************************
+ * ARI helper functions
+ ******************************************************************************/
+static inline uint32_t ari_read_32(uint32_t ari_base, uint32_t reg)
+{
+	return mmio_read_32(ari_base + reg);
+}
+
+static inline void ari_write_32(uint32_t ari_base, uint32_t val, uint32_t reg)
+{
+	mmio_write_32(ari_base + reg, val);
+}
+
+static inline uint32_t ari_get_request_low(uint32_t ari_base)
+{
+	return ari_read_32(ari_base, ARI_REQUEST_DATA_LO);
+}
+
+static inline uint32_t ari_get_request_high(uint32_t ari_base)
+{
+	return ari_read_32(ari_base, ARI_REQUEST_DATA_HI);
+}
+
+static inline uint32_t ari_get_response_low(uint32_t ari_base)
+{
+	return ari_read_32(ari_base, ARI_RESPONSE_DATA_LO);
+}
+
+static inline uint32_t ari_get_response_high(uint32_t ari_base)
+{
+	return ari_read_32(ari_base, ARI_RESPONSE_DATA_HI);
+}
+
+static inline void ari_clobber_response(uint32_t ari_base)
+{
+	ari_write_32(ari_base, 0, ARI_RESPONSE_DATA_LO);
+	ari_write_32(ari_base, 0, ARI_RESPONSE_DATA_HI);
+}
+
+static int ari_request_wait(uint32_t ari_base, uint32_t evt_mask, uint32_t req,
+		uint32_t lo, uint32_t hi)
+{
+	int status;
+
+	/* program the request, event_mask, hi and lo registers */
+	ari_write_32(ari_base, lo, ARI_REQUEST_DATA_LO);
+	ari_write_32(ari_base, hi, ARI_REQUEST_DATA_HI);
+	ari_write_32(ari_base, evt_mask, ARI_REQUEST_EVENT_MASK);
+	ari_write_32(ari_base, req | ARI_REQUEST_VALID_BIT, ARI_REQUEST);
+
+	/*
+	 * For commands that have an event trigger, we should bypass
+	 * ARI_STATUS polling, since MCE is waiting for SW to trigger
+	 * the event.
+	 */
+	if (evt_mask)
+		return 0;
+
+	/* NOTE: add timeout check if needed */
+	status = ari_read_32(ari_base, ARI_STATUS);
+	while (status & (ARI_REQ_ONGOING | ARI_REQ_PENDING))
+		status = ari_read_32(ari_base, ARI_STATUS);
+
+	return 0;
+}
+
+int ari_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time)
+{
+	/* check for allowed power state */
+	if (state != TEGRA_ARI_CORE_C0 && state != TEGRA_ARI_CORE_C1 &&
+	    state != TEGRA_ARI_CORE_C6 && state != TEGRA_ARI_CORE_C7) {
+		ERROR("%s: unknown cstate (%d)\n", __func__, state);
+		return EINVAL;
+	}
+
+	/* Enter the cstate, to be woken up after wake_time (TSC ticks) */
+	return ari_request_wait(ari_base, ARI_EVT_MASK_STANDBYWFI_BIT,
+		TEGRA_ARI_ENTER_CSTATE, state, wake_time);
+}
+
+int ari_update_cstate_info(uint32_t ari_base, uint32_t cluster, uint32_t ccplex,
+	uint32_t system, uint8_t sys_state_force, uint32_t wake_mask,
+	uint8_t update_wake_mask)
+{
+	uint32_t val = 0;
+
+	/* update CLUSTER_CSTATE? */
+	if (cluster)
+		val |= (cluster & CLUSTER_CSTATE_MASK) |
+			CLUSTER_CSTATE_UPDATE_BIT;
+
+	/* update CCPLEX_CSTATE? */
+	if (ccplex)
+		val |= (ccplex & CCPLEX_CSTATE_MASK) << CCPLEX_CSTATE_SHIFT |
+			CCPLEX_CSTATE_UPDATE_BIT;
+
+	/* update SYSTEM_CSTATE? */
+	if (system)
+		val |= ((system & SYSTEM_CSTATE_MASK) << SYSTEM_CSTATE_SHIFT) |
+		       ((sys_state_force << SYSTEM_CSTATE_FORCE_UPDATE_SHIFT) |
+			SYSTEM_CSTATE_UPDATE_BIT);
+
+	/* update wake mask value? */
+	if (update_wake_mask)
+		val |= CSTATE_WAKE_MASK_UPDATE_BIT;
+
+	/* set the updated cstate info */
+	return ari_request_wait(ari_base, 0, TEGRA_ARI_UPDATE_CSTATE_INFO, val,
+			wake_mask);
+}
+
+int ari_update_crossover_time(uint32_t ari_base, uint32_t type, uint32_t time)
+{
+	/* sanity check crossover type */
+	if ((type == TEGRA_ARI_CROSSOVER_C1_C6) ||
+	    (type > TEGRA_ARI_CROSSOVER_CCP3_SC1))
+		return EINVAL;
+
+	/* update crossover threshold time */
+	return ari_request_wait(ari_base, 0, TEGRA_ARI_UPDATE_CROSSOVER,
+			type, time);
+}
+
+uint64_t ari_read_cstate_stats(uint32_t ari_base, uint32_t state)
+{
+	int ret;
+
+	/* sanity check crossover type */
+	if (state == 0)
+		return EINVAL;
+
+	ret = ari_request_wait(ari_base, 0, TEGRA_ARI_CSTATE_STATS, state, 0);
+	if (ret != 0)
+		return EINVAL;
+
+	return (uint64_t)ari_get_response_low(ari_base);
+}
+
+int ari_write_cstate_stats(uint32_t ari_base, uint32_t state, uint32_t stats)
+{
+	/* write the cstate stats */
+	return ari_request_wait(ari_base, 0, TEGRA_ARI_WRITE_CSTATE_STATS, state,
+			stats);
+}
+
+uint64_t ari_enumeration_misc(uint32_t ari_base, uint32_t cmd, uint32_t data)
+{
+	uint64_t resp;
+	int ret;
+
+	/* clean the previous response state */
+	ari_clobber_response(ari_base);
+
+	/* ARI_REQUEST_DATA_HI is reserved for commands other than 'ECHO' */
+	if (cmd != TEGRA_ARI_MISC_ECHO)
+		data = 0;
+
+	ret = ari_request_wait(ari_base, 0, TEGRA_ARI_MISC, cmd, data);
+	if (ret)
+		return (uint64_t)ret;
+
+	/* get the command response */
+	resp = ari_get_response_low(ari_base);
+	resp |= ((uint64_t)ari_get_response_high(ari_base) << 32);
+
+	return resp;
+}
+
+int ari_is_ccx_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time)
+{
+	int ret;
+
+	ret = ari_request_wait(ari_base, 0, TEGRA_ARI_IS_CCX_ALLOWED, state & 0x7,
+			wake_time);
+	if (ret) {
+		ERROR("%s: failed (%d)\n", __func__, ret);
+		return 0;
+	}
+
+	/* 1 = CCx allowed, 0 = CCx not allowed */
+	return (ari_get_response_low(ari_base) & 0x1);
+}
+
+int ari_is_sc7_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time)
+{
+	int ret;
+
+	/* check for allowed power state */
+	if (state != TEGRA_ARI_CORE_C0 && state != TEGRA_ARI_CORE_C1 &&
+	    state != TEGRA_ARI_CORE_C6 && state != TEGRA_ARI_CORE_C7) {
+		ERROR("%s: unknown cstate (%d)\n", __func__, state);
+		return EINVAL;
+	}
+
+	ret = ari_request_wait(ari_base, 0, TEGRA_ARI_IS_SC7_ALLOWED, state,
+			wake_time);
+	if (ret) {
+		ERROR("%s: failed (%d)\n", __func__, ret);
+		return 0;
+	}
+
+	/* 1 = SC7 allowed, 0 = SC7 not allowed */
+	return !!ari_get_response_low(ari_base);
+}
+
+int ari_online_core(uint32_t ari_base, uint32_t core)
+{
+	int cpu = read_mpidr() & MPIDR_CPU_MASK;
+	int cluster = (read_mpidr() & MPIDR_CLUSTER_MASK) >>
+			MPIDR_AFFINITY_BITS;
+	int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
+
+	/* construct the current CPU # */
+	cpu |= (cluster << 2);
+
+	/* sanity check target core id */
+	if ((core >= MCE_CORE_ID_MAX) || (cpu == core)) {
+		ERROR("%s: unsupported core id (%d)\n", __func__, core);
+		return EINVAL;
+	}
+
+	/*
+	 * The Denver cluster has 2 CPUs only - 0, 1.
+	 */
+	if (impl == DENVER_IMPL && ((core == 2) || (core == 3))) {
+		ERROR("%s: unknown core id (%d)\n", __func__, core);
+		return EINVAL;
+	}
+
+	return ari_request_wait(ari_base, 0, TEGRA_ARI_ONLINE_CORE, core, 0);
+}
+
+int ari_cc3_ctrl(uint32_t ari_base, uint32_t freq, uint32_t volt, uint8_t enable)
+{
+	int val;
+
+	/*
+	 * If the enable bit is cleared, Auto-CC3 will be disabled by setting
+	 * the SW visible voltage/frequency request registers for all non
+	 * floorswept cores valid independent of StandbyWFI and disabling
+	 * the IDLE voltage/frequency request register. If set, Auto-CC3
+	 * will be enabled by setting the ARM SW visible voltage/frequency
+	 * request registers for all non floorswept cores to be enabled by
+	 * StandbyWFI or the equivalent signal, and always keeping the IDLE
+	 * voltage/frequency request register enabled.
+	 */
+	val = (((freq & MCE_AUTO_CC3_FREQ_MASK) << MCE_AUTO_CC3_FREQ_SHIFT) |\
+		((volt & MCE_AUTO_CC3_VTG_MASK) << MCE_AUTO_CC3_VTG_SHIFT) |\
+		(enable ? MCE_AUTO_CC3_ENABLE_BIT : 0));
+
+	return ari_request_wait(ari_base, 0, TEGRA_ARI_CC3_CTRL, val, 0);
+}
+
+int ari_reset_vector_update(uint32_t ari_base, uint32_t lo, uint32_t hi)
+{
+	/*
+	 * Need to program the CPU reset vector one time during cold boot
+	 * and SC7 exit
+	 */
+	ari_request_wait(ari_base, 0, TEGRA_ARI_COPY_MISCREG_AA64_RST, lo, hi);
+
+	return 0;
+}
+
+int ari_roc_flush_cache_trbits(uint32_t ari_base)
+{
+	return ari_request_wait(ari_base, 0, TEGRA_ARI_ROC_FLUSH_CACHE_TRBITS,
+			0, 0);
+}
+
+int ari_roc_flush_cache(uint32_t ari_base)
+{
+	return ari_request_wait(ari_base, 0, TEGRA_ARI_ROC_FLUSH_CACHE_ONLY,
+			0, 0);
+}
+
+int ari_roc_clean_cache(uint32_t ari_base)
+{
+	return ari_request_wait(ari_base, 0, TEGRA_ARI_ROC_CLEAN_CACHE_ONLY,
+			0, 0);
+}
+
+uint64_t ari_read_write_mca(uint32_t ari_base, mca_cmd_t cmd, uint64_t *data)
+{
+	mca_arg_t mca_arg;
+	int ret;
+
+	/* Set data (write) */
+	mca_arg.data = data ? *data : 0ull;
+
+	/* Set command */
+	ari_write_32(ari_base, cmd.input.low, ARI_RESPONSE_DATA_LO);
+	ari_write_32(ari_base, cmd.input.high, ARI_RESPONSE_DATA_HI);
+
+	ret = ari_request_wait(ari_base, 0, TEGRA_ARI_MCA, mca_arg.arg.low,
+			mca_arg.arg.high);
+	if (!ret) {
+		mca_arg.arg.low = ari_get_response_low(ari_base);
+		mca_arg.arg.high = ari_get_response_high(ari_base);
+		if (!mca_arg.err.finish)
+			return (uint64_t)mca_arg.err.error;
+
+		if (data) {
+			mca_arg.arg.low = ari_get_request_low(ari_base);
+			mca_arg.arg.high = ari_get_request_high(ari_base);
+			*data = mca_arg.data;
+		}
+	}
+
+	return 0;
+}
+
+int ari_update_ccplex_gsc(uint32_t ari_base, uint32_t gsc_idx)
+{
+	/* sanity check GSC ID */
+	if (gsc_idx > TEGRA_ARI_GSC_VPR_IDX)
+		return EINVAL;
+
+	/*
+	 * The MCE code will read the GSC carveout value, corrseponding to
+	 * the ID, from the MC registers and update the internal GSC registers
+	 * of the CCPLEX.
+	 */
+	ari_request_wait(ari_base, 0, TEGRA_ARI_UPDATE_CCPLEX_GSC, gsc_idx, 0);
+
+	return 0;
+}
+
+void ari_enter_ccplex_state(uint32_t ari_base, uint32_t state_idx)
+{
+	/*
+	 * The MCE will shutdown or restart the entire system
+	 */
+	(void)ari_request_wait(ari_base, 0, TEGRA_ARI_MISC_CCPLEX, state_idx, 0);
+}
diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
new file mode 100644
index 0000000..745b6f4
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
@@ -0,0 +1,431 @@
+/*
+ * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <context.h>
+#include <context_mgmt.h>
+#include <debug.h>
+#include <denver.h>
+#include <mce.h>
+#include <mmio.h>
+#include <string.h>
+#include <sys/errno.h>
+#include <t18x_ari.h>
+#include <tegra_def.h>
+
+/* NVG functions handlers */
+static arch_mce_ops_t nvg_mce_ops = {
+	.enter_cstate = nvg_enter_cstate,
+	.update_cstate_info = nvg_update_cstate_info,
+	.update_crossover_time = nvg_update_crossover_time,
+	.read_cstate_stats = nvg_read_cstate_stats,
+	.write_cstate_stats = nvg_write_cstate_stats,
+	.call_enum_misc = ari_enumeration_misc,
+	.is_ccx_allowed = nvg_is_ccx_allowed,
+	.is_sc7_allowed = nvg_is_sc7_allowed,
+	.online_core = nvg_online_core,
+	.cc3_ctrl = nvg_cc3_ctrl,
+	.update_reset_vector = ari_reset_vector_update,
+	.roc_flush_cache = ari_roc_flush_cache,
+	.roc_flush_cache_trbits = ari_roc_flush_cache_trbits,
+	.roc_clean_cache = ari_roc_clean_cache,
+	.read_write_mca = ari_read_write_mca,
+	.update_ccplex_gsc = ari_update_ccplex_gsc,
+	.enter_ccplex_state = ari_enter_ccplex_state
+};
+
+/* ARI functions handlers */
+static arch_mce_ops_t ari_mce_ops = {
+	.enter_cstate = ari_enter_cstate,
+	.update_cstate_info = ari_update_cstate_info,
+	.update_crossover_time = ari_update_crossover_time,
+	.read_cstate_stats = ari_read_cstate_stats,
+	.write_cstate_stats = ari_write_cstate_stats,
+	.call_enum_misc = ari_enumeration_misc,
+	.is_ccx_allowed = ari_is_ccx_allowed,
+	.is_sc7_allowed = ari_is_sc7_allowed,
+	.online_core = ari_online_core,
+	.cc3_ctrl = ari_cc3_ctrl,
+	.update_reset_vector = ari_reset_vector_update,
+	.roc_flush_cache = ari_roc_flush_cache,
+	.roc_flush_cache_trbits = ari_roc_flush_cache_trbits,
+	.roc_clean_cache = ari_roc_clean_cache,
+	.read_write_mca = ari_read_write_mca,
+	.update_ccplex_gsc = ari_update_ccplex_gsc,
+	.enter_ccplex_state = ari_enter_ccplex_state
+};
+
+typedef struct mce_config {
+	uint32_t ari_base;
+	arch_mce_ops_t *ops;
+} mce_config_t;
+
+/* Table to hold the per-CPU ARI base address and function handlers */
+static mce_config_t mce_cfg_table[MCE_ARI_APERTURES_MAX] = {
+	{
+		/* A57 Core 0 */
+		.ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_0_OFFSET,
+		.ops = &ari_mce_ops,
+	},
+	{
+		/* A57 Core 1 */
+		.ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_1_OFFSET,
+		.ops = &ari_mce_ops,
+	},
+	{
+		/* A57 Core 2 */
+		.ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_2_OFFSET,
+		.ops = &ari_mce_ops,
+	},
+	{
+		/* A57 Core 3 */
+		.ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_3_OFFSET,
+		.ops = &ari_mce_ops,
+	},
+	{
+		/* D15 Core 0 */
+		.ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_4_OFFSET,
+		.ops = &nvg_mce_ops,
+	},
+	{
+		/* D15 Core 1 */
+		.ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_5_OFFSET,
+		.ops = &nvg_mce_ops,
+	}
+};
+
+static uint32_t mce_get_curr_cpu_ari_base(void)
+{
+	uint32_t mpidr = read_mpidr();
+	int cpuid =  mpidr & MPIDR_CPU_MASK;
+	int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
+
+	/*
+	 * T186 has 2 CPU clusters, one with Denver CPUs and the other with
+	 * ARM CortexA-57 CPUs. Each cluster consists of 4 CPUs and the CPU
+	 * numbers start from 0. In order to get the proper arch_mce_ops_t
+	 * struct, we have to convert the Denver CPU ids to the corresponding
+	 * indices in the mce_ops_table array.
+	 */
+	if (impl == DENVER_IMPL)
+		cpuid |= 0x4;
+
+	return mce_cfg_table[cpuid].ari_base;
+}
+
+static arch_mce_ops_t *mce_get_curr_cpu_ops(void)
+{
+	uint32_t mpidr = read_mpidr();
+	int cpuid =  mpidr & MPIDR_CPU_MASK;
+	int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
+
+	/*
+	 * T186 has 2 CPU clusters, one with Denver CPUs and the other with
+	 * ARM CortexA-57 CPUs. Each cluster consists of 4 CPUs and the CPU
+	 * numbers start from 0. In order to get the proper arch_mce_ops_t
+	 * struct, we have to convert the Denver CPU ids to the corresponding
+	 * indices in the mce_ops_table array.
+	 */
+	if (impl == DENVER_IMPL)
+		cpuid |= 0x4;
+
+	return mce_cfg_table[cpuid].ops;
+}
+
+/*******************************************************************************
+ * Common handler for all MCE commands
+ ******************************************************************************/
+int mce_command_handler(mce_cmd_t cmd, uint64_t arg0, uint64_t arg1,
+			uint64_t arg2)
+{
+	arch_mce_ops_t *ops;
+	uint32_t cpu_ari_base;
+	uint64_t ret64 = 0, arg3, arg4, arg5;
+	int ret = 0;
+	mca_cmd_t mca_cmd;
+	cpu_context_t *ctx = cm_get_context(NON_SECURE);
+	gp_regs_t *gp_regs = get_gpregs_ctx(ctx);
+
+	assert(ctx);
+	assert(gp_regs);
+
+	/* get a pointer to the CPU's arch_mce_ops_t struct */
+	ops = mce_get_curr_cpu_ops();
+
+	/* get the CPU's ARI base address */
+	cpu_ari_base = mce_get_curr_cpu_ari_base();
+
+	switch (cmd) {
+	case MCE_CMD_ENTER_CSTATE:
+		ret = ops->enter_cstate(cpu_ari_base, arg0, arg1);
+		if (ret < 0)
+			ERROR("%s: enter_cstate failed(%d)\n", __func__, ret);
+
+		break;
+
+	case MCE_CMD_UPDATE_CSTATE_INFO:
+		/*
+		 * get the parameters required for the update cstate info
+		 * command
+		 */
+		arg3 = read_ctx_reg(gp_regs, CTX_GPREG_X4);
+		arg4 = read_ctx_reg(gp_regs, CTX_GPREG_X5);
+		arg5 = read_ctx_reg(gp_regs, CTX_GPREG_X6);
+
+		ret = ops->update_cstate_info(cpu_ari_base, (uint32_t)arg0,
+				(uint32_t)arg1, (uint32_t)arg2, (uint8_t)arg3,
+				(uint32_t)arg4, (uint8_t)arg5);
+		if (ret < 0)
+			ERROR("%s: update_cstate_info failed(%d)\n",
+				__func__, ret);
+
+		write_ctx_reg(gp_regs, CTX_GPREG_X4, 0);
+		write_ctx_reg(gp_regs, CTX_GPREG_X5, 0);
+		write_ctx_reg(gp_regs, CTX_GPREG_X6, 0);
+
+		break;
+
+	case MCE_CMD_UPDATE_CROSSOVER_TIME:
+		ret = ops->update_crossover_time(cpu_ari_base, arg0, arg1);
+		if (ret < 0)
+			ERROR("%s: update_crossover_time failed(%d)\n",
+				__func__, ret);
+
+		break;
+
+	case MCE_CMD_READ_CSTATE_STATS:
+		ret64 = ops->read_cstate_stats(cpu_ari_base, arg0);
+
+		/* update context to return cstate stats value */
+		write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64);
+		write_ctx_reg(gp_regs, CTX_GPREG_X2, ret64);
+
+		break;
+
+	case MCE_CMD_WRITE_CSTATE_STATS:
+		ret = ops->write_cstate_stats(cpu_ari_base, arg0, arg1);
+		if (ret < 0)
+			ERROR("%s: write_cstate_stats failed(%d)\n",
+				__func__, ret);
+
+		break;
+
+	case MCE_CMD_IS_CCX_ALLOWED:
+		ret = ops->is_ccx_allowed(cpu_ari_base, arg0, arg1);
+		if (ret < 0) {
+			ERROR("%s: is_ccx_allowed failed(%d)\n", __func__, ret);
+			break;
+		}
+
+		/* update context to return CCx status value */
+		write_ctx_reg(gp_regs, CTX_GPREG_X1, ret);
+
+		break;
+
+	case MCE_CMD_IS_SC7_ALLOWED:
+		ret = ops->is_sc7_allowed(cpu_ari_base, arg0, arg1);
+		if (ret < 0) {
+			ERROR("%s: is_sc7_allowed failed(%d)\n", __func__, ret);
+			break;
+		}
+
+		/* update context to return SC7 status value */
+		write_ctx_reg(gp_regs, CTX_GPREG_X1, ret);
+		write_ctx_reg(gp_regs, CTX_GPREG_X3, ret);
+
+		break;
+
+	case MCE_CMD_ONLINE_CORE:
+		ret = ops->online_core(cpu_ari_base, arg0);
+		if (ret < 0)
+			ERROR("%s: online_core failed(%d)\n", __func__, ret);
+
+		break;
+
+	case MCE_CMD_CC3_CTRL:
+		ret = ops->cc3_ctrl(cpu_ari_base, arg0, arg1, arg2);
+		if (ret < 0)
+			ERROR("%s: cc3_ctrl failed(%d)\n", __func__, ret);
+
+		break;
+
+	case MCE_CMD_ECHO_DATA:
+		ret64 = ops->call_enum_misc(cpu_ari_base, TEGRA_ARI_MISC_ECHO,
+				arg0);
+
+		/* update context to return if echo'd data matched source */
+		write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64 == arg0);
+		write_ctx_reg(gp_regs, CTX_GPREG_X2, ret64 == arg0);
+
+		break;
+
+	case MCE_CMD_READ_VERSIONS:
+		ret64 = ops->call_enum_misc(cpu_ari_base, TEGRA_ARI_MISC_VERSION,
+			arg0);
+
+		/*
+		 * version = minor(63:32) | major(31:0). Update context
+		 * to return major and minor version number.
+		 */
+		write_ctx_reg(gp_regs, CTX_GPREG_X1, (uint32_t)ret64);
+		write_ctx_reg(gp_regs, CTX_GPREG_X2, (uint32_t)(ret64 >> 32));
+
+		break;
+
+	case MCE_CMD_ENUM_FEATURES:
+		ret = ops->call_enum_misc(cpu_ari_base,
+				TEGRA_ARI_MISC_FEATURE_LEAF_0, arg0);
+
+		/* update context to return features value */
+		write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64);
+
+		ret = 0;
+
+		break;
+
+	case MCE_CMD_ROC_FLUSH_CACHE_TRBITS:
+		ret = ops->roc_flush_cache_trbits(cpu_ari_base);
+		if (ret < 0)
+			ERROR("%s: flush cache_trbits failed(%d)\n", __func__,
+				ret);
+
+		break;
+
+	case MCE_CMD_ROC_FLUSH_CACHE:
+		ret = ops->roc_flush_cache(cpu_ari_base);
+		if (ret < 0)
+			ERROR("%s: flush cache failed(%d)\n", __func__, ret);
+
+		break;
+
+	case MCE_CMD_ROC_CLEAN_CACHE:
+		ret = ops->roc_clean_cache(cpu_ari_base);
+		if (ret < 0)
+			ERROR("%s: clean cache failed(%d)\n", __func__, ret);
+
+		break;
+
+	case MCE_CMD_ENUM_READ_MCA:
+		memcpy(&mca_cmd, &arg0, sizeof(arg0));
+		ret64 = ops->read_write_mca(cpu_ari_base, mca_cmd, &arg1);
+
+		/* update context to return MCA data/error */
+		write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64);
+		write_ctx_reg(gp_regs, CTX_GPREG_X2, arg1);
+		write_ctx_reg(gp_regs, CTX_GPREG_X3, ret64);
+
+		break;
+
+	case MCE_CMD_ENUM_WRITE_MCA:
+		memcpy(&mca_cmd, &arg0, sizeof(arg0));
+		ret64 = ops->read_write_mca(cpu_ari_base, mca_cmd, &arg1);
+
+		/* update context to return MCA error */
+		write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64);
+		write_ctx_reg(gp_regs, CTX_GPREG_X3, ret64);
+
+		break;
+
+	default:
+		ERROR("unknown MCE command (%d)\n", cmd);
+		return EINVAL;
+	}
+
+	return ret;
+}
+
+/*******************************************************************************
+ * Handler to update the reset vector for CPUs
+ ******************************************************************************/
+int mce_update_reset_vector(uint32_t addr_lo, uint32_t addr_hi)
+{
+	arch_mce_ops_t *ops = mce_get_curr_cpu_ops();
+
+	ops->update_reset_vector(mce_get_curr_cpu_ari_base(), addr_lo, addr_hi);
+
+	return 0;
+}
+
+static int mce_update_ccplex_gsc(tegra_ari_gsc_index_t gsc_idx)
+{
+	arch_mce_ops_t *ops = mce_get_curr_cpu_ops();
+
+	ops->update_ccplex_gsc(mce_get_curr_cpu_ari_base(), gsc_idx);
+
+	return 0;
+}
+
+/*******************************************************************************
+ * Handler to update carveout values for Video Memory Carveout region
+ ******************************************************************************/
+int mce_update_gsc_videomem(void)
+{
+	return mce_update_ccplex_gsc(TEGRA_ARI_GSC_VPR_IDX);
+}
+
+/*******************************************************************************
+ * Handler to update carveout values for TZDRAM aperture
+ ******************************************************************************/
+int mce_update_gsc_tzdram(void)
+{
+	return mce_update_ccplex_gsc(TEGRA_ARI_GSC_TZ_DRAM_IDX);
+}
+
+/*******************************************************************************
+ * Handler to update carveout values for TZ SysRAM aperture
+ ******************************************************************************/
+int mce_update_gsc_tzram(void)
+{
+	return mce_update_ccplex_gsc(TEGRA_ARI_GSC_TZRAM);
+}
+
+/*******************************************************************************
+ * Handler to shutdown/reset the entire system
+ ******************************************************************************/
+__dead2 void mce_enter_ccplex_state(uint32_t state_idx)
+{
+	arch_mce_ops_t *ops = mce_get_curr_cpu_ops();
+
+	/* sanity check state value */
+	if (state_idx != TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF &&
+	    state_idx != TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT)
+		panic();
+
+	ops->enter_ccplex_state(mce_get_curr_cpu_ari_base(), state_idx);
+
+	/* wait till the CCPLEX powers down */
+	for (;;)
+		;
+
+	panic();
+}
diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c b/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c
new file mode 100644
index 0000000..25479a2
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <debug.h>
+#include <denver.h>
+#include <mmio.h>
+#include <mce.h>
+#include <sys/errno.h>
+#include <t18x_ari.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);
+
+int nvg_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time)
+{
+	/* check for allowed power state */
+	if (state != TEGRA_ARI_CORE_C0 && state != TEGRA_ARI_CORE_C1 &&
+	    state != TEGRA_ARI_CORE_C6 && state != TEGRA_ARI_CORE_C7) {
+		ERROR("%s: unknown cstate (%d)\n", __func__, state);
+		return EINVAL;
+	}
+
+	/* time (TSC ticks) until the core is expected to get a wake event */
+	nvg_set_request_data(TEGRA_NVG_CHANNEL_WAKE_TIME, wake_time);
+
+	/* set the core cstate */
+	write_actlr_el1(state);
+
+	return 0;
+}
+
+/*
+ * This request allows updating of CLUSTER_CSTATE, CCPLEX_CSTATE and
+ * SYSTEM_CSTATE values.
+ */
+int nvg_update_cstate_info(uint32_t ari_base, uint32_t cluster, uint32_t ccplex,
+		uint32_t system, uint8_t sys_state_force, uint32_t wake_mask,
+		uint8_t update_wake_mask)
+{
+	uint64_t val = 0;
+
+	/* update CLUSTER_CSTATE? */
+	if (cluster)
+		val |= (cluster & CLUSTER_CSTATE_MASK) |
+			CLUSTER_CSTATE_UPDATE_BIT;
+
+	/* update CCPLEX_CSTATE? */
+	if (ccplex)
+		val |= (ccplex & CCPLEX_CSTATE_MASK) << CCPLEX_CSTATE_SHIFT |
+			CCPLEX_CSTATE_UPDATE_BIT;
+
+	/* update SYSTEM_CSTATE? */
+	if (system)
+		val |= ((system & SYSTEM_CSTATE_MASK) << SYSTEM_CSTATE_SHIFT) |
+		       ((sys_state_force << SYSTEM_CSTATE_FORCE_UPDATE_SHIFT) |
+			SYSTEM_CSTATE_UPDATE_BIT);
+
+	/* update wake mask value? */
+	if (update_wake_mask)
+		val |= CSTATE_WAKE_MASK_UPDATE_BIT;
+
+	/* set the wake mask */
+	val &= CSTATE_WAKE_MASK_CLEAR;
+	val |= ((uint64_t)wake_mask << CSTATE_WAKE_MASK_SHIFT);
+
+	/* set the updated cstate info */
+	nvg_set_request_data(TEGRA_NVG_CHANNEL_CSTATE_INFO, val);
+
+	return 0;
+}
+
+int nvg_update_crossover_time(uint32_t ari_base, uint32_t type, uint32_t time)
+{
+	/* sanity check crossover type */
+	if (type > TEGRA_ARI_CROSSOVER_CCP3_SC1)
+		return EINVAL;
+
+	/*
+	 * The crossover threshold limit types start from
+	 * TEGRA_CROSSOVER_TYPE_C1_C6 to TEGRA_CROSSOVER_TYPE_CCP3_SC7. The
+	 * command indices for updating the threshold can be generated
+	 * by adding the type to the NVG_SET_THRESHOLD_CROSSOVER_C1_C6
+	 * command index.
+	 */
+	nvg_set_request_data(TEGRA_NVG_CHANNEL_CROSSOVER_C1_C6 + type,
+		(uint64_t)time);
+
+	return 0;
+}
+
+uint64_t nvg_read_cstate_stats(uint32_t ari_base, uint32_t state)
+{
+	/* sanity check state */
+	if (state == 0)
+		return EINVAL;
+
+	/*
+	 * The cstate types start from NVG_READ_CSTATE_STATS_SC7_ENTRIES
+	 * to NVG_GET_LAST_CSTATE_ENTRY_A57_3. The command indices for
+	 * reading the threshold can be generated by adding the type to
+	 * the NVG_CLEAR_CSTATE_STATS command index.
+	 */
+	nvg_set_request(TEGRA_NVG_CHANNEL_CSTATE_STATS_CLEAR + state);
+
+	return (int64_t)nvg_get_result();
+}
+
+int nvg_write_cstate_stats(uint32_t ari_base, uint32_t state, uint32_t stats)
+{
+	uint64_t val;
+
+	/*
+	 * The only difference between a CSTATE_STATS_WRITE and
+	 * CSTATE_STATS_READ is the usage of the 63:32 in the request.
+	 * 63:32 are set to '0' for a read, while a write contains the
+	 * actual stats value to be written.
+	 */
+	val = ((uint64_t)stats << MCE_CSTATE_STATS_TYPE_SHIFT) | state;
+
+	/*
+	 * The cstate types start from NVG_READ_CSTATE_STATS_SC7_ENTRIES
+	 * to NVG_GET_LAST_CSTATE_ENTRY_A57_3. The command indices for
+	 * reading the threshold can be generated by adding the type to
+	 * the NVG_CLEAR_CSTATE_STATS command index.
+	 */
+	nvg_set_request_data(TEGRA_NVG_CHANNEL_CSTATE_STATS_CLEAR + state, val);
+
+	return 0;
+}
+
+int nvg_is_ccx_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time)
+{
+	/* This does not apply to the Denver cluster */
+	return 0;
+}
+
+int nvg_is_sc7_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time)
+{
+	uint64_t val;
+
+	/* check for allowed power state */
+	if (state != TEGRA_ARI_CORE_C0 && state != TEGRA_ARI_CORE_C1 &&
+	    state != TEGRA_ARI_CORE_C6 && state != TEGRA_ARI_CORE_C7) {
+		ERROR("%s: unknown cstate (%d)\n", __func__, state);
+		return EINVAL;
+	}
+
+	/*
+	 * Request format -
+	 * 63:32 = wake time
+	 * 31:0 = C-state for this core
+	 */
+	val = ((uint64_t)wake_time << MCE_SC7_WAKE_TIME_SHIFT) |
+			(state & MCE_SC7_ALLOWED_MASK);
+
+	/* issue command to check if SC7 is allowed */
+	nvg_set_request_data(TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED, val);
+
+	/* 1 = SC7 allowed, 0 = SC7 not allowed */
+	return !!nvg_get_result();
+}
+
+int nvg_online_core(uint32_t ari_base, uint32_t core)
+{
+	int cpu = read_mpidr() & MPIDR_CPU_MASK;
+	int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
+
+	/* sanity check code id */
+	if ((core >= MCE_CORE_ID_MAX) || (cpu == core)) {
+		ERROR("%s: unsupported core id (%d)\n", __func__, core);
+		return EINVAL;
+	}
+
+	/*
+	 * The Denver cluster has 2 CPUs only - 0, 1.
+	 */
+	if (impl == DENVER_IMPL && ((core == 2) || (core == 3))) {
+		ERROR("%s: unknown core id (%d)\n", __func__, core);
+		return EINVAL;
+	}
+
+	/* get a core online */
+	nvg_set_request_data(TEGRA_NVG_CHANNEL_ONLINE_CORE, core & MCE_CORE_ID_MASK);
+
+	return 0;
+}
+
+int nvg_cc3_ctrl(uint32_t ari_base, uint32_t freq, uint32_t volt, uint8_t enable)
+{
+	int val;
+
+	/*
+	 * If the enable bit is cleared, Auto-CC3 will be disabled by setting
+	 * the SW visible voltage/frequency request registers for all non
+	 * floorswept cores valid independent of StandbyWFI and disabling
+	 * the IDLE voltage/frequency request register. If set, Auto-CC3
+	 * will be enabled by setting the ARM SW visible voltage/frequency
+	 * request registers for all non floorswept cores to be enabled by
+	 * StandbyWFI or the equivalent signal, and always keeping the IDLE
+	 * voltage/frequency request register enabled.
+	 */
+	val = (((freq & MCE_AUTO_CC3_FREQ_MASK) << MCE_AUTO_CC3_FREQ_SHIFT) |\
+		((volt & MCE_AUTO_CC3_VTG_MASK) << MCE_AUTO_CC3_VTG_SHIFT) |\
+		(enable ? MCE_AUTO_CC3_ENABLE_BIT : 0));
+
+	nvg_set_request_data(TEGRA_NVG_CHANNEL_CC3_CTRL, val);
+
+	return 0;
+}
diff --git a/plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c b/plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c
new file mode 100644
index 0000000..2940f58
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c
@@ -0,0 +1,466 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <debug.h>
+#include <memctrl_v2.h>
+#include <smmu.h>
+
+typedef struct smmu_regs {
+	uint32_t reg;
+	uint32_t val;
+} smmu_regs_t;
+
+#define mc_make_sid_override_cfg(name) \
+	{ \
+		.reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_OVERRIDE_CFG_ ## name, \
+		.val = 0x00000000, \
+	}
+
+#define mc_make_sid_security_cfg(name) \
+	{ \
+		.reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_SECURITY_CFG_ ## name, \
+		.val = 0x00000000, \
+	}
+
+#define smmu_make_gnsr0_sec_cfg(name) \
+	{ \
+		.reg = TEGRA_SMMU_BASE + SMMU_GNSR0_ ## name, \
+		.val = 0x00000000, \
+	}
+
+/*
+ * On ARM-SMMU, conditional offset to access secure aliases of non-secure registers
+ * is 0x400. So, add it to register address
+ */
+#define smmu_make_gnsr0_nsec_cfg(name) \
+	{ \
+		.reg = TEGRA_SMMU_BASE + 0x400 + SMMU_GNSR0_ ## name, \
+		.val = 0x00000000, \
+	}
+
+#define smmu_make_gnsr0_smr_cfg(n) \
+	{ \
+		.reg = TEGRA_SMMU_BASE + SMMU_GNSR0_SMR ## n, \
+		.val = 0x00000000, \
+	}
+
+#define smmu_make_gnsr0_s2cr_cfg(n) \
+	{ \
+		.reg = TEGRA_SMMU_BASE + SMMU_GNSR0_S2CR ## n, \
+		.val = 0x00000000, \
+	}
+
+#define smmu_make_gnsr1_cbar_cfg(n) \
+	{ \
+		.reg = TEGRA_SMMU_BASE + (1 << PGSHIFT) + SMMU_GNSR1_CBAR ## n, \
+		.val = 0x00000000, \
+	}
+
+#define smmu_make_gnsr1_cba2r_cfg(n) \
+	{ \
+		.reg = TEGRA_SMMU_BASE + (1 << PGSHIFT) + SMMU_GNSR1_CBA2R ## n, \
+		.val = 0x00000000, \
+	}
+
+#define make_smmu_cb_cfg(name, n) \
+	{ \
+		.reg = TEGRA_SMMU_BASE + (CB_SIZE >> 1) + (n * (1 << PGSHIFT)) \
+			+ SMMU_CBn_ ## name, \
+		.val = 0x00000000, \
+	}
+
+#define smmu_make_smrg_group(n)	\
+	smmu_make_gnsr0_smr_cfg(n),	\
+	smmu_make_gnsr0_s2cr_cfg(n),	\
+	smmu_make_gnsr1_cbar_cfg(n),	\
+	smmu_make_gnsr1_cba2r_cfg(n)	/* don't put "," here. */
+
+#define smmu_make_cb_group(n)		\
+	make_smmu_cb_cfg(SCTLR, n),	\
+	make_smmu_cb_cfg(TCR2, n),	\
+	make_smmu_cb_cfg(TTBR0_LO, n),	\
+	make_smmu_cb_cfg(TTBR0_HI, n),	\
+	make_smmu_cb_cfg(TCR, n),	\
+	make_smmu_cb_cfg(PRRR_MAIR0, n),\
+	make_smmu_cb_cfg(FSR, n),	\
+	make_smmu_cb_cfg(FAR_LO, n),	\
+	make_smmu_cb_cfg(FAR_HI, n),	\
+	make_smmu_cb_cfg(FSYNR0, n)	/* don't put "," here. */
+
+#define smmu_bypass_cfg \
+	{ \
+		.reg = TEGRA_MC_BASE + MC_SMMU_BYPASS_CONFIG, \
+		.val = 0x00000000, \
+	}
+
+#define _START_OF_TABLE_ \
+	{ \
+		.reg = 0xCAFE05C7, \
+		.val = 0x00000000, \
+	}
+
+#define _END_OF_TABLE_ \
+	{ \
+		.reg = 0xFFFFFFFF, \
+		.val = 0xFFFFFFFF, \
+	}
+
+static smmu_regs_t smmu_ctx_regs[] = {
+	_START_OF_TABLE_,
+	mc_make_sid_security_cfg(SCEW),
+	mc_make_sid_security_cfg(AFIR),
+	mc_make_sid_security_cfg(NVDISPLAYR1),
+	mc_make_sid_security_cfg(XUSB_DEVR),
+	mc_make_sid_security_cfg(VICSRD1),
+	mc_make_sid_security_cfg(NVENCSWR),
+	mc_make_sid_security_cfg(TSECSRDB),
+	mc_make_sid_security_cfg(AXISW),
+	mc_make_sid_security_cfg(SDMMCWAB),
+	mc_make_sid_security_cfg(AONDMAW),
+	mc_make_sid_security_cfg(GPUSWR2),
+	mc_make_sid_security_cfg(SATAW),
+	mc_make_sid_security_cfg(UFSHCW),
+	mc_make_sid_security_cfg(AFIW),
+	mc_make_sid_security_cfg(SDMMCR),
+	mc_make_sid_security_cfg(SCEDMAW),
+	mc_make_sid_security_cfg(UFSHCR),
+	mc_make_sid_security_cfg(SDMMCWAA),
+	mc_make_sid_security_cfg(APEDMAW),
+	mc_make_sid_security_cfg(SESWR),
+	mc_make_sid_security_cfg(MPCORER),
+	mc_make_sid_security_cfg(PTCR),
+	mc_make_sid_security_cfg(BPMPW),
+	mc_make_sid_security_cfg(ETRW),
+	mc_make_sid_security_cfg(GPUSRD),
+	mc_make_sid_security_cfg(VICSWR),
+	mc_make_sid_security_cfg(SCEDMAR),
+	mc_make_sid_security_cfg(HDAW),
+	mc_make_sid_security_cfg(ISPWA),
+	mc_make_sid_security_cfg(EQOSW),
+	mc_make_sid_security_cfg(XUSB_HOSTW),
+	mc_make_sid_security_cfg(TSECSWR),
+	mc_make_sid_security_cfg(SDMMCRAA),
+	mc_make_sid_security_cfg(APER),
+	mc_make_sid_security_cfg(VIW),
+	mc_make_sid_security_cfg(APEW),
+	mc_make_sid_security_cfg(AXISR),
+	mc_make_sid_security_cfg(SDMMCW),
+	mc_make_sid_security_cfg(BPMPDMAW),
+	mc_make_sid_security_cfg(ISPRA),
+	mc_make_sid_security_cfg(NVDECSWR),
+	mc_make_sid_security_cfg(XUSB_DEVW),
+	mc_make_sid_security_cfg(NVDECSRD),
+	mc_make_sid_security_cfg(MPCOREW),
+	mc_make_sid_security_cfg(NVDISPLAYR),
+	mc_make_sid_security_cfg(BPMPDMAR),
+	mc_make_sid_security_cfg(NVJPGSWR),
+	mc_make_sid_security_cfg(NVDECSRD1),
+	mc_make_sid_security_cfg(TSECSRD),
+	mc_make_sid_security_cfg(NVJPGSRD),
+	mc_make_sid_security_cfg(SDMMCWA),
+	mc_make_sid_security_cfg(SCER),
+	mc_make_sid_security_cfg(XUSB_HOSTR),
+	mc_make_sid_security_cfg(VICSRD),
+	mc_make_sid_security_cfg(AONDMAR),
+	mc_make_sid_security_cfg(AONW),
+	mc_make_sid_security_cfg(SDMMCRA),
+	mc_make_sid_security_cfg(HOST1XDMAR),
+	mc_make_sid_security_cfg(EQOSR),
+	mc_make_sid_security_cfg(SATAR),
+	mc_make_sid_security_cfg(BPMPR),
+	mc_make_sid_security_cfg(HDAR),
+	mc_make_sid_security_cfg(SDMMCRAB),
+	mc_make_sid_security_cfg(ETRR),
+	mc_make_sid_security_cfg(AONR),
+	mc_make_sid_security_cfg(APEDMAR),
+	mc_make_sid_security_cfg(SESRD),
+	mc_make_sid_security_cfg(NVENCSRD),
+	mc_make_sid_security_cfg(GPUSWR),
+	mc_make_sid_security_cfg(TSECSWRB),
+	mc_make_sid_security_cfg(ISPWB),
+	mc_make_sid_security_cfg(GPUSRD2),
+	mc_make_sid_override_cfg(APER),
+	mc_make_sid_override_cfg(VICSRD),
+	mc_make_sid_override_cfg(NVENCSRD),
+	mc_make_sid_override_cfg(NVJPGSWR),
+	mc_make_sid_override_cfg(AONW),
+	mc_make_sid_override_cfg(BPMPR),
+	mc_make_sid_override_cfg(BPMPW),
+	mc_make_sid_override_cfg(HDAW),
+	mc_make_sid_override_cfg(NVDISPLAYR1),
+	mc_make_sid_override_cfg(APEDMAR),
+	mc_make_sid_override_cfg(AFIR),
+	mc_make_sid_override_cfg(AXISR),
+	mc_make_sid_override_cfg(VICSRD1),
+	mc_make_sid_override_cfg(TSECSRD),
+	mc_make_sid_override_cfg(BPMPDMAW),
+	mc_make_sid_override_cfg(MPCOREW),
+	mc_make_sid_override_cfg(XUSB_HOSTR),
+	mc_make_sid_override_cfg(GPUSWR),
+	mc_make_sid_override_cfg(XUSB_DEVR),
+	mc_make_sid_override_cfg(UFSHCW),
+	mc_make_sid_override_cfg(XUSB_HOSTW),
+	mc_make_sid_override_cfg(SDMMCWAB),
+	mc_make_sid_override_cfg(SATAW),
+	mc_make_sid_override_cfg(SCEDMAR),
+	mc_make_sid_override_cfg(HOST1XDMAR),
+	mc_make_sid_override_cfg(SDMMCWA),
+	mc_make_sid_override_cfg(APEDMAW),
+	mc_make_sid_override_cfg(SESWR),
+	mc_make_sid_override_cfg(AXISW),
+	mc_make_sid_override_cfg(AONDMAW),
+	mc_make_sid_override_cfg(TSECSWRB),
+	mc_make_sid_override_cfg(MPCORER),
+	mc_make_sid_override_cfg(ISPWB),
+	mc_make_sid_override_cfg(AONR),
+	mc_make_sid_override_cfg(BPMPDMAR),
+	mc_make_sid_override_cfg(HDAR),
+	mc_make_sid_override_cfg(SDMMCRA),
+	mc_make_sid_override_cfg(ETRW),
+	mc_make_sid_override_cfg(GPUSWR2),
+	mc_make_sid_override_cfg(EQOSR),
+	mc_make_sid_override_cfg(TSECSWR),
+	mc_make_sid_override_cfg(ETRR),
+	mc_make_sid_override_cfg(NVDECSRD),
+	mc_make_sid_override_cfg(TSECSRDB),
+	mc_make_sid_override_cfg(SDMMCRAA),
+	mc_make_sid_override_cfg(NVDECSRD1),
+	mc_make_sid_override_cfg(SDMMCR),
+	mc_make_sid_override_cfg(NVJPGSRD),
+	mc_make_sid_override_cfg(SCEDMAW),
+	mc_make_sid_override_cfg(SDMMCWAA),
+	mc_make_sid_override_cfg(APEW),
+	mc_make_sid_override_cfg(AONDMAR),
+	mc_make_sid_override_cfg(PTCR),
+	mc_make_sid_override_cfg(SCER),
+	mc_make_sid_override_cfg(ISPRA),
+	mc_make_sid_override_cfg(ISPWA),
+	mc_make_sid_override_cfg(VICSWR),
+	mc_make_sid_override_cfg(SESRD),
+	mc_make_sid_override_cfg(SDMMCW),
+	mc_make_sid_override_cfg(SDMMCRAB),
+	mc_make_sid_override_cfg(EQOSW),
+	mc_make_sid_override_cfg(GPUSRD2),
+	mc_make_sid_override_cfg(SCEW),
+	mc_make_sid_override_cfg(GPUSRD),
+	mc_make_sid_override_cfg(NVDECSWR),
+	mc_make_sid_override_cfg(XUSB_DEVW),
+	mc_make_sid_override_cfg(SATAR),
+	mc_make_sid_override_cfg(NVDISPLAYR),
+	mc_make_sid_override_cfg(VIW),
+	mc_make_sid_override_cfg(UFSHCR),
+	mc_make_sid_override_cfg(NVENCSWR),
+	mc_make_sid_override_cfg(AFIW),
+	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_,
+};
+
+/*
+ * Save SMMU settings before "System Suspend"
+ */
+void tegra_smmu_save_context(void)
+{
+	uint32_t i;
+#if DEBUG
+	uint32_t reg_id1, pgshift, cb_size;
+
+	/* sanity check SMMU settings c*/
+	reg_id1 = mmio_read_32((TEGRA_SMMU_BASE + SMMU_GNSR0_IDR1));
+	pgshift = (reg_id1 & ID1_PAGESIZE) ? 16 : 12;
+	cb_size = (2 << pgshift) * \
+	(1 << (((reg_id1 >> ID1_NUMPAGENDXB_SHIFT) & ID1_NUMPAGENDXB_MASK) + 1));
+
+	assert(!((pgshift != PGSHIFT) || (cb_size != CB_SIZE)));
+#endif
+
+	/* index of _END_OF_TABLE_ */
+	smmu_ctx_regs[0].val = ARRAY_SIZE(smmu_ctx_regs) - 1;
+
+	/* save SMMU register values */
+	for (i = 1; i < ARRAY_SIZE(smmu_ctx_regs) - 1; i++)
+		smmu_ctx_regs[i].val = mmio_read_32(smmu_ctx_regs[i].reg);
+
+	/* save the SMMU table address */
+	mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV11_LO,
+		(uint32_t)(unsigned long)smmu_ctx_regs);
+	mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV11_HI,
+		(uint32_t)(((unsigned long)smmu_ctx_regs) >> 32));
+}
+
+/*
+ * Init SMMU during boot or "System Suspend" exit
+ */
+void tegra_smmu_init(void)
+{
+	uint32_t val;
+
+	/* Program the SMMU pagesize */
+	val = tegra_smmu_read_32(SMMU_GSR0_SECURE_ACR);
+	val |= SMMU_GSR0_PGSIZE_64K;
+	tegra_smmu_write_32(SMMU_GSR0_SECURE_ACR, val);
+}
diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
new file mode 100644
index 0000000..7e35cc6
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
@@ -0,0 +1,295 @@
+/*
+ * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <context.h>
+#include <context_mgmt.h>
+#include <debug.h>
+#include <denver.h>
+#include <mce.h>
+#include <psci.h>
+#include <smmu.h>
+#include <t18x_ari.h>
+#include <tegra_private.h>
+
+extern void prepare_cpu_pwr_dwn(void);
+
+/* state id mask */
+#define TEGRA186_STATE_ID_MASK		0xF
+/* constants to get power state's wake time */
+#define TEGRA186_WAKE_TIME_MASK		0xFFFFFF
+#define TEGRA186_WAKE_TIME_SHIFT	4
+/* context size to save during system suspend */
+#define TEGRA186_SE_CONTEXT_SIZE		3
+
+static uint32_t se_regs[TEGRA186_SE_CONTEXT_SIZE];
+static unsigned int wake_time[PLATFORM_CORE_COUNT];
+
+/* System power down state */
+uint32_t tegra186_system_powerdn_state = TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF;
+
+int32_t tegra_soc_validate_power_state(unsigned int power_state,
+					psci_power_state_t *req_state)
+{
+	int state_id = psci_get_pstate_id(power_state) & TEGRA186_STATE_ID_MASK;
+	int cpu = read_mpidr() & MPIDR_CPU_MASK;
+	int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
+
+	if (impl == DENVER_IMPL)
+		cpu |= 0x4;
+
+	wake_time[cpu] = (power_state  >> TEGRA186_WAKE_TIME_SHIFT) &
+			 TEGRA186_WAKE_TIME_MASK;
+
+	/* Sanity check the requested state id */
+	switch (state_id) {
+	case PSTATE_ID_CORE_IDLE:
+	case PSTATE_ID_CORE_POWERDN:
+		/*
+		 * Core powerdown request only for afflvl 0
+		 */
+		req_state->pwr_domain_state[MPIDR_AFFLVL0] = 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;
+	int cpu = read_mpidr() & MPIDR_CPU_MASK;
+	int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
+	cpu_context_t *ctx = cm_get_context(NON_SECURE);
+	gp_regs_t *gp_regs = get_gpregs_ctx(ctx);
+	uint32_t val;
+
+	assert(ctx);
+	assert(gp_regs);
+
+	if (impl == DENVER_IMPL)
+		cpu |= 0x4;
+
+	/* 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) {
+
+		/* Prepare for cpu idle */
+		(void)mce_command_handler(MCE_CMD_ENTER_CSTATE,
+			TEGRA_ARI_CORE_C6, wake_time[cpu], 0);
+
+	} else if (stateid_afflvl0 == PSTATE_ID_CORE_POWERDN) {
+
+		/* Prepare for cpu powerdn */
+		(void)mce_command_handler(MCE_CMD_ENTER_CSTATE,
+			TEGRA_ARI_CORE_C7, wake_time[cpu], 0);
+
+	} else if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
+
+		/* loop until SC7 is allowed */
+		do {
+			val = mce_command_handler(MCE_CMD_IS_SC7_ALLOWED,
+					TEGRA_ARI_CORE_C7,
+					MCE_CORE_SLEEP_TIME_INFINITE,
+					0);
+		} while (val == 0);
+
+		/* 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);
+
+		/* save SMMU context */
+		tegra_smmu_save_context();
+
+		/* Prepare for system suspend */
+		write_ctx_reg(gp_regs, CTX_GPREG_X4, 1);
+		write_ctx_reg(gp_regs, CTX_GPREG_X5, 0);
+		write_ctx_reg(gp_regs, CTX_GPREG_X6, 1);
+		(void)mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO,
+			TEGRA_ARI_CLUSTER_CC7, 0, TEGRA_ARI_SYSTEM_SC7);
+
+		/* Enter system suspend state */
+		(void)mce_command_handler(MCE_CMD_ENTER_CSTATE,
+			TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0);
+
+	} else {
+		ERROR("%s: Unknown state id\n", __func__);
+		return PSCI_E_NOT_SUPPORTED;
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
+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 state_id = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL];
+
+	/*
+	 * Check if we are exiting from deep sleep and restore SE
+	 * context if we are.
+	 */
+	if (state_id == 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 */
+		tegra_smmu_init();
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
+int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
+{
+	cpu_context_t *ctx = cm_get_context(NON_SECURE);
+	gp_regs_t *gp_regs = get_gpregs_ctx(ctx);
+	int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
+
+	assert(ctx);
+	assert(gp_regs);
+
+	/* Turn off wake_mask */
+	write_ctx_reg(gp_regs, CTX_GPREG_X4, 0);
+	write_ctx_reg(gp_regs, CTX_GPREG_X5, 0);
+	write_ctx_reg(gp_regs, CTX_GPREG_X6, 1);
+	mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO, TEGRA_ARI_CLUSTER_CC7,
+		0, TEGRA_ARI_SYSTEM_SC7);
+
+	/* Disable Denver's DCO operations */
+	if (impl == DENVER_IMPL)
+		denver_disable_dco();
+
+	/* Turn off CPU */
+	return mce_command_handler(MCE_CMD_ENTER_CSTATE, TEGRA_ARI_CORE_C7,
+			MCE_CORE_SLEEP_TIME_INFINITE, 0);
+}
+
+__dead2 void tegra_soc_prepare_system_off(void)
+{
+	cpu_context_t *ctx = cm_get_context(NON_SECURE);
+	gp_regs_t *gp_regs = get_gpregs_ctx(ctx);
+	uint32_t val;
+
+	if (tegra186_system_powerdn_state == TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF) {
+
+		/* power off the entire system */
+		mce_enter_ccplex_state(tegra186_system_powerdn_state);
+
+	} else if (tegra186_system_powerdn_state == TEGRA_ARI_SYSTEM_SC8) {
+
+		/* loop until other CPUs power down */
+		do {
+			val = mce_command_handler(MCE_CMD_IS_SC7_ALLOWED,
+					TEGRA_ARI_CORE_C7,
+					MCE_CORE_SLEEP_TIME_INFINITE,
+					0);
+		} while (val == 0);
+
+		/* Prepare for quasi power down */
+		write_ctx_reg(gp_regs, CTX_GPREG_X4, 1);
+		write_ctx_reg(gp_regs, CTX_GPREG_X5, 0);
+		write_ctx_reg(gp_regs, CTX_GPREG_X6, 1);
+		(void)mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO,
+			TEGRA_ARI_CLUSTER_CC7, 0, TEGRA_ARI_SYSTEM_SC8);
+
+		/* Enter quasi power down state */
+		(void)mce_command_handler(MCE_CMD_ENTER_CSTATE,
+			TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0);
+
+		/* disable GICC */
+		tegra_gic_cpuif_deactivate();
+
+		/* power down core */
+		prepare_cpu_pwr_dwn();
+
+	} else {
+		ERROR("%s: unsupported power down state (%d)\n", __func__,
+			tegra186_system_powerdn_state);
+	}
+
+	wfi();
+
+	/* wait for the system to power down */
+	for (;;) {
+		;
+	}
+}
+
+int tegra_soc_prepare_system_reset(void)
+{
+	mce_enter_ccplex_state(TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT);
+
+	return PSCI_E_SUCCESS;
+}
diff --git a/plat/nvidia/tegra/soc/t186/plat_secondary.c b/plat/nvidia/tegra/soc/t186/plat_secondary.c
new file mode 100644
index 0000000..df80289
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t186/plat_secondary.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <debug.h>
+#include <mce.h>
+#include <mmio.h>
+#include <tegra_def.h>
+
+#define MISCREG_CPU_RESET_VECTOR	0x2000
+#define MISCREG_AA64_RST_LOW		0x2004
+#define MISCREG_AA64_RST_HIGH		0x2008
+
+#define SCRATCH_SECURE_RSV1_SCRATCH_0	0x658
+#define SCRATCH_SECURE_RSV1_SCRATCH_1	0x65C
+
+#define CPU_RESET_MODE_AA64		1
+
+extern void tegra_secure_entrypoint(void);
+
+/*******************************************************************************
+ * Setup secondary CPU vectors
+ ******************************************************************************/
+void plat_secondary_setup(void)
+{
+	uint32_t addr_low, addr_high;
+	uint64_t reset_addr = (uint64_t)tegra_secure_entrypoint;
+
+	INFO("Setting up secondary CPU boot\n");
+
+	addr_low = (uint32_t)reset_addr | CPU_RESET_MODE_AA64;
+	addr_high = (uint32_t)((reset_addr >> 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 + SCRATCH_SECURE_RSV1_SCRATCH_0,
+			addr_low);
+	mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_RSV1_SCRATCH_1,
+			addr_high);
+
+	/* update reset vector address to the CCPLEX */
+	mce_update_reset_vector(addr_low, addr_high);
+}
diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c
new file mode 100644
index 0000000..d6b8bc3
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t186/plat_setup.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <console.h>
+#include <context.h>
+#include <context_mgmt.h>
+#include <debug.h>
+#include <denver.h>
+#include <interrupt_mgmt.h>
+#include <platform.h>
+#include <tegra_def.h>
+#include <tegra_private.h>
+#include <xlat_tables.h>
+
+/*******************************************************************************
+ * The Tegra power domain tree has a single system level power domain i.e. a
+ * single root node. The first entry in the power domain descriptor specifies
+ * the number of power domains at the highest power level.
+ *******************************************************************************
+ */
+const unsigned char tegra_power_domain_tree_desc[] = {
+	/* No of root nodes */
+	1,
+	/* No of clusters */
+	PLATFORM_CLUSTER_COUNT,
+	/* No of CPU cores - cluster0 */
+	PLATFORM_MAX_CPUS_PER_CLUSTER,
+	/* No of CPU cores - cluster1 */
+	PLATFORM_MAX_CPUS_PER_CLUSTER
+};
+
+/*
+ * 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_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 */
+			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_SMMU_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];
+}
+
+/* Secure IRQs for Tegra186 */
+static const irq_sec_cfg_t tegra186_sec_irqs[] = {
+	{
+		TEGRA186_TOP_WDT_IRQ,
+		TEGRA186_SEC_IRQ_TARGET_MASK,
+		INTR_TYPE_EL3,
+	},
+	{
+		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();
+}
diff --git a/plat/nvidia/tegra/soc/t186/plat_sip_calls.c b/plat/nvidia/tegra/soc/t186/plat_sip_calls.c
new file mode 100644
index 0000000..fabab01
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t186/plat_sip_calls.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <context_mgmt.h>
+#include <debug.h>
+#include <errno.h>
+#include <mce.h>
+#include <memctrl.h>
+#include <runtime_svc.h>
+#include <t18x_ari.h>
+#include <tegra_private.h>
+
+extern uint32_t tegra186_system_powerdn_state;
+
+/*******************************************************************************
+ * Tegra186 SiP SMCs
+ ******************************************************************************/
+#define TEGRA_SIP_NEW_VIDEOMEM_REGION			0x82000003
+#define TEGRA_SIP_SYSTEM_SHUTDOWN_STATE			0x82FFFE01
+#define TEGRA_SIP_MCE_CMD_ENTER_CSTATE			0x82FFFF00
+#define TEGRA_SIP_MCE_CMD_UPDATE_CSTATE_INFO		0x82FFFF01
+#define TEGRA_SIP_MCE_CMD_UPDATE_CROSSOVER_TIME		0x82FFFF02
+#define TEGRA_SIP_MCE_CMD_READ_CSTATE_STATS		0x82FFFF03
+#define TEGRA_SIP_MCE_CMD_WRITE_CSTATE_STATS		0x82FFFF04
+#define TEGRA_SIP_MCE_CMD_IS_SC7_ALLOWED		0x82FFFF05
+#define TEGRA_SIP_MCE_CMD_ONLINE_CORE			0x82FFFF06
+#define TEGRA_SIP_MCE_CMD_CC3_CTRL			0x82FFFF07
+#define TEGRA_SIP_MCE_CMD_ECHO_DATA			0x82FFFF08
+#define TEGRA_SIP_MCE_CMD_READ_VERSIONS			0x82FFFF09
+#define TEGRA_SIP_MCE_CMD_ENUM_FEATURES			0x82FFFF0A
+#define TEGRA_SIP_MCE_CMD_ROC_FLUSH_CACHE_TRBITS	0x82FFFF0B
+#define TEGRA_SIP_MCE_CMD_ENUM_READ_MCA			0x82FFFF0C
+#define TEGRA_SIP_MCE_CMD_ENUM_WRITE_MCA		0x82FFFF0D
+#define TEGRA_SIP_MCE_CMD_ROC_FLUSH_CACHE		0x82FFFF0E
+#define TEGRA_SIP_MCE_CMD_ROC_CLEAN_CACHE		0x82FFFF0F
+
+/*******************************************************************************
+ * 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;
+
+	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:
+
+		/* 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_NEW_VIDEOMEM_REGION:
+		/* clean up the high bits */
+		x1 = (uint32_t)x1;
+		x2 = (uint32_t)x2;
+
+		/*
+		 * Check if Video Memory overlaps TZDRAM (contains bl31/bl32)
+		 * or falls outside of the valid DRAM range
+		 */
+		mce_ret = bl31_check_ns_address(x1, x2);
+		if (mce_ret)
+			return -ENOTSUP;
+
+		/*
+		 * Check if Video Memory is aligned to 1MB.
+		 */
+		if ((x1 & 0xFFFFF) || (x2 & 0xFFFFF)) {
+			ERROR("Unaligned Video Memory base address!\n");
+			return -ENOTSUP;
+		}
+
+		/* new video memory carveout settings */
+		tegra_memctrl_videomem_setup(x1, x2);
+
+		return 0;
+
+	case TEGRA_SIP_SYSTEM_SHUTDOWN_STATE:
+
+		/* clean up the high bits */
+		x1 = (uint32_t)x1;
+
+		/*
+		 * SC8 is a special Tegra186 system state where the CPUs and
+		 * DRAM are powered down but the other subsystem is still
+		 * alive.
+		 */
+		if ((x1 == TEGRA_ARI_SYSTEM_SC8) ||
+		    (x1 == TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF)) {
+
+			tegra186_system_powerdn_state = x1;
+			flush_dcache_range(
+				(uintptr_t)&tegra186_system_powerdn_state,
+				sizeof(tegra186_system_powerdn_state));
+
+		} else {
+
+			ERROR("%s: unhandled powerdn state (%d)\n", __func__,
+				(uint32_t)x1);
+			return -ENOTSUP;
+		}
+
+		return 0;
+
+	default:
+		break;
+	}
+
+	return -ENOTSUP;
+}
diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk
new file mode 100644
index 0000000..adc4a9e
--- /dev/null
+++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk
@@ -0,0 +1,65 @@
+#
+# Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+# platform configs
+ENABLE_NS_L2_CPUECTRL_RW_ACCESS		:= 1
+$(eval $(call add_define,ENABLE_NS_L2_CPUECTRL_RW_ACCESS))
+
+# platform settings
+TZDRAM_BASE				:= 0x30000000
+$(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				:= 15
+$(eval $(call add_define,MAX_XLAT_TABLES))
+
+MAX_MMAP_REGIONS			:= 15
+$(eval $(call add_define,MAX_MMAP_REGIONS))
+
+# platform files
+PLAT_INCLUDES		+=	-I${SOC_DIR}/drivers/include
+
+BL31_SOURCES		+=	lib/cpus/aarch64/denver.S		\
+				lib/cpus/aarch64/cortex_a57.S		\
+				${COMMON_DIR}/drivers/memctrl/memctrl_v2.c	\
+				${SOC_DIR}/drivers/mce/mce.c		\
+				${SOC_DIR}/drivers/mce/ari.c		\
+				${SOC_DIR}/drivers/mce/nvg.c		\
+				${SOC_DIR}/drivers/mce/aarch64/nvg_helpers.S \
+				${SOC_DIR}/drivers/smmu/smmu.c		\
+				${SOC_DIR}/plat_psci_handlers.c		\
+				${SOC_DIR}/plat_setup.c			\
+				${SOC_DIR}/plat_secondary.c		\
+				${SOC_DIR}/plat_sip_calls.c
diff --git a/plat/nvidia/tegra/soc/t210/platform_t210.mk b/plat/nvidia/tegra/soc/t210/platform_t210.mk
index 822240f..8946869 100644
--- a/plat/nvidia/tegra/soc/t210/platform_t210.mk
+++ b/plat/nvidia/tegra/soc/t210/platform_t210.mk
@@ -66,3 +66,4 @@
 A53_DISABLE_NON_TEMPORAL_HINT	:=	1
 ERRATA_A53_826319		:=	1
 ERRATA_A53_836870		:=	1
+ERRATA_A53_855873		:=	1