diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
index 41a4ede80a1e600c9f631895860f42274970513d..87c7ed03df3cae7855f4fd1600221caf740bc627 100644
--- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
+++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
@@ -40,7 +40,8 @@
 #include <string.h>
 #include <tegra_def.h>
 #include <tegra_platform.h>
-#include <xlat_tables.h>
+#include <utils.h>
+#include <xlat_tables_v2.h>
 
 #define TEGRA_GPU_RESET_REG_OFFSET	0x30
 #define  GPU_RESET_BIT			(1 << 0)
@@ -450,7 +451,7 @@ void tegra_memctrl_restore_settings(void)
 		tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size_mb);
 
 		/*
-		 * MCE propogates the VideoMem configuration values across the
+		 * MCE propagates the VideoMem configuration values across the
 		 * CCPLEX.
 		 */
 		mce_update_gsc_videomem();
@@ -490,7 +491,7 @@ void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes)
 					tegra_mc_read_32(MC_SECURITY_CFG1_0));
 
 	/*
-	 * MCE propogates the security configuration values across the
+	 * MCE propagates the security configuration values across the
 	 * CCPLEX.
 	 */
 	mce_update_gsc_tzdram();
@@ -506,25 +507,28 @@ void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes)
 {
 	uint32_t index;
 	uint32_t total_128kb_blocks = size_in_bytes >> 17;
-	uint32_t residual_4kb_blocks = (size_in_bytes & 0x1FFFF) >> 12;
+	uint32_t residual_4kb_blocks = (size_in_bytes & (uint32_t)0x1FFFF) >> 12;
 	uint32_t val;
 
+	INFO("Configuring TrustZone SRAM Memory Carveout\n");
+
 	/*
 	 * Reset the access configuration registers to restrict access
 	 * to the TZRAM aperture
 	 */
-	for (index = MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG0;
-	     index <= MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS5;
-	     index += 4)
+	for (index = MC_TZRAM_CLIENT_ACCESS_CFG0;
+	     index < ((uint32_t)MC_TZRAM_CARVEOUT_CFG + (uint32_t)MC_GSC_CONFIG_REGS_SIZE);
+	     index += 4U) {
 		tegra_mc_write_32(index, 0);
+	}
 
 	/*
 	 * Set the TZRAM base. TZRAM base must be 4k aligned, at least.
 	 */
-	assert(!(phys_base & 0xFFF));
+	assert((phys_base & (uint64_t)0xFFF) == 0U);
 	tegra_mc_write_32(MC_TZRAM_BASE_LO, (uint32_t)phys_base);
 	tegra_mc_write_32(MC_TZRAM_BASE_HI,
-		(uint32_t)(phys_base >> 32) & TZRAM_BASE_HI_MASK);
+		(uint32_t)(phys_base >> 32) & MC_GSC_BASE_HI_MASK);
 
 	/*
 	 * Set the TZRAM size
@@ -533,7 +537,7 @@ void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes)
 	 * blocks)
 	 *
 	 */
-	val = (residual_4kb_blocks << TZRAM_SIZE_RANGE_4KB_SHIFT) |
+	val = (residual_4kb_blocks << MC_GSC_SIZE_RANGE_4KB_SHIFT) |
 	      total_128kb_blocks;
 	tegra_mc_write_32(MC_TZRAM_SIZE, val);
 
@@ -543,17 +547,96 @@ void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes)
 	 * at all.
 	 */
 	val = tegra_mc_read_32(MC_TZRAM_CARVEOUT_CFG);
-	val &= ~TZRAM_ENABLE_TZ_LOCK_BIT;
-	val |= TZRAM_LOCK_CFG_SETTINGS_BIT;
+	val &= ~MC_GSC_ENABLE_TZ_LOCK_BIT;
+	val |= MC_GSC_LOCK_CFG_SETTINGS_BIT;
 	tegra_mc_write_32(MC_TZRAM_CARVEOUT_CFG, val);
 
 	/*
-	 * MCE propogates the security configuration values across the
+	 * MCE propagates the security configuration values across the
 	 * CCPLEX.
 	 */
 	mce_update_gsc_tzram();
 }
 
+static void tegra_lock_videomem_nonoverlap(uint64_t phys_base,
+					   uint64_t size_in_bytes)
+{
+	uint32_t index;
+	uint64_t total_128kb_blocks = size_in_bytes >> 17;
+	uint64_t residual_4kb_blocks = (size_in_bytes & (uint32_t)0x1FFFF) >> 12;
+	uint64_t val;
+
+	/*
+	 * Reset the access configuration registers to restrict access to
+	 * old Videomem aperture
+	 */
+	for (index = MC_VIDEO_PROTECT_CLEAR_ACCESS_CFG0;
+	     index < ((uint32_t)MC_VIDEO_PROTECT_CLEAR_ACCESS_CFG0 + (uint32_t)MC_GSC_CONFIG_REGS_SIZE);
+	     index += 4U) {
+		tegra_mc_write_32(index, 0);
+	}
+
+	/*
+	 * Set the base. It must be 4k aligned, at least.
+	 */
+	assert((phys_base & (uint64_t)0xFFF) == 0U);
+	tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_BASE_LO, (uint32_t)phys_base);
+	tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_BASE_HI,
+		(uint32_t)(phys_base >> 32) & (uint32_t)MC_GSC_BASE_HI_MASK);
+
+	/*
+	 * Set the aperture size
+	 *
+	 * total size = (number of 128KB blocks) + (number of remaining 4KB
+	 * blocks)
+	 *
+	 */
+	val = (uint32_t)((residual_4kb_blocks << MC_GSC_SIZE_RANGE_4KB_SHIFT) |
+			 total_128kb_blocks);
+	tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_SIZE, (uint32_t)val);
+
+	/*
+	 * Lock the configuration settings by enabling TZ-only lock and
+	 * locking the configuration against any future changes from NS
+	 * world.
+	 */
+	tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_CFG,
+			  (uint32_t)MC_GSC_ENABLE_TZ_LOCK_BIT);
+
+	/*
+	 * MCE propagates the GSC configuration values across the
+	 * CCPLEX.
+	 */
+}
+
+static void tegra_unlock_videomem_nonoverlap(void)
+{
+	/* Clear the base */
+	tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_BASE_LO, 0);
+	tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_BASE_HI, 0);
+
+	/* Clear the size */
+	tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_SIZE, 0);
+}
+
+static void tegra_clear_videomem(uintptr_t non_overlap_area_start,
+				 unsigned long long non_overlap_area_size)
+{
+	/*
+	 * Map the NS memory first, clean it and then unmap it.
+	 */
+	mmap_add_dynamic_region(non_overlap_area_start, /* PA */
+				non_overlap_area_start, /* VA */
+				non_overlap_area_size, /* size */
+				MT_NS | MT_RW | MT_EXECUTE_NEVER); /* attrs */
+
+	zero_normalmem((void *)non_overlap_area_start, non_overlap_area_size);
+	flush_dcache_range(non_overlap_area_start, non_overlap_area_size);
+
+	mmap_remove_dynamic_region(non_overlap_area_start,
+		non_overlap_area_size);
+}
+
 /*
  * Program the Video Memory carveout region
  *
@@ -562,7 +645,10 @@ void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes)
  */
 void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes)
 {
+	uintptr_t vmem_end_old = video_mem_base + (video_mem_size_mb << 20);
+	uintptr_t vmem_end_new = phys_base + size_in_bytes;
 	uint32_t regval;
+	unsigned long long non_overlap_area_size;
 
 	/*
 	 * The GPU is the user of the Video Memory region. In order to
@@ -570,7 +656,7 @@ void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes)
 	 * 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) {
+	if ((regval & GPU_RESET_BIT) == 0U) {
 		ERROR("GPU not in reset! Video Memory setup failed\n");
 		return;
 	}
@@ -581,17 +667,61 @@ void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes)
 	 */
 	INFO("Configuring Video Memory Carveout\n");
 
+	/*
+	 * Configure Memory Controller directly for the first time.
+	 */
+	if (video_mem_base == 0U)
+		goto done;
+
+	/*
+	 * Lock the non overlapping memory being cleared so that other masters
+	 * do not accidently write to it. The memory would be unlocked once
+	 * the non overlapping region is cleared and the new memory
+	 * settings take effect.
+	 */
+	tegra_lock_videomem_nonoverlap(video_mem_base,
+				       video_mem_size_mb << 20);
+
+	/*
+	 * Clear the old regions now being exposed. The following cases
+	 * can occur -
+	 *
+	 * 1. clear whole old region (no overlap with new region)
+	 * 2. clear old sub-region below new base
+	 * 3. clear old sub-region above new end
+	 */
+	INFO("Cleaning previous Video Memory Carveout\n");
+
+	if (phys_base > vmem_end_old || video_mem_base > vmem_end_new) {
+		tegra_clear_videomem(video_mem_base,
+				     (uint64_t)video_mem_size_mb << 20);
+	} else {
+		if (video_mem_base < phys_base) {
+			non_overlap_area_size = phys_base - video_mem_base;
+			tegra_clear_videomem(video_mem_base, non_overlap_area_size);
+		}
+		if (vmem_end_old > vmem_end_new) {
+			non_overlap_area_size = vmem_end_old - vmem_end_new;
+			tegra_clear_videomem(vmem_end_new, non_overlap_area_size);
+		}
+	}
+
+done:
+	/* program the Videomem aperture */
 	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 >> 20);
 
+	/* unlock the previous locked nonoverlapping aperture */
+	tegra_unlock_videomem_nonoverlap();
+
 	/* store new values */
 	video_mem_base = phys_base;
 	video_mem_size_mb = size_in_bytes >> 20;
 
 	/*
-	 * MCE propogates the VideoMem configuration values across the
+	 * MCE propagates the VideoMem configuration values across the
 	 * CCPLEX.
 	 */
 	mce_update_gsc_videomem();
diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h
index 6693cb3ae6daa9a35aab603bf02f604815129757..8d7ab6eae566d174946bce2c174b1ed1cc53397b 100644
--- a/plat/nvidia/tegra/include/t186/tegra_def.h
+++ b/plat/nvidia/tegra/include/t186/tegra_def.h
@@ -157,6 +157,16 @@
 #define TEGRA_MC_STREAMID_BASE		0x02C00000
 #define TEGRA_MC_BASE			0x02C10000
 
+/* General Security Carveout register macros */
+#define MC_GSC_CONFIG_REGS_SIZE		0x40UL
+#define MC_GSC_LOCK_CFG_SETTINGS_BIT	(1UL << 1)
+#define MC_GSC_ENABLE_TZ_LOCK_BIT	(1UL << 0)
+#define MC_GSC_SIZE_RANGE_4KB_SHIFT	27UL
+#define MC_GSC_BASE_LO_SHIFT		12UL
+#define MC_GSC_BASE_LO_MASK		0xFFFFFUL
+#define MC_GSC_BASE_HI_SHIFT		0UL
+#define MC_GSC_BASE_HI_MASK		3UL
+
 /* TZDRAM carveout configuration registers */
 #define MC_SECURITY_CFG0_0		0x70
 #define MC_SECURITY_CFG1_0		0x74
@@ -165,34 +175,24 @@
 /* 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
+#define MC_VIDEO_PROTECT_SIZE_MB	0x64C
+
+/*
+ * Carveout (MC_SECURITY_CARVEOUT24) registers used to clear the
+ * non-overlapping Video memory region
+ */
+#define MC_VIDEO_PROTECT_CLEAR_CFG	0x25A0
+#define MC_VIDEO_PROTECT_CLEAR_BASE_LO	0x25A4
+#define MC_VIDEO_PROTECT_CLEAR_BASE_HI	0x25A8
+#define MC_VIDEO_PROTECT_CLEAR_SIZE	0x25AC
+#define MC_VIDEO_PROTECT_CLEAR_ACCESS_CFG0	0x25B0
 
 /* TZRAM carveout (MC_SECURITY_CARVEOUT11) configuration registers */
+#define MC_TZRAM_CARVEOUT_CFG		0x2190
 #define MC_TZRAM_BASE_LO		0x2194
-#define  TZRAM_BASE_LO_SHIFT		12
-#define  TZRAM_BASE_LO_MASK		0xFFFFF
 #define MC_TZRAM_BASE_HI		0x2198
-#define  TZRAM_BASE_HI_SHIFT		0
-#define  TZRAM_BASE_HI_MASK		3
 #define MC_TZRAM_SIZE			0x219C
-#define  TZRAM_SIZE_RANGE_4KB_SHIFT	27
-
-#define MC_TZRAM_CARVEOUT_CFG			0x2190
-#define  TZRAM_LOCK_CFG_SETTINGS_BIT		(1 << 1)
-#define  TZRAM_ENABLE_TZ_LOCK_BIT		(1 << 0)
-#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG0	0x21A0
-#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG1	0x21A4
-#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG2	0x21A8
-#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG3	0x21AC
-#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG4	0x21B0
-#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG5	0x21B4
-
-#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS0	0x21B8
-#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS1	0x21BC
-#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS2	0x21C0
-#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS3	0x21C4
-#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS4	0x21C8
-#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS5	0x21CC
+#define MC_TZRAM_CLIENT_ACCESS_CFG0	0x21A0
 
 /*******************************************************************************
  * Tegra UART Controller constants