ARM: tegra: Enable SMMU when going non-secure
authorThierry Reding <treding@nvidia.com>
Tue, 21 Apr 2015 05:18:38 +0000 (07:18 +0200)
committerTom Warren <twarren@nvidia.com>
Wed, 13 May 2015 16:24:16 +0000 (09:24 -0700)
Make sure to enable the SMMU when booting the kernel in non-secure mode.
This is necessary because some of the SMMU registers are restricted to
TrustZone-secured requestors, hence the kernel wouldn't be able to turn
the SMMU on. At the same time, enable translation for all memory clients
for the same reasons. The kernel will still be able to control SMMU IOVA
translation using the per-SWGROUP enable bits.

Signed-off-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Tom Warren <twarren@nvidia.com>
arch/arm/include/asm/arch-tegra124/mc.h
arch/arm/mach-tegra/ap.c

index 55577327d9fd66a64df951f6f47940af820bac29..37998a4d606ebd82c5f97ef11d0d6aacc38a0142 100644 (file)
@@ -74,6 +74,8 @@ struct mc_ctlr {
        u32 mc_video_protect_reg_ctrl;          /* offset 0x650 */
 };
 
+#define TEGRA_MC_SMMU_CONFIG_ENABLE (1 << 0)
+
 #define TEGRA_MC_VIDEO_PROTECT_REG_WRITE_ACCESS_ENABLED                (0 << 0)
 #define TEGRA_MC_VIDEO_PROTECT_REG_WRITE_ACCESS_DISABLED       (1 << 0)
 
index 869a2ed6bc35ef29a646dd9ab3600588c0ff0d6a..0b94e8aaf9c329a7433217cd72086e594b0550a0 100644 (file)
@@ -169,6 +169,43 @@ void protect_secure_section(void)
 }
 #endif
 
+#if defined(CONFIG_ARMV7_NONSEC)
+static void smmu_flush(struct mc_ctlr *mc)
+{
+       (void)readl(&mc->mc_smmu_config);
+}
+
+static void smmu_enable(void)
+{
+       struct mc_ctlr *mc = (struct mc_ctlr *)NV_PA_MC_BASE;
+       u32 value;
+
+       /*
+        * Enable translation for all clients since access to this register
+        * is restricted to TrustZone-secured requestors. The kernel will use
+        * the per-SWGROUP enable bits to enable or disable translations.
+        */
+       writel(0xffffffff, &mc->mc_smmu_translation_enable_0);
+       writel(0xffffffff, &mc->mc_smmu_translation_enable_1);
+       writel(0xffffffff, &mc->mc_smmu_translation_enable_2);
+       writel(0xffffffff, &mc->mc_smmu_translation_enable_3);
+
+       /*
+        * Enable SMMU globally since access to this register is restricted
+        * to TrustZone-secured requestors.
+        */
+       value = readl(&mc->mc_smmu_config);
+       value |= TEGRA_MC_SMMU_CONFIG_ENABLE;
+       writel(value, &mc->mc_smmu_config);
+
+       smmu_flush(mc);
+}
+#else
+static void smmu_enable(void)
+{
+}
+#endif
+
 void s_init(void)
 {
        /* Init PMC scratch memory */
@@ -179,6 +216,9 @@ void s_init(void)
        /* init the cache */
        config_cache();
 
+       /* enable SMMU */
+       smmu_enable();
+
        /* init vpr */
        config_vpr();
 }