summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorSushmita Susheelendra <ssusheel@codeaurora.org>2017-03-02 15:56:27 -0700
committerSushmita Susheelendra <ssusheel@codeaurora.org>2017-03-10 15:56:04 -0700
commitd3d1c6e768bbd034be9c8b7e10e57f24ae706f9b (patch)
tree65e95fafaf659cc78c9f20736836c3e3b711503d /drivers/gpu/drm
parentb8c4038d1470287a9ab6ff897f62fe5d01484c0c (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.c5
-rw-r--r--drivers/gpu/drm/msm/msm_iommu.c9
-rw-r--r--drivers/gpu/drm/msm/msm_iommu.h9
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