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@xxxxxxxxxxxxxx> --- 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 _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox