[PATCH v2 13/29] soc: starfive: add support for JH7100 incoherent interconnect

Ahmad Fatoum a.fatoum at pengutronix.de
Fri Jun 18 21:50:39 PDT 2021


The preproduction JH7100 used in the BeagleV beta does not ensure cache
coherence between CPU and some DMA masters like the Ethernet MAC.

Fix this for streaming DMA mappings by implementing cache cleaning and
discarding.  The Flush64 primitive can be used for both as it will
invalidate after flushing and not write-back clean lines.

Coherent DMA mapping will be implemented using allocation from uncached
SRAM in a follow-up commit.

Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 arch/riscv/Kconfig.socs              |  5 +++
 drivers/soc/Makefile                 |  1 +
 drivers/soc/sifive/sifive_l2_cache.c |  1 +
 drivers/soc/starfive/Makefile        |  1 +
 drivers/soc/starfive/jh7100_dma.c    | 55 ++++++++++++++++++++++++++++
 5 files changed, 63 insertions(+)
 create mode 100644 drivers/soc/starfive/Makefile
 create mode 100644 drivers/soc/starfive/jh7100_dma.c

diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index b4fdfd9741cd..c112fcc82e1a 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -61,6 +61,11 @@ config SOC_STARFIVE_JH71XX
 config SOC_STARFIVE_JH7100
 	bool
 	select SOC_STARFIVE_JH71XX
+	select SIFIVE_L2
+	help
+	  Unlike JH7110 and later, CPU on the JH7100 are not cache-coherent
+	  with respect to DMA masters like GMAC and DW MMC controller.
+	  Select this if barebox needs to do DMA on this SoC.
 
 endif
 
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index b787379586ae..c3499c0c7f30 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -2,3 +2,4 @@
 
 obj-y	+= imx/
 obj-$(CONFIG_CPU_SIFIVE)	+= sifive/
+obj-$(CONFIG_SOC_STARFIVE)	+= starfive/
diff --git a/drivers/soc/sifive/sifive_l2_cache.c b/drivers/soc/sifive/sifive_l2_cache.c
index 96d6d4ec4773..9e54474f7ae8 100644
--- a/drivers/soc/sifive/sifive_l2_cache.c
+++ b/drivers/soc/sifive/sifive_l2_cache.c
@@ -105,6 +105,7 @@ static int sifive_l2_probe(struct device_d *dev)
 static const struct of_device_id sifive_l2_ids[] = {
 	{ .compatible = "sifive,fu540-c000-ccache" },
 	{ .compatible = "sifive,fu740-c000-ccache" },
+	{ .compatible = "starfive,ccache0" },
 	{ /* end of table */ },
 };
 
diff --git a/drivers/soc/starfive/Makefile b/drivers/soc/starfive/Makefile
new file mode 100644
index 000000000000..72504b3bef26
--- /dev/null
+++ b/drivers/soc/starfive/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_SOC_STARFIVE_JH7100) += jh7100_dma.o
diff --git a/drivers/soc/starfive/jh7100_dma.c b/drivers/soc/starfive/jh7100_dma.c
new file mode 100644
index 000000000000..a1dc48e73f6e
--- /dev/null
+++ b/drivers/soc/starfive/jh7100_dma.c
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Ahmad Fatoum, Pengutronix
+ */
+
+#include <common.h>
+#include <asm/dma.h>
+#include <soc/sifive/l2_cache.h>
+
+#define SDRAM_CACHED_BASE	0x80000000
+#define SDRAM_UNCACHED_BASE	0x1000000000
+
+static inline void *jh7100_alloc_coherent(size_t size, dma_addr_t *dma_handle)
+{
+	dma_addr_t cpu_base;
+	void *ret;
+
+	ret = xmemalign(PAGE_SIZE, size);
+
+	memset(ret, 0, size);
+
+	cpu_base = (dma_addr_t)ret;
+
+	if (dma_handle)
+		*dma_handle = cpu_base;
+
+	sifive_l2_flush64_range(cpu_base, cpu_base + size);
+
+	return ret - SDRAM_CACHED_BASE + SDRAM_UNCACHED_BASE;
+
+}
+
+static inline void jh7100_free_coherent(void *vaddr, dma_addr_t dma_handle, size_t size)
+{
+	free((void *)dma_handle);
+}
+
+static const struct dma_ops jh7100_dma_ops = {
+	.alloc_coherent = jh7100_alloc_coherent,
+	.free_coherent = jh7100_free_coherent,
+	.flush_range = sifive_l2_flush64_range,
+	.inv_range = sifive_l2_flush64_range,
+};
+
+static int jh7100_dma_init(void)
+{
+	/* board drivers can claim the machine compatible, so no driver here */
+	if (!of_machine_is_compatible("starfive,jh7100"))
+		return 0;
+
+	dma_set_ops(&jh7100_dma_ops);
+
+	return 0;
+}
+mmu_initcall(jh7100_dma_init);
-- 
2.29.2




More information about the barebox mailing list