dma: Use dma-mapping for cache ops and sync after write

The DMA'd memory area needs cleaned and invalidated after the DMA
write so that any stale cache lines do not mask new data.

Signed-off-by: Andrew Davis <afd@ti.com>
diff --git a/drivers/dma/dma-uclass.c b/drivers/dma/dma-uclass.c
index 012609b..70f06f1 100644
--- a/drivers/dma/dma-uclass.c
+++ b/drivers/dma/dma-uclass.c
@@ -19,6 +19,7 @@
 #include <asm/cache.h>
 #include <dm/read.h>
 #include <dma-uclass.h>
+#include <linux/dma-mapping.h>
 #include <dt-structs.h>
 #include <errno.h>
 
@@ -235,6 +236,8 @@
 {
 	struct udevice *dev;
 	const struct dma_ops *ops;
+	dma_addr_t destination;
+	dma_addr_t source;
 	int ret;
 
 	ret = dma_get_device(DMA_SUPPORTS_MEM_TO_MEM, &dev);
@@ -245,11 +248,17 @@
 	if (!ops->transfer)
 		return -ENOSYS;
 
-	/* Invalidate the area, so no writeback into the RAM races with DMA */
-	invalidate_dcache_range((unsigned long)dst, (unsigned long)dst +
-				roundup(len, ARCH_DMA_MINALIGN));
+	/* Clean the areas, so no writeback into the RAM races with DMA */
+	destination = dma_map_single(dst, len, DMA_FROM_DEVICE);
+	source = dma_map_single(src, len, DMA_TO_DEVICE);
 
-	return ops->transfer(dev, DMA_MEM_TO_MEM, dst, src, len);
+	ret = ops->transfer(dev, DMA_MEM_TO_MEM, dst, src, len);
+
+	/* Clean+Invalidate the areas after, so we can see DMA'd data */
+	dma_unmap_single(destination, len, DMA_FROM_DEVICE);
+	dma_unmap_single(source, len, DMA_TO_DEVICE);
+
+	return ret;
 }
 
 UCLASS_DRIVER(dma) = {