VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   33 Branches   55 Tags
author: Andy Hu <andy.hu@starfivetech.com> 2023-06-28 17:55:01 +0800 committer: Andy Hu <andy.hu@starfivetech.com> 2023-06-28 17:55:01 +0800 commit: 22bc1c3edae297432eb51fd4216bec01581f9e0d parent: 265b3faa7b0a9e27cc5138a89f9a06efc9beaee6
Commit Summary:
Merge tag 'JH7110_515_SDK_v5.3.0' into vf2-515-devel
Diffstat:
4 files changed, 68 insertions, 1 deletion
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 6fe5d24bcf30..2a48a038cbd9 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -220,6 +220,17 @@ config PGTABLE_LEVELS
 config LOCKDEP_SUPPORT
 	def_bool y
 
+config RISCV_DMA_NONCOHERENT
+	bool "Support non-coherent DMA"
+	default SOC_STARFIVE
+	select ARCH_HAS_DMA_PREP_COHERENT
+	select ARCH_HAS_DMA_SET_UNCACHED
+	select ARCH_HAS_DMA_CLEAR_UNCACHED
+	select ARCH_HAS_SYNC_DMA_FOR_DEVICE
+	select ARCH_HAS_SYNC_DMA_FOR_CPU
+	select ARCH_HAS_SETUP_DMA_OPS
+	select DMA_DIRECT_REMAP
+
 source "arch/riscv/Kconfig.socs"
 source "arch/riscv/Kconfig.erratas"
 
diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
index b5bce82a2207..83677f5a87ba 100755
--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
@@ -247,6 +247,7 @@
 			cache-sets = <2048>;
 			cache-size = <2097152>;
 			cache-unified;
+			uncached-offset = <0x4 0x00000000>;
 		};
 
 		aon_syscon: aon_syscon@17010000 {
@@ -461,6 +462,7 @@
 			ranges;
 			usbdrd_cdns3: usb@10100000 {
 				compatible = "cdns,usb3";
+				dma-coherent;
 				reg = <0x0 0x10100000 0x0 0x10000>,
 				      <0x0 0x10110000 0x0 0x10000>,
 				      <0x0 0x10120000 0x0 0x10000>;
@@ -621,6 +623,7 @@
 
 		dma: dma-controller@16050000 {
 			compatible = "starfive,jh7110-dma", "snps,axi-dma-1.01a";
+			dma-coherent;
 			reg = <0x0 0x16050000 0x0 0x10000>;
 			clocks = <&clkgen JH7110_DMA1P_CLK_AXI>,
 				 <&clkgen JH7110_DMA1P_CLK_AHB>,
@@ -730,6 +733,7 @@
 
 		sec_dma: sec_dma@16008000 {
 			compatible = "arm,pl080", "arm,primecell";
+			dma-coherent;
 			arm,primecell-periphid = <0x00041080>;
 			reg = <0x0 0x16008000 0x0 0x4000>;
 			reg-names = "sec_dma";
@@ -749,6 +753,7 @@
 
 		crypto: crypto@16000000 {
 			compatible = "starfive,jh7110-sec";
+			dma-coherent;
 			reg = <0x0 0x16000000 0x0 0x4000>,
 			      <0x0 0x16008000 0x0 0x4000>;
 			reg-names = "secreg","secdma";
@@ -861,6 +866,7 @@
 		/* unremovable emmc as mmcblk0 */
 		sdio0: sdio0@16010000 {
 			compatible = "starfive,jh7110-sdio";
+			dma-coherent;
 			reg = <0x0 0x16010000 0x0 0x10000>;
 			clocks = <&clkgen JH7110_SDIO0_CLK_AHB>,
 				 <&clkgen JH7110_SDIO0_CLK_SDCARD>;
@@ -877,6 +883,7 @@
 
 		sdio1: sdio1@16020000 {
 			compatible = "starfive,jh7110-sdio";
+			dma-coherent;
 			reg = <0x0 0x16020000 0x0 0x10000>;
 			clocks = <&clkgen JH7110_SDIO1_CLK_AHB>,
 				 <&clkgen JH7110_SDIO1_CLK_SDCARD>;
@@ -1036,6 +1043,7 @@
 
 		gmac0: ethernet@16030000 {
 			compatible = "starfive,dwmac","snps,dwmac-5.10a";
+			dma-coherent;
 			reg = <0x0 0x16030000 0x0 0x10000>;
 			clock-names = "gtx",
 				"tx",
@@ -1079,6 +1087,7 @@
 
 		gmac1: ethernet@16040000 {
 			compatible = "starfive,dwmac","snps,dwmac-5.10a";
+			dma-coherent;
 			reg = <0x0 0x16040000 0x0 0x10000>;
 			clock-names = "gtx",
 				"tx",
@@ -1173,7 +1182,7 @@
 			reset-names = "rst_apb", "rst_core", "rst_timer";
 			frequency = <40000000>;
 			starfive,sys-syscon = <&sys_syscon 0x88 0x12 0x40000>;
-			syscon,can_or_canfd = <1>;
+			syscon,can_or_canfd = <0>;
 			status = "disabled";
 		};
 
@@ -1527,6 +1536,7 @@
 
 		pcie0: pcie@2B000000 {
 			compatible = "starfive,jh7110-pcie","plda,pci-xpressrich3-axi";
+			dma-coherent;
 			#address-cells = <3>;
 			#size-cells = <2>;
 			#interrupt-cells = <1>;
@@ -1567,6 +1577,7 @@
 
 		pcie1: pcie@2C000000 {
 			compatible = "starfive,jh7110-pcie","plda,pci-xpressrich3-axi";
+			dma-coherent;
 			#address-cells = <3>;
 			#size-cells = <2>;
 			#interrupt-cells = <1>;
@@ -1798,6 +1809,7 @@
 
 		co_process: e24@0 {
 			compatible = "starfive,e24";
+			dma-coherent;
 			reg = <0x0 0xc0110000 0x0 0x00001000>,
 				<0x0 0xc0111000 0x0 0x0001f000>;
 			reg-names = "ecmd", "espace";
@@ -1822,6 +1834,7 @@
 
 		xrp: xrp@0 {
 			compatible = "cdns,xrp";
+			dma-coherent;
 			reg = <0x0  0x10230000 0x0 0x00010000
 				0x0  0x10240000 0x0 0x00010000>;
 			memory-region = <&xrp_reserved>;
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..86d23046b958
--- /dev/null
+++ b/arch/riscv/mm/dma-noncoherent.c
@@ -0,0 +1,52 @@
+// 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-map-ops.h>
+
+#include <soc/sifive/sifive_l2_cache.h>
+
+void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, enum dma_data_direction dir)
+{
+	if (sifive_l2_handle_noncoherent())
+		sifive_l2_flush_range(paddr, size);
+}
+
+void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, enum dma_data_direction dir)
+{
+	if (sifive_l2_handle_noncoherent())
+		sifive_l2_flush_range(paddr, size);
+}
+
+void *arch_dma_set_uncached(void *addr, size_t size)
+{
+	if (sifive_l2_handle_noncoherent())
+		return sifive_l2_set_uncached(addr, size);
+
+	return addr;
+}
+
+void arch_dma_clear_uncached(void *addr, size_t size)
+{
+	if (sifive_l2_handle_noncoherent())
+		sifive_l2_clear_uncached(addr, size);
+}
+
+void arch_dma_prep_coherent(struct page *page, size_t size)
+{
+	void *flush_addr = page_address(page);
+
+	memset(flush_addr, 0, size);
+	if (sifive_l2_handle_noncoherent())
+		sifive_l2_flush_range(__pa(flush_addr), size);
+}
+
+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;
+}