diff --git a/drivers/gpu/msm/adreno-gpulist.h b/drivers/gpu/msm/adreno-gpulist.h index 9a9e1fc6d321..770cf3b490ba 100644 --- a/drivers/gpu/msm/adreno-gpulist.h +++ b/drivers/gpu/msm/adreno-gpulist.h @@ -347,7 +347,8 @@ static const struct adreno_gpu_core adreno_gpulist[] = { .minor = 0, .patchid = ANY_ID, .features = ADRENO_64BIT | ADRENO_RPMH | ADRENO_IFPC | - ADRENO_GPMU | ADRENO_CONTENT_PROTECTION | ADRENO_LM, + ADRENO_GPMU | ADRENO_CONTENT_PROTECTION | ADRENO_LM | + ADRENO_IOCOHERENT, .sqefw_name = "a630_sqe.fw", .zap_name = "a630_zap", .gpudev = &adreno_a6xx_gpudev, diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 373264a0d8b8..46256b42d8a3 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -1148,6 +1148,9 @@ static int adreno_probe(struct platform_device *pdev) if (!ADRENO_FEATURE(adreno_dev, ADRENO_CONTENT_PROTECTION)) device->mmu.secured = false; + if (ADRENO_FEATURE(adreno_dev, ADRENO_IOCOHERENT)) + device->mmu.features |= KGSL_MMU_IO_COHERENT; + status = adreno_ringbuffer_probe(adreno_dev, nopreempt); if (status) goto out; diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h index 6f5fb6b7aa7c..0b4e1dfb9a65 100644 --- a/drivers/gpu/msm/adreno.h +++ b/drivers/gpu/msm/adreno.h @@ -121,6 +121,8 @@ #define ADRENO_HW_NAP BIT(14) /* The GMU supports min voltage*/ #define ADRENO_MIN_VOLT BIT(15) +/* The core supports IO-coherent memory */ +#define ADRENO_IOCOHERENT BIT(16) /* * Adreno GPU quirks - control bits for various workarounds diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index a5e3804e6cb2..5d07380fea85 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -2294,7 +2294,8 @@ static long _gpuobj_map_useraddr(struct kgsl_device *device, param->flags &= KGSL_MEMFLAGS_GPUREADONLY | KGSL_CACHEMODE_MASK | KGSL_MEMTYPE_MASK - | KGSL_MEMFLAGS_FORCE_32BIT; + | KGSL_MEMFLAGS_FORCE_32BIT + | KGSL_MEMFLAGS_IOCOHERENT; /* Specifying SECURE is an explicit error */ if (param->flags & KGSL_MEMFLAGS_SECURE) @@ -2388,7 +2389,12 @@ long kgsl_ioctl_gpuobj_import(struct kgsl_device_private *dev_priv, | KGSL_MEMALIGN_MASK | KGSL_MEMFLAGS_USE_CPU_MAP | KGSL_MEMFLAGS_SECURE - | KGSL_MEMFLAGS_FORCE_32BIT; + | KGSL_MEMFLAGS_FORCE_32BIT + | KGSL_MEMFLAGS_IOCOHERENT; + + /* Disable IO coherence if it is not supported on the chip */ + if (!MMU_FEATURE(mmu, KGSL_MMU_IO_COHERENT)) + param->flags &= ~((uint64_t)KGSL_MEMFLAGS_IOCOHERENT); entry->memdesc.flags = param->flags; @@ -2673,7 +2679,13 @@ long kgsl_ioctl_map_user_mem(struct kgsl_device_private *dev_priv, | KGSL_MEMTYPE_MASK | KGSL_MEMALIGN_MASK | KGSL_MEMFLAGS_USE_CPU_MAP - | KGSL_MEMFLAGS_SECURE; + | KGSL_MEMFLAGS_SECURE + | KGSL_MEMFLAGS_IOCOHERENT; + + /* Disable IO coherence if it is not supported on the chip */ + if (!MMU_FEATURE(mmu, KGSL_MMU_IO_COHERENT)) + param->flags &= ~((uint64_t)KGSL_MEMFLAGS_IOCOHERENT); + entry->memdesc.flags = ((uint64_t) param->flags) | KGSL_MEMFLAGS_FORCE_32BIT; @@ -3072,6 +3084,7 @@ struct kgsl_mem_entry *gpumem_alloc_entry( int ret; struct kgsl_process_private *private = dev_priv->process_priv; struct kgsl_mem_entry *entry; + struct kgsl_mmu *mmu = &dev_priv->device->mmu; unsigned int align; flags &= KGSL_MEMFLAGS_GPUREADONLY @@ -3080,14 +3093,15 @@ struct kgsl_mem_entry *gpumem_alloc_entry( | KGSL_MEMALIGN_MASK | KGSL_MEMFLAGS_USE_CPU_MAP | KGSL_MEMFLAGS_SECURE - | KGSL_MEMFLAGS_FORCE_32BIT; + | KGSL_MEMFLAGS_FORCE_32BIT + | KGSL_MEMFLAGS_IOCOHERENT; /* Turn off SVM if the system doesn't support it */ - if (!kgsl_mmu_use_cpu_map(&dev_priv->device->mmu)) + if (!kgsl_mmu_use_cpu_map(mmu)) flags &= ~((uint64_t) KGSL_MEMFLAGS_USE_CPU_MAP); /* Return not supported error if secure memory isn't enabled */ - if (!kgsl_mmu_is_secured(&dev_priv->device->mmu) && + if (!kgsl_mmu_is_secured(mmu) && (flags & KGSL_MEMFLAGS_SECURE)) { dev_WARN_ONCE(dev_priv->device->dev, 1, "Secure memory not supported"); @@ -3116,11 +3130,15 @@ struct kgsl_mem_entry *gpumem_alloc_entry( flags = kgsl_filter_cachemode(flags); + /* Disable IO coherence if it is not supported on the chip */ + if (!MMU_FEATURE(mmu, KGSL_MMU_IO_COHERENT)) + flags &= ~((uint64_t)KGSL_MEMFLAGS_IOCOHERENT); + entry = kgsl_mem_entry_create(); if (entry == NULL) return ERR_PTR(-ENOMEM); - if (MMU_FEATURE(&dev_priv->device->mmu, KGSL_MMU_NEED_GUARD_PAGE)) + if (MMU_FEATURE(mmu, KGSL_MMU_NEED_GUARD_PAGE)) entry->memdesc.priv |= KGSL_MEMDESC_GUARD_PAGE; if (flags & KGSL_MEMFLAGS_SECURE) diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index 8fc2c82bdedc..ab3ab313d3a9 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -1835,6 +1835,9 @@ static unsigned int _get_protection_flags(struct kgsl_memdesc *memdesc) if (memdesc->priv & KGSL_MEMDESC_PRIVILEGED) flags |= IOMMU_PRIV; + if (memdesc->flags & KGSL_MEMFLAGS_IOCOHERENT) + flags |= IOMMU_CACHE; + return flags; } diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h index 2ea904ef1d93..430a14081d35 100644 --- a/drivers/gpu/msm/kgsl_mmu.h +++ b/drivers/gpu/msm/kgsl_mmu.h @@ -138,6 +138,8 @@ struct kgsl_mmu_pt_ops { #define KGSL_MMU_PAGED BIT(8) /* The device requires a guard page */ #define KGSL_MMU_NEED_GUARD_PAGE BIT(9) +/* The device supports IO coherency */ +#define KGSL_MMU_IO_COHERENT BIT(10) /** * struct kgsl_mmu - Master definition for KGSL MMU devices diff --git a/include/uapi/linux/msm_kgsl.h b/include/uapi/linux/msm_kgsl.h index f05155b6fb58..9ee2a8b1d016 100644 --- a/include/uapi/linux/msm_kgsl.h +++ b/include/uapi/linux/msm_kgsl.h @@ -142,6 +142,7 @@ #define KGSL_MEMFLAGS_USE_CPU_MAP 0x10000000ULL #define KGSL_MEMFLAGS_SPARSE_PHYS 0x20000000ULL #define KGSL_MEMFLAGS_SPARSE_VIRT 0x40000000ULL +#define KGSL_MEMFLAGS_IOCOHERENT 0x80000000ULL /* Memory types for which allocations are made */ #define KGSL_MEMTYPE_MASK 0x0000FF00