All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/11] mmc: sdhci: code clean-up and fix cache coherency problem
@ 2020-02-14  7:40 Masahiro Yamada
  2020-02-14  7:40 ` [PATCH v3 01/11] dma-mapping: fix the prototype of dma_map_single() Masahiro Yamada
                   ` (10 more replies)
  0 siblings, 11 replies; 17+ messages in thread
From: Masahiro Yamada @ 2020-02-14  7:40 UTC (permalink / raw)
  To: u-boot

My main motivation of this series is the last patch
"mmc: sdhci: fix missing cache invalidation after reading by DMA".

Currently, read data are occasionally corrupted due to the
missing cache invalidation.

To fix it nicely (adds dma_unmap_single(), which follows the
Linux coding style), I did some cleaups first.

Patch 01-04 tidies up the DMA helpers.

Patch 05-10 are code clean-ups.

Patch 11 fixes the bug.


Masahiro Yamada (11):
  dma-mapping: fix the prototype of dma_map_single()
  dma-mapping: fix the prototype of dma_unmap_single()
  dma-mapping: move dma_map_(un)single() to <linux/dma-mapping.h>
  dma-mapping: add <asm/dma-mapping.h> for all architectures
  mmc: sdhci: put the aligned buffer pointer to struct sdhci_host
  mmc: sdhci: reduce code duplication for aligned buffer
  mmc: sdhci: use lower_32_bit2() and upper_32_bits() for setting
    adma_addr
  mmc: sdhci: remove unneeded casts
  mmc: add mmc_get_dma_dir() helper
  mmc: sdhci: use dma_map_single() instead of flush_cache() before DMA
  mmc: sdhci: fix missing cache invalidation after reading by DMA

 arch/arc/include/asm/dma-mapping.h        |  1 +
 arch/arm/include/asm/dma-mapping.h        | 29 +------
 arch/m68k/include/asm/dma-mapping.h       |  1 +
 arch/microblaze/include/asm/dma-mapping.h |  1 +
 arch/mips/include/asm/dma-mapping.h       |  1 +
 arch/nds32/include/asm/dma-mapping.h      | 27 +------
 arch/nios2/include/asm/dma-mapping.h      | 25 +-----
 arch/powerpc/include/asm/dma-mapping.h    |  1 +
 arch/riscv/include/asm/dma-mapping.h      | 29 +------
 arch/sandbox/include/asm/dma-mapping.h    |  1 +
 arch/sh/include/asm/dma-mapping.h         |  1 +
 arch/x86/include/asm/dma-mapping.h        | 29 +------
 arch/xtensa/include/asm/dma-mapping.h     |  1 +
 drivers/dma/ti/k3-udma.c                  |  2 +-
 drivers/mmc/sdhci.c                       | 96 +++++++++++------------
 drivers/mmc/tmio-common.c                 |  5 +-
 drivers/mtd/nand/raw/denali.c             |  5 +-
 drivers/net/altera_tse.c                  |  2 +-
 drivers/net/ftmac110.c                    |  2 +-
 drivers/net/macb.c                        |  4 +-
 drivers/soc/ti/k3-navss-ringacc.c         |  2 +-
 drivers/ufs/ufs.c                         |  2 +-
 drivers/usb/cdns3/gadget.c                |  2 +-
 drivers/usb/dwc3/core.c                   |  8 +-
 drivers/usb/dwc3/gadget.c                 |  2 +-
 drivers/usb/gadget/udc/udc-core.c         |  4 +-
 include/linux/dma-mapping.h               | 63 +++++++++++++++
 include/mmc.h                             |  6 ++
 include/sdhci.h                           |  3 +
 29 files changed, 150 insertions(+), 205 deletions(-)
 create mode 100644 arch/arc/include/asm/dma-mapping.h
 create mode 100644 arch/m68k/include/asm/dma-mapping.h
 create mode 100644 arch/microblaze/include/asm/dma-mapping.h
 create mode 100644 arch/mips/include/asm/dma-mapping.h
 create mode 100644 arch/powerpc/include/asm/dma-mapping.h
 create mode 100644 arch/sandbox/include/asm/dma-mapping.h
 create mode 100644 arch/sh/include/asm/dma-mapping.h
 create mode 100644 arch/xtensa/include/asm/dma-mapping.h
 create mode 100644 include/linux/dma-mapping.h

-- 
2.17.1

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v3 01/11] dma-mapping: fix the prototype of dma_map_single()
  2020-02-14  7:40 [PATCH v3 00/11] mmc: sdhci: code clean-up and fix cache coherency problem Masahiro Yamada
@ 2020-02-14  7:40 ` Masahiro Yamada
  2020-02-14  7:40 ` [PATCH v3 02/11] dma-mapping: fix the prototype of dma_unmap_single() Masahiro Yamada
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Masahiro Yamada @ 2020-02-14  7:40 UTC (permalink / raw)
  To: u-boot

Make dma_map_single() return the dma address, and remove the
pointless volatile.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---

Changes in v3: None
Changes in v2: None

 arch/arm/include/asm/dma-mapping.h   | 5 +++--
 arch/nds32/include/asm/dma-mapping.h | 5 +++--
 arch/riscv/include/asm/dma-mapping.h | 5 +++--
 arch/x86/include/asm/dma-mapping.h   | 5 +++--
 4 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index d20703739fad..d0895a209666 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -11,6 +11,7 @@
 #include <asm/cache.h>
 #include <cpu_func.h>
 #include <linux/dma-direction.h>
+#include <linux/types.h>
 #include <malloc.h>
 
 #define	dma_mapping_error(x, y)	0
@@ -26,8 +27,8 @@ static inline void dma_free_coherent(void *addr)
 	free(addr);
 }
 
-static inline unsigned long dma_map_single(volatile void *vaddr, size_t len,
-					   enum dma_data_direction dir)
+static inline dma_addr_t dma_map_single(void *vaddr, size_t len,
+					enum dma_data_direction dir)
 {
 	unsigned long addr = (unsigned long)vaddr;
 
diff --git a/arch/nds32/include/asm/dma-mapping.h b/arch/nds32/include/asm/dma-mapping.h
index c8876ceadda6..9387dec34768 100644
--- a/arch/nds32/include/asm/dma-mapping.h
+++ b/arch/nds32/include/asm/dma-mapping.h
@@ -10,6 +10,7 @@
 #include <asm/cache.h>
 #include <cpu_func.h>
 #include <linux/dma-direction.h>
+#include <linux/types.h>
 #include <malloc.h>
 
 static void *dma_alloc_coherent(size_t len, unsigned long *handle)
@@ -18,8 +19,8 @@ static void *dma_alloc_coherent(size_t len, unsigned long *handle)
 	return (void *)*handle;
 }
 
-static inline unsigned long dma_map_single(volatile void *vaddr, size_t len,
-					   enum dma_data_direction dir)
+static inline dma_addr_t dma_map_single(void *vaddr, size_t len,
+					enum dma_data_direction dir)
 {
 	unsigned long addr = (unsigned long)vaddr;
 
diff --git a/arch/riscv/include/asm/dma-mapping.h b/arch/riscv/include/asm/dma-mapping.h
index 6cc39469590a..eac56f8fbdfa 100644
--- a/arch/riscv/include/asm/dma-mapping.h
+++ b/arch/riscv/include/asm/dma-mapping.h
@@ -10,6 +10,7 @@
 #define __ASM_RISCV_DMA_MAPPING_H
 
 #include <common.h>
+#include <linux/types.h>
 #include <asm/cache.h>
 #include <cpu_func.h>
 #include <linux/dma-direction.h>
@@ -28,8 +29,8 @@ static inline void dma_free_coherent(void *addr)
 	free(addr);
 }
 
-static inline unsigned long dma_map_single(volatile void *vaddr, size_t len,
-					   enum dma_data_direction dir)
+static inline dma_addr_t dma_map_single(void *vaddr, size_t len,
+					enum dma_data_direction dir)
 {
 	unsigned long addr = (unsigned long)vaddr;
 
diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h
index 900b99b8a69a..7e205e3313ac 100644
--- a/arch/x86/include/asm/dma-mapping.h
+++ b/arch/x86/include/asm/dma-mapping.h
@@ -11,6 +11,7 @@
 #include <asm/cache.h>
 #include <cpu_func.h>
 #include <linux/dma-direction.h>
+#include <linux/types.h>
 #include <malloc.h>
 
 #define	dma_mapping_error(x, y)	0
@@ -26,8 +27,8 @@ static inline void dma_free_coherent(void *addr)
 	free(addr);
 }
 
-static inline unsigned long dma_map_single(volatile void *vaddr, size_t len,
-					   enum dma_data_direction dir)
+static inline dma_addr_t dma_map_single(void *vaddr, size_t len,
+					enum dma_data_direction dir)
 {
 	unsigned long addr = (unsigned long)vaddr;
 
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 02/11] dma-mapping: fix the prototype of dma_unmap_single()
  2020-02-14  7:40 [PATCH v3 00/11] mmc: sdhci: code clean-up and fix cache coherency problem Masahiro Yamada
  2020-02-14  7:40 ` [PATCH v3 01/11] dma-mapping: fix the prototype of dma_map_single() Masahiro Yamada
@ 2020-02-14  7:40 ` Masahiro Yamada
  2020-02-14  7:40 ` [PATCH v3 03/11] dma-mapping: move dma_map_(un)single() to <linux/dma-mapping.h> Masahiro Yamada
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Masahiro Yamada @ 2020-02-14  7:40 UTC (permalink / raw)
  To: u-boot

dma_unmap_single() takes the dma address, not virtual address.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---

Changes in v3: None
Changes in v2: None

 arch/arm/include/asm/dma-mapping.h   | 4 +---
 arch/nds32/include/asm/dma-mapping.h | 4 +---
 arch/riscv/include/asm/dma-mapping.h | 4 +---
 arch/x86/include/asm/dma-mapping.h   | 4 +---
 drivers/mmc/tmio-common.c            | 2 +-
 drivers/mtd/nand/raw/denali.c        | 2 +-
 drivers/net/macb.c                   | 2 +-
 drivers/usb/dwc3/core.c              | 6 +++---
 drivers/usb/gadget/udc/udc-core.c    | 2 +-
 9 files changed, 11 insertions(+), 19 deletions(-)

diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index d0895a209666..efdbed7280dd 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -42,11 +42,9 @@ static inline dma_addr_t dma_map_single(void *vaddr, size_t len,
 	return addr;
 }
 
-static inline void dma_unmap_single(volatile void *vaddr, size_t len,
+static inline void dma_unmap_single(dma_addr_t addr, size_t len,
 				    enum dma_data_direction dir)
 {
-	unsigned long addr = (unsigned long)vaddr;
-
 	len = ALIGN(len, ARCH_DMA_MINALIGN);
 
 	if (dir != DMA_TO_DEVICE)
diff --git a/arch/nds32/include/asm/dma-mapping.h b/arch/nds32/include/asm/dma-mapping.h
index 9387dec34768..784f489db54e 100644
--- a/arch/nds32/include/asm/dma-mapping.h
+++ b/arch/nds32/include/asm/dma-mapping.h
@@ -34,11 +34,9 @@ static inline dma_addr_t dma_map_single(void *vaddr, size_t len,
 	return addr;
 }
 
-static inline void dma_unmap_single(volatile void *vaddr, size_t len,
+static inline void dma_unmap_single(dma_addr_t addr, size_t len,
 				    enum dma_data_direction dir)
 {
-	unsigned long addr = (unsigned long)vaddr;
-
 	len = ALIGN(len, ARCH_DMA_MINALIGN);
 
 	if (dir != DMA_TO_DEVICE)
diff --git a/arch/riscv/include/asm/dma-mapping.h b/arch/riscv/include/asm/dma-mapping.h
index eac56f8fbdfa..1ac4a4fed58d 100644
--- a/arch/riscv/include/asm/dma-mapping.h
+++ b/arch/riscv/include/asm/dma-mapping.h
@@ -44,11 +44,9 @@ static inline dma_addr_t dma_map_single(void *vaddr, size_t len,
 	return addr;
 }
 
-static inline void dma_unmap_single(volatile void *vaddr, size_t len,
+static inline void dma_unmap_single(dma_addr_t addr, size_t len,
 				    enum dma_data_direction dir)
 {
-	unsigned long addr = (unsigned long)vaddr;
-
 	len = ALIGN(len, ARCH_DMA_MINALIGN);
 
 	if (dir != DMA_TO_DEVICE)
diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h
index 7e205e3313ac..37704da5dd4f 100644
--- a/arch/x86/include/asm/dma-mapping.h
+++ b/arch/x86/include/asm/dma-mapping.h
@@ -42,11 +42,9 @@ static inline dma_addr_t dma_map_single(void *vaddr, size_t len,
 	return addr;
 }
 
-static inline void dma_unmap_single(volatile void *vaddr, size_t len,
+static inline void dma_unmap_single(dma_addr_t addr, size_t len,
 				    enum dma_data_direction dir)
 {
-	unsigned long addr = (unsigned long)vaddr;
-
 	len = ALIGN(len, ARCH_DMA_MINALIGN);
 
 	if (dir != DMA_TO_DEVICE)
diff --git a/drivers/mmc/tmio-common.c b/drivers/mmc/tmio-common.c
index 092b740f564e..53213888473b 100644
--- a/drivers/mmc/tmio-common.c
+++ b/drivers/mmc/tmio-common.c
@@ -353,7 +353,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(buf, len, dir);
+	dma_unmap_single(dma_addr, len, dir);
 
 	return ret;
 }
diff --git a/drivers/mtd/nand/raw/denali.c b/drivers/mtd/nand/raw/denali.c
index f51d3e25c762..3e0ac39777d8 100644
--- a/drivers/mtd/nand/raw/denali.c
+++ b/drivers/mtd/nand/raw/denali.c
@@ -581,7 +581,7 @@ static int denali_dma_xfer(struct denali_nand_info *denali, void *buf,
 
 	iowrite32(0, denali->reg + DMA_ENABLE);
 
-	dma_unmap_single(buf, size, dir);
+	dma_unmap_single(dma_addr, size, dir);
 
 	if (irq_status & INTR__ERASED_PAGE)
 		memset(buf, 0xff, size);
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 0d4929bec131..7a2b1abeeb03 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -342,7 +342,7 @@ static int _macb_send(struct macb_device *macb, const char *name, void *packet,
 		udelay(1);
 	}
 
-	dma_unmap_single(packet, length, DMA_TO_DEVICE);
+	dma_unmap_single(paddr, length, DMA_TO_DEVICE);
 
 	if (i <= MACB_TX_TIMEOUT) {
 		if (ctrl & MACB_BIT(TX_UNDERRUN))
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index c5066529b7d0..6ad1000c9af6 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -288,8 +288,8 @@ static int dwc3_setup_scratch_buffers(struct dwc3 *dwc)
 	return 0;
 
 err1:
-	dma_unmap_single((void *)(uintptr_t)dwc->scratch_addr, dwc->nr_scratch *
-			 DWC3_SCRATCHBUF_SIZE, DMA_BIDIRECTIONAL);
+	dma_unmap_single(scratch_addr, dwc->nr_scratch * DWC3_SCRATCHBUF_SIZE,
+			 DMA_BIDIRECTIONAL);
 
 err0:
 	return ret;
@@ -303,7 +303,7 @@ static void dwc3_free_scratch_buffers(struct dwc3 *dwc)
 	if (!dwc->nr_scratch)
 		return;
 
-	dma_unmap_single((void *)(uintptr_t)dwc->scratch_addr, dwc->nr_scratch *
+	dma_unmap_single(dwc->scratch_addr, dwc->nr_scratch *
 			 DWC3_SCRATCHBUF_SIZE, DMA_BIDIRECTIONAL);
 	kfree(dwc->scratchbuf);
 }
diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c
index a33ab5c95d4e..528874507b41 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -67,7 +67,7 @@ void usb_gadget_unmap_request(struct usb_gadget *gadget,
 	if (req->length == 0)
 		return;
 
-	dma_unmap_single((void *)(uintptr_t)req->dma, req->length,
+	dma_unmap_single(req->dma, req->length,
 			 is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
 }
 EXPORT_SYMBOL_GPL(usb_gadget_unmap_request);
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 03/11] dma-mapping: move dma_map_(un)single() to <linux/dma-mapping.h>
  2020-02-14  7:40 [PATCH v3 00/11] mmc: sdhci: code clean-up and fix cache coherency problem Masahiro Yamada
  2020-02-14  7:40 ` [PATCH v3 01/11] dma-mapping: fix the prototype of dma_map_single() Masahiro Yamada
  2020-02-14  7:40 ` [PATCH v3 02/11] dma-mapping: fix the prototype of dma_unmap_single() Masahiro Yamada
@ 2020-02-14  7:40 ` Masahiro Yamada
  2020-02-14  7:40 ` [PATCH v3 04/11] dma-mapping: add <asm/dma-mapping.h> for all architectures Masahiro Yamada
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Masahiro Yamada @ 2020-02-14  7:40 UTC (permalink / raw)
  To: u-boot

The implementation of dma_map_single() and dma_unmap_single() is
exactly the same for all the architectures that support them.

Factor them out to <linux/dma-mapping.h>, and make all drivers to
include <linux/dma-mapping.h> instead of <asm/dma-mapping.h>.

If we need to differentiate them for some architectures, we can
move the generic definitions to <asm-generic/dma-mapping.h>.

Add some comments to the helpers. The concept is quite similar to
the DMA-API of Linux kernel. Drivers are agnostic about what is
going on behind the scene. Just call dma_map_single() before the
DMA, and dma_unmap_single() after it.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---

Changes in v3:
  - Rebase

Changes in v2:
  - New patch

 arch/arm/include/asm/dma-mapping.h   | 26 ------------
 arch/nds32/include/asm/dma-mapping.h | 24 -----------
 arch/riscv/include/asm/dma-mapping.h | 26 ------------
 arch/x86/include/asm/dma-mapping.h   | 26 ------------
 drivers/dma/ti/k3-udma.c             |  2 +-
 drivers/mmc/tmio-common.c            |  3 +-
 drivers/mtd/nand/raw/denali.c        |  3 +-
 drivers/net/altera_tse.c             |  2 +-
 drivers/net/ftmac110.c               |  2 +-
 drivers/net/macb.c                   |  2 +-
 drivers/soc/ti/k3-navss-ringacc.c    |  2 +-
 drivers/ufs/ufs.c                    |  2 +-
 drivers/usb/cdns3/gadget.c           |  2 +-
 drivers/usb/dwc3/core.c              |  2 +-
 drivers/usb/dwc3/gadget.c            |  2 +-
 drivers/usb/gadget/udc/udc-core.c    |  2 +-
 include/linux/dma-mapping.h          | 63 ++++++++++++++++++++++++++++
 17 files changed, 75 insertions(+), 116 deletions(-)
 create mode 100644 include/linux/dma-mapping.h

diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index efdbed7280dd..8bb3fa2e0ee7 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -14,8 +14,6 @@
 #include <linux/types.h>
 #include <malloc.h>
 
-#define	dma_mapping_error(x, y)	0
-
 static inline void *dma_alloc_coherent(size_t len, unsigned long *handle)
 {
 	*handle = (unsigned long)memalign(ARCH_DMA_MINALIGN, ROUND(len, ARCH_DMA_MINALIGN));
@@ -27,28 +25,4 @@ static inline void dma_free_coherent(void *addr)
 	free(addr);
 }
 
-static inline dma_addr_t dma_map_single(void *vaddr, size_t len,
-					enum dma_data_direction dir)
-{
-	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(dma_addr_t addr, size_t len,
-				    enum dma_data_direction dir)
-{
-	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 784f489db54e..f8668f1fe5db 100644
--- a/arch/nds32/include/asm/dma-mapping.h
+++ b/arch/nds32/include/asm/dma-mapping.h
@@ -19,28 +19,4 @@ static void *dma_alloc_coherent(size_t len, unsigned long *handle)
 	return (void *)*handle;
 }
 
-static inline dma_addr_t dma_map_single(void *vaddr, size_t len,
-					enum dma_data_direction dir)
-{
-	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(dma_addr_t addr, size_t len,
-				    enum dma_data_direction dir)
-{
-	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 1ac4a4fed58d..6ecadab41cd9 100644
--- a/arch/riscv/include/asm/dma-mapping.h
+++ b/arch/riscv/include/asm/dma-mapping.h
@@ -16,8 +16,6 @@
 #include <linux/dma-direction.h>
 #include <malloc.h>
 
-#define dma_mapping_error(x, y)	0
-
 static inline void *dma_alloc_coherent(size_t len, unsigned long *handle)
 {
 	*handle = (unsigned long)memalign(ARCH_DMA_MINALIGN, len);
@@ -29,28 +27,4 @@ static inline void dma_free_coherent(void *addr)
 	free(addr);
 }
 
-static inline dma_addr_t dma_map_single(void *vaddr, size_t len,
-					enum dma_data_direction dir)
-{
-	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(dma_addr_t addr, size_t len,
-				    enum dma_data_direction dir)
-{
-	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 37704da5dd4f..8be1003e6baf 100644
--- a/arch/x86/include/asm/dma-mapping.h
+++ b/arch/x86/include/asm/dma-mapping.h
@@ -14,8 +14,6 @@
 #include <linux/types.h>
 #include <malloc.h>
 
-#define	dma_mapping_error(x, y)	0
-
 static inline void *dma_alloc_coherent(size_t len, unsigned long *handle)
 {
 	*handle = (unsigned long)memalign(ARCH_DMA_MINALIGN, len);
@@ -27,28 +25,4 @@ static inline void dma_free_coherent(void *addr)
 	free(addr);
 }
 
-static inline dma_addr_t dma_map_single(void *vaddr, size_t len,
-					enum dma_data_direction dir)
-{
-	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(dma_addr_t addr, size_t len,
-				    enum dma_data_direction dir)
-{
-	len = ALIGN(len, ARCH_DMA_MINALIGN);
-
-	if (dir != DMA_TO_DEVICE)
-		invalidate_dcache_range(addr, addr + len);
-}
-
 #endif /* __ASM_X86_DMA_MAPPING_H */
diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
index f274100f3222..e587f1fcb2b4 100644
--- a/drivers/dma/ti/k3-udma.c
+++ b/drivers/dma/ti/k3-udma.c
@@ -10,7 +10,7 @@
 #include <asm/io.h>
 #include <asm/bitops.h>
 #include <malloc.h>
-#include <asm/dma-mapping.h>
+#include <linux/dma-mapping.h>
 #include <dm.h>
 #include <dm/device_compat.h>
 #include <dm/devres.h>
diff --git a/drivers/mmc/tmio-common.c b/drivers/mmc/tmio-common.c
index 53213888473b..faf18191b30d 100644
--- a/drivers/mmc/tmio-common.c
+++ b/drivers/mmc/tmio-common.c
@@ -4,7 +4,6 @@
  *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  */
 
-#include <asm/dma-mapping.h>
 #include <common.h>
 #include <clk.h>
 #include <cpu_func.h>
@@ -14,7 +13,7 @@
 #include <dm/device_compat.h>
 #include <dm/pinctrl.h>
 #include <linux/compat.h>
-#include <linux/dma-direction.h>
+#include <linux/dma-mapping.h>
 #include <linux/io.h>
 #include <linux/sizes.h>
 #include <power/regulator.h>
diff --git a/drivers/mtd/nand/raw/denali.c b/drivers/mtd/nand/raw/denali.c
index 3e0ac39777d8..b525b1be5496 100644
--- a/drivers/mtd/nand/raw/denali.c
+++ b/drivers/mtd/nand/raw/denali.c
@@ -5,14 +5,13 @@
  * Copyright (C) 2009-2010, Intel Corporation and its suppliers.
  */
 
-#include <asm/dma-mapping.h>
 #include <dm.h>
 #include <malloc.h>
 #include <nand.h>
 #include <dm/device_compat.h>
 #include <dm/devres.h>
 #include <linux/bitfield.h>
-#include <linux/dma-direction.h>
+#include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/errno.h>
 #include <linux/io.h>
diff --git a/drivers/net/altera_tse.c b/drivers/net/altera_tse.c
index aabddd6bb698..a511068d9ae1 100644
--- a/drivers/net/altera_tse.c
+++ b/drivers/net/altera_tse.c
@@ -17,7 +17,7 @@
 #include <miiphy.h>
 #include <net.h>
 #include <asm/cache.h>
-#include <asm/dma-mapping.h>
+#include <linux/dma-mapping.h>
 #include <asm/io.h>
 #include "altera_tse.h"
 
diff --git a/drivers/net/ftmac110.c b/drivers/net/ftmac110.c
index 1fa93d4d5855..84082407d277 100644
--- a/drivers/net/ftmac110.c
+++ b/drivers/net/ftmac110.c
@@ -12,7 +12,7 @@
 #include <net.h>
 #include <linux/errno.h>
 #include <asm/io.h>
-#include <asm/dma-mapping.h>
+#include <linux/dma-mapping.h>
 
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
 #include <miiphy.h>
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 7a2b1abeeb03..631b53b0930a 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -38,7 +38,7 @@
 
 #include <linux/mii.h>
 #include <asm/io.h>
-#include <asm/dma-mapping.h>
+#include <linux/dma-mapping.h>
 #include <asm/arch/clk.h>
 #include <linux/errno.h>
 
diff --git a/drivers/soc/ti/k3-navss-ringacc.c b/drivers/soc/ti/k3-navss-ringacc.c
index 8cbfe2bf49c3..c5661c52facc 100644
--- a/drivers/soc/ti/k3-navss-ringacc.c
+++ b/drivers/soc/ti/k3-navss-ringacc.c
@@ -9,7 +9,6 @@
 #include <cpu_func.h>
 #include <asm/io.h>
 #include <malloc.h>
-#include <asm/dma-mapping.h>
 #include <asm/bitops.h>
 #include <dm.h>
 #include <dm/device_compat.h>
@@ -17,6 +16,7 @@
 #include <dm/read.h>
 #include <dm/uclass.h>
 #include <linux/compat.h>
+#include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/soc/ti/k3-navss-ringacc.h>
 #include <linux/soc/ti/ti_sci_protocol.h>
diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c
index c9346c2edc8f..24e1bc2a19c2 100644
--- a/drivers/ufs/ufs.c
+++ b/drivers/ufs/ufs.c
@@ -19,7 +19,7 @@
 #include <hexdump.h>
 #include <scsi.h>
 
-#include <asm/dma-mapping.h>
+#include <linux/dma-mapping.h>
 
 #include "ufs.h"
 
diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c
index 22e90a57179f..8377eb458b6a 100644
--- a/drivers/usb/cdns3/gadget.c
+++ b/drivers/usb/cdns3/gadget.c
@@ -63,7 +63,7 @@
 #include <linux/usb/gadget.h>
 #include <linux/compat.h>
 #include <linux/iopoll.h>
-#include <asm/dma-mapping.h>
+#include <linux/dma-mapping.h>
 #include <linux/bitmap.h>
 #include <linux/bug.h>
 
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 6ad1000c9af6..4ec3f6df6a9a 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -17,9 +17,9 @@
 #include <cpu_func.h>
 #include <malloc.h>
 #include <dwc3-uboot.h>
-#include <asm/dma-mapping.h>
 #include <dm/device_compat.h>
 #include <dm/devres.h>
+#include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/ioport.h>
 #include <dm.h>
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 1502d67362a9..e445c705f18e 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -16,10 +16,10 @@
 #include <common.h>
 #include <cpu_func.h>
 #include <malloc.h>
-#include <asm/dma-mapping.h>
 #include <dm/device_compat.h>
 #include <dm/devres.h>
 #include <linux/bug.h>
+#include <linux/dma-mapping.h>
 #include <linux/list.h>
 
 #include <linux/usb/ch9.h>
diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c
index 528874507b41..7f73926cb3e1 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -18,7 +18,7 @@
 #include <linux/compat.h>
 #include <malloc.h>
 #include <asm/cache.h>
-#include <asm/dma-mapping.h>
+#include <linux/dma-mapping.h>
 #include <common.h>
 #include <dm.h>
 #include <dm/device-internal.h>
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
new file mode 100644
index 000000000000..20b6d60dd880
--- /dev/null
+++ b/include/linux/dma-mapping.h
@@ -0,0 +1,63 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_DMA_MAPPING_H
+#define _LINUX_DMA_MAPPING_H
+
+#include <linux/dma-direction.h>
+#include <linux/types.h>
+#include <asm/dma-mapping.h>
+#include <cpu_func.h>
+
+#define dma_mapping_error(x, y)	0
+
+/**
+ * Map a buffer to make it available to the DMA device
+ *
+ * Linux-like DMA API that is intended to be used from drivers. This hides the
+ * underlying cache operation from drivers. Call this before starting the DMA
+ * transfer. In most of architectures in U-Boot, the virtual address matches to
+ * the physical address (but we have exceptions like sandbox). U-Boot does not
+ * support iommu at the driver level, so it also matches to the DMA address.
+ * Hence, this helper currently just performs the cache operation, then returns
+ * straight-mapped dma_address, which is intended to be set to the register of
+ * the DMA device.
+ *
+ * @vaddr: address of the buffer
+ * @len: length of the buffer
+ * @dir: the direction of DMA
+ */
+static inline dma_addr_t dma_map_single(void *vaddr, size_t len,
+					enum dma_data_direction dir)
+{
+	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;
+}
+
+/**
+ * Unmap a buffer to make it available to CPU
+ *
+ * Linux-like DMA API that is intended to be used from drivers. This hides the
+ * underlying cache operation from drivers. Call this after finishin the DMA
+ * transfer.
+ *
+ * @addr: DMA address
+ * @len: length of the buffer
+ * @dir: the direction of DMA
+ */
+static inline void dma_unmap_single(dma_addr_t addr, size_t len,
+				    enum dma_data_direction dir)
+{
+	len = ALIGN(len, ARCH_DMA_MINALIGN);
+
+	if (dir != DMA_TO_DEVICE)
+		invalidate_dcache_range(addr, addr + len);
+}
+
+#endif
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 04/11] dma-mapping: add <asm/dma-mapping.h> for all architectures
  2020-02-14  7:40 [PATCH v3 00/11] mmc: sdhci: code clean-up and fix cache coherency problem Masahiro Yamada
                   ` (2 preceding siblings ...)
  2020-02-14  7:40 ` [PATCH v3 03/11] dma-mapping: move dma_map_(un)single() to <linux/dma-mapping.h> Masahiro Yamada
@ 2020-02-14  7:40 ` Masahiro Yamada
  2020-02-14  7:40 ` [PATCH v3 05/11] mmc: sdhci: put the aligned buffer pointer to struct sdhci_host Masahiro Yamada
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 17+ messages in thread
From: Masahiro Yamada @ 2020-02-14  7:40 UTC (permalink / raw)
  To: u-boot

To avoid "asm/dma-mapping.h: No such file or directory" error,
we need something.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---

Changes in v3: None
Changes in v2:
  - New patch

 arch/arc/include/asm/dma-mapping.h        |  1 +
 arch/m68k/include/asm/dma-mapping.h       |  1 +
 arch/microblaze/include/asm/dma-mapping.h |  1 +
 arch/mips/include/asm/dma-mapping.h       |  1 +
 arch/nios2/include/asm/dma-mapping.h      | 25 +----------------------
 arch/powerpc/include/asm/dma-mapping.h    |  1 +
 arch/sandbox/include/asm/dma-mapping.h    |  1 +
 arch/sh/include/asm/dma-mapping.h         |  1 +
 arch/xtensa/include/asm/dma-mapping.h     |  1 +
 9 files changed, 9 insertions(+), 24 deletions(-)
 create mode 100644 arch/arc/include/asm/dma-mapping.h
 create mode 100644 arch/m68k/include/asm/dma-mapping.h
 create mode 100644 arch/microblaze/include/asm/dma-mapping.h
 create mode 100644 arch/mips/include/asm/dma-mapping.h
 create mode 100644 arch/powerpc/include/asm/dma-mapping.h
 create mode 100644 arch/sandbox/include/asm/dma-mapping.h
 create mode 100644 arch/sh/include/asm/dma-mapping.h
 create mode 100644 arch/xtensa/include/asm/dma-mapping.h

diff --git a/arch/arc/include/asm/dma-mapping.h b/arch/arc/include/asm/dma-mapping.h
new file mode 100644
index 000000000000..853b0877b33d
--- /dev/null
+++ b/arch/arc/include/asm/dma-mapping.h
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
diff --git a/arch/m68k/include/asm/dma-mapping.h b/arch/m68k/include/asm/dma-mapping.h
new file mode 100644
index 000000000000..853b0877b33d
--- /dev/null
+++ b/arch/m68k/include/asm/dma-mapping.h
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
diff --git a/arch/microblaze/include/asm/dma-mapping.h b/arch/microblaze/include/asm/dma-mapping.h
new file mode 100644
index 000000000000..853b0877b33d
--- /dev/null
+++ b/arch/microblaze/include/asm/dma-mapping.h
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h
new file mode 100644
index 000000000000..853b0877b33d
--- /dev/null
+++ b/arch/mips/include/asm/dma-mapping.h
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
diff --git a/arch/nios2/include/asm/dma-mapping.h b/arch/nios2/include/asm/dma-mapping.h
index 65f67bc1f442..853b0877b33d 100644
--- a/arch/nios2/include/asm/dma-mapping.h
+++ b/arch/nios2/include/asm/dma-mapping.h
@@ -1,24 +1 @@
-#ifndef __ASM_NIOS2_DMA_MAPPING_H
-#define __ASM_NIOS2_DMA_MAPPING_H
-
-#include <memalign.h>
-#include <asm/io.h>
-
-/*
- * dma_alloc_coherent() return cache-line aligned allocation which is mapped
- * to uncached io region.
- */
-static inline void *dma_alloc_coherent(size_t len, unsigned long *handle)
-{
-	unsigned long addr = (unsigned long)malloc_cache_aligned(len);
-
-	if (!addr)
-		return NULL;
-
-	invalidate_dcache_range(addr, addr + len);
-	if (handle)
-		*handle = addr;
-
-	return map_physmem(addr, len, MAP_NOCACHE);
-}
-#endif /* __ASM_NIOS2_DMA_MAPPING_H */
+/* SPDX-License-Identifier: GPL-2.0-only */
diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h
new file mode 100644
index 000000000000..853b0877b33d
--- /dev/null
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
diff --git a/arch/sandbox/include/asm/dma-mapping.h b/arch/sandbox/include/asm/dma-mapping.h
new file mode 100644
index 000000000000..853b0877b33d
--- /dev/null
+++ b/arch/sandbox/include/asm/dma-mapping.h
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
diff --git a/arch/sh/include/asm/dma-mapping.h b/arch/sh/include/asm/dma-mapping.h
new file mode 100644
index 000000000000..853b0877b33d
--- /dev/null
+++ b/arch/sh/include/asm/dma-mapping.h
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
diff --git a/arch/xtensa/include/asm/dma-mapping.h b/arch/xtensa/include/asm/dma-mapping.h
new file mode 100644
index 000000000000..853b0877b33d
--- /dev/null
+++ b/arch/xtensa/include/asm/dma-mapping.h
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 05/11] mmc: sdhci: put the aligned buffer pointer to struct sdhci_host
  2020-02-14  7:40 [PATCH v3 00/11] mmc: sdhci: code clean-up and fix cache coherency problem Masahiro Yamada
                   ` (3 preceding siblings ...)
  2020-02-14  7:40 ` [PATCH v3 04/11] dma-mapping: add <asm/dma-mapping.h> for all architectures Masahiro Yamada
@ 2020-02-14  7:40 ` Masahiro Yamada
  2020-02-18 11:19   ` Jaehoon Chung
  2020-02-14  7:40 ` [PATCH v3 06/11] mmc: sdhci: reduce code duplication for aligned buffer Masahiro Yamada
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 17+ messages in thread
From: Masahiro Yamada @ 2020-02-14  7:40 UTC (permalink / raw)
  To: u-boot

Using the global variable does not look nice.

Add a new field sthci::align_buffer to point to the bounce buffer.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---

Changes in v3: None
Changes in v2: None

 drivers/mmc/sdhci.c | 27 +++++++++++++--------------
 include/sdhci.h     |  1 +
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 01fa5a9d4d5b..18fbcb5f1864 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -16,12 +16,6 @@
 #include <sdhci.h>
 #include <dm.h>
 
-#if defined(CONFIG_FIXED_SDHCI_ALIGNED_BUFFER)
-void *aligned_buffer = (void *)CONFIG_FIXED_SDHCI_ALIGNED_BUFFER;
-#else
-void *aligned_buffer;
-#endif
-
 static void sdhci_reset(struct sdhci_host *host, u8 mask)
 {
 	unsigned long timeout;
@@ -149,9 +143,10 @@ static void sdhci_prepare_dma(struct sdhci_host *host, struct mmc_data *data,
 		if ((host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) &&
 		    (host->start_addr & 0x7) != 0x0) {
 			*is_aligned = 0;
-			host->start_addr = (unsigned long)aligned_buffer;
+			host->start_addr = (unsigned long)host->align_buffer;
 			if (data->flags != MMC_DATA_READ)
-				memcpy(aligned_buffer, data->src, trans_bytes);
+				memcpy(host->align_buffer, data->src,
+				       trans_bytes);
 		}
 
 #if defined(CONFIG_FIXED_SDHCI_ALIGNED_BUFFER)
@@ -160,9 +155,9 @@ static void sdhci_prepare_dma(struct sdhci_host *host, struct mmc_data *data,
 		 * CONFIG_FIXED_SDHCI_ALIGNED_BUFFER is defined
 		 */
 		*is_aligned = 0;
-		host->start_addr = (unsigned long)aligned_buffer;
+		host->start_addr = (unsigned long)host->align_buffer;
 		if (data->flags != MMC_DATA_READ)
-			memcpy(aligned_buffer, data->src, trans_bytes);
+			memcpy(host->align_buffer, data->src, trans_bytes);
 #endif
 		sdhci_writel(host, host->start_addr, SDHCI_DMA_ADDRESS);
 
@@ -381,7 +376,7 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
 	if (!ret) {
 		if ((host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) &&
 				!is_aligned && (data->flags == MMC_DATA_READ))
-			memcpy(data->dest, aligned_buffer, trans_bytes);
+			memcpy(data->dest, host->align_buffer, trans_bytes);
 		return 0;
 	}
 
@@ -630,14 +625,18 @@ static int sdhci_init(struct mmc *mmc)
 
 	sdhci_reset(host, SDHCI_RESET_ALL);
 
-	if ((host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) && !aligned_buffer) {
-		aligned_buffer = memalign(8, 512*1024);
-		if (!aligned_buffer) {
+#if defined(CONFIG_FIXED_SDHCI_ALIGNED_BUFFER)
+	host->align_buffer = (void *)CONFIG_FIXED_SDHCI_ALIGNED_BUFFER;
+#else
+	if (host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) {
+		host->align_buffer = memalign(8, 512 * 1024);
+		if (!host->align_buffer) {
 			printf("%s: Aligned buffer alloc failed!!!\n",
 			       __func__);
 			return -ENOMEM;
 		}
 	}
+#endif
 
 	sdhci_set_power(host, fls(mmc->cfg->voltages) - 1);
 
diff --git a/include/sdhci.h b/include/sdhci.h
index 01addb7a6036..1358218270b8 100644
--- a/include/sdhci.h
+++ b/include/sdhci.h
@@ -321,6 +321,7 @@ struct sdhci_host {
 	uint	voltages;
 
 	struct mmc_config cfg;
+	void *align_buffer;
 	dma_addr_t start_addr;
 	int flags;
 #define USE_SDMA	(0x1 << 0)
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 06/11] mmc: sdhci: reduce code duplication for aligned buffer
  2020-02-14  7:40 [PATCH v3 00/11] mmc: sdhci: code clean-up and fix cache coherency problem Masahiro Yamada
                   ` (4 preceding siblings ...)
  2020-02-14  7:40 ` [PATCH v3 05/11] mmc: sdhci: put the aligned buffer pointer to struct sdhci_host Masahiro Yamada
@ 2020-02-14  7:40 ` Masahiro Yamada
  2020-02-18 11:19   ` Jaehoon Chung
  2020-02-14  7:40 ` [PATCH v3 07/11] mmc: sdhci: use lower_32_bit2() and upper_32_bits() for setting adma_addr Masahiro Yamada
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 17+ messages in thread
From: Masahiro Yamada @ 2020-02-14  7:40 UTC (permalink / raw)
  To: u-boot

The same code is run for both SDHCI_QUIRK_32BIT_DMA_ADDR and
define(CONFIG_FIXED_SDHCI_ALIGNED_BUFFER).

Unify the code.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---

Changes in v3: None
Changes in v2: None

 drivers/mmc/sdhci.c | 22 ++++++++--------------
 include/sdhci.h     |  2 ++
 2 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 18fbcb5f1864..b4713e7b9bba 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -140,27 +140,16 @@ static void sdhci_prepare_dma(struct sdhci_host *host, struct mmc_data *data,
 	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 
 	if (host->flags & USE_SDMA) {
-		if ((host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) &&
-		    (host->start_addr & 0x7) != 0x0) {
+		if (host->force_align_buffer ||
+		    (host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR &&
+		     (host->start_addr & 0x7) != 0x0)) {
 			*is_aligned = 0;
 			host->start_addr = (unsigned long)host->align_buffer;
 			if (data->flags != MMC_DATA_READ)
 				memcpy(host->align_buffer, data->src,
 				       trans_bytes);
 		}
-
-#if defined(CONFIG_FIXED_SDHCI_ALIGNED_BUFFER)
-		/*
-		 * Always use this bounce-buffer when
-		 * CONFIG_FIXED_SDHCI_ALIGNED_BUFFER is defined
-		 */
-		*is_aligned = 0;
-		host->start_addr = (unsigned long)host->align_buffer;
-		if (data->flags != MMC_DATA_READ)
-			memcpy(host->align_buffer, data->src, trans_bytes);
-#endif
 		sdhci_writel(host, host->start_addr, SDHCI_DMA_ADDRESS);
-
 	} else if (host->flags & (USE_ADMA | USE_ADMA64)) {
 		sdhci_prepare_adma_table(host, data);
 
@@ -627,6 +616,11 @@ static int sdhci_init(struct mmc *mmc)
 
 #if defined(CONFIG_FIXED_SDHCI_ALIGNED_BUFFER)
 	host->align_buffer = (void *)CONFIG_FIXED_SDHCI_ALIGNED_BUFFER;
+	/*
+	 * Always use this bounce-buffer when CONFIG_FIXED_SDHCI_ALIGNED_BUFFER
+	 * is defined.
+	 */
+	host->force_align_buffer = true;
 #else
 	if (host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) {
 		host->align_buffer = memalign(8, 512 * 1024);
diff --git a/include/sdhci.h b/include/sdhci.h
index 1358218270b8..7f8feefa450b 100644
--- a/include/sdhci.h
+++ b/include/sdhci.h
@@ -9,6 +9,7 @@
 #ifndef __SDHCI_HW_H
 #define __SDHCI_HW_H
 
+#include <linux/types.h>
 #include <asm/io.h>
 #include <mmc.h>
 #include <asm/gpio.h>
@@ -322,6 +323,7 @@ struct sdhci_host {
 
 	struct mmc_config cfg;
 	void *align_buffer;
+	bool force_align_buffer;
 	dma_addr_t start_addr;
 	int flags;
 #define USE_SDMA	(0x1 << 0)
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 07/11] mmc: sdhci: use lower_32_bit2() and upper_32_bits() for setting adma_addr
  2020-02-14  7:40 [PATCH v3 00/11] mmc: sdhci: code clean-up and fix cache coherency problem Masahiro Yamada
                   ` (5 preceding siblings ...)
  2020-02-14  7:40 ` [PATCH v3 06/11] mmc: sdhci: reduce code duplication for aligned buffer Masahiro Yamada
@ 2020-02-14  7:40 ` Masahiro Yamada
  2020-02-18 11:19   ` Jaehoon Chung
  2020-02-14  7:40 ` [PATCH v3 08/11] mmc: sdhci: remove unneeded casts Masahiro Yamada
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 17+ messages in thread
From: Masahiro Yamada @ 2020-02-14  7:40 UTC (permalink / raw)
  To: u-boot

Use {lower,upper}_32_bits() instead of the combination of cast
and shift.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---

Changes in v3: None
Changes in v2: None

 drivers/mmc/sdhci.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index b4713e7b9bba..fefe81016eb1 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -153,9 +153,10 @@ static void sdhci_prepare_dma(struct sdhci_host *host, struct mmc_data *data,
 	} else if (host->flags & (USE_ADMA | USE_ADMA64)) {
 		sdhci_prepare_adma_table(host, data);
 
-		sdhci_writel(host, (u32)host->adma_addr, SDHCI_ADMA_ADDRESS);
+		sdhci_writel(host, lower_32_bits(host->adma_addr),
+			     SDHCI_ADMA_ADDRESS);
 		if (host->flags & USE_ADMA64)
-			sdhci_writel(host, (u64)host->adma_addr >> 32,
+			sdhci_writel(host, upper_32_bits(host->adma_addr),
 				     SDHCI_ADMA_ADDRESS_HI);
 	}
 
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 08/11] mmc: sdhci: remove unneeded casts
  2020-02-14  7:40 [PATCH v3 00/11] mmc: sdhci: code clean-up and fix cache coherency problem Masahiro Yamada
                   ` (6 preceding siblings ...)
  2020-02-14  7:40 ` [PATCH v3 07/11] mmc: sdhci: use lower_32_bit2() and upper_32_bits() for setting adma_addr Masahiro Yamada
@ 2020-02-14  7:40 ` Masahiro Yamada
  2020-02-18 11:20   ` Jaehoon Chung
  2020-02-14  7:40 ` [PATCH v3 09/11] mmc: add mmc_get_dma_dir() helper Masahiro Yamada
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 17+ messages in thread
From: Masahiro Yamada @ 2020-02-14  7:40 UTC (permalink / raw)
  To: u-boot

host->mmc is already (struct mmc *).

memalign() returns an opaque pointer, so there is no need for casting.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---

Changes in v3: None
Changes in v2: None

 drivers/mmc/sdhci.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index fefe81016eb1..ee54d78a28f2 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -522,7 +522,7 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
 
 void sdhci_set_uhs_timing(struct sdhci_host *host)
 {
-	struct mmc *mmc = (struct mmc *)host->mmc;
+	struct mmc *mmc = host->mmc;
 	u32 reg;
 
 	reg = sdhci_readw(host, SDHCI_HOST_CONTROL2);
@@ -735,8 +735,7 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
 		       __func__);
 		return -EINVAL;
 	}
-	host->adma_desc_table = (struct sdhci_adma_desc *)
-				memalign(ARCH_DMA_MINALIGN, ADMA_TABLE_SZ);
+	host->adma_desc_table = memalign(ARCH_DMA_MINALIGN, ADMA_TABLE_SZ);
 
 	host->adma_addr = (dma_addr_t)host->adma_desc_table;
 #ifdef CONFIG_DMA_ADDR_T_64BIT
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 09/11] mmc: add mmc_get_dma_dir() helper
  2020-02-14  7:40 [PATCH v3 00/11] mmc: sdhci: code clean-up and fix cache coherency problem Masahiro Yamada
                   ` (7 preceding siblings ...)
  2020-02-14  7:40 ` [PATCH v3 08/11] mmc: sdhci: remove unneeded casts Masahiro Yamada
@ 2020-02-14  7:40 ` Masahiro Yamada
  2020-02-18 11:20   ` Jaehoon Chung
  2020-02-14  7:40 ` [PATCH v3 10/11] mmc: sdhci: use dma_map_single() instead of flush_cache() before DMA Masahiro Yamada
  2020-02-14  7:40 ` [PATCH v3 11/11] mmc: sdhci: fix missing cache invalidation after reading by DMA Masahiro Yamada
  10 siblings, 1 reply; 17+ messages in thread
From: Masahiro Yamada @ 2020-02-14  7:40 UTC (permalink / raw)
  To: u-boot

Copied from Linux kernel.
include/linux/mmc/host.h

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---

Changes in v3: None
Changes in v2: None

 include/mmc.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/include/mmc.h b/include/mmc.h
index b5cb514f57d6..71e2e1735ad5 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -12,6 +12,7 @@
 #include <linux/list.h>
 #include <linux/sizes.h>
 #include <linux/compiler.h>
+#include <linux/dma-direction.h>
 #include <part.h>
 
 #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
@@ -880,4 +881,9 @@ int mmc_get_env_dev(void);
  */
 struct blk_desc *mmc_get_blk_desc(struct mmc *mmc);
 
+static inline enum dma_data_direction mmc_get_dma_dir(struct mmc_data *data)
+{
+	return data->flags & MMC_DATA_WRITE ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+}
+
 #endif /* _MMC_H_ */
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 10/11] mmc: sdhci: use dma_map_single() instead of flush_cache() before DMA
  2020-02-14  7:40 [PATCH v3 00/11] mmc: sdhci: code clean-up and fix cache coherency problem Masahiro Yamada
                   ` (8 preceding siblings ...)
  2020-02-14  7:40 ` [PATCH v3 09/11] mmc: add mmc_get_dma_dir() helper Masahiro Yamada
@ 2020-02-14  7:40 ` Masahiro Yamada
  2020-02-14  7:40 ` [PATCH v3 11/11] mmc: sdhci: fix missing cache invalidation after reading by DMA Masahiro Yamada
  10 siblings, 0 replies; 17+ messages in thread
From: Masahiro Yamada @ 2020-02-14  7:40 UTC (permalink / raw)
  To: u-boot

Currently, sdhci_prepare_dma() calls flush_cache() regardless of the
DMA direction.

Actually, cache invalidation is enough when reading data from the device.

This is correctly handled by dma_map_single(), which mimics the DMA-API
in Linux kernel. Drivers can be agnostic which cache operation occurs
behind the scene.

This commit also sanitizes the difference between the virtual address
and the dma address.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---

Changes in v3: None
Changes in v2: None

 drivers/mmc/sdhci.c | 51 ++++++++++++++++++++++-----------------------
 1 file changed, 25 insertions(+), 26 deletions(-)

diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index ee54d78a28f2..77a88bc043e4 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -15,6 +15,7 @@
 #include <mmc.h>
 #include <sdhci.h>
 #include <dm.h>
+#include <linux/dma-mapping.h>
 
 static void sdhci_reset(struct sdhci_host *host, u8 mask)
 {
@@ -65,8 +66,8 @@ static void sdhci_transfer_pio(struct sdhci_host *host, struct mmc_data *data)
 }
 
 #if CONFIG_IS_ENABLED(MMC_SDHCI_ADMA)
-static void sdhci_adma_desc(struct sdhci_host *host, char *buf, u16 len,
-			    bool end)
+static void sdhci_adma_desc(struct sdhci_host *host, dma_addr_t dma_addr,
+			    u16 len, bool end)
 {
 	struct sdhci_adma_desc *desc;
 	u8 attr;
@@ -82,9 +83,9 @@ static void sdhci_adma_desc(struct sdhci_host *host, char *buf, u16 len,
 	desc->attr = attr;
 	desc->len = len;
 	desc->reserved = 0;
-	desc->addr_lo = (dma_addr_t)buf;
+	desc->addr_lo = lower_32_bits(dma_addr);
 #ifdef CONFIG_DMA_ADDR_T_64BIT
-	desc->addr_hi = (u64)buf >> 32;
+	desc->addr_hi = upper_32_bits(dma_addr);
 #endif
 }
 
@@ -94,22 +95,17 @@ static void sdhci_prepare_adma_table(struct sdhci_host *host,
 	uint trans_bytes = data->blocksize * data->blocks;
 	uint desc_count = DIV_ROUND_UP(trans_bytes, ADMA_MAX_LEN);
 	int i = desc_count;
-	char *buf;
+	dma_addr_t dma_addr = host->start_addr;
 
 	host->desc_slot = 0;
 
-	if (data->flags & MMC_DATA_READ)
-		buf = data->dest;
-	else
-		buf = (char *)data->src;
-
 	while (--i) {
-		sdhci_adma_desc(host, buf, ADMA_MAX_LEN, false);
-		buf += ADMA_MAX_LEN;
+		sdhci_adma_desc(host, dma_addr, ADMA_MAX_LEN, false);
+		dma_addr += ADMA_MAX_LEN;
 		trans_bytes -= ADMA_MAX_LEN;
 	}
 
-	sdhci_adma_desc(host, buf, trans_bytes, true);
+	sdhci_adma_desc(host, dma_addr, trans_bytes, true);
 
 	flush_cache((dma_addr_t)host->adma_desc_table,
 		    ROUND(desc_count * sizeof(struct sdhci_adma_desc),
@@ -125,11 +121,12 @@ static void sdhci_prepare_dma(struct sdhci_host *host, struct mmc_data *data,
 			      int *is_aligned, int trans_bytes)
 {
 	unsigned char ctrl;
+	void *buf;
 
 	if (data->flags == MMC_DATA_READ)
-		host->start_addr = (dma_addr_t)data->dest;
+		buf = data->dest;
 	else
-		host->start_addr = (dma_addr_t)data->src;
+		buf = (void *)data->src;
 
 	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
 	ctrl &= ~SDHCI_CTRL_DMA_MASK;
@@ -139,16 +136,20 @@ static void sdhci_prepare_dma(struct sdhci_host *host, struct mmc_data *data,
 		ctrl |= SDHCI_CTRL_ADMA32;
 	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 
+	if (host->flags & USE_SDMA &&
+	    (host->force_align_buffer ||
+	     (host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR &&
+	      ((unsigned long)buf & 0x7) != 0x0))) {
+		*is_aligned = 0;
+		if (data->flags != MMC_DATA_READ)
+			memcpy(host->align_buffer, buf, trans_bytes);
+		buf = host->align_buffer;
+	}
+
+	host->start_addr = dma_map_single(buf, trans_bytes,
+					  mmc_get_dma_dir(data));
+
 	if (host->flags & USE_SDMA) {
-		if (host->force_align_buffer ||
-		    (host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR &&
-		     (host->start_addr & 0x7) != 0x0)) {
-			*is_aligned = 0;
-			host->start_addr = (unsigned long)host->align_buffer;
-			if (data->flags != MMC_DATA_READ)
-				memcpy(host->align_buffer, data->src,
-				       trans_bytes);
-		}
 		sdhci_writel(host, host->start_addr, SDHCI_DMA_ADDRESS);
 	} else if (host->flags & (USE_ADMA | USE_ADMA64)) {
 		sdhci_prepare_adma_table(host, data);
@@ -159,8 +160,6 @@ static void sdhci_prepare_dma(struct sdhci_host *host, struct mmc_data *data,
 			sdhci_writel(host, upper_32_bits(host->adma_addr),
 				     SDHCI_ADMA_ADDRESS_HI);
 	}
-
-	flush_cache(host->start_addr, ROUND(trans_bytes, ARCH_DMA_MINALIGN));
 }
 #else
 static void sdhci_prepare_dma(struct sdhci_host *host, struct mmc_data *data,
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 11/11] mmc: sdhci: fix missing cache invalidation after reading by DMA
  2020-02-14  7:40 [PATCH v3 00/11] mmc: sdhci: code clean-up and fix cache coherency problem Masahiro Yamada
                   ` (9 preceding siblings ...)
  2020-02-14  7:40 ` [PATCH v3 10/11] mmc: sdhci: use dma_map_single() instead of flush_cache() before DMA Masahiro Yamada
@ 2020-02-14  7:40 ` Masahiro Yamada
  10 siblings, 0 replies; 17+ messages in thread
From: Masahiro Yamada @ 2020-02-14  7:40 UTC (permalink / raw)
  To: u-boot

This driver currently performs cache operation before the DMA start,
but does nothing after the DMA completion.

When reading data by DMA, the cache invalidation is needed also after
finishing the DMA transfer. Otherwise, the CPU might read data from
the cache instead of from the main memory when speculative memory read
or memory prefetch occurs.

Instead of calling the cache operation directly, this commit adds
dma_unmap_single(), which performs cache invalidation internally,
but drivers do not need which operation is being run.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---

Changes in v3: None
Changes in v2: None

 drivers/mmc/sdhci.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 77a88bc043e4..9b7c5f8f684f 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -215,6 +215,10 @@ static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data)
 			return -ETIMEDOUT;
 		}
 	} while (!(stat & SDHCI_INT_DATA_END));
+
+	dma_unmap_single(host->start_addr, data->blocks * data->blocksize,
+			 mmc_get_dma_dir(data));
+
 	return 0;
 }
 
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v3 05/11] mmc: sdhci: put the aligned buffer pointer to struct sdhci_host
  2020-02-14  7:40 ` [PATCH v3 05/11] mmc: sdhci: put the aligned buffer pointer to struct sdhci_host Masahiro Yamada
@ 2020-02-18 11:19   ` Jaehoon Chung
  0 siblings, 0 replies; 17+ messages in thread
From: Jaehoon Chung @ 2020-02-18 11:19 UTC (permalink / raw)
  To: u-boot

On 2/14/20 4:40 PM, Masahiro Yamada wrote:
> Using the global variable does not look nice.
> 
> Add a new field sthci::align_buffer to point to the bounce buffer.
> 
> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>

Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>

Best Regards,
Jaehoon Chung

> ---
> 
> Changes in v3: None
> Changes in v2: None
> 
>  drivers/mmc/sdhci.c | 27 +++++++++++++--------------
>  include/sdhci.h     |  1 +
>  2 files changed, 14 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
> index 01fa5a9d4d5b..18fbcb5f1864 100644
> --- a/drivers/mmc/sdhci.c
> +++ b/drivers/mmc/sdhci.c
> @@ -16,12 +16,6 @@
>  #include <sdhci.h>
>  #include <dm.h>
>  
> -#if defined(CONFIG_FIXED_SDHCI_ALIGNED_BUFFER)
> -void *aligned_buffer = (void *)CONFIG_FIXED_SDHCI_ALIGNED_BUFFER;
> -#else
> -void *aligned_buffer;
> -#endif
> -
>  static void sdhci_reset(struct sdhci_host *host, u8 mask)
>  {
>  	unsigned long timeout;
> @@ -149,9 +143,10 @@ static void sdhci_prepare_dma(struct sdhci_host *host, struct mmc_data *data,
>  		if ((host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) &&
>  		    (host->start_addr & 0x7) != 0x0) {
>  			*is_aligned = 0;
> -			host->start_addr = (unsigned long)aligned_buffer;
> +			host->start_addr = (unsigned long)host->align_buffer;
>  			if (data->flags != MMC_DATA_READ)
> -				memcpy(aligned_buffer, data->src, trans_bytes);
> +				memcpy(host->align_buffer, data->src,
> +				       trans_bytes);
>  		}
>  
>  #if defined(CONFIG_FIXED_SDHCI_ALIGNED_BUFFER)
> @@ -160,9 +155,9 @@ static void sdhci_prepare_dma(struct sdhci_host *host, struct mmc_data *data,
>  		 * CONFIG_FIXED_SDHCI_ALIGNED_BUFFER is defined
>  		 */
>  		*is_aligned = 0;
> -		host->start_addr = (unsigned long)aligned_buffer;
> +		host->start_addr = (unsigned long)host->align_buffer;
>  		if (data->flags != MMC_DATA_READ)
> -			memcpy(aligned_buffer, data->src, trans_bytes);
> +			memcpy(host->align_buffer, data->src, trans_bytes);
>  #endif
>  		sdhci_writel(host, host->start_addr, SDHCI_DMA_ADDRESS);
>  
> @@ -381,7 +376,7 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
>  	if (!ret) {
>  		if ((host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) &&
>  				!is_aligned && (data->flags == MMC_DATA_READ))
> -			memcpy(data->dest, aligned_buffer, trans_bytes);
> +			memcpy(data->dest, host->align_buffer, trans_bytes);
>  		return 0;
>  	}
>  
> @@ -630,14 +625,18 @@ static int sdhci_init(struct mmc *mmc)
>  
>  	sdhci_reset(host, SDHCI_RESET_ALL);
>  
> -	if ((host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) && !aligned_buffer) {
> -		aligned_buffer = memalign(8, 512*1024);
> -		if (!aligned_buffer) {
> +#if defined(CONFIG_FIXED_SDHCI_ALIGNED_BUFFER)
> +	host->align_buffer = (void *)CONFIG_FIXED_SDHCI_ALIGNED_BUFFER;
> +#else
> +	if (host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) {
> +		host->align_buffer = memalign(8, 512 * 1024);
> +		if (!host->align_buffer) {
>  			printf("%s: Aligned buffer alloc failed!!!\n",
>  			       __func__);
>  			return -ENOMEM;
>  		}
>  	}
> +#endif
>  
>  	sdhci_set_power(host, fls(mmc->cfg->voltages) - 1);
>  
> diff --git a/include/sdhci.h b/include/sdhci.h
> index 01addb7a6036..1358218270b8 100644
> --- a/include/sdhci.h
> +++ b/include/sdhci.h
> @@ -321,6 +321,7 @@ struct sdhci_host {
>  	uint	voltages;
>  
>  	struct mmc_config cfg;
> +	void *align_buffer;
>  	dma_addr_t start_addr;
>  	int flags;
>  #define USE_SDMA	(0x1 << 0)
> 

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v3 06/11] mmc: sdhci: reduce code duplication for aligned buffer
  2020-02-14  7:40 ` [PATCH v3 06/11] mmc: sdhci: reduce code duplication for aligned buffer Masahiro Yamada
@ 2020-02-18 11:19   ` Jaehoon Chung
  0 siblings, 0 replies; 17+ messages in thread
From: Jaehoon Chung @ 2020-02-18 11:19 UTC (permalink / raw)
  To: u-boot

On 2/14/20 4:40 PM, Masahiro Yamada wrote:
> The same code is run for both SDHCI_QUIRK_32BIT_DMA_ADDR and
> define(CONFIG_FIXED_SDHCI_ALIGNED_BUFFER).
> 
> Unify the code.
> 
> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>

Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>

Best Regards,
Jaehoon Chung

> ---
> 
> Changes in v3: None
> Changes in v2: None
> 
>  drivers/mmc/sdhci.c | 22 ++++++++--------------
>  include/sdhci.h     |  2 ++
>  2 files changed, 10 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
> index 18fbcb5f1864..b4713e7b9bba 100644
> --- a/drivers/mmc/sdhci.c
> +++ b/drivers/mmc/sdhci.c
> @@ -140,27 +140,16 @@ static void sdhci_prepare_dma(struct sdhci_host *host, struct mmc_data *data,
>  	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
>  
>  	if (host->flags & USE_SDMA) {
> -		if ((host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) &&
> -		    (host->start_addr & 0x7) != 0x0) {
> +		if (host->force_align_buffer ||
> +		    (host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR &&
> +		     (host->start_addr & 0x7) != 0x0)) {
>  			*is_aligned = 0;
>  			host->start_addr = (unsigned long)host->align_buffer;
>  			if (data->flags != MMC_DATA_READ)
>  				memcpy(host->align_buffer, data->src,
>  				       trans_bytes);
>  		}
> -
> -#if defined(CONFIG_FIXED_SDHCI_ALIGNED_BUFFER)
> -		/*
> -		 * Always use this bounce-buffer when
> -		 * CONFIG_FIXED_SDHCI_ALIGNED_BUFFER is defined
> -		 */
> -		*is_aligned = 0;
> -		host->start_addr = (unsigned long)host->align_buffer;
> -		if (data->flags != MMC_DATA_READ)
> -			memcpy(host->align_buffer, data->src, trans_bytes);
> -#endif
>  		sdhci_writel(host, host->start_addr, SDHCI_DMA_ADDRESS);
> -
>  	} else if (host->flags & (USE_ADMA | USE_ADMA64)) {
>  		sdhci_prepare_adma_table(host, data);
>  
> @@ -627,6 +616,11 @@ static int sdhci_init(struct mmc *mmc)
>  
>  #if defined(CONFIG_FIXED_SDHCI_ALIGNED_BUFFER)
>  	host->align_buffer = (void *)CONFIG_FIXED_SDHCI_ALIGNED_BUFFER;
> +	/*
> +	 * Always use this bounce-buffer when CONFIG_FIXED_SDHCI_ALIGNED_BUFFER
> +	 * is defined.
> +	 */
> +	host->force_align_buffer = true;
>  #else
>  	if (host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) {
>  		host->align_buffer = memalign(8, 512 * 1024);
> diff --git a/include/sdhci.h b/include/sdhci.h
> index 1358218270b8..7f8feefa450b 100644
> --- a/include/sdhci.h
> +++ b/include/sdhci.h
> @@ -9,6 +9,7 @@
>  #ifndef __SDHCI_HW_H
>  #define __SDHCI_HW_H
>  
> +#include <linux/types.h>
>  #include <asm/io.h>
>  #include <mmc.h>
>  #include <asm/gpio.h>
> @@ -322,6 +323,7 @@ struct sdhci_host {
>  
>  	struct mmc_config cfg;
>  	void *align_buffer;
> +	bool force_align_buffer;
>  	dma_addr_t start_addr;
>  	int flags;
>  #define USE_SDMA	(0x1 << 0)
> 

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v3 07/11] mmc: sdhci: use lower_32_bit2() and upper_32_bits() for setting adma_addr
  2020-02-14  7:40 ` [PATCH v3 07/11] mmc: sdhci: use lower_32_bit2() and upper_32_bits() for setting adma_addr Masahiro Yamada
@ 2020-02-18 11:19   ` Jaehoon Chung
  0 siblings, 0 replies; 17+ messages in thread
From: Jaehoon Chung @ 2020-02-18 11:19 UTC (permalink / raw)
  To: u-boot

On 2/14/20 4:40 PM, Masahiro Yamada wrote:
> Use {lower,upper}_32_bits() instead of the combination of cast
> and shift.
> 
> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>

Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>

Best Regards,
Jaehoon Chung

> ---
> 
> Changes in v3: None
> Changes in v2: None
> 
>  drivers/mmc/sdhci.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
> index b4713e7b9bba..fefe81016eb1 100644
> --- a/drivers/mmc/sdhci.c
> +++ b/drivers/mmc/sdhci.c
> @@ -153,9 +153,10 @@ static void sdhci_prepare_dma(struct sdhci_host *host, struct mmc_data *data,
>  	} else if (host->flags & (USE_ADMA | USE_ADMA64)) {
>  		sdhci_prepare_adma_table(host, data);
>  
> -		sdhci_writel(host, (u32)host->adma_addr, SDHCI_ADMA_ADDRESS);
> +		sdhci_writel(host, lower_32_bits(host->adma_addr),
> +			     SDHCI_ADMA_ADDRESS);
>  		if (host->flags & USE_ADMA64)
> -			sdhci_writel(host, (u64)host->adma_addr >> 32,
> +			sdhci_writel(host, upper_32_bits(host->adma_addr),
>  				     SDHCI_ADMA_ADDRESS_HI);
>  	}
>  
> 

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v3 08/11] mmc: sdhci: remove unneeded casts
  2020-02-14  7:40 ` [PATCH v3 08/11] mmc: sdhci: remove unneeded casts Masahiro Yamada
@ 2020-02-18 11:20   ` Jaehoon Chung
  0 siblings, 0 replies; 17+ messages in thread
From: Jaehoon Chung @ 2020-02-18 11:20 UTC (permalink / raw)
  To: u-boot

On 2/14/20 4:40 PM, Masahiro Yamada wrote:
> host->mmc is already (struct mmc *).
> 
> memalign() returns an opaque pointer, so there is no need for casting.
> 
> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>

Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>

Best Regards,
Jaehoon Chung

> ---
> 
> Changes in v3: None
> Changes in v2: None
> 
>  drivers/mmc/sdhci.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
> index fefe81016eb1..ee54d78a28f2 100644
> --- a/drivers/mmc/sdhci.c
> +++ b/drivers/mmc/sdhci.c
> @@ -522,7 +522,7 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
>  
>  void sdhci_set_uhs_timing(struct sdhci_host *host)
>  {
> -	struct mmc *mmc = (struct mmc *)host->mmc;
> +	struct mmc *mmc = host->mmc;
>  	u32 reg;
>  
>  	reg = sdhci_readw(host, SDHCI_HOST_CONTROL2);
> @@ -735,8 +735,7 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
>  		       __func__);
>  		return -EINVAL;
>  	}
> -	host->adma_desc_table = (struct sdhci_adma_desc *)
> -				memalign(ARCH_DMA_MINALIGN, ADMA_TABLE_SZ);
> +	host->adma_desc_table = memalign(ARCH_DMA_MINALIGN, ADMA_TABLE_SZ);
>  
>  	host->adma_addr = (dma_addr_t)host->adma_desc_table;
>  #ifdef CONFIG_DMA_ADDR_T_64BIT
> 

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v3 09/11] mmc: add mmc_get_dma_dir() helper
  2020-02-14  7:40 ` [PATCH v3 09/11] mmc: add mmc_get_dma_dir() helper Masahiro Yamada
@ 2020-02-18 11:20   ` Jaehoon Chung
  0 siblings, 0 replies; 17+ messages in thread
From: Jaehoon Chung @ 2020-02-18 11:20 UTC (permalink / raw)
  To: u-boot

On 2/14/20 4:40 PM, Masahiro Yamada wrote:
> Copied from Linux kernel.
> include/linux/mmc/host.h
> 
> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>

Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>

Best Regards,
Jaehoon Chung

> ---
> 
> Changes in v3: None
> Changes in v2: None
> 
>  include/mmc.h | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/include/mmc.h b/include/mmc.h
> index b5cb514f57d6..71e2e1735ad5 100644
> --- a/include/mmc.h
> +++ b/include/mmc.h
> @@ -12,6 +12,7 @@
>  #include <linux/list.h>
>  #include <linux/sizes.h>
>  #include <linux/compiler.h>
> +#include <linux/dma-direction.h>
>  #include <part.h>
>  
>  #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
> @@ -880,4 +881,9 @@ int mmc_get_env_dev(void);
>   */
>  struct blk_desc *mmc_get_blk_desc(struct mmc *mmc);
>  
> +static inline enum dma_data_direction mmc_get_dma_dir(struct mmc_data *data)
> +{
> +	return data->flags & MMC_DATA_WRITE ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
> +}
> +
>  #endif /* _MMC_H_ */
> 

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2020-02-18 11:20 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-14  7:40 [PATCH v3 00/11] mmc: sdhci: code clean-up and fix cache coherency problem Masahiro Yamada
2020-02-14  7:40 ` [PATCH v3 01/11] dma-mapping: fix the prototype of dma_map_single() Masahiro Yamada
2020-02-14  7:40 ` [PATCH v3 02/11] dma-mapping: fix the prototype of dma_unmap_single() Masahiro Yamada
2020-02-14  7:40 ` [PATCH v3 03/11] dma-mapping: move dma_map_(un)single() to <linux/dma-mapping.h> Masahiro Yamada
2020-02-14  7:40 ` [PATCH v3 04/11] dma-mapping: add <asm/dma-mapping.h> for all architectures Masahiro Yamada
2020-02-14  7:40 ` [PATCH v3 05/11] mmc: sdhci: put the aligned buffer pointer to struct sdhci_host Masahiro Yamada
2020-02-18 11:19   ` Jaehoon Chung
2020-02-14  7:40 ` [PATCH v3 06/11] mmc: sdhci: reduce code duplication for aligned buffer Masahiro Yamada
2020-02-18 11:19   ` Jaehoon Chung
2020-02-14  7:40 ` [PATCH v3 07/11] mmc: sdhci: use lower_32_bit2() and upper_32_bits() for setting adma_addr Masahiro Yamada
2020-02-18 11:19   ` Jaehoon Chung
2020-02-14  7:40 ` [PATCH v3 08/11] mmc: sdhci: remove unneeded casts Masahiro Yamada
2020-02-18 11:20   ` Jaehoon Chung
2020-02-14  7:40 ` [PATCH v3 09/11] mmc: add mmc_get_dma_dir() helper Masahiro Yamada
2020-02-18 11:20   ` Jaehoon Chung
2020-02-14  7:40 ` [PATCH v3 10/11] mmc: sdhci: use dma_map_single() instead of flush_cache() before DMA Masahiro Yamada
2020-02-14  7:40 ` [PATCH v3 11/11] mmc: sdhci: fix missing cache invalidation after reading by DMA Masahiro Yamada

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.