From patchwork Thu Jan 16 08:53:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vignesh Raghavendra X-Patchwork-Id: 239650 List-Id: U-Boot discussion From: vigneshr at ti.com (Vignesh Raghavendra) Date: Thu, 16 Jan 2020 14:23:45 +0530 Subject: [PATCH v2 1/4] asm: dma-mapping.h: Fix dma mapping functions In-Reply-To: <20200116085348.24031-1-vigneshr@ti.com> References: <20200116085348.24031-1-vigneshr@ti.com> Message-ID: <20200116085348.24031-2-vigneshr@ti.com> Subsystems such as USB expect dma_map_single() and dma_unmap_single() to do dcache flush/invalidate operations as required. For example, see see drivers/usb/gadget/udc/udc-core.c::usb_gadget_map_request(). Currently drivers do this locally, (see drivers/usb/dwc3/ep0.c, drivers/mtd/nand/raw/denali.c etc..) Update arch specific dma_map_single() and dma_unmap_single() APIs to do cache flush/invalidate operations, so that drivers need not implement them locally. Signed-off-by: Vignesh Raghavendra Reviewed-by: Masahiro Yamada Reviewed-by: Rick Chen --- arch/arm/include/asm/dma-mapping.h | 23 +++++++++++++++++++++-- arch/nds32/include/asm/dma-mapping.h | 23 +++++++++++++++++++++-- arch/riscv/include/asm/dma-mapping.h | 23 +++++++++++++++++++++-- arch/x86/include/asm/dma-mapping.h | 23 +++++++++++++++++++++-- 4 files changed, 84 insertions(+), 8 deletions(-) diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index fc5b8f634d54..d20703739fad 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h @@ -7,7 +7,11 @@ #ifndef __ASM_ARM_DMA_MAPPING_H #define __ASM_ARM_DMA_MAPPING_H +#include +#include +#include #include +#include #define dma_mapping_error(x, y) 0 @@ -25,12 +29,27 @@ static inline void dma_free_coherent(void *addr) static inline unsigned long dma_map_single(volatile void *vaddr, size_t len, enum dma_data_direction dir) { - return (unsigned long)vaddr; + unsigned long addr = (unsigned long)vaddr; + + len = ALIGN(len, ARCH_DMA_MINALIGN); + + if (dir == DMA_FROM_DEVICE) + invalidate_dcache_range(addr, addr + len); + else + flush_dcache_range(addr, addr + len); + + return addr; } static inline void dma_unmap_single(volatile void *vaddr, size_t len, - unsigned long paddr) + enum dma_data_direction dir) { + unsigned long addr = (unsigned long)vaddr; + + len = ALIGN(len, ARCH_DMA_MINALIGN); + + if (dir != DMA_TO_DEVICE) + invalidate_dcache_range(addr, addr + len); } #endif /* __ASM_ARM_DMA_MAPPING_H */ diff --git a/arch/nds32/include/asm/dma-mapping.h b/arch/nds32/include/asm/dma-mapping.h index e6808dc84089..c8876ceadda6 100644 --- a/arch/nds32/include/asm/dma-mapping.h +++ b/arch/nds32/include/asm/dma-mapping.h @@ -6,7 +6,11 @@ #ifndef __ASM_NDS_DMA_MAPPING_H #define __ASM_NDS_DMA_MAPPING_H +#include +#include +#include #include +#include static void *dma_alloc_coherent(size_t len, unsigned long *handle) { @@ -17,12 +21,27 @@ static void *dma_alloc_coherent(size_t len, unsigned long *handle) static inline unsigned long dma_map_single(volatile void *vaddr, size_t len, enum dma_data_direction dir) { - return (unsigned long)vaddr; + unsigned long addr = (unsigned long)vaddr; + + len = ALIGN(len, ARCH_DMA_MINALIGN); + + if (dir == DMA_FROM_DEVICE) + invalidate_dcache_range(addr, addr + len); + else + flush_dcache_range(addr, addr + len); + + return addr; } static inline void dma_unmap_single(volatile void *vaddr, size_t len, - unsigned long paddr) + enum dma_data_direction dir) { + unsigned long addr = (unsigned long)vaddr; + + len = ALIGN(len, ARCH_DMA_MINALIGN); + + if (dir != DMA_TO_DEVICE) + invalidate_dcache_range(addr, addr + len); } #endif /* __ASM_NDS_DMA_MAPPING_H */ diff --git a/arch/riscv/include/asm/dma-mapping.h b/arch/riscv/include/asm/dma-mapping.h index 3d930c90eceb..6cc39469590a 100644 --- a/arch/riscv/include/asm/dma-mapping.h +++ b/arch/riscv/include/asm/dma-mapping.h @@ -9,7 +9,11 @@ #ifndef __ASM_RISCV_DMA_MAPPING_H #define __ASM_RISCV_DMA_MAPPING_H +#include +#include +#include #include +#include #define dma_mapping_error(x, y) 0 @@ -27,12 +31,27 @@ static inline void dma_free_coherent(void *addr) static inline unsigned long dma_map_single(volatile void *vaddr, size_t len, enum dma_data_direction dir) { - return (unsigned long)vaddr; + unsigned long addr = (unsigned long)vaddr; + + len = ALIGN(len, ARCH_DMA_MINALIGN); + + if (dir == DMA_FROM_DEVICE) + invalidate_dcache_range(addr, addr + len); + else + flush_dcache_range(addr, addr + len); + + return addr; } static inline void dma_unmap_single(volatile void *vaddr, size_t len, - unsigned long paddr) + enum dma_data_direction dir) { + unsigned long addr = (unsigned long)vaddr; + + len = ALIGN(len, ARCH_DMA_MINALIGN); + + if (dir != DMA_TO_DEVICE) + invalidate_dcache_range(addr, addr + len); } #endif /* __ASM_RISCV_DMA_MAPPING_H */ diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h index b353ff0bef59..900b99b8a69a 100644 --- a/arch/x86/include/asm/dma-mapping.h +++ b/arch/x86/include/asm/dma-mapping.h @@ -7,7 +7,11 @@ #ifndef __ASM_X86_DMA_MAPPING_H #define __ASM_X86_DMA_MAPPING_H +#include +#include +#include #include +#include #define dma_mapping_error(x, y) 0 @@ -25,12 +29,27 @@ static inline void dma_free_coherent(void *addr) static inline unsigned long dma_map_single(volatile void *vaddr, size_t len, enum dma_data_direction dir) { - return (unsigned long)vaddr; + unsigned long addr = (unsigned long)vaddr; + + len = ALIGN(len, ARCH_DMA_MINALIGN); + + if (dir == DMA_FROM_DEVICE) + invalidate_dcache_range(addr, addr + len); + else + flush_dcache_range(addr, addr + len); + + return addr; } static inline void dma_unmap_single(volatile void *vaddr, size_t len, - unsigned long paddr) + enum dma_data_direction dir) { + unsigned long addr = (unsigned long)vaddr; + + len = ALIGN(len, ARCH_DMA_MINALIGN); + + if (dir != DMA_TO_DEVICE) + invalidate_dcache_range(addr, addr + len); } #endif /* __ASM_X86_DMA_MAPPING_H */ From patchwork Thu Jan 16 08:53:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vignesh Raghavendra X-Patchwork-Id: 239653 List-Id: U-Boot discussion From: vigneshr at ti.com (Vignesh Raghavendra) Date: Thu, 16 Jan 2020 14:23:46 +0530 Subject: [PATCH v2 2/4] mmc: tmio-common: Drop custom dma mapping functions In-Reply-To: <20200116085348.24031-1-vigneshr@ti.com> References: <20200116085348.24031-1-vigneshr@ti.com> Message-ID: <20200116085348.24031-3-vigneshr@ti.com> Drop local dma_map_single() and dma_unmap_single() and use arch specific common implementation Signed-off-by: Vignesh Raghavendra Acked-by: Masahiro Yamada --- drivers/mmc/tmio-common.c | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/drivers/mmc/tmio-common.c b/drivers/mmc/tmio-common.c index 669410d97f6e..5a8506dcb6bd 100644 --- a/drivers/mmc/tmio-common.c +++ b/drivers/mmc/tmio-common.c @@ -4,6 +4,7 @@ * Author: Masahiro Yamada */ +#include #include #include #include @@ -76,26 +77,6 @@ void tmio_sd_writel(struct tmio_sd_priv *priv, writel(val, priv->regbase + reg); } -static dma_addr_t __dma_map_single(void *ptr, size_t size, - enum dma_data_direction dir) -{ - unsigned long addr = (unsigned long)ptr; - - if (dir == DMA_FROM_DEVICE) - invalidate_dcache_range(addr, addr + size); - else - flush_dcache_range(addr, addr + size); - - return addr; -} - -static void __dma_unmap_single(dma_addr_t addr, size_t size, - enum dma_data_direction dir) -{ - if (dir != DMA_TO_DEVICE) - invalidate_dcache_range(addr, addr + size); -} - static int tmio_sd_check_error(struct udevice *dev, struct mmc_cmd *cmd) { struct tmio_sd_priv *priv = dev_get_priv(dev); @@ -362,7 +343,7 @@ static int tmio_sd_dma_xfer(struct udevice *dev, struct mmc_data *data) tmio_sd_writel(priv, tmp, TMIO_SD_DMA_MODE); - dma_addr = __dma_map_single(buf, len, dir); + dma_addr = dma_map_single(buf, len, dir); tmio_sd_dma_start(priv, dma_addr); @@ -371,7 +352,7 @@ static int tmio_sd_dma_xfer(struct udevice *dev, struct mmc_data *data) if (poll_flag == TMIO_SD_DMA_INFO1_END_RD) udelay(1); - __dma_unmap_single(dma_addr, len, dir); + dma_unmap_single(buf, len, dir); return ret; } From patchwork Thu Jan 16 08:53:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vignesh Raghavendra X-Patchwork-Id: 239652 List-Id: U-Boot discussion From: vigneshr at ti.com (Vignesh Raghavendra) Date: Thu, 16 Jan 2020 14:23:47 +0530 Subject: [PATCH v2 3/4] mtd: denali: Drop custom dma mapping functions In-Reply-To: <20200116085348.24031-1-vigneshr@ti.com> References: <20200116085348.24031-1-vigneshr@ti.com> Message-ID: <20200116085348.24031-4-vigneshr@ti.com> Drop local dma_map_single() and dma_unmap_single() and use arch specific common implementation Signed-off-by: Vignesh Raghavendra Acked-by: Masahiro Yamada --- drivers/mtd/nand/raw/denali.c | 35 +++-------------------------------- 1 file changed, 3 insertions(+), 32 deletions(-) diff --git a/drivers/mtd/nand/raw/denali.c b/drivers/mtd/nand/raw/denali.c index 0a7ca8a8dfb4..8537c609fb62 100644 --- a/drivers/mtd/nand/raw/denali.c +++ b/drivers/mtd/nand/raw/denali.c @@ -5,7 +5,7 @@ * Copyright (C) 2009-2010, Intel Corporation and its suppliers. */ -#include +#include #include #include #include @@ -17,35 +17,6 @@ #include "denali.h" -static dma_addr_t dma_map_single(void *dev, void *ptr, size_t size, - enum dma_data_direction dir) -{ - unsigned long addr = (unsigned long)ptr; - - size = ALIGN(size, ARCH_DMA_MINALIGN); - - if (dir == DMA_FROM_DEVICE) - invalidate_dcache_range(addr, addr + size); - else - flush_dcache_range(addr, addr + size); - - return addr; -} - -static void dma_unmap_single(void *dev, dma_addr_t addr, size_t size, - enum dma_data_direction dir) -{ - size = ALIGN(size, ARCH_DMA_MINALIGN); - - if (dir != DMA_TO_DEVICE) - invalidate_dcache_range(addr, addr + size); -} - -static int dma_mapping_error(void *dev, dma_addr_t addr) -{ - return 0; -} - #define DENALI_NAND_NAME "denali-nand" /* for Indexed Addressing */ @@ -565,7 +536,7 @@ static int denali_dma_xfer(struct denali_nand_info *denali, void *buf, enum dma_data_direction dir = write ? DMA_TO_DEVICE : DMA_FROM_DEVICE; int ret = 0; - dma_addr = dma_map_single(denali->dev, buf, size, dir); + dma_addr = dma_map_single(buf, size, dir); if (dma_mapping_error(denali->dev, dma_addr)) { dev_dbg(denali->dev, "Failed to DMA-map buffer. Trying PIO.\n"); return denali_pio_xfer(denali, buf, size, page, raw, write); @@ -606,7 +577,7 @@ static int denali_dma_xfer(struct denali_nand_info *denali, void *buf, iowrite32(0, denali->reg + DMA_ENABLE); - dma_unmap_single(denali->dev, dma_addr, size, dir); + dma_unmap_single(buf, size, dir); if (irq_status & INTR__ERASED_PAGE) memset(buf, 0xff, size); From patchwork Thu Jan 16 08:53:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vignesh Raghavendra X-Patchwork-Id: 239654 List-Id: U-Boot discussion From: vigneshr at ti.com (Vignesh Raghavendra) Date: Thu, 16 Jan 2020 14:23:48 +0530 Subject: [PATCH v2 4/4] net: macb: Drop local cache flush In-Reply-To: <20200116085348.24031-1-vigneshr@ti.com> References: <20200116085348.24031-1-vigneshr@ti.com> Message-ID: <20200116085348.24031-5-vigneshr@ti.com> Now that arch specific dma mapping APIs take care of cache flush/invalidate, drop local cache flush operation. While at that fix dma_unmap_single() call to match new prototype Signed-off-by: Vignesh Raghavendra --- drivers/net/macb.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 83594253787c..0d4929bec131 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -327,8 +327,6 @@ static int _macb_send(struct macb_device *macb, const char *name, void *packet, macb->tx_ring[tx_head].addr = paddr; barrier(); macb_flush_ring_desc(macb, TX); - /* Do we need check paddr and length is dcache line aligned? */ - flush_dcache_range(paddr, paddr + ALIGN(length, ARCH_DMA_MINALIGN)); macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART)); /* @@ -344,7 +342,7 @@ static int _macb_send(struct macb_device *macb, const char *name, void *packet, udelay(1); } - dma_unmap_single(packet, length, paddr); + dma_unmap_single(packet, length, DMA_TO_DEVICE); if (i <= MACB_TX_TIMEOUT) { if (ctrl & MACB_BIT(TX_UNDERRUN))