mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 0/3] MIPS: dma-default: fix dma_sync_single_for_*
@ 2023-03-13 10:53 Denis Orlov
  2023-03-13 10:53 ` [PATCH 1/3] dma: use dma/cpu conversions correctly in dma_map/unmap_single Denis Orlov
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Denis Orlov @ 2023-03-13 10:53 UTC (permalink / raw)
  To: barebox; +Cc: Denis Orlov

This fixes a few issues with streaming DMA functions, which should make
those work on real hardware. It also improves the code a bit, removing
unnecessary cache flushing in some cases.

Denis Orlov (3):
  dma: use dma/cpu conversions correctly in dma_map/unmap_single
  MIPS: dma-default: use virtual addresses when flushing caches
  MIPS: dma-default: do not flush caches in dma_sync_single_*
    excessively

 arch/mips/lib/dma-default.c | 36 +++++++++++++++++++-----------------
 drivers/dma/map.c           | 10 ++++------
 2 files changed, 23 insertions(+), 23 deletions(-)

-- 
2.30.2




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

* [PATCH 1/3] dma: use dma/cpu conversions correctly in dma_map/unmap_single
  2023-03-13 10:53 [PATCH 0/3] MIPS: dma-default: fix dma_sync_single_for_* Denis Orlov
@ 2023-03-13 10:53 ` Denis Orlov
  2023-03-13 10:53 ` [PATCH 2/3] MIPS: dma-default: use virtual addresses when flushing caches Denis Orlov
  2023-03-13 10:53 ` [PATCH 3/3] MIPS: dma-default: do not flush caches in dma_sync_single_* excessively Denis Orlov
  2 siblings, 0 replies; 4+ messages in thread
From: Denis Orlov @ 2023-03-13 10:53 UTC (permalink / raw)
  To: barebox; +Cc: Denis Orlov

We should not treat dma handles as if they correspond one-to-one to the
virtual addresses in common code. So make sure that dma handles are
properly passed to the dma_sync_single_for_* functions. Otherwise, it
just doesn't make much sense, as dma_sync funcs will receive proper dma
handles when called directly, and a virtual address treated as one when
called from dma_map funcs.

Signed-off-by: Denis Orlov <denorl2009@gmail.com>
---
 drivers/dma/map.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/dma/map.c b/drivers/dma/map.c
index 114c0f7db3..fea04c38a3 100644
--- a/drivers/dma/map.c
+++ b/drivers/dma/map.c
@@ -23,17 +23,15 @@ static inline void *dma_to_cpu(struct device *dev, dma_addr_t addr)
 dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
 			  enum dma_data_direction dir)
 {
-	unsigned long addr = (unsigned long)ptr;
+	dma_addr_t ret = cpu_to_dma(dev, ptr);
 
-	dma_sync_single_for_device(addr, size, dir);
+	dma_sync_single_for_device(ret, size, dir);
 
-	return cpu_to_dma(dev, ptr);
+	return ret;
 }
 
 void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
 		      enum dma_data_direction dir)
 {
-	unsigned long addr = (unsigned long)dma_to_cpu(dev, dma_addr);
-
-	dma_sync_single_for_cpu(addr, size, dir);
+	dma_sync_single_for_cpu(dma_addr, size, dir);
 }
-- 
2.30.2




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

* [PATCH 2/3] MIPS: dma-default: use virtual addresses when flushing caches
  2023-03-13 10:53 [PATCH 0/3] MIPS: dma-default: fix dma_sync_single_for_* Denis Orlov
  2023-03-13 10:53 ` [PATCH 1/3] dma: use dma/cpu conversions correctly in dma_map/unmap_single Denis Orlov
@ 2023-03-13 10:53 ` Denis Orlov
  2023-03-13 10:53 ` [PATCH 3/3] MIPS: dma-default: do not flush caches in dma_sync_single_* excessively Denis Orlov
  2 siblings, 0 replies; 4+ messages in thread
From: Denis Orlov @ 2023-03-13 10:53 UTC (permalink / raw)
  To: barebox; +Cc: Denis Orlov

Cache flushing functions expect virtual addresses, so make sure those
are properly converted from the physical ones in dma_sync_single_for_*.
QEMU doesn't care as it ignores cache instructions, but without such
change this code would result in TLB exceptions on real hardware.

Signed-off-by: Denis Orlov <denorl2009@gmail.com>
---
 arch/mips/lib/dma-default.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/mips/lib/dma-default.c b/arch/mips/lib/dma-default.c
index 48176e5d28..f6c750b8ac 100644
--- a/arch/mips/lib/dma-default.c
+++ b/arch/mips/lib/dma-default.c
@@ -30,11 +30,15 @@ static inline void __dma_sync_mips(unsigned long addr, size_t size,
 void dma_sync_single_for_cpu(dma_addr_t address, size_t size,
 			     enum dma_data_direction dir)
 {
-	__dma_sync_mips(address, size, dir);
+	unsigned long virt = (unsigned long)phys_to_virt(address);
+
+	__dma_sync_mips(virt, size, dir);
 }
 
 void dma_sync_single_for_device(dma_addr_t address, size_t size,
 				enum dma_data_direction dir)
 {
-	__dma_sync_mips(address, size, dir);
+	unsigned long virt = (unsigned long)phys_to_virt(address);
+
+	__dma_sync_mips(virt, size, dir);
 }
-- 
2.30.2




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

* [PATCH 3/3] MIPS: dma-default: do not flush caches in dma_sync_single_* excessively
  2023-03-13 10:53 [PATCH 0/3] MIPS: dma-default: fix dma_sync_single_for_* Denis Orlov
  2023-03-13 10:53 ` [PATCH 1/3] dma: use dma/cpu conversions correctly in dma_map/unmap_single Denis Orlov
  2023-03-13 10:53 ` [PATCH 2/3] MIPS: dma-default: use virtual addresses when flushing caches Denis Orlov
@ 2023-03-13 10:53 ` Denis Orlov
  2 siblings, 0 replies; 4+ messages in thread
From: Denis Orlov @ 2023-03-13 10:53 UTC (permalink / raw)
  To: barebox; +Cc: Denis Orlov

Change the logic to be different depending on whether we are doing
synchronization for a cpu or a device. This gets rid of unnecessary
cache flushing in some cases. While at it, also simplify code a bit,
collapsing two cases with the same code in a switch statement in
dma_sync_single_for_device().

The functional change itself is taken from Linux commit
'MIPS: make dma_sync_*_for_cpu a little less overzealous'
(hash: cbf1449ba5aec9cf4c68b69f899391a8d42e9b8f).

Signed-off-by: Denis Orlov <denorl2009@gmail.com>
---
 arch/mips/lib/dma-default.c | 36 +++++++++++++++++-------------------
 1 file changed, 17 insertions(+), 19 deletions(-)

diff --git a/arch/mips/lib/dma-default.c b/arch/mips/lib/dma-default.c
index f6c750b8ac..0347d7a7db 100644
--- a/arch/mips/lib/dma-default.c
+++ b/arch/mips/lib/dma-default.c
@@ -6,39 +6,37 @@
 #include <dma.h>
 #include <asm/io.h>
 
-static inline void __dma_sync_mips(unsigned long addr, size_t size,
-				   enum dma_data_direction direction)
+void dma_sync_single_for_cpu(dma_addr_t address, size_t size,
+			     enum dma_data_direction dir)
 {
-	switch (direction) {
+	unsigned long virt = (unsigned long)phys_to_virt(address);
+
+	switch (dir) {
 	case DMA_TO_DEVICE:
-		dma_flush_range(addr, addr + size);
 		break;
-
 	case DMA_FROM_DEVICE:
-		dma_inv_range(addr, addr + size);
-		break;
-
 	case DMA_BIDIRECTIONAL:
-		dma_flush_range(addr, addr + size);
+		dma_inv_range(virt, virt + size);
 		break;
-
 	default:
 		BUG();
 	}
 }
 
-void dma_sync_single_for_cpu(dma_addr_t address, size_t size,
-			     enum dma_data_direction dir)
-{
-	unsigned long virt = (unsigned long)phys_to_virt(address);
-
-	__dma_sync_mips(virt, size, dir);
-}
-
 void dma_sync_single_for_device(dma_addr_t address, size_t size,
 				enum dma_data_direction dir)
 {
 	unsigned long virt = (unsigned long)phys_to_virt(address);
 
-	__dma_sync_mips(virt, size, dir);
+	switch (dir) {
+	case DMA_FROM_DEVICE:
+		dma_inv_range(virt, virt + size);
+		break;
+	case DMA_TO_DEVICE:
+	case DMA_BIDIRECTIONAL:
+		dma_flush_range(virt, virt + size);
+		break;
+	default:
+		BUG();
+	}
 }
-- 
2.30.2




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

end of thread, other threads:[~2023-03-13 10:55 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-13 10:53 [PATCH 0/3] MIPS: dma-default: fix dma_sync_single_for_* Denis Orlov
2023-03-13 10:53 ` [PATCH 1/3] dma: use dma/cpu conversions correctly in dma_map/unmap_single Denis Orlov
2023-03-13 10:53 ` [PATCH 2/3] MIPS: dma-default: use virtual addresses when flushing caches Denis Orlov
2023-03-13 10:53 ` [PATCH 3/3] MIPS: dma-default: do not flush caches in dma_sync_single_* excessively Denis Orlov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox