iommu/exynos: Enable default VM instance on SysMMU v7
authorSam Protsenko <semen.protsenko@linaro.org>
Thu, 14 Jul 2022 16:55:50 +0000 (19:55 +0300)
committerJoerg Roedel <jroedel@suse.de>
Fri, 15 Jul 2022 08:30:45 +0000 (10:30 +0200)
In order to enable SysMMU v7 with VM register layout, at least the
default VM instance (n=0) must be enabled, in addition to enabling the
SysMMU itself. To do so, add corresponding write to MMU_CTRL_VM[0]
register, before writing to MMU_CTRL register.

Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
Acked-by: Marek Szyprowski <m.szyprowski@samsung.com>
Link: https://lore.kernel.org/r/20220714165550.8884-7-semen.protsenko@linaro.org
Signed-off-by: Joerg Roedel <jroedel@suse.de>
drivers/iommu/exynos-iommu.c

index 0a773b6a525d72fca2313cdaf4ccf1f1fadb653f..768594d107ad086a9333e61e924767ac3cac87a4 100644 (file)
@@ -135,6 +135,8 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
 #define CFG_SYSSEL     (1 << 22) /* System MMU 3.2 only */
 #define CFG_FLPDCACHE  (1 << 20) /* System MMU 3.2+ only */
 
+#define CTRL_VM_ENABLE                 BIT(0)
+#define CTRL_VM_FAULT_MODE_STALL       BIT(3)
 #define CAPA0_CAPA1_EXIST              BIT(11)
 #define CAPA1_VCR_ENABLED              BIT(14)
 
@@ -163,6 +165,7 @@ static u32 lv2ent_offset(sysmmu_iova_t iova)
 /* v7.x registers */
 #define REG_V7_CAPA0           0x870
 #define REG_V7_CAPA1           0x874
+#define REG_V7_CTRL_VM         0x8000
 
 #define has_sysmmu(dev)                (dev_iommu_priv_get(dev) != NULL)
 
@@ -548,6 +551,18 @@ static void __sysmmu_init_config(struct sysmmu_drvdata *data)
        writel(cfg, data->sfrbase + REG_MMU_CFG);
 }
 
+static void __sysmmu_enable_vid(struct sysmmu_drvdata *data)
+{
+       u32 ctrl;
+
+       if (MMU_MAJ_VER(data->version) < 7 || !data->has_vcr)
+               return;
+
+       ctrl = readl(data->sfrbase + REG_V7_CTRL_VM);
+       ctrl |= CTRL_VM_ENABLE | CTRL_VM_FAULT_MODE_STALL;
+       writel(ctrl, data->sfrbase + REG_V7_CTRL_VM);
+}
+
 static void __sysmmu_enable(struct sysmmu_drvdata *data)
 {
        unsigned long flags;
@@ -558,6 +573,7 @@ static void __sysmmu_enable(struct sysmmu_drvdata *data)
        writel(CTRL_BLOCK, data->sfrbase + REG_MMU_CTRL);
        __sysmmu_init_config(data);
        __sysmmu_set_ptbase(data, data->pgtable);
+       __sysmmu_enable_vid(data);
        writel(CTRL_ENABLE, data->sfrbase + REG_MMU_CTRL);
        data->active = true;
        spin_unlock_irqrestore(&data->lock, flags);