From bfd51517d49d1cd1d2ac79426a21862fe4db67f2 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Wed, 19 Aug 2020 17:19:55 -0600 Subject: [PATCH] msm: kgsl: Allow I/O coherency on imported buffers if we can Allow I/O coherency to be enabled on imported buffers if I/O coherency is enabled and we can determine the cache characteristics of the imported buffer. The caller should check the flags after allocation to determine if I/O coherency was enabled. Change-Id: Ic0dedbade77189bd51dddad64d15f0835601e925 Signed-off-by: Jordan Crouse --- drivers/gpu/msm/kgsl.c | 50 ++++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 060b7ef6091f..68063b6af32b 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -2419,9 +2419,12 @@ static int kgsl_setup_dmabuf_useraddr(struct kgsl_device *device, entry->memdesc.useraddr = hostptr; _setup_cache_mode(entry, vma); - if (IS_ENABLED(CONFIG_QCOM_KGSL_IOCOHERENCY_DEFAULT) && - kgsl_cachemode_is_cached(entry->memdesc.flags)) + if (kgsl_mmu_has_feature(device, KGSL_MMU_IO_COHERENT) && + (IS_ENABLED(CONFIG_QCOM_KGSL_IOCOHERENCY_DEFAULT) && + kgsl_cachemode_is_cached(entry->memdesc.flags))) entry->memdesc.flags |= KGSL_MEMFLAGS_IOCOHERENT; + else + entry->memdesc.flags &= ~((u64) KGSL_MEMFLAGS_IOCOHERENT); up_read(¤t->mm->mmap_sem); return 0; @@ -2465,6 +2468,7 @@ static long _gpuobj_map_useraddr(struct kgsl_device *device, param->flags &= KGSL_MEMFLAGS_GPUREADONLY | KGSL_CACHEMODE_MASK + | KGSL_MEMFLAGS_USE_CPU_MAP | KGSL_MEMTYPE_MASK | KGSL_MEMFLAGS_FORCE_32BIT | KGSL_MEMFLAGS_IOCOHERENT; @@ -2473,6 +2477,8 @@ static long _gpuobj_map_useraddr(struct kgsl_device *device, if (param->flags & KGSL_MEMFLAGS_SECURE) return -ENOTSUPP; + kgsl_memdesc_init(device, &entry->memdesc, param->flags); + ret = kgsl_copy_from_user(&useraddr, u64_to_user_ptr(param->priv), sizeof(useraddr), param->priv_len); @@ -2494,11 +2500,21 @@ static long _gpuobj_map_dma_buf(struct kgsl_device *device, struct kgsl_gpuobj_import *param, int *fd) { + bool iocoherent = (param->flags & KGSL_MEMFLAGS_IOCOHERENT); struct kgsl_gpuobj_import_dma_buf buf; struct dma_buf *dmabuf; unsigned long flags = 0; int ret; + param->flags &= KGSL_MEMFLAGS_GPUREADONLY | + KGSL_MEMTYPE_MASK | + KGSL_MEMALIGN_MASK | + KGSL_MEMFLAGS_SECURE | + KGSL_MEMFLAGS_FORCE_32BIT | + KGSL_MEMFLAGS_GUARD_PAGE; + + kgsl_memdesc_init(device, &entry->memdesc, param->flags); + /* * If content protection is not enabled and secure buffer * is requested to be mapped return error. @@ -2533,10 +2549,20 @@ static long _gpuobj_map_dma_buf(struct kgsl_device *device, * fails. */ dma_buf_get_flags(dmabuf, &flags); - if (flags & ION_FLAG_CACHED) + if (flags & ION_FLAG_CACHED) { entry->memdesc.flags |= KGSL_CACHEMODE_WRITEBACK << KGSL_CACHEMODE_SHIFT; + /* + * Enable I/O coherency if it is 1) a thing, and either + * 2) enabled by default or 3) enabled by the caller + */ + if (kgsl_mmu_has_feature(device, KGSL_MMU_IO_COHERENT) && + (IS_ENABLED(CONFIG_QCOM_KGSL_IOCOHERENCY_DEFAULT) || + iocoherent)) + entry->memdesc.flags |= KGSL_MEMFLAGS_IOCOHERENT; + } + ret = kgsl_setup_dma_buf(device, pagetable, entry, dmabuf); if (ret) dma_buf_put(dmabuf); @@ -2572,28 +2598,20 @@ long kgsl_ioctl_gpuobj_import(struct kgsl_device_private *dev_priv, struct kgsl_mem_entry *entry; int ret, fd = -1; + if (param->type != KGSL_USER_MEM_TYPE_ADDR && + param->type != KGSL_USER_MEM_TYPE_DMABUF) + return -ENOTSUPP; + entry = kgsl_mem_entry_create(); if (entry == NULL) return -ENOMEM; - param->flags &= KGSL_MEMFLAGS_GPUREADONLY - | KGSL_MEMTYPE_MASK - | KGSL_MEMALIGN_MASK - | KGSL_MEMFLAGS_USE_CPU_MAP - | KGSL_MEMFLAGS_SECURE - | KGSL_MEMFLAGS_FORCE_32BIT - | KGSL_MEMFLAGS_IOCOHERENT - | KGSL_MEMFLAGS_GUARD_PAGE; - - kgsl_memdesc_init(dev_priv->device, &entry->memdesc, param->flags); if (param->type == KGSL_USER_MEM_TYPE_ADDR) ret = _gpuobj_map_useraddr(dev_priv->device, private->pagetable, entry, param); - else if (param->type == KGSL_USER_MEM_TYPE_DMABUF) + else ret = _gpuobj_map_dma_buf(dev_priv->device, private->pagetable, entry, param, &fd); - else - ret = -ENOTSUPP; if (ret) goto out;