Tegra210: se: enable entropy/SE clocks before system suspend

This patch enables clocks to the SE and Entropy block and gets them
out of reset, before starting the context save operation.

Change-Id: Ic196be8fb833dfd04c0e8d460c07058429999613
Signed-off-by: Samuel Payne <spayne@nvidia.com>
diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h
index cdd7ce7..ee76b66 100644
--- a/plat/nvidia/tegra/include/t210/tegra_def.h
+++ b/plat/nvidia/tegra/include/t210/tegra_def.h
@@ -89,6 +89,16 @@
 #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/drivers/se/security_engine.c b/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c
index 64c1736..5bd52b9 100644
--- a/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c
+++ b/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c
@@ -394,6 +394,46 @@
 	INFO("%s: SE init done\n", __func__);
 }
 
+static void tegra_se_enable_clocks(void)
+{
+	uint32_t val = 0;
+
+	/* Enable entropy clock */
+	val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_W);
+	val |= ENTROPY_CLK_ENB_BIT;
+	mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_W, val);
+
+	/* De-Assert Entropy Reset */
+	val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEVICES_W);
+	val &= ~ENTROPY_RESET_BIT;
+	mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEVICES_W, val);
+
+	/* Enable SE clock */
+	val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_V);
+	val |= SE_CLK_ENB_BIT;
+	mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_V, val);
+
+	/* De-Assert SE Reset */
+	val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEVICES_V);
+	val &= ~SE_RESET_BIT;
+	mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEVICES_V, val);
+}
+
+static void tegra_se_disable_clocks(void)
+{
+	uint32_t val = 0;
+
+	/* Disable entropy clock */
+	val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_W);
+	val &= ~ENTROPY_CLK_ENB_BIT;
+	mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_W, val);
+
+	/* Disable SE clock */
+	val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_V);
+	val &= ~SE_CLK_ENB_BIT;
+	mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_V, val);
+}
+
 /*
  * Security engine power suspend entry point.
  * This function is invoked from PSCI power domain suspend handler.
@@ -409,6 +449,7 @@
 	val &= ~PPCS_SMMU_ENABLE;
 	mmio_write_32(TEGRA_MC_BASE + MC_SMMU_PPCS_ASID_0, val);
 
+	tegra_se_enable_clocks();
 
 	/* Atomic context save se2 and pka1 */
 	INFO("%s: SE2/PKA1 atomic context save\n", __func__);
@@ -424,6 +465,8 @@
 		INFO("%s: SE atomic context save done\n", __func__);
 	}
 
+	tegra_se_disable_clocks();
+
 	return ret;
 }
 
@@ -437,6 +480,7 @@
 	uint32_t timeout;
 
 	INFO("%s: SE TZRAM save start\n", __func__);
+	tegra_se_enable_clocks();
 
 	val = (SE_TZRAM_OP_REQ_INIT | SE_TZRAM_OP_MODE_SAVE);
 	tegra_se_write_32(&se_dev_1, SE_TZRAM_OPERATION, val);
@@ -457,6 +501,8 @@
 		INFO("%s: SE TZRAM save done!\n", __func__);
 	}
 
+	tegra_se_disable_clocks();
+
 	return ret;
 }