Re: [PATCH v3 21/33] iommu/mediatek: Add infra iommu support

2022-01-04 Thread AngeloGioacchino Del Regno

Il 23/09/21 13:58, Yong Wu ha scritto:

The infra iommu enable bits in mt8195 is in the pericfg register segment,
use regmap to update it.

If infra iommu master translation fault, It don't have the larbid/portid,
thus print out the whole register value.

Since regmap_update_bits may fail, add return value for mtk_iommu_config.

Signed-off-by: Yong Wu 




Reviewed-by: AngeloGioacchino Del Regno 



___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v3 21/33] iommu/mediatek: Add infra iommu support

2021-09-23 Thread Yong Wu
The infra iommu enable bits in mt8195 is in the pericfg register segment,
use regmap to update it.

If infra iommu master translation fault, It don't have the larbid/portid,
thus print out the whole register value.

Since regmap_update_bits may fail, add return value for mtk_iommu_config.

Signed-off-by: Yong Wu 
---
 drivers/iommu/mtk_iommu.c | 36 +---
 drivers/iommu/mtk_iommu.h |  2 ++
 2 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index d103e4f33078..37d6dfb4feab 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -112,6 +112,8 @@
 
 #define MTK_PROTECT_PA_ALIGN   256
 
+#define PERICFG_IOMMU_10x714
+
 #define HAS_4GB_MODE   BIT(0)
 /* HW will use the EMI clock if there isn't the "bclk". */
 #define HAS_BCLK   BIT(1)
@@ -324,8 +326,8 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
   write ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ)) {
dev_err_ratelimited(
data->dev,
-   "fault type=0x%x iova=0x%llx pa=0x%llx larb=%d port=%d 
layer=%d %s\n",
-   int_state, fault_iova, fault_pa, fault_larb, fault_port,
+   "fault type=0x%x iova=0x%llx pa=0x%llx 
master=0x%x(larb=%d port=%d) layer=%d %s\n",
+   int_state, fault_iova, fault_pa, regval, fault_larb, 
fault_port,
layer, write ? "write" : "read");
}
 
@@ -369,14 +371,15 @@ static int mtk_iommu_get_domain_id(struct device *dev,
return -EINVAL;
 }
 
-static void mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev,
-bool enable, unsigned int domid)
+static int mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev,
+   bool enable, unsigned int domid)
 {
struct mtk_smi_larb_iommu*larb_mmu;
unsigned int larbid, portid;
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
const struct mtk_iommu_iova_region *region;
-   int i;
+   u32 peri_mmuen, peri_mmuen_msk;
+   int i, ret = 0;
 
for (i = 0; i < fwspec->num_ids; ++i) {
larbid = MTK_M4U_TO_LARB(fwspec->ids[i]);
@@ -396,8 +399,19 @@ static void mtk_iommu_config(struct mtk_iommu_data *data, 
struct device *dev,
larb_mmu->mmu |= MTK_SMI_MMU_EN(portid);
else
larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid);
+   } else if (MTK_IOMMU_IS_TYPE(data->plat_data, 
MTK_IOMMU_TYPE_INFRA)) {
+   peri_mmuen_msk = BIT(portid);
+   peri_mmuen = enable ? peri_mmuen_msk : 0;
+
+   ret = regmap_update_bits(data->pericfg, PERICFG_IOMMU_1,
+peri_mmuen_msk, peri_mmuen);
+   if (ret)
+   dev_err(dev, "%s iommu(%s) inframaster 0x%x 
fail(%d).\n",
+   enable ? "enable" : "disable",
+   dev_name(data->dev), peri_mmuen_msk, 
ret);
}
}
+   return ret;
 }
 
 static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom,
@@ -504,8 +518,7 @@ static int mtk_iommu_attach_device(struct iommu_domain 
*domain,
pm_runtime_put(m4udev);
}
 
-   mtk_iommu_config(data, dev, true, domid);
-   return 0;
+   return mtk_iommu_config(data, dev, true, domid);
 }
 
 static void mtk_iommu_detach_device(struct iommu_domain *domain,
@@ -921,6 +934,15 @@ static int mtk_iommu_probe(struct platform_device *pdev)
ret = mtk_iommu_mm_dts_parse(dev, , data);
if (ret)
goto out_runtime_disable;
+   } else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA) &&
+  data->plat_data->pericfg_comp_str) {
+   infracfg = 
syscon_regmap_lookup_by_compatible(data->plat_data->pericfg_comp_str);
+   if (IS_ERR(infracfg)) {
+   ret = PTR_ERR(infracfg);
+   goto out_runtime_disable;
+   }
+
+   data->pericfg = infracfg;
}
 
platform_set_drvdata(pdev, data);
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index 5b32277fee99..d83c79bf800a 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -55,6 +55,7 @@ struct mtk_iommu_plat_data {
u32 flags;
u32 inv_sel_reg;
 
+   char*pericfg_comp_str;
struct list_head*hw_list;
unsigned intiova_region_nr;
const struct