msm: kgsl: Add function to get the register map information
Add a function that returns the memory descriptor which has information
about the register map of MMU. This is required to change pagetables
and flush tlb in stream for IOMMU
Change-Id: I0f8ed81754b4ea4ba5eaf270fe231a52b2bf4290
Signed-off-by: Shubhraprakash Das <sadas@codeaurora.org>
diff --git a/drivers/gpu/msm/kgsl_gpummu.c b/drivers/gpu/msm/kgsl_gpummu.c
index f49d3e3..ab47f40 100644
--- a/drivers/gpu/msm/kgsl_gpummu.c
+++ b/drivers/gpu/msm/kgsl_gpummu.c
@@ -728,6 +728,7 @@
.mmu_disable_clk = NULL,
.mmu_get_hwpagetable_asid = NULL,
.mmu_get_pt_lsb = NULL,
+ .mmu_get_reg_map_desc = NULL,
};
struct kgsl_mmu_pt_ops gpummu_pt_ops = {
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index 0113f6e..2f83a40 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -856,6 +856,43 @@
kgsl_iommu_disable_clk(mmu);
}
+/*
+ * kgsl_iommu_get_reg_map_desc - Returns an array of pointers that contain
+ * the address of memory descriptors which map the IOMMU registers
+ * @mmu - Pointer to mmu structure
+ * @reg_map_desc - Out parameter in which the address of the array containing
+ * pointers to register map descriptors is returned. The caller is supposed
+ * to free this array
+ *
+ * Return - The number of iommu units which is also the number of register
+ * mapped descriptor arrays which the out parameter will have
+ */
+static int kgsl_iommu_get_reg_map_desc(struct kgsl_mmu *mmu,
+ void **reg_map_desc)
+{
+ struct kgsl_iommu *iommu = mmu->priv;
+ void **reg_desc_ptr;
+ int i;
+
+ /*
+ * Alocate array of pointers that will hold address of the register map
+ * descriptors
+ */
+ reg_desc_ptr = kmalloc(iommu->unit_count *
+ sizeof(struct kgsl_memdesc *), GFP_KERNEL);
+ if (!reg_desc_ptr) {
+ KGSL_CORE_ERR("Failed to kmalloc(%d)\n",
+ iommu->unit_count * sizeof(struct kgsl_memdesc *));
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < iommu->unit_count; i++)
+ reg_desc_ptr[i] = &(iommu->iommu_units[i].reg_map);
+
+ *reg_map_desc = reg_desc_ptr;
+ return i;
+}
+
struct kgsl_mmu_ops iommu_ops = {
.mmu_init = kgsl_iommu_init,
.mmu_close = kgsl_iommu_close,
@@ -869,6 +906,7 @@
.mmu_disable_clk = kgsl_iommu_disable_clk,
.mmu_get_hwpagetable_asid = kgsl_iommu_get_hwpagetable_asid,
.mmu_get_pt_lsb = kgsl_iommu_get_pt_lsb,
+ .mmu_get_reg_map_desc = kgsl_iommu_get_reg_map_desc,
};
struct kgsl_mmu_pt_ops iommu_pt_ops = {
diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h
index 9f812ec..df4a64b 100644
--- a/drivers/gpu/msm/kgsl_mmu.h
+++ b/drivers/gpu/msm/kgsl_mmu.h
@@ -138,6 +138,8 @@
int (*mmu_get_pt_lsb)(struct kgsl_mmu *mmu,
unsigned int unit_id,
enum kgsl_iommu_context_id ctx_id);
+ int (*mmu_get_reg_map_desc)(struct kgsl_mmu *mmu,
+ void **reg_map_desc);
};
struct kgsl_mmu_pt_ops {
@@ -250,4 +252,13 @@
return pt->pt_ops->mmu_pt_get_base_addr(pt);
}
+static inline int kgsl_mmu_get_reg_map_desc(struct kgsl_mmu *mmu,
+ void **reg_map_desc)
+{
+ if (mmu->mmu_ops && mmu->mmu_ops->mmu_get_reg_map_desc)
+ return mmu->mmu_ops->mmu_get_reg_map_desc(mmu, reg_map_desc);
+ else
+ return 0;
+}
+
#endif /* __KGSL_MMU_H */