Prepare for supporting INFRA_IOMMU, and APU_IOMMU later.

For Infra IOMMU/APU IOMMU, it doesn't have the "larb""port". thus, Use
the MM flag contain the MM_IOMMU special flow, Also, it moves a big
chunk code about parsing the mediatek,larbs into a function, this is
only needed for MM IOMMU. and all the current SoC are MM_IOMMU.

Signed-off-by: Yong Wu <yong...@mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 190 +++++++++++++++++++++-----------------
 1 file changed, 107 insertions(+), 83 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 20d15f80dd6e..a4479916ad33 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -288,7 +288,7 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 {
        struct mtk_iommu_data *data = dev_id;
        struct mtk_iommu_domain *dom = data->m4u_dom;
-       unsigned int fault_larb, fault_port, sub_comm = 0;
+       unsigned int fault_larb = 0, fault_port = 0, sub_comm = 0;
        u32 int_state, regval, va34_32, pa34_32;
        u64 fault_iova, fault_pa;
        bool layer, write;
@@ -314,17 +314,19 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
        pa34_32 = FIELD_GET(F_MMU_INVAL_PA_34_32_MASK, fault_iova);
        fault_pa |= (u64)pa34_32 << 32;
 
-       fault_port = F_MMU_INT_ID_PORT_ID(regval);
-       if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM_2BITS)) {
-               fault_larb = F_MMU_INT_ID_COMM_ID(regval);
-               sub_comm = F_MMU_INT_ID_SUB_COMM_ID(regval);
-       } else if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM_3BITS)) {
-               fault_larb = F_MMU_INT_ID_COMM_ID_EXT(regval);
-               sub_comm = F_MMU_INT_ID_SUB_COMM_ID_EXT(regval);
-       } else {
-               fault_larb = F_MMU_INT_ID_LARB_ID(regval);
+       if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
+               fault_port = F_MMU_INT_ID_PORT_ID(regval);
+               if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM_2BITS)) {
+                       fault_larb = F_MMU_INT_ID_COMM_ID(regval);
+                       sub_comm = F_MMU_INT_ID_SUB_COMM_ID(regval);
+               } else if (MTK_IOMMU_HAS_FLAG(data->plat_data, 
HAS_SUB_COMM_3BITS)) {
+                       fault_larb = F_MMU_INT_ID_COMM_ID_EXT(regval);
+                       sub_comm = F_MMU_INT_ID_SUB_COMM_ID_EXT(regval);
+               } else {
+                       fault_larb = F_MMU_INT_ID_LARB_ID(regval);
+               }
+               fault_larb = 
data->plat_data->larbid_remap[fault_larb][sub_comm];
        }
-       fault_larb = data->plat_data->larbid_remap[fault_larb][sub_comm];
 
        if (report_iommu_fault(&dom->domain, data->dev, fault_iova,
                               write ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ)) {
@@ -388,19 +390,21 @@ static void mtk_iommu_config(struct mtk_iommu_data *data, 
struct device *dev,
                larbid = MTK_M4U_TO_LARB(fwspec->ids[i]);
                portid = MTK_M4U_TO_PORT(fwspec->ids[i]);
 
-               larb_mmu = &data->larb_imu[larbid];
+               if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
+                       larb_mmu = &data->larb_imu[larbid];
 
-               region = data->plat_data->iova_region + domid;
-               larb_mmu->bank[portid] = upper_32_bits(region->iova_base);
+                       region = data->plat_data->iova_region + domid;
+                       larb_mmu->bank[portid] = 
upper_32_bits(region->iova_base);
 
-               dev_dbg(dev, "%s iommu for larb(%s) port %d dom %d bank %d.\n",
-                       enable ? "enable" : "disable", dev_name(larb_mmu->dev),
-                       portid, domid, larb_mmu->bank[portid]);
+                       dev_dbg(dev, "%s iommu for larb(%s) port %d dom %d bank 
%d.\n",
+                               enable ? "enable" : "disable", 
dev_name(larb_mmu->dev),
+                               portid, domid, larb_mmu->bank[portid]);
 
-               if (enable)
-                       larb_mmu->mmu |= MTK_SMI_MMU_EN(portid);
-               else
-                       larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid);
+                       if (enable)
+                               larb_mmu->mmu |= MTK_SMI_MMU_EN(portid);
+                       else
+                               larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid);
+               }
        }
 }
 
@@ -796,19 +800,75 @@ static const struct component_master_ops 
mtk_iommu_com_ops = {
        .unbind         = mtk_iommu_unbind,
 };
 
+static int mtk_iommu_mm_dts_parse(struct device *dev,
+                                 struct component_match **match,
+                                 struct mtk_iommu_data *data)
+{
+       struct platform_device  *plarbdev;
+       struct device_link      *link;
+       struct device_node *larbnode, *smicomm_node;
+       int i, larb_nr, ret;
+
+       larb_nr = of_count_phandle_with_args(dev->of_node, "mediatek,larbs", 
NULL);
+       if (larb_nr < 0)
+               return larb_nr;
+
+       for (i = 0; i < larb_nr; i++) {
+               u32 id;
+
+               larbnode = of_parse_phandle(dev->of_node, "mediatek,larbs", i);
+               if (!larbnode)
+                       return -EINVAL;
+
+               if (!of_device_is_available(larbnode)) {
+                       of_node_put(larbnode);
+                       continue;
+               }
+
+               ret = of_property_read_u32(larbnode, "mediatek,larb-id", &id);
+               if (ret)/* The id is consecutive if there is no this property */
+                       id = i;
+
+               plarbdev = of_find_device_by_node(larbnode);
+               if (!plarbdev) {
+                       of_node_put(larbnode);
+                       return -EPROBE_DEFER;
+               }
+               data->larb_imu[id].dev = &plarbdev->dev;
+
+               component_match_add_release(dev, match, release_of,
+                                           compare_of, larbnode);
+       }
+
+       /* Get smi-common dev from the last larb. */
+       smicomm_node = of_parse_phandle(larbnode, "mediatek,smi", 0);
+       if (!smicomm_node)
+               return -EINVAL;
+
+       plarbdev = of_find_device_by_node(smicomm_node);
+       of_node_put(smicomm_node);
+       data->smicomm_dev = &plarbdev->dev;
+
+       link = device_link_add(data->smicomm_dev, dev,
+                              DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
+
+       if (!link) {
+               dev_err(dev, "Unable link %s.\n", dev_name(data->smicomm_dev));
+               return PTR_ERR(link);
+       }
+       return 0;
+}
+
 static int mtk_iommu_probe(struct platform_device *pdev)
 {
        struct mtk_iommu_data   *data;
        struct device           *dev = &pdev->dev;
-       struct device_node      *larbnode, *smicomm_node;
-       struct platform_device  *plarbdev;
-       struct device_link      *link;
        struct resource         *res;
        resource_size_t         ioaddr;
        struct component_match  *match = NULL;
        struct regmap           *infracfg;
        void                    *protect;
-       int                     i, larb_nr, ret;
+       int                     ret;
        u32                     val;
        char                    *p;
 
@@ -863,55 +923,12 @@ static int mtk_iommu_probe(struct platform_device *pdev)
                        return PTR_ERR(data->bclk);
        }
 
-       larb_nr = of_count_phandle_with_args(dev->of_node,
-                                            "mediatek,larbs", NULL);
-       if (larb_nr < 0)
-               return larb_nr;
-
-       for (i = 0; i < larb_nr; i++) {
-               u32 id;
-
-               larbnode = of_parse_phandle(dev->of_node, "mediatek,larbs", i);
-               if (!larbnode)
-                       return -EINVAL;
-
-               if (!of_device_is_available(larbnode)) {
-                       of_node_put(larbnode);
-                       continue;
-               }
-
-               ret = of_property_read_u32(larbnode, "mediatek,larb-id", &id);
-               if (ret)/* The id is consecutive if there is no this property */
-                       id = i;
-
-               plarbdev = of_find_device_by_node(larbnode);
-               if (!plarbdev) {
-                       of_node_put(larbnode);
-                       return -EPROBE_DEFER;
-               }
-               data->larb_imu[id].dev = &plarbdev->dev;
-
-               component_match_add_release(dev, &match, release_of,
-                                           compare_of, larbnode);
-       }
-
-       /* Get smi-common dev from the last larb. */
-       smicomm_node = of_parse_phandle(larbnode, "mediatek,smi", 0);
-       if (!smicomm_node)
-               return -EINVAL;
-
-       plarbdev = of_find_device_by_node(smicomm_node);
-       of_node_put(smicomm_node);
-       data->smicomm_dev = &plarbdev->dev;
-
        pm_runtime_enable(dev);
 
-       link = device_link_add(data->smicomm_dev, dev,
-                       DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
-       if (!link) {
-               dev_err(dev, "Unable to link %s.\n", 
dev_name(data->smicomm_dev));
-               ret = -EINVAL;
-               goto out_runtime_disable;
+       if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
+               ret = mtk_iommu_mm_dts_parse(dev, &match, data);
+               if (ret)
+                       goto out_runtime_disable;
        }
 
        platform_set_drvdata(pdev, data);
@@ -942,9 +959,11 @@ static int mtk_iommu_probe(struct platform_device *pdev)
                        goto out_list_del;
        }
 
-       ret = component_master_add_with_match(dev, &mtk_iommu_com_ops, match);
-       if (ret)
-               goto out_bus_set_null;
+       if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
+               ret = component_master_add_with_match(dev, &mtk_iommu_com_ops, 
match);
+               if (ret)
+                       goto out_bus_set_null;
+       }
        return ret;
 
 out_bus_set_null:
@@ -955,7 +974,8 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 out_sysfs_remove:
        iommu_device_sysfs_remove(&data->iommu);
 out_link_remove:
-       device_link_remove(data->smicomm_dev, dev);
+       if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM))
+               device_link_remove(data->smicomm_dev, dev);
 out_runtime_disable:
        pm_runtime_disable(dev);
        return ret;
@@ -972,7 +992,8 @@ static int mtk_iommu_remove(struct platform_device *pdev)
                bus_set_iommu(&platform_bus_type, NULL);
 
        clk_disable_unprepare(data->bclk);
-       device_link_remove(data->smicomm_dev, &pdev->dev);
+       if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM))
+               device_link_remove(data->smicomm_dev, &pdev->dev);
        pm_runtime_disable(&pdev->dev);
        devm_free_irq(&pdev->dev, data->irq, data);
        component_master_del(&pdev->dev, &mtk_iommu_com_ops);
@@ -1039,7 +1060,7 @@ static const struct dev_pm_ops mtk_iommu_pm_ops = {
 static const struct mtk_iommu_plat_data mt2712_data = {
        .m4u_plat     = M4U_MT2712,
        .flags        = HAS_4GB_MODE | HAS_BCLK | HAS_VLD_PA_RNG | 
SHARE_PGTABLE |
-                       NOT_STD_AXI_MODE,
+                       NOT_STD_AXI_MODE | MTK_IOMMU_TYPE_MM,
        .hw_list      = &m4ulist,
        .inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
        .iova_region  = single_domain,
@@ -1050,7 +1071,7 @@ static const struct mtk_iommu_plat_data mt2712_data = {
 static const struct mtk_iommu_plat_data mt6779_data = {
        .m4u_plat      = M4U_MT6779,
        .flags         = HAS_SUB_COMM_2BITS | OUT_ORDER_WR_EN | WR_THROT_EN |
-                        NOT_STD_AXI_MODE,
+                        NOT_STD_AXI_MODE | MTK_IOMMU_TYPE_MM,
        .inv_sel_reg   = REG_MMU_INV_SEL_GEN2,
        .iova_region   = single_domain,
        .iova_region_nr = ARRAY_SIZE(single_domain),
@@ -1059,7 +1080,8 @@ static const struct mtk_iommu_plat_data mt6779_data = {
 
 static const struct mtk_iommu_plat_data mt8167_data = {
        .m4u_plat     = M4U_MT8167,
-       .flags        = RESET_AXI | HAS_LEGACY_IVRP_PADDR | NOT_STD_AXI_MODE,
+       .flags        = RESET_AXI | HAS_LEGACY_IVRP_PADDR | NOT_STD_AXI_MODE |
+                       MTK_IOMMU_TYPE_MM,
        .inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
        .iova_region  = single_domain,
        .iova_region_nr = ARRAY_SIZE(single_domain),
@@ -1069,7 +1091,8 @@ static const struct mtk_iommu_plat_data mt8167_data = {
 static const struct mtk_iommu_plat_data mt8173_data = {
        .m4u_plat     = M4U_MT8173,
        .flags        = HAS_4GB_MODE | HAS_BCLK | RESET_AXI |
-                       HAS_LEGACY_IVRP_PADDR | NOT_STD_AXI_MODE,
+                       HAS_LEGACY_IVRP_PADDR | NOT_STD_AXI_MODE |
+                       MTK_IOMMU_TYPE_MM,
        .inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
        .iova_region  = single_domain,
        .iova_region_nr = ARRAY_SIZE(single_domain),
@@ -1078,7 +1101,7 @@ static const struct mtk_iommu_plat_data mt8173_data = {
 
 static const struct mtk_iommu_plat_data mt8183_data = {
        .m4u_plat     = M4U_MT8183,
-       .flags        = RESET_AXI,
+       .flags        = RESET_AXI | MTK_IOMMU_TYPE_MM,
        .inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
        .iova_region  = single_domain,
        .iova_region_nr = ARRAY_SIZE(single_domain),
@@ -1088,7 +1111,8 @@ static const struct mtk_iommu_plat_data mt8183_data = {
 static const struct mtk_iommu_plat_data mt8192_data = {
        .m4u_plat       = M4U_MT8192,
        .flags          = HAS_BCLK | HAS_SUB_COMM_2BITS | OUT_ORDER_WR_EN |
-                         WR_THROT_EN | IOVA_34_EN | NOT_STD_AXI_MODE,
+                         WR_THROT_EN | IOVA_34_EN | NOT_STD_AXI_MODE |
+                         MTK_IOMMU_TYPE_MM,
        .inv_sel_reg    = REG_MMU_INV_SEL_GEN2,
        .iova_region    = mt8192_multi_dom,
        .iova_region_nr = ARRAY_SIZE(mt8192_multi_dom),
-- 
2.18.0

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

Reply via email to