[PATCH 4/4] drm/nouveau: introduce CPU cache flushing macro

From: Alexandre Courbot
Date: Mon May 19 2014 - 03:11:42 EST


Some architectures (e.g. ARM) need the CPU buffers to be explicitely
flushed for a memory write to take effect. Not doing so results in
synchronization issues, especially after writing to BOs.

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@xxxxxxxxxx>
---
drivers/gpu/drm/nouveau/core/os.h | 17 +++++++++++++++++
drivers/gpu/drm/nouveau/nouveau_bo.c | 8 ++++++--
2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/core/os.h b/drivers/gpu/drm/nouveau/core/os.h
index d0ced94ca54c..274b4460bb03 100644
--- a/drivers/gpu/drm/nouveau/core/os.h
+++ b/drivers/gpu/drm/nouveau/core/os.h
@@ -38,4 +38,21 @@
#endif /* def __BIG_ENDIAN else */
#endif /* !ioread32_native */

+#if defined(__arm__)
+
+#define nv_cpu_cache_flush_area(va, size) \
+do { \
+ phys_addr_t pa = virt_to_phys(va); \
+ __cpuc_flush_dcache_area(va, size); \
+ outer_flush_range(pa, pa + size); \
+} while (0)
+
+#else
+
+#define nv_cpu_cache_flush_area(va, size) \
+do { \
+} while (0)
+
+#endif /* defined(__arm__) */
+
#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 0886f47e5244..b9c9729c5733 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 *
--
1.9.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/