From 4fd6a5635ca9f839b04757402bf3ebd4e001d3be Mon Sep 17 00:00:00 2001 From: Shrenuj Bansal Date: Mon, 7 Aug 2017 15:12:54 -0700 Subject: [PATCH] msm: kgsl: Add the flags for IO coherency Add a flag in the UAPI header to allow userspace to mark a buffer as IO coherent. If this flag is set, mark the buffer as IO coherent when mapping it. Change-Id: I4cd28144cf818fa016e085f6f5ec29b778ccd8ad Signed-off-by: Shrenuj Bansal Signed-off-by: Lynus Vaz --- drivers/gpu/msm/adreno-gpulist.h | 3 ++- drivers/gpu/msm/adreno.c | 3 +++ drivers/gpu/msm/adreno.h | 2 ++ drivers/gpu/msm/kgsl.c | 32 +++++++++++++++++++++++++------- drivers/gpu/msm/kgsl_iommu.c | 3 +++ drivers/gpu/msm/kgsl_mmu.h | 2 ++ include/uapi/linux/msm_kgsl.h | 1 + 7 files changed, 38 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/msm/adreno-gpulist.h b/drivers/gpu/msm/adreno-gpulist.h index d0e6d739f2b9..18c729249987 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 f9a6fa2b2e7d..f90773c4be6a 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 2e1ceea0e8f8..675d9d756996 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -2284,7 +2284,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) @@ -2378,7 +2379,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; @@ -2663,7 +2669,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; @@ -3062,6 +3074,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 @@ -3070,14 +3083,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"); @@ -3106,11 +3120,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 dc0e733d5bb4..476ad9808f93 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -1840,6 +1840,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 7a8ab74054e7..8732eb9df669 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