All of lore.kernel.org
 help / color / mirror / Atom feed
From: guoren@kernel.org
To: anup.patel@wdc.com, atish.patra@wdc.com,
	palmerdabbelt@google.com, guoren@kernel.org,
	christoph.muellner@vrull.eu, philipp.tomsich@vrull.eu,
	hch@lst.de, liush@allwinnertech.com, wefu@redhat.com,
	lazyparser@gmail.com, drew@beagleboard.org
Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org,
	taiten.peng@canonical.com, aniket.ponkshe@canonical.com,
	heinrich.schuchardt@canonical.com, gordan.markus@canonical.com
Subject: [RFC PATCH V4 4/6] RISC-V: Implement arch_sync_dma* functions
Date: Sat, 11 Sep 2021 17:21:37 +0800	[thread overview]
Message-ID: <20210911092139.79607-5-guoren@kernel.org> (raw)
In-Reply-To: <20210911092139.79607-1-guoren@kernel.org>

From: Atish Patra <atish.patra@wdc.com>

To facilitate streaming DMA APIs, this patch introduces a set of generic
cache operations related dma sync. Any platform can use the generic ops
to provide platform specific cache management operations. Once the
standard RISC-V CMO extension is available, it can be built on top of it.

Below Added by Guo Ren:
1. Fixup arch_sync_dma_for_cpu with "add DMA_TO_DEVICE force" by Guo Ren and
follow the tips by Christoph:
/*
 * Cache operations depending on function and direction argument, inspired by
 * https://lkml.org/lkml/2018/5/18/979
 * "dma_sync_*_for_cpu and direction=TO_DEVICE (was Re: [PATCH 02/20]
 * dma-mapping: provide a generic dma-noncoherent implementation)"
 *
 *          |   map          ==  for_device     |   unmap     ==  for_cpu
 *          |----------------------------------------------------------------
 * TO_DEV   |   writeback        writeback      |   none          none
 * FROM_DEV |   invalidate       invalidate     |   invalidate*   invalidate*
 * BIDIR    |   writeback+inv    writeback+inv  |   invalidate    invalidate
 *
 *     [*] needed for CPU speculative prefetches
 *
 * NOTE: we don't check the validity of direction argument as it is done in
 * upper layer functions (in include/linux/dma-mapping.h)
 */

2. Christoph:
As told a bunch of times before: doing indirect calls here is a
performance nightmare.  Use something that actually does perform
horribly like alternatives.  Or even delay implementing that until
              ^^^^^^^^^^^^ Agree, and TODO in Atish next path?
we need it and do a plain direct call for now.

Signed-off-by: Atish Patra <atish.patra@wdc.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Christoph Hellwig <hch@lst.de>
---
 arch/riscv/include/asm/dma-noncoherent.h | 19 +++++++
 arch/riscv/mm/Makefile                   |  1 +
 arch/riscv/mm/dma-noncoherent.c          | 66 ++++++++++++++++++++++++
 3 files changed, 86 insertions(+)
 create mode 100644 arch/riscv/include/asm/dma-noncoherent.h
 create mode 100644 arch/riscv/mm/dma-noncoherent.c

diff --git a/arch/riscv/include/asm/dma-noncoherent.h b/arch/riscv/include/asm/dma-noncoherent.h
new file mode 100644
index 000000000000..5bdb03c9c427
--- /dev/null
+++ b/arch/riscv/include/asm/dma-noncoherent.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021 Western Digital Corporation or its affiliates.
+ */
+
+#ifndef __ASM_RISCV_DMA_NON_COHERENT_H
+#define __ASM_RISCV_DMA_NON_COHERENT_H
+
+#ifdef CONFIG_RISCV_DMA_NONCOHERENT
+struct riscv_dma_cache_sync {
+	void (*cache_invalidate)(phys_addr_t paddr, size_t size);
+	void (*cache_clean)(phys_addr_t paddr, size_t size);
+	void (*cache_flush)(phys_addr_t paddr, size_t size);
+};
+
+void riscv_dma_cache_sync_set(struct riscv_dma_cache_sync *ops);
+#endif
+
+#endif
diff --git a/arch/riscv/mm/Makefile b/arch/riscv/mm/Makefile
index 7ebaef10ea1b..959bef49098b 100644
--- a/arch/riscv/mm/Makefile
+++ b/arch/riscv/mm/Makefile
@@ -27,3 +27,4 @@ KASAN_SANITIZE_init.o := n
 endif
 
 obj-$(CONFIG_DEBUG_VIRTUAL) += physaddr.o
+obj-$(CONFIG_RISCV_DMA_NONCOHERENT) += dma-noncoherent.o
diff --git a/arch/riscv/mm/dma-noncoherent.c b/arch/riscv/mm/dma-noncoherent.c
new file mode 100644
index 000000000000..63134d57016c
--- /dev/null
+++ b/arch/riscv/mm/dma-noncoherent.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * RISC-V specific functions to support DMA for non-coherent devices
+ *
+ * Copyright (c) 2021 Western Digital Corporation or its affiliates.
+ */
+
+#include <linux/dma-direct.h>
+#include <linux/dma-map-ops.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/libfdt.h>
+#include <linux/mm.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <asm/dma-noncoherent.h>
+
+static struct riscv_dma_cache_sync *dma_cache_sync;
+unsigned long riscv_dma_uc_offset;
+
+static void __dma_sync(phys_addr_t paddr, size_t size, enum dma_data_direction dir)
+{
+	if ((dir == DMA_FROM_DEVICE) && (dma_cache_sync->cache_invalidate))
+		dma_cache_sync->cache_invalidate(paddr, size);
+	else if ((dir == DMA_TO_DEVICE) && (dma_cache_sync->cache_clean))
+		dma_cache_sync->cache_clean(paddr, size);
+	else if ((dir == DMA_BIDIRECTIONAL) && dma_cache_sync->cache_flush)
+		dma_cache_sync->cache_flush(paddr, size);
+}
+
+void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, enum dma_data_direction dir)
+{
+	if (!dma_cache_sync)
+		return;
+
+	__dma_sync(paddr, size, dir);
+}
+
+void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, enum dma_data_direction dir)
+{
+	if (!dma_cache_sync || dir == DMA_TO_DEVICE)
+		return;
+
+	__dma_sync(paddr, size, DMA_FROM_DEVICE);
+}
+
+void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+		const struct iommu_ops *iommu, bool coherent)
+{
+	/* If a specific device is dma-coherent, set it here */
+	dev->dma_coherent = coherent;
+}
+
+void arch_dma_prep_coherent(struct page *page, size_t size)
+{
+	void *flush_addr = page_address(page);
+
+	memset(flush_addr, 0, size);
+	if (dma_cache_sync && dma_cache_sync->cache_flush)
+		dma_cache_sync->cache_flush(__pa(flush_addr), size);
+}
+
+void riscv_dma_cache_sync_set(struct riscv_dma_cache_sync *ops)
+{
+	dma_cache_sync = ops;
+}
-- 
2.25.1


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

WARNING: multiple messages have this Message-ID (diff)
From: guoren@kernel.org
To: anup.patel@wdc.com, atish.patra@wdc.com,
	palmerdabbelt@google.com, guoren@kernel.org,
	christoph.muellner@vrull.eu, philipp.tomsich@vrull.eu,
	hch@lst.de, liush@allwinnertech.com, wefu@redhat.com,
	lazyparser@gmail.com, drew@beagleboard.org
Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org,
	taiten.peng@canonical.com, aniket.ponkshe@canonical.com,
	heinrich.schuchardt@canonical.com, gordan.markus@canonical.com
Subject: [RFC PATCH V4 4/6] RISC-V: Implement arch_sync_dma* functions
Date: Sat, 11 Sep 2021 17:21:37 +0800	[thread overview]
Message-ID: <20210911092139.79607-5-guoren@kernel.org> (raw)
In-Reply-To: <20210911092139.79607-1-guoren@kernel.org>

From: Atish Patra <atish.patra@wdc.com>

To facilitate streaming DMA APIs, this patch introduces a set of generic
cache operations related dma sync. Any platform can use the generic ops
to provide platform specific cache management operations. Once the
standard RISC-V CMO extension is available, it can be built on top of it.

Below Added by Guo Ren:
1. Fixup arch_sync_dma_for_cpu with "add DMA_TO_DEVICE force" by Guo Ren and
follow the tips by Christoph:
/*
 * Cache operations depending on function and direction argument, inspired by
 * https://lkml.org/lkml/2018/5/18/979
 * "dma_sync_*_for_cpu and direction=TO_DEVICE (was Re: [PATCH 02/20]
 * dma-mapping: provide a generic dma-noncoherent implementation)"
 *
 *          |   map          ==  for_device     |   unmap     ==  for_cpu
 *          |----------------------------------------------------------------
 * TO_DEV   |   writeback        writeback      |   none          none
 * FROM_DEV |   invalidate       invalidate     |   invalidate*   invalidate*
 * BIDIR    |   writeback+inv    writeback+inv  |   invalidate    invalidate
 *
 *     [*] needed for CPU speculative prefetches
 *
 * NOTE: we don't check the validity of direction argument as it is done in
 * upper layer functions (in include/linux/dma-mapping.h)
 */

2. Christoph:
As told a bunch of times before: doing indirect calls here is a
performance nightmare.  Use something that actually does perform
horribly like alternatives.  Or even delay implementing that until
              ^^^^^^^^^^^^ Agree, and TODO in Atish next path?
we need it and do a plain direct call for now.

Signed-off-by: Atish Patra <atish.patra@wdc.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Christoph Hellwig <hch@lst.de>
---
 arch/riscv/include/asm/dma-noncoherent.h | 19 +++++++
 arch/riscv/mm/Makefile                   |  1 +
 arch/riscv/mm/dma-noncoherent.c          | 66 ++++++++++++++++++++++++
 3 files changed, 86 insertions(+)
 create mode 100644 arch/riscv/include/asm/dma-noncoherent.h
 create mode 100644 arch/riscv/mm/dma-noncoherent.c

diff --git a/arch/riscv/include/asm/dma-noncoherent.h b/arch/riscv/include/asm/dma-noncoherent.h
new file mode 100644
index 000000000000..5bdb03c9c427
--- /dev/null
+++ b/arch/riscv/include/asm/dma-noncoherent.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021 Western Digital Corporation or its affiliates.
+ */
+
+#ifndef __ASM_RISCV_DMA_NON_COHERENT_H
+#define __ASM_RISCV_DMA_NON_COHERENT_H
+
+#ifdef CONFIG_RISCV_DMA_NONCOHERENT
+struct riscv_dma_cache_sync {
+	void (*cache_invalidate)(phys_addr_t paddr, size_t size);
+	void (*cache_clean)(phys_addr_t paddr, size_t size);
+	void (*cache_flush)(phys_addr_t paddr, size_t size);
+};
+
+void riscv_dma_cache_sync_set(struct riscv_dma_cache_sync *ops);
+#endif
+
+#endif
diff --git a/arch/riscv/mm/Makefile b/arch/riscv/mm/Makefile
index 7ebaef10ea1b..959bef49098b 100644
--- a/arch/riscv/mm/Makefile
+++ b/arch/riscv/mm/Makefile
@@ -27,3 +27,4 @@ KASAN_SANITIZE_init.o := n
 endif
 
 obj-$(CONFIG_DEBUG_VIRTUAL) += physaddr.o
+obj-$(CONFIG_RISCV_DMA_NONCOHERENT) += dma-noncoherent.o
diff --git a/arch/riscv/mm/dma-noncoherent.c b/arch/riscv/mm/dma-noncoherent.c
new file mode 100644
index 000000000000..63134d57016c
--- /dev/null
+++ b/arch/riscv/mm/dma-noncoherent.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * RISC-V specific functions to support DMA for non-coherent devices
+ *
+ * Copyright (c) 2021 Western Digital Corporation or its affiliates.
+ */
+
+#include <linux/dma-direct.h>
+#include <linux/dma-map-ops.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/libfdt.h>
+#include <linux/mm.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <asm/dma-noncoherent.h>
+
+static struct riscv_dma_cache_sync *dma_cache_sync;
+unsigned long riscv_dma_uc_offset;
+
+static void __dma_sync(phys_addr_t paddr, size_t size, enum dma_data_direction dir)
+{
+	if ((dir == DMA_FROM_DEVICE) && (dma_cache_sync->cache_invalidate))
+		dma_cache_sync->cache_invalidate(paddr, size);
+	else if ((dir == DMA_TO_DEVICE) && (dma_cache_sync->cache_clean))
+		dma_cache_sync->cache_clean(paddr, size);
+	else if ((dir == DMA_BIDIRECTIONAL) && dma_cache_sync->cache_flush)
+		dma_cache_sync->cache_flush(paddr, size);
+}
+
+void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, enum dma_data_direction dir)
+{
+	if (!dma_cache_sync)
+		return;
+
+	__dma_sync(paddr, size, dir);
+}
+
+void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, enum dma_data_direction dir)
+{
+	if (!dma_cache_sync || dir == DMA_TO_DEVICE)
+		return;
+
+	__dma_sync(paddr, size, DMA_FROM_DEVICE);
+}
+
+void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+		const struct iommu_ops *iommu, bool coherent)
+{
+	/* If a specific device is dma-coherent, set it here */
+	dev->dma_coherent = coherent;
+}
+
+void arch_dma_prep_coherent(struct page *page, size_t size)
+{
+	void *flush_addr = page_address(page);
+
+	memset(flush_addr, 0, size);
+	if (dma_cache_sync && dma_cache_sync->cache_flush)
+		dma_cache_sync->cache_flush(__pa(flush_addr), size);
+}
+
+void riscv_dma_cache_sync_set(struct riscv_dma_cache_sync *ops)
+{
+	dma_cache_sync = ops;
+}
-- 
2.25.1


  parent reply	other threads:[~2021-09-11  9:22 UTC|newest]

Thread overview: 76+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-11  9:21 [RFC PATCH V4 0/6] riscv: Add PBMT & DMA for D1 bringup guoren
2021-09-11  9:21 ` guoren
2021-09-11  9:21 ` [RFC PATCH V4 1/6] riscv: pgtable: Add custom protection_map init guoren
2021-09-11  9:21   ` guoren
2021-09-15  7:45   ` Christoph Hellwig
2021-09-15  7:45     ` Christoph Hellwig
2021-09-15 23:52     ` Guo Ren
2021-09-15 23:52       ` Guo Ren
2021-09-11  9:21 ` [RFC PATCH V4 2/6] riscv: errata: pgtable: Add custom Svpbmt supported for Allwinner D1 guoren
2021-09-11  9:21   ` guoren
2021-09-15  7:47   ` Christoph Hellwig
2021-09-15  7:47     ` Christoph Hellwig
2021-09-16  0:48     ` Guo Ren
2021-09-16  0:48       ` Guo Ren
2021-09-16  7:31   ` Atish Patra
2021-09-16  7:31     ` Atish Patra
2021-09-11  9:21 ` [RFC PATCH V4 3/6] RISC-V: Support a new config option for non-coherent DMA guoren
2021-09-11  9:21   ` guoren
2021-09-15  7:48   ` Christoph Hellwig
2021-09-15  7:48     ` Christoph Hellwig
2021-09-16  1:20     ` Guo Ren
2021-09-16  1:20       ` Guo Ren
2021-09-16  4:39       ` Atish Patra
2021-09-16  4:39         ` Atish Patra
2021-09-16  6:09         ` Guo Ren
2021-09-16  6:09           ` Guo Ren
2021-09-11  9:21 ` guoren [this message]
2021-09-11  9:21   ` [RFC PATCH V4 4/6] RISC-V: Implement arch_sync_dma* functions guoren
2021-09-15  7:50   ` Christoph Hellwig
2021-09-15  7:50     ` Christoph Hellwig
2021-09-16  1:32     ` Guo Ren
2021-09-16  1:32       ` Guo Ren
2021-09-16  4:24       ` Anup Patel
2021-09-16  4:24         ` Anup Patel
2021-09-16  4:42         ` Atish Patra
2021-09-16  4:42           ` Atish Patra
2021-09-11  9:21 ` [RFC PATCH V4 5/6] riscv: errata: Support T-HEAD custom dcache ops guoren
2021-09-11  9:21   ` guoren
2021-09-11  9:21 ` [RFC PATCH V4 6/6] riscv: soc: Add Allwinner SoC kconfig option guoren
2021-09-11  9:21   ` guoren
2021-09-13  8:45   ` Maxime Ripard
2021-09-13  8:45     ` Maxime Ripard
2021-09-13  9:20     ` Guo Ren
2021-09-13  9:20       ` Guo Ren
2021-09-13 18:48       ` Randy Dunlap
2021-09-13 18:48         ` Randy Dunlap
2021-09-14  2:34         ` Guo Ren
2021-09-14  2:34           ` Guo Ren
2021-09-14  3:06           ` Randy Dunlap
2021-09-14  3:06             ` Randy Dunlap
2021-09-14  5:16             ` Anup Patel
2021-09-14  5:16               ` Anup Patel
2021-09-14  5:20               ` Randy Dunlap
2021-09-14  5:20                 ` Randy Dunlap
2021-09-14  9:29           ` Arnd Bergmann
2021-09-14  9:29             ` Arnd Bergmann
2021-09-14 10:07             ` Krzysztof Kozlowski
2021-09-14 10:07               ` Krzysztof Kozlowski
2021-09-14 10:13               ` Maxime Ripard
2021-09-14 10:13                 ` Maxime Ripard
2021-09-14 12:09                 ` Krzysztof Kozlowski
2021-09-14 12:09                   ` Krzysztof Kozlowski
2021-09-14 13:02                   ` Arnd Bergmann
2021-09-14 13:02                     ` Arnd Bergmann
2021-09-16  6:37             ` Guo Ren
2021-09-16  6:37               ` Guo Ren
2021-09-14  3:49     ` Heinrich Schuchardt
2021-09-14  3:49       ` Heinrich Schuchardt
2021-09-14  5:16       ` Samuel Holland
2021-09-14  5:16         ` Samuel Holland
2021-09-14  6:30         ` Heinrich Schuchardt
2021-09-14  6:30           ` Heinrich Schuchardt
2021-09-14  7:20       ` Maxime Ripard
2021-09-14  7:20         ` Maxime Ripard
2021-09-14  9:26     ` Ben Dooks
2021-09-14  9:26       ` Ben Dooks

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210911092139.79607-5-guoren@kernel.org \
    --to=guoren@kernel.org \
    --cc=aniket.ponkshe@canonical.com \
    --cc=anup.patel@wdc.com \
    --cc=atish.patra@wdc.com \
    --cc=christoph.muellner@vrull.eu \
    --cc=drew@beagleboard.org \
    --cc=gordan.markus@canonical.com \
    --cc=hch@lst.de \
    --cc=heinrich.schuchardt@canonical.com \
    --cc=lazyparser@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=liush@allwinnertech.com \
    --cc=palmerdabbelt@google.com \
    --cc=philipp.tomsich@vrull.eu \
    --cc=taiten.peng@canonical.com \
    --cc=wefu@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.