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:
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;
+}