For multiple iommu_domains, we need to reserve some iova
regions, so we will add mtk_iommu_resv_iova_region structure.
It includes the start address and size of iova and iommu_resv_type.
Based on the function, we will realize multiple mtk_iommu_domains

Signed-off-by: Anan Sun <anan....@mediatek.com>
Signed-off-by: Chao Hao <chao....@mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 47 +++++++++++++++++++++++++++++++++++++++
 drivers/iommu/mtk_iommu.h | 12 ++++++++++
 2 files changed, 59 insertions(+)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 8c06d2a793a7..c0cd7da71c2c 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -697,6 +697,51 @@ static int mtk_iommu_of_xlate(struct device *dev, struct 
of_phandle_args *args)
        return iommu_fwspec_add_ids(dev, args->args, 1);
 }
 
+/* reserve/dir-map iova region */
+static void mtk_iommu_get_resv_regions(struct device *dev,
+                                      struct list_head *head)
+{
+       struct mtk_iommu_data *data = dev_iommu_fwspec_get(dev)->iommu_priv;
+       unsigned int i, total_cnt = data->plat_data->resv_cnt;
+       const struct mtk_iommu_resv_iova_region *resv_data;
+       struct iommu_resv_region *region;
+       unsigned long base = 0;
+       size_t size = 0;
+       int prot = IOMMU_WRITE | IOMMU_READ;
+
+       resv_data = data->plat_data->resv_region;
+
+       for (i = 0; i < total_cnt; i++) {
+               size = 0;
+               if (resv_data[i].iova_size) {
+                       base = (unsigned long)resv_data[i].iova_base;
+                       size = resv_data[i].iova_size;
+               }
+               if (!size)
+                       continue;
+
+               region = iommu_alloc_resv_region(base, size, prot,
+                                                resv_data[i].type);
+               if (!region)
+                       return;
+
+               list_add_tail(&region->list, head);
+
+               dev_dbg(data->dev, "%s iova 0x%x ~ 0x%x\n",
+                       (resv_data[i].type == IOMMU_RESV_DIRECT) ? "dm" : "rsv",
+                       (unsigned int)base, (unsigned int)(base + size - 1));
+       }
+}
+
+static void mtk_iommu_put_resv_regions(struct device *dev,
+                                      struct list_head *head)
+{
+       struct iommu_resv_region *entry, *next;
+
+       list_for_each_entry_safe(entry, next, head, list)
+               kfree(entry);
+}
+
 static const struct iommu_ops mtk_iommu_ops = {
        .domain_alloc   = mtk_iommu_domain_alloc,
        .domain_free    = mtk_iommu_domain_free,
@@ -711,6 +756,8 @@ static const struct iommu_ops mtk_iommu_ops = {
        .remove_device  = mtk_iommu_remove_device,
        .device_group   = mtk_iommu_device_group,
        .of_xlate       = mtk_iommu_of_xlate,
+       .get_resv_regions = mtk_iommu_get_resv_regions,
+       .put_resv_regions = mtk_iommu_put_resv_regions,
        .pgsize_bitmap  = SZ_4K | SZ_64K | SZ_1M | SZ_16M,
 };
 
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index d8aef0d57b1a..10476b23adee 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -36,6 +36,12 @@ enum mtk_iommu_plat {
        M4U_MT8183,
 };
 
+struct mtk_iommu_resv_iova_region {
+       dma_addr_t              iova_base;
+       size_t                  iova_size;
+       enum iommu_resv_type    type;
+};
+
 /*
  * reserved IOVA Domain for IOMMU users of HW limitation.
  */
@@ -68,6 +74,12 @@ struct mtk_iommu_plat_data {
        u32                 dom_cnt;
        unsigned char       larbid_remap[2][MTK_LARB_NR_MAX];
        const struct mtk_domain_data    *dom_data;
+       /*
+        * reserve/dir-mapping iova region data
+        * todo: for different reserve needs on multiple iommu domains
+        */
+       const unsigned int  resv_cnt;
+       const struct mtk_iommu_resv_iova_region *resv_region;
 };
 
 struct mtk_iommu_domain;
-- 
2.18.0
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to