msm: kgsl: Make tlb flags common for all MMU types
Remove tlb flags variable from gpu MMU specific structure and
declare it in common MMU structure since it can be used by both
MMU types i.e GPUMMU and IOMMU
Change-Id: Ia8bea65bc9acf257dc1277c98cd358963c291fd7
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 bbb5d46..65bcb09 100644
--- a/drivers/gpu/msm/kgsl_gpummu.c
+++ b/drivers/gpu/msm/kgsl_gpummu.c
@@ -397,25 +397,6 @@
return baseptr[pte] & GSL_PT_PAGE_ADDR_MASK;
}
-static unsigned int kgsl_gpummu_pt_get_flags(struct kgsl_pagetable *pt,
- enum kgsl_deviceid id)
-{
- unsigned int result = 0;
- struct kgsl_gpummu_pt *gpummu_pt;
-
- if (pt == NULL)
- return 0;
- gpummu_pt = pt->priv;
-
- spin_lock(&pt->lock);
- if (gpummu_pt->tlb_flags && (1<<id)) {
- result = KGSL_MMUFLAGS_TLBFLUSH;
- gpummu_pt->tlb_flags &= ~(1<<id);
- }
- spin_unlock(&pt->lock);
- return result;
-}
-
static void kgsl_gpummu_pagefault(struct kgsl_device *device)
{
unsigned int reg;
@@ -440,7 +421,6 @@
if (!gpummu_pt)
return NULL;
- gpummu_pt->tlb_flags = 0;
gpummu_pt->last_superpte = 0;
gpummu_pt->tlbflushfilter.size = (CONFIG_MSM_KGSL_PAGE_TABLE_SIZE /
@@ -504,7 +484,6 @@
struct kgsl_pagetable *pagetable)
{
struct kgsl_mmu *mmu = &device->mmu;
- struct kgsl_gpummu_pt *gpummu_pt;
if (mmu->flags & KGSL_FLAGS_STARTED) {
/* page table not current, then setup mmu to use new
@@ -512,10 +491,10 @@
*/
if (mmu->hwpagetable != pagetable) {
mmu->hwpagetable = pagetable;
- spin_lock(&mmu->hwpagetable->lock);
- gpummu_pt = mmu->hwpagetable->priv;
- gpummu_pt->tlb_flags &= ~(1<<device->id);
- spin_unlock(&mmu->hwpagetable->lock);
+ /* Since we do a TLB flush the tlb_flags should
+ * be cleared by calling kgsl_mmu_pt_get_flags
+ */
+ kgsl_mmu_pt_get_flags(pagetable, mmu->device->id);
/* call device specific set page table */
kgsl_setstate(mmu->device, KGSL_MMUFLAGS_TLBFLUSH |
@@ -670,7 +649,8 @@
static int
kgsl_gpummu_map(void *mmu_specific_pt,
struct kgsl_memdesc *memdesc,
- unsigned int protflags)
+ unsigned int protflags,
+ unsigned int *tlb_flags)
{
unsigned int pte;
struct kgsl_gpummu_pt *gpummu_pt = mmu_specific_pt;
@@ -704,7 +684,7 @@
if (flushtlb) {
/*set all devices as needing flushing*/
- gpummu_pt->tlb_flags = UINT_MAX;
+ *tlb_flags = UINT_MAX;
GSL_TLBFLUSH_FILTER_RESET();
}
@@ -764,5 +744,4 @@
.mmu_create_pagetable = kgsl_gpummu_create_pagetable,
.mmu_destroy_pagetable = kgsl_gpummu_destroy_pagetable,
.mmu_pt_equal = kgsl_gpummu_pt_equal,
- .mmu_pt_get_flags = kgsl_gpummu_pt_get_flags,
};
diff --git a/drivers/gpu/msm/kgsl_gpummu.h b/drivers/gpu/msm/kgsl_gpummu.h
index cac6930..c61a8b2 100644
--- a/drivers/gpu/msm/kgsl_gpummu.h
+++ b/drivers/gpu/msm/kgsl_gpummu.h
@@ -47,7 +47,6 @@
struct kgsl_gpummu_pt {
struct kgsl_memdesc base;
unsigned int last_superpte;
- unsigned int tlb_flags;
/* Maintain filter to manage tlb flushing */
struct kgsl_tlbflushfilter tlbflushfilter;
};
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index 50086d2..b7f7b0a 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -271,7 +271,8 @@
static int
kgsl_iommu_map(void *mmu_specific_pt,
struct kgsl_memdesc *memdesc,
- unsigned int protflags)
+ unsigned int protflags,
+ unsigned int *tlb_flags)
{
int ret;
unsigned int iommu_virt_addr;
@@ -292,6 +293,14 @@
return ret;
}
+#ifdef CONFIG_KGSL_PER_PROCESS_PAGE_TABLE
+ /*
+ * Flushing only required if per process pagetables are used. With
+ * global case, flushing will happen inside iommu_map function
+ */
+ if (!ret)
+ *tlb_flags = UINT_MAX;
+#endif
return ret;
}
@@ -350,5 +359,4 @@
.mmu_create_pagetable = kgsl_iommu_create_pagetable,
.mmu_destroy_pagetable = kgsl_iommu_destroy_pagetable,
.mmu_pt_equal = kgsl_iommu_pt_equal,
- .mmu_pt_get_flags = NULL,
};
diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c
index 8077323e..323c992 100644
--- a/drivers/gpu/msm/kgsl_mmu.c
+++ b/drivers/gpu/msm/kgsl_mmu.c
@@ -640,7 +640,8 @@
if (KGSL_MMU_TYPE_IOMMU != kgsl_mmu_get_mmutype())
spin_lock(&pagetable->lock);
- ret = pagetable->pt_ops->mmu_map(pagetable->priv, memdesc, protflags);
+ ret = pagetable->pt_ops->mmu_map(pagetable->priv, memdesc, protflags,
+ &pagetable->tlb_flags);
if (KGSL_MMU_TYPE_IOMMU == kgsl_mmu_get_mmutype())
spin_lock(&pagetable->lock);
@@ -771,10 +772,18 @@
int kgsl_mmu_pt_get_flags(struct kgsl_pagetable *pt,
enum kgsl_deviceid id)
{
- if (KGSL_MMU_TYPE_GPU == kgsl_mmu_type)
- return pt->pt_ops->mmu_pt_get_flags(pt, id);
- else
+ unsigned int result = 0;
+
+ if (pt == NULL)
return 0;
+
+ spin_lock(&pt->lock);
+ if (pt->tlb_flags && (1<<id)) {
+ result = KGSL_MMUFLAGS_TLBFLUSH;
+ pt->tlb_flags &= ~(1<<id);
+ }
+ spin_unlock(&pt->lock);
+ return result;
}
EXPORT_SYMBOL(kgsl_mmu_pt_get_flags);
diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h
index bff41bf..63ecdd6 100644
--- a/drivers/gpu/msm/kgsl_mmu.h
+++ b/drivers/gpu/msm/kgsl_mmu.h
@@ -112,6 +112,7 @@
unsigned int max_entries;
} stats;
const struct kgsl_mmu_pt_ops *pt_ops;
+ unsigned int tlb_flags;
void *priv;
};
@@ -132,15 +133,14 @@
struct kgsl_mmu_pt_ops {
int (*mmu_map) (void *mmu_pt,
struct kgsl_memdesc *memdesc,
- unsigned int protflags);
+ unsigned int protflags,
+ unsigned int *tlb_flags);
int (*mmu_unmap) (void *mmu_pt,
struct kgsl_memdesc *memdesc);
void *(*mmu_create_pagetable) (void);
void (*mmu_destroy_pagetable) (void *pt);
int (*mmu_pt_equal) (struct kgsl_pagetable *pt,
unsigned int pt_base);
- unsigned int (*mmu_pt_get_flags) (struct kgsl_pagetable *pt,
- enum kgsl_deviceid id);
};
struct kgsl_mmu {