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;
}