summaryrefslogtreecommitdiff
path: root/drivers/gpu/msm/kgsl_iommu.c
diff options
context:
space:
mode:
authorShrenuj Bansal <shrenujb@codeaurora.org>2015-11-03 13:28:02 -0800
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 21:21:32 -0700
commit479fb507ddfe64d4a22e93d001fd67db1287766c (patch)
tree07a9740c6dcc60c04a8a1a243d8e6455ee356947 /drivers/gpu/msm/kgsl_iommu.c
parentf6536636d15a8fb894b4dda048e489b1b83f152d (diff)
msm: kgsl: Submit a set of critical packets right after ME init
During the initialization sequence, submit a set of important packets to the GPU in order to pre-load the I-cache with the critical ucode instructions. CRs-Fixed: 978777 Change-Id: Ic6a17b24d8c3aa383af8e25cf9ef771459d65796 Signed-off-by: Shrenuj Bansal <shrenujb@codeaurora.org>
Diffstat (limited to 'drivers/gpu/msm/kgsl_iommu.c')
-rw-r--r--drivers/gpu/msm/kgsl_iommu.c55
1 files changed, 49 insertions, 6 deletions
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index fb5eba5bbd01..978d7ac405aa 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -93,6 +93,7 @@ static struct kmem_cache *addr_entry_cache;
#define GLOBAL_PT_ENTRIES 32
static struct kgsl_memdesc *global_pt_entries[GLOBAL_PT_ENTRIES];
+static struct kgsl_memdesc *kgsl_global_secure_pt_entry;
static int global_pt_count;
uint64_t global_pt_alloc;
@@ -119,6 +120,28 @@ static void kgsl_iommu_map_globals(struct kgsl_pagetable *pagetable)
}
}
+static void kgsl_iommu_unmap_global_secure_pt_entry(struct kgsl_pagetable
+ *pagetable)
+{
+ struct kgsl_memdesc *entry = kgsl_global_secure_pt_entry;
+
+ if (entry != NULL)
+ kgsl_mmu_unmap(pagetable, entry);
+
+}
+
+static void kgsl_map_global_secure_pt_entry(struct kgsl_pagetable *pagetable)
+{
+ int ret;
+ struct kgsl_memdesc *entry = kgsl_global_secure_pt_entry;
+
+ if (entry != NULL) {
+ entry->pagetable = pagetable;
+ ret = kgsl_mmu_map(pagetable, entry);
+ BUG_ON(ret);
+ }
+}
+
static void kgsl_iommu_remove_global(struct kgsl_mmu *mmu,
struct kgsl_memdesc *memdesc)
{
@@ -153,6 +176,14 @@ static void kgsl_iommu_add_global(struct kgsl_mmu *mmu,
global_pt_entries[global_pt_count++] = memdesc;
}
+void kgsl_add_global_secure_entry(struct kgsl_device *device,
+ struct kgsl_memdesc *memdesc)
+{
+ memdesc->gpuaddr = KGSL_IOMMU_SECURE_BASE;
+ kgsl_global_secure_pt_entry = memdesc;
+}
+
+
static inline void _iommu_sync_mmu_pc(bool lock)
{
if (need_iommu_sync == false)
@@ -694,8 +725,10 @@ static void kgsl_iommu_destroy_pagetable(struct kgsl_pagetable *pt)
iommu = _IOMMU_PRIV(mmu);
- if (KGSL_MMU_SECURE_PT == pt->name)
+ if (KGSL_MMU_SECURE_PT == pt->name) {
ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_SECURE];
+ kgsl_iommu_unmap_global_secure_pt_entry(pt);
+ }
else {
ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER];
kgsl_iommu_unmap_globals(pt);
@@ -716,10 +749,13 @@ static void setup_64bit_pagetable(struct kgsl_mmu *mmu,
struct kgsl_pagetable *pagetable,
struct kgsl_iommu_pt *pt)
{
+ unsigned int secure_global_size = kgsl_global_secure_pt_entry != NULL ?
+ kgsl_global_secure_pt_entry->size : 0;
if (mmu->secured && pagetable->name == KGSL_MMU_SECURE_PT) {
- pt->compat_va_start = KGSL_IOMMU_SECURE_BASE;
+ pt->compat_va_start = KGSL_IOMMU_SECURE_BASE +
+ secure_global_size;
pt->compat_va_end = KGSL_IOMMU_SECURE_END;
- pt->va_start = KGSL_IOMMU_SECURE_BASE;
+ pt->va_start = KGSL_IOMMU_SECURE_BASE + secure_global_size;
pt->va_end = KGSL_IOMMU_SECURE_END;
} else {
pt->compat_va_start = KGSL_IOMMU_SVM_BASE32;
@@ -744,15 +780,20 @@ static void setup_32bit_pagetable(struct kgsl_mmu *mmu,
struct kgsl_pagetable *pagetable,
struct kgsl_iommu_pt *pt)
{
+ unsigned int secure_global_size = kgsl_global_secure_pt_entry != NULL ?
+ kgsl_global_secure_pt_entry->size : 0;
if (mmu->secured) {
if (pagetable->name == KGSL_MMU_SECURE_PT) {
- pt->compat_va_start = KGSL_IOMMU_SECURE_BASE;
+ pt->compat_va_start = KGSL_IOMMU_SECURE_BASE +
+ secure_global_size;
pt->compat_va_end = KGSL_IOMMU_SECURE_END;
- pt->va_start = KGSL_IOMMU_SECURE_BASE;
+ pt->va_start = KGSL_IOMMU_SECURE_BASE +
+ secure_global_size;
pt->va_end = KGSL_IOMMU_SECURE_END;
} else {
pt->va_start = KGSL_IOMMU_SVM_BASE32;
- pt->va_end = KGSL_IOMMU_SECURE_BASE;
+ pt->va_end = KGSL_IOMMU_SECURE_BASE +
+ secure_global_size;
pt->compat_va_start = pt->va_start;
pt->compat_va_end = pt->va_end;
}
@@ -942,6 +983,8 @@ static int _init_secure_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt)
ctx->regbase = iommu->regbase + KGSL_IOMMU_CB0_OFFSET
+ (cb_num << KGSL_IOMMU_CB_SHIFT);
+ kgsl_map_global_secure_pt_entry(pt);
+
done:
if (ret)
_free_pt(ctx, pt);