diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h
index 02c5f135e01d0b3bed711858b1991316f7d2a019..eed443d11dff0cb486c39932432ce3381e3698bc 100644
--- a/plat/nvidia/tegra/include/t210/tegra_def.h
+++ b/plat/nvidia/tegra/include/t210/tegra_def.h
@@ -41,6 +41,7 @@
  * iRAM memory constants
  ******************************************************************************/
 #define TEGRA_IRAM_BASE			U(0x40000000)
+#define TEGRA_IRAM_A_SIZE		U(0x10000) /* 64KB */
 #define TEGRA_IRAM_SIZE			U(40000) /* 256KB */
 
 /*******************************************************************************
@@ -95,23 +96,55 @@
  * Tegra Clock and Reset Controller constants
  ******************************************************************************/
 #define TEGRA_CAR_RESET_BASE		U(0x60006000)
+#define TEGRA_BOND_OUT_H		U(0x74)
+#define  APB_DMA_LOCK_BIT		(U(1) << 2)
+#define  AHB_DMA_LOCK_BIT		(U(1) << 1)
+#define TEGRA_BOND_OUT_U		U(0x78)
+#define  IRAM_D_LOCK_BIT		(U(1) << 23)
+#define  IRAM_C_LOCK_BIT		(U(1) << 22)
+#define  IRAM_B_LOCK_BIT		(U(1) << 21)
 #define TEGRA_GPU_RESET_REG_OFFSET	U(0x28C)
 #define TEGRA_GPU_RESET_GPU_SET_OFFSET	U(0x290)
 #define  GPU_RESET_BIT			(U(1) << 24)
 #define  GPU_SET_BIT			(U(1) << 24)
+#define TEGRA_RST_DEV_SET_Y		U(0x2a8)
+#define  NVENC_RESET_BIT		(U(1) << 27)
+#define  TSECB_RESET_BIT		(U(1) << 14)
+#define  APE_RESET_BIT			(U(1) << 6)
+#define  NVJPG_RESET_BIT		(U(1) << 3)
+#define  NVDEC_RESET_BIT		(U(1) << 2)
+#define TEGRA_RST_DEV_SET_L		U(0x300)
+#define  HOST1X_RESET_BIT		(U(1) << 28)
+#define  ISP_RESET_BIT			(U(1) << 23)
+#define  USBD_RESET_BIT			(U(1) << 22)
+#define  VI_RESET_BIT			(U(1) << 20)
+#define  SDMMC4_RESET_BIT		(U(1) << 15)
+#define  SDMMC1_RESET_BIT		(U(1) << 14)
+#define  SDMMC2_RESET_BIT		(U(1) << 9)
+#define TEGRA_RST_DEV_SET_H		U(0x308)
+#define  USB2_RESET_BIT			(U(1) << 26)
+#define  APBDMA_RESET_BIT		(U(1) << 2)
+#define  AHBDMA_RESET_BIT		(U(1) << 1)
+#define TEGRA_RST_DEV_SET_U		U(0x310)
+#define  XUSB_DEV_RESET_BIT		(U(1) << 31)
+#define  XUSB_HOST_RESET_BIT		(U(1) << 25)
+#define  TSEC_RESET_BIT			(U(1) << 19)
+#define  PCIE_RESET_BIT			(U(1) << 6)
+#define  SDMMC3_RESET_BIT		(U(1) << 5)
+#define TEGRA_RST_DEVICES_V		U(0x358)
+#define TEGRA_RST_DEVICES_W		U(0x35C)
+#define  ENTROPY_CLK_ENB_BIT		(U(1) << 21)
+#define TEGRA_CLK_OUT_ENB_V		U(0x360)
+#define  SE_CLK_ENB_BIT			(U(1) << 31)
+#define TEGRA_CLK_OUT_ENB_W		U(0x364)
+#define  ENTROPY_RESET_BIT 		(U(1) << 21)
+#define TEGRA_RST_DEV_SET_V		U(0x430)
+#define  SE_RESET_BIT			(U(1) << 31)
+#define  HDA_RESET_BIT			(U(1) << 29)
+#define  SATA_RESET_BIT			(U(1) << 28)
 #define TEGRA_RST_DEV_CLR_V		U(0x434)
 #define TEGRA_CLK_ENB_V			U(0x440)
 
-/* SE Clock Offsets */
-#define TEGRA_RST_DEVICES_V		0x358UL
-#define  SE_RESET_BIT 			(0x1UL << 31)
-#define TEGRA_RST_DEVICES_W		 0x35CUL
-#define  ENTROPY_CLK_ENB_BIT		(0x1UL << 21)
-#define TEGRA_CLK_OUT_ENB_V		0x360UL
-#define  SE_CLK_ENB_BIT			(0x1UL << 31)
-#define TEGRA_CLK_OUT_ENB_W		0x364UL
-#define  ENTROPY_RESET_BIT 		(0x1UL << 21)
-
 /*******************************************************************************
  * Tegra Flow Controller constants
  ******************************************************************************/
diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
index 4c49386bbfae414160cdba7dac2ccc8ee21fea1a..4e9206f97b74f987561d3d93ca04760371259025 100644
--- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
@@ -21,6 +21,7 @@
 #include <tegra_def.h>
 #include <tegra_private.h>
 #include <tegra_platform.h>
+#include <utils.h>
 
 /*
  * Register used to clear CPU reset signals. Each CPU has two reset
@@ -255,6 +256,74 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
 	return ret;
 }
 
+static void tegra_reset_all_dma_masters(void)
+{
+	uint32_t val, mask;
+
+	/*
+	 * Reset all possible DMA masters in the system.
+	 */
+	val = GPU_RESET_BIT;
+	mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_GPU_RESET_REG_OFFSET, val);
+
+	val = NVENC_RESET_BIT | TSECB_RESET_BIT | APE_RESET_BIT |
+	      NVJPG_RESET_BIT | NVDEC_RESET_BIT;
+	mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_Y, val);
+
+	val = HOST1X_RESET_BIT | ISP_RESET_BIT | USBD_RESET_BIT |
+	      VI_RESET_BIT | SDMMC4_RESET_BIT | SDMMC1_RESET_BIT |
+	      SDMMC2_RESET_BIT;
+	mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_L, val);
+
+	val = USB2_RESET_BIT | APBDMA_RESET_BIT | AHBDMA_RESET_BIT;
+	mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_H, val);
+
+	val = XUSB_DEV_RESET_BIT | XUSB_HOST_RESET_BIT | TSEC_RESET_BIT |
+	      PCIE_RESET_BIT | SDMMC3_RESET_BIT;
+	mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_U, val);
+
+	val = SE_RESET_BIT | HDA_RESET_BIT | SATA_RESET_BIT;
+	mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_V, val);
+
+	/*
+	 * If any of the DMA masters are still alive, assume
+	 * that the system has been compromised and reboot.
+	 */
+	val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_GPU_RESET_REG_OFFSET);
+	mask = GPU_RESET_BIT;
+	if ((val & mask) != mask)
+		tegra_pmc_system_reset();
+
+	mask = NVENC_RESET_BIT | TSECB_RESET_BIT | APE_RESET_BIT |
+	      NVJPG_RESET_BIT | NVDEC_RESET_BIT;
+	val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_Y);
+	if ((val & mask) != mask)
+		tegra_pmc_system_reset();
+
+	mask = HOST1X_RESET_BIT | ISP_RESET_BIT | USBD_RESET_BIT |
+	       VI_RESET_BIT | SDMMC4_RESET_BIT | SDMMC1_RESET_BIT |
+	       SDMMC2_RESET_BIT;
+	val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_L);
+	if ((val & mask) != mask)
+		tegra_pmc_system_reset();
+
+	mask = USB2_RESET_BIT | APBDMA_RESET_BIT | AHBDMA_RESET_BIT;
+	val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_H);
+	if ((val & mask) != mask)
+		tegra_pmc_system_reset();
+
+	mask = XUSB_DEV_RESET_BIT | XUSB_HOST_RESET_BIT | TSEC_RESET_BIT |
+	       PCIE_RESET_BIT | SDMMC3_RESET_BIT;
+	val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_U);
+	if ((val & mask) != mask)
+		tegra_pmc_system_reset();
+
+	val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEV_SET_V);
+	mask = SE_RESET_BIT | HDA_RESET_BIT | SATA_RESET_BIT;
+	if ((val & mask) != mask)
+		tegra_pmc_system_reset();
+}
+
 int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
 {
 	u_register_t mpidr = read_mpidr();
@@ -287,6 +356,28 @@ int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
 			/* Power off BPMP before we proceed */
 			tegra_fc_bpmp_off();
 
+			/* bond out IRAM banks B, C and D */
+			mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_BOND_OUT_U,
+				IRAM_B_LOCK_BIT | IRAM_C_LOCK_BIT |
+				IRAM_D_LOCK_BIT);
+
+			/* bond out APB/AHB DMAs */
+			mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_BOND_OUT_H,
+				APB_DMA_LOCK_BIT | AHB_DMA_LOCK_BIT);
+
+			/* Power off BPMP before we proceed */
+			tegra_fc_bpmp_off();
+
+			/*
+			 * Reset all the hardware blocks that can act as DMA
+			 * masters on the bus.
+			 */
+			tegra_reset_all_dma_masters();
+
+			/* clean up IRAM of any cruft */
+			zeromem((void *)(uintptr_t)TEGRA_IRAM_BASE,
+					TEGRA_IRAM_A_SIZE);
+
 			/* Copy the firmware to BPMP's internal RAM */
 			(void)memcpy((void *)(uintptr_t)TEGRA_IRAM_BASE,
 				(const void *)plat_params->sc7entry_fw_base,
diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c
index 4fdd5a8ad8e9c69508f23a7da38282e04570ac51..0aeb9fff64fe0c27ddb897c828c3361498031464 100644
--- a/plat/nvidia/tegra/soc/t210/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t210/plat_setup.c
@@ -160,7 +160,7 @@ void plat_late_platform_setup(void)
 	/* memmap TZDRAM area containing the SC7 Entry Firmware */
 	if (plat_params->sc7entry_fw_base && plat_params->sc7entry_fw_size) {
 
-		assert(plat_params->sc7entry_fw_size <= TEGRA_IRAM_SIZE);
+		assert(plat_params->sc7entry_fw_size <= TEGRA_IRAM_A_SIZE);
 
 		/*
 		 * Verify that the SC7 entry firmware resides inside the TZDRAM