summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Davis <afd@ti.com>2022-10-07 20:11:11 +0300
committerTom Rini <trini@konsulko.com>2022-10-18 20:40:40 +0300
commitc8d2fc75171465e19c8583a1ef266b3a7fe49281 (patch)
treeef7448600ab3a5283398dafd78ccffeceb557f17
parentfc95f83ec9543efb32774efda9e4352df49b1132 (diff)
downloadu-boot-c8d2fc75171465e19c8583a1ef266b3a7fe49281.tar.xz
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>
-rw-r--r--drivers/dma/dma-uclass.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/dma/dma-uclass.c b/drivers/dma/dma-uclass.c
index 012609bb53..70f06f1f09 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 @@ int dma_memcpy(void *dst, void *src, size_t len)
{
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 @@ int dma_memcpy(void *dst, void *src, size_t len)
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) = {