summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Davis <afd@ti.com>2022-10-07 20:11:12 +0300
committerTom Rini <trini@konsulko.com>2022-10-18 20:40:40 +0300
commitb8392650462094ed15e123f836daccd7617946a5 (patch)
treefd424a5e02b3c587ddcf09785993ff430729038a
parentc8d2fc75171465e19c8583a1ef266b3a7fe49281 (diff)
downloadu-boot-b8392650462094ed15e123f836daccd7617946a5.tar.xz
dma: ti-edma3: Add DMA map operations before and after transfers
We should clean the caches before any DMA operation and clean+invalidate after. This matches what the DMA framework does for us already but adds it to the two functions here in this driver that don't yet go through the new DMA framework. Signed-off-by: Andrew Davis <afd@ti.com>
-rw-r--r--drivers/dma/ti-edma3.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/dma/ti-edma3.c b/drivers/dma/ti-edma3.c
index ec3dc62d2f..53dc4e8ce5 100644
--- a/drivers/dma/ti-edma3.c
+++ b/drivers/dma/ti-edma3.c
@@ -13,6 +13,7 @@
#include <common.h>
#include <dm.h>
#include <dma-uclass.h>
+#include <linux/dma-mapping.h>
#include <asm/omap_common.h>
#include <asm/ti-common/ti-edma3.h>
@@ -487,8 +488,10 @@ void __edma3_fill(unsigned long edma3_base_addr, unsigned int edma_slot_num,
{
int xfer_len;
int max_xfer = EDMA_FILL_BUFFER_SIZE * 65535;
+ dma_addr_t source;
memset((void *)edma_fill_buffer, val, sizeof(edma_fill_buffer));
+ source = dma_map_single(edma_fill_buffer, len, DMA_TO_DEVICE);
while (len) {
xfer_len = len;
@@ -501,6 +504,8 @@ void __edma3_fill(unsigned long edma3_base_addr, unsigned int edma_slot_num,
len -= xfer_len;
dst += xfer_len;
}
+
+ dma_unmap_single(source, len, DMA_FROM_DEVICE);
}
#ifndef CONFIG_DMA
@@ -508,13 +513,27 @@ void __edma3_fill(unsigned long edma3_base_addr, unsigned int edma_slot_num,
void edma3_transfer(unsigned long edma3_base_addr, unsigned int edma_slot_num,
void *dst, void *src, size_t len)
{
+ /* Clean the areas, so no writeback into the RAM races with DMA */
+ dma_addr_t destination = dma_map_single(dst, len, DMA_FROM_DEVICE);
+ dma_addr_t source = dma_map_single(src, len, DMA_TO_DEVICE);
+
__edma3_transfer(edma3_base_addr, edma_slot_num, dst, src, len, 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);
}
void edma3_fill(unsigned long edma3_base_addr, unsigned int edma_slot_num,
void *dst, u8 val, size_t len)
{
+ /* Clean the area, so no writeback into the RAM races with DMA */
+ dma_addr_t destination = dma_map_single(dst, len, DMA_FROM_DEVICE);
+
__edma3_fill(edma3_base_addr, edma_slot_num, dst, val, len);
+
+ /* Clean+Invalidate the area after, so we can see DMA'd data */
+ dma_unmap_single(destination, len, DMA_FROM_DEVICE);
}
#else