diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index e529c6143e88..030e2ac879d0 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -2377,9 +2377,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; @@ -2423,6 +2426,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; @@ -2431,6 +2435,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); @@ -2452,11 +2458,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. @@ -2491,10 +2507,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); @@ -2530,28 +2556,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;