summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Courbot <acourbot@nvidia.com>2014-05-19 15:53:39 +0900
committerThierry Reding <treding@nvidia.com>2014-08-07 16:54:52 +0200
commitb3568d11aefd49a321243cea9a9438d8581f8b93 (patch)
treeae80c1245db35d6865584ac6c5d616b97abb8011
parentcb4d747f734f136495ec8c151bf44a783c78aeee (diff)
drm/nouveau: introduce CPU cache flushing macro
BOs in non-coherent memory need to be explicitly flushed to ensure a memory write took effect. Not doing so could result in synchronization issues. This patch introduces a macro that flushes the caches on ARM and translates to a no-op on other architectures, and uses it when writing to in-memory BOs. It will also be useful for implementations of instmem that access shared memory directly instead of going through PRAMIN. Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
-rw-r--r--drivers/gpu/drm/nouveau/core/os.h20
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c8
2 files changed, 26 insertions, 2 deletions
diff --git a/drivers/gpu/drm/nouveau/core/os.h b/drivers/gpu/drm/nouveau/core/os.h
index d0ced94ca54c..fc84a258f910 100644
--- a/drivers/gpu/drm/nouveau/core/os.h
+++ b/drivers/gpu/drm/nouveau/core/os.h
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/log2.h>
#include <linux/pm_runtime.h>
+#include <asm/cacheflush.h>
#include <asm/unaligned.h>
@@ -38,4 +39,23 @@
#endif /* def __BIG_ENDIAN else */
#endif /* !ioread32_native */
+#if defined(__arm__)
+
+static inline void
+nv_cpu_cache_flush_area(void *va, size_t size)
+{
+ phys_addr_t pa = virt_to_phys(va);
+ __cpuc_flush_dcache_area(va, size);
+ outer_flush_range(pa, pa + size);
+}
+
+#else
+
+static inline void
+nv_cpu_cache_flush_area(void *va, size_t size)
+{
+}
+
+#endif /* defined(__arm__) */
+
#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 1464c1cb2c7a..28e3daef0a5a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -437,8 +437,10 @@ nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val)
mem = &mem[index];
if (is_iomem)
iowrite16_native(val, (void __force __iomem *)mem);
- else
+ else {
*mem = val;
+ nv_cpu_cache_flush_area(mem, 2);
+ }
}
u32
@@ -461,8 +463,10 @@ nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val)
mem = &mem[index];
if (is_iomem)
iowrite32_native(val, (void __force __iomem *)mem);
- else
+ else {
*mem = val;
+ nv_cpu_cache_flush_area(mem, 4);
+ }
}
static struct ttm_tt *