diff options
author | Sushmita Susheelendra <ssusheel@codeaurora.org> | 2017-03-02 15:56:27 -0700 |
---|---|---|
committer | Sushmita Susheelendra <ssusheel@codeaurora.org> | 2017-03-10 15:56:04 -0700 |
commit | d3d1c6e768bbd034be9c8b7e10e57f24ae706f9b (patch) | |
tree | 65e95fafaf659cc78c9f20736836c3e3b711503d /drivers/gpu/drm | |
parent | b8c4038d1470287a9ab6ff897f62fe5d01484c0c (diff) |
drm/msm: Enable I/O coherence for CPU cached buffers
This makes buffers allocated as cached on the CPU to be
coherent with the GPU. With this, the GPU is able to
snoop into the CPU's caches to get the data. If the data
is not present in any of the CPU's caches, it is fetched
from main memory. This avoids the need for CPU cache
maintenance operations in software.
Change-Id: I5fd4df0182a4b4c36528904d9e4bb35221da0053
Signed-off-by: Sushmita Susheelendra <ssusheel@codeaurora.org>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/msm/msm_gem_vma.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/msm_iommu.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/msm_iommu.h | 9 |
3 files changed, 22 insertions, 1 deletions
diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c b/drivers/gpu/drm/msm/msm_gem_vma.c index 7ca96831a9b3..a227f1ba0573 100644 --- a/drivers/gpu/drm/msm/msm_gem_vma.c +++ b/drivers/gpu/drm/msm/msm_gem_vma.c @@ -17,7 +17,7 @@ #include "msm_drv.h" #include "msm_gem.h" -#include "msm_mmu.h" +#include "msm_iommu.h" static void msm_gem_address_space_destroy(struct kref *kref) @@ -149,6 +149,9 @@ static int iommu_aspace_map_vma(struct msm_gem_address_space *aspace, if (flags & MSM_BO_PRIVILEGED) iommu_flags |= IOMMU_PRIV; + if ((flags & MSM_BO_CACHED) && msm_iommu_coherent(aspace->mmu)) + iommu_flags |= IOMMU_CACHE; + if (WARN_ON(drm_mm_node_allocated(&vma->node))) return 0; diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c index 3c16222b8890..3af24646f4f1 100644 --- a/drivers/gpu/drm/msm/msm_iommu.c +++ b/drivers/gpu/drm/msm/msm_iommu.c @@ -16,6 +16,7 @@ */ #include <linux/of_platform.h> +#include <linux/of_address.h> #include "msm_drv.h" #include "msm_iommu.h" @@ -126,6 +127,9 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const char **names, int cnt) if (ret) iommu->allow_dynamic = false; + /* Mark the GPU as I/O coherent if it is supported */ + iommu->is_coherent = of_dma_is_coherent(mmu->dev->of_node); + /* Attach the device to the domain */ ret = _attach_iommu_device(mmu, iommu->domain, names, cnt); if (ret) @@ -312,6 +316,7 @@ struct msm_mmu *msm_iommu_new_dynamic(struct msm_mmu *base) struct iommu_domain *domain; struct msm_mmu *mmu; int ret, val = 1; + struct msm_iommu *child_iommu; /* Don't continue if the base domain didn't have the support we need */ if (!base || base_iommu->allow_dynamic == false) @@ -339,5 +344,9 @@ struct msm_mmu *msm_iommu_new_dynamic(struct msm_mmu *base) iommu_domain_set_attr(domain, DOMAIN_ATTR_CONTEXT_BANK, &base_iommu->cb); + /* Mark the dynamic domain as I/O coherent if the base domain is */ + child_iommu = to_msm_iommu(mmu); + child_iommu->is_coherent = base_iommu->is_coherent; + return mmu; } diff --git a/drivers/gpu/drm/msm/msm_iommu.h b/drivers/gpu/drm/msm/msm_iommu.h index d005cfb9758f..3a67b60ad81d 100644 --- a/drivers/gpu/drm/msm/msm_iommu.h +++ b/drivers/gpu/drm/msm/msm_iommu.h @@ -25,6 +25,8 @@ struct msm_iommu { struct clk *clocks[5]; int nr_clocks; + + bool is_coherent; }; #define to_msm_iommu(x) container_of(x, struct msm_iommu, base) @@ -34,4 +36,11 @@ static inline bool msm_iommu_allow_dynamic(struct msm_mmu *mmu) return iommu->allow_dynamic; } + +static inline bool msm_iommu_coherent(struct msm_mmu *mmu) +{ + struct msm_iommu *iommu = to_msm_iommu(mmu); + + return iommu->is_coherent; +} #endif |