summaryrefslogtreecommitdiff
path: root/arch/riscv
diff options
context:
space:
mode:
Diffstat (limited to 'arch/riscv')
-rw-r--r--arch/riscv/Kconfig9
-rw-r--r--arch/riscv/cpu/cpu.c6
-rw-r--r--arch/riscv/cpu/cv1800b/Kconfig1
-rw-r--r--arch/riscv/cpu/cv1800b/Makefile1
-rw-r--r--arch/riscv/cpu/th1520/Kconfig22
-rw-r--r--arch/riscv/cpu/th1520/Makefile8
-rw-r--r--arch/riscv/cpu/th1520/cache.c32
-rw-r--r--arch/riscv/cpu/th1520/cpu.c21
-rw-r--r--arch/riscv/cpu/th1520/dram.c21
-rw-r--r--arch/riscv/cpu/th1520/spl.c96
-rw-r--r--arch/riscv/dts/binman.dtsi15
-rw-r--r--arch/riscv/dts/jh7110-common-u-boot.dtsi1
-rw-r--r--arch/riscv/dts/jh7110-u-boot.dtsi73
-rw-r--r--arch/riscv/dts/th1520-lichee-module-4a.dtsi9
-rw-r--r--arch/riscv/dts/th1520-lichee-pi-4a.dts1
-rw-r--r--arch/riscv/dts/th1520.dtsi91
-rw-r--r--arch/riscv/dts/thead-th1520-binman.dtsi55
-rw-r--r--arch/riscv/include/asm/arch-th1520/cpu.h9
-rw-r--r--arch/riscv/include/asm/arch-th1520/iopmp.h42
-rw-r--r--arch/riscv/include/asm/arch-th1520/spl.h10
-rw-r--r--arch/riscv/include/asm/global_data.h19
-rw-r--r--arch/riscv/include/asm/insn-def.h6
-rw-r--r--arch/riscv/include/asm/u-boot.h4
-rw-r--r--arch/riscv/lib/Makefile1
-rw-r--r--arch/riscv/lib/bootm.c4
-rw-r--r--arch/riscv/lib/thead_cmo.c (renamed from arch/riscv/cpu/cv1800b/cache.c)0
26 files changed, 459 insertions, 98 deletions
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index b24623590f2..8c6feae5735 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -77,6 +77,14 @@ config SYS_DCACHE_OFF
help
Do not enable data cache in U-Boot.
+config SYS_CACHE_THEAD_CMO
+ bool "THEAD non-standard cache operations"
+ depends on !SYS_DCACHE_OFF
+ default n
+ help
+ Support for non-standard cache management operations on SoCs based on
+ T-Head C906/C910 cores.
+
config SPL_SYS_DCACHE_OFF
bool "Do not enable dcache in SPL"
depends on SPL
@@ -118,6 +126,7 @@ source "arch/riscv/cpu/generic/Kconfig"
source "arch/riscv/cpu/jh7110/Kconfig"
source "arch/riscv/cpu/k1/Kconfig"
source "arch/riscv/cpu/k230/Kconfig"
+source "arch/riscv/cpu/th1520/Kconfig"
# architecture-specific options below
diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c
index 5b31da64cbd..15c4e14599d 100644
--- a/arch/riscv/cpu/cpu.c
+++ b/arch/riscv/cpu/cpu.c
@@ -18,6 +18,7 @@
#include <asm/hwcap.h>
#include <asm/cpufeature.h>
#include <asm/cache.h>
+#include <asm/global_data.h>
#include <dm/uclass-internal.h>
#include <linux/bitops.h>
#include <linux/log2.h>
@@ -746,3 +747,8 @@ __weak int cleanup_before_linux(void)
return 0;
}
+
+void arch_setup_gd(gd_t *new_gd)
+{
+ set_gd(new_gd);
+}
diff --git a/arch/riscv/cpu/cv1800b/Kconfig b/arch/riscv/cpu/cv1800b/Kconfig
index 7225b1210c5..57f724ae043 100644
--- a/arch/riscv/cpu/cv1800b/Kconfig
+++ b/arch/riscv/cpu/cv1800b/Kconfig
@@ -6,6 +6,7 @@ config SOPHGO_CV1800B
bool
select ARCH_EARLY_INIT_R
select SYS_CACHE_SHIFT_6
+ select SYS_CACHE_THEAD_CMO
imply CPU
imply CPU_RISCV
imply RISCV_TIMER
diff --git a/arch/riscv/cpu/cv1800b/Makefile b/arch/riscv/cpu/cv1800b/Makefile
index 95beb34b51a..da12e0f64e1 100644
--- a/arch/riscv/cpu/cv1800b/Makefile
+++ b/arch/riscv/cpu/cv1800b/Makefile
@@ -4,4 +4,3 @@
obj-y += dram.o
obj-y += cpu.o
-obj-y += cache.o
diff --git a/arch/riscv/cpu/th1520/Kconfig b/arch/riscv/cpu/th1520/Kconfig
new file mode 100644
index 00000000000..4d44191bd22
--- /dev/null
+++ b/arch/riscv/cpu/th1520/Kconfig
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+# Copyright (C) 2025, Yao Zi <ziyao@disroot.org>
+
+config THEAD_TH1520
+ bool
+ select ARCH_EARLY_INIT_R
+ select SYS_CACHE_SHIFT_6
+ select SUPPORT_SPL
+ select BINMAN if SPL
+ select SYS_CACHE_THEAD_CMO
+ select CLK_THEAD
+ imply CPU
+ imply CPU_RISCV
+ imply RISCV_TIMER if (RISCV_SMODE || SPL_RISCV_SMODE)
+ imply RISCV_ACLINT if RISCV_MMODE
+ imply SPL_RISCV_ACLINT if SPL_RISCV_MMODE
+ imply CMD_CPU
+ imply SPL_CPU
+ imply SPL_OPENSBI
+ imply SPL_LOAD_FIT
diff --git a/arch/riscv/cpu/th1520/Makefile b/arch/riscv/cpu/th1520/Makefile
new file mode 100644
index 00000000000..5d806c06e2e
--- /dev/null
+++ b/arch/riscv/cpu/th1520/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2025, Yao Zi <ziyao@disroot.org>
+
+obj-y += cache.o
+obj-y += cpu.o
+obj-y += dram.o
+obj-y += spl.o
diff --git a/arch/riscv/cpu/th1520/cache.c b/arch/riscv/cpu/th1520/cache.c
new file mode 100644
index 00000000000..08aa1f789fd
--- /dev/null
+++ b/arch/riscv/cpu/th1520/cache.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2025 Yao Zi <ziyao@disroot.org>
+ */
+
+#include <asm/io.h>
+#include <cpu_func.h>
+#include <linux/bitops.h>
+
+#define CSR_MHCR 0x7c1
+#define CSR_MHCR_IE BIT(0)
+#define CSR_MHCR_DE BIT(1)
+
+void icache_enable(void)
+{
+ csr_write(CSR_MHCR, csr_read(CSR_MHCR) | CSR_MHCR_IE);
+}
+
+void dcache_enable(void)
+{
+ csr_write(CSR_MHCR, csr_read(CSR_MHCR) | CSR_MHCR_DE);
+}
+
+int icache_status(void)
+{
+ return (csr_read(CSR_MHCR) & CSR_MHCR_IE) != 0;
+}
+
+int dcache_status(void)
+{
+ return (csr_read(CSR_MHCR) & CSR_MHCR_DE) != 0;
+}
diff --git a/arch/riscv/cpu/th1520/cpu.c b/arch/riscv/cpu/th1520/cpu.c
new file mode 100644
index 00000000000..b83f1272c67
--- /dev/null
+++ b/arch/riscv/cpu/th1520/cpu.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2025 Yao Zi <ziyao@disroot.org>
+ *
+ * TH1520 SoC has a set of undocumented customized PMP registers that are
+ * configured through MMIO operation. It must be disabled before entering
+ * the DRAM region, or an exception will be raised.
+ */
+
+#include <asm/io.h>
+#include <cpu_func.h>
+
+#define TH1520_PMP_BASE (void *)0xffdc020000
+
+void th1520_invalidate_pmp(void)
+{
+ /* Invalidate the PMP configuration as in vendor U-Boot code */
+ writel(0x0, TH1520_PMP_BASE + 0x0);
+
+ invalidate_icache_all();
+}
diff --git a/arch/riscv/cpu/th1520/dram.c b/arch/riscv/cpu/th1520/dram.c
new file mode 100644
index 00000000000..91007c0a3d3
--- /dev/null
+++ b/arch/riscv/cpu/th1520/dram.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ */
+
+#include <fdtdec.h>
+#include <init.h>
+#include <asm/global_data.h>
+#include <linux/sizes.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+ return fdtdec_setup_mem_size_base();
+}
+
+int dram_init_banksize(void)
+{
+ return fdtdec_setup_memory_banksize();
+}
diff --git a/arch/riscv/cpu/th1520/spl.c b/arch/riscv/cpu/th1520/spl.c
new file mode 100644
index 00000000000..362fe895f86
--- /dev/null
+++ b/arch/riscv/cpu/th1520/spl.c
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2025 Yao Zi <ziyao@disroot.org>
+ */
+#include <asm/arch/iopmp.h>
+#include <asm/io.h>
+#include <dm.h>
+#include <linux/sizes.h>
+#include <log.h>
+#include <init.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define TH1520_SUBSYS_CLK (void __iomem *)(0xffff011000 + 0x220)
+#define TH1520_SUBSYS_CLK_VO_EN BIT(2)
+#define TH1520_SUBSYS_CLK_VI_EN BIT(1)
+#define TH1520_SUBSYS_CLK_DSP_EN BIT(0)
+#define TH1520_SUBSYS_RST (void __iomem *)(0xffff015000 + 0x220)
+#define TH1520_SUBSYS_RST_VP_N BIT(3)
+#define TH1520_SUBSYS_RST_VO_N BIT(2)
+#define TH1520_SUBSYS_RST_VI_N BIT(1)
+#define TH1520_SUBSYS_RST_DSP_N BIT(0)
+
+int spl_dram_init(void)
+{
+ int ret;
+ struct udevice *dev;
+
+ ret = fdtdec_setup_mem_size_base();
+ if (ret) {
+ printf("failed to setup memory size and base: %d\n", ret);
+ return ret;
+ }
+
+ /* DDR init */
+ ret = uclass_get_device(UCLASS_RAM, 0, &dev);
+ if (ret) {
+ printf("DRAM init failed: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void __iomem *th1520_iopmp_regs[] = {
+ TH1520_IOPMP_EMMC,
+ TH1520_IOPMP_SDIO0,
+ TH1520_IOPMP_SDIO1,
+ TH1520_IOPMP_USB0,
+ TH1520_IOPMP_AO,
+ TH1520_IOPMP_AUD,
+ TH1520_IOPMP_CHIP_DBG,
+ TH1520_IOPMP_EIP120I,
+ TH1520_IOPMP_EIP120II,
+ TH1520_IOPMP_EIP120III,
+ TH1520_IOPMP_ISP0,
+ TH1520_IOPMP_ISP1,
+ TH1520_IOPMP_DW200,
+ TH1520_IOPMP_VIPRE,
+ TH1520_IOPMP_VENC,
+ TH1520_IOPMP_VDEC,
+ TH1520_IOPMP_G2D,
+ TH1520_IOPMP_FCE,
+ TH1520_IOPMP_NPU,
+ TH1520_IOPMP_DPU0,
+ TH1520_IOPMP_DPU1,
+ TH1520_IOPMP_GPU,
+ TH1520_IOPMP_GMAC1,
+ TH1520_IOPMP_GMAC2,
+ TH1520_IOPMP_DMAC,
+ TH1520_IOPMP_TEE_DMAC,
+ TH1520_IOPMP_DSP0,
+ TH1520_IOPMP_DSP1,
+};
+
+void harts_early_init(void)
+{
+ int i;
+
+ /*
+ * Set IOPMPs to the default attribute, allowing the application
+ * processor to access various peripherals. Subsystem clocks should be
+ * enabled and resets should be deasserted ahead of time, or the HART
+ * will hang when configuring corresponding IOPMP entries.
+ */
+ setbits_le32(TH1520_SUBSYS_CLK, TH1520_SUBSYS_CLK_VO_EN |
+ TH1520_SUBSYS_CLK_VI_EN |
+ TH1520_SUBSYS_CLK_DSP_EN);
+ setbits_le32(TH1520_SUBSYS_RST, TH1520_SUBSYS_RST_VP_N |
+ TH1520_SUBSYS_RST_VO_N |
+ TH1520_SUBSYS_RST_VI_N |
+ TH1520_SUBSYS_RST_DSP_N);
+
+ for (i = 0; i < ARRAY_SIZE(th1520_iopmp_regs); i++)
+ writel(TH1520_IOPMP_DEFAULT_ATTR, th1520_iopmp_regs[i]);
+}
diff --git a/arch/riscv/dts/binman.dtsi b/arch/riscv/dts/binman.dtsi
index 5aeeeddb59f..c5b0464d6a7 100644
--- a/arch/riscv/dts/binman.dtsi
+++ b/arch/riscv/dts/binman.dtsi
@@ -5,6 +5,12 @@
#include <config.h>
+#ifdef CONFIG_64BIT
+#define ARCH "riscv64"
+#else
+#define ARCH "riscv"
+
+#endif
/ {
binman: binman {
multiple-images;
@@ -31,12 +37,11 @@
description = "U-Boot";
type = "standalone";
os = "U-Boot";
- arch = "riscv";
+ arch = ARCH;
compression = "none";
load = /bits/ 64 <CONFIG_TEXT_BASE>;
uboot_blob: u-boot-nodtb {
- filename = "u-boot-nodtb.bin";
};
};
#else
@@ -44,7 +49,7 @@
description = "Linux";
type = "standalone";
os = "Linux";
- arch = "riscv";
+ arch = ARCH;
compression = "none";
load = /bits/ 64 <CONFIG_TEXT_BASE>;
@@ -57,7 +62,7 @@
tee {
description = "OP-TEE";
type = "tee";
- arch = "riscv";
+ arch = ARCH;
compression = "none";
os = "tee";
load = /bits/ 64 <CONFIG_SPL_OPTEE_LOAD_ADDR>;
@@ -71,7 +76,7 @@
description = "OpenSBI fw_dynamic Firmware";
type = "firmware";
os = "opensbi";
- arch = "riscv";
+ arch = ARCH;
compression = "none";
load = /bits/ 64 <CONFIG_SPL_OPENSBI_LOAD_ADDR>;
entry = /bits/ 64 <CONFIG_SPL_OPENSBI_LOAD_ADDR>;
diff --git a/arch/riscv/dts/jh7110-common-u-boot.dtsi b/arch/riscv/dts/jh7110-common-u-boot.dtsi
index 6d85b2d91a7..049b0a7ce28 100644
--- a/arch/riscv/dts/jh7110-common-u-boot.dtsi
+++ b/arch/riscv/dts/jh7110-common-u-boot.dtsi
@@ -27,7 +27,6 @@
bootph-pre-ram;
reg-offset = <0>;
current-speed = <115200>;
- clock-frequency = <24000000>;
};
&mmc0 {
diff --git a/arch/riscv/dts/jh7110-u-boot.dtsi b/arch/riscv/dts/jh7110-u-boot.dtsi
index a9e318c4a31..f8d13277d24 100644
--- a/arch/riscv/dts/jh7110-u-boot.dtsi
+++ b/arch/riscv/dts/jh7110-u-boot.dtsi
@@ -6,46 +6,6 @@
#include <dt-bindings/reset/starfive,jh7110-crg.h>
/ {
- cpus: cpus {
- bootph-pre-ram;
-
- S7_0: cpu@0 {
- bootph-pre-ram;
- status = "okay";
- cpu0_intc: interrupt-controller {
- bootph-pre-ram;
- };
- };
-
- U74_1: cpu@1 {
- bootph-pre-ram;
- cpu1_intc: interrupt-controller {
- bootph-pre-ram;
- };
- };
-
- U74_2: cpu@2 {
- bootph-pre-ram;
- cpu2_intc: interrupt-controller {
- bootph-pre-ram;
- };
- };
-
- U74_3: cpu@3 {
- bootph-pre-ram;
- cpu3_intc: interrupt-controller {
- bootph-pre-ram;
- };
- };
-
- U74_4: cpu@4 {
- bootph-pre-ram;
- cpu4_intc: interrupt-controller {
- bootph-pre-ram;
- };
- };
- };
-
timer {
compatible = "riscv,timer";
interrupts-extended = <&cpu0_intc 5>,
@@ -58,10 +18,6 @@
soc {
bootph-pre-ram;
- clint: timer@2000000 {
- bootph-pre-ram;
- };
-
dmc: dmc@15700000 {
bootph-pre-ram;
compatible = "starfive,jh7110-dmc";
@@ -78,6 +34,34 @@
};
};
+&clint {
+ bootph-pre-ram;
+};
+
+&cpu0_intc {
+ bootph-pre-ram;
+};
+
+&cpu1_intc {
+ bootph-pre-ram;
+};
+
+&cpu2_intc {
+ bootph-pre-ram;
+};
+
+&cpu3_intc {
+ bootph-pre-ram;
+};
+
+&cpu4_intc {
+ bootph-pre-ram;
+};
+
+&cpus {
+ bootph-pre-ram;
+};
+
&osc {
bootph-pre-ram;
};
@@ -107,6 +91,7 @@
};
&syscrg {
+ assigned-clock-rates = <0>; /* cpufreq not implemented, use defaults */
bootph-pre-ram;
};
diff --git a/arch/riscv/dts/th1520-lichee-module-4a.dtsi b/arch/riscv/dts/th1520-lichee-module-4a.dtsi
index 86a81bdcf77..9b255f8243c 100644
--- a/arch/riscv/dts/th1520-lichee-module-4a.dtsi
+++ b/arch/riscv/dts/th1520-lichee-module-4a.dtsi
@@ -14,6 +14,7 @@
memory@0 {
device_type = "memory";
reg = <0x0 0x00000000 0x2 0x00000000>;
+ bootph-pre-ram;
};
};
@@ -25,14 +26,6 @@
clock-frequency = <32768>;
};
-&apb_clk {
- clock-frequency = <62500000>;
-};
-
-&uart_sclk {
- clock-frequency = <100000000>;
-};
-
&emmc {
bus-width = <8>;
max-frequency = <198000000>;
diff --git a/arch/riscv/dts/th1520-lichee-pi-4a.dts b/arch/riscv/dts/th1520-lichee-pi-4a.dts
index a1248b2ee3a..49af88b7adf 100644
--- a/arch/riscv/dts/th1520-lichee-pi-4a.dts
+++ b/arch/riscv/dts/th1520-lichee-pi-4a.dts
@@ -4,6 +4,7 @@
*/
#include "th1520-lichee-module-4a.dtsi"
+#include "thead-th1520-binman.dtsi"
/ {
model = "Sipeed Lichee Pi 4A";
diff --git a/arch/riscv/dts/th1520.dtsi b/arch/riscv/dts/th1520.dtsi
index cbe3481fadd..28107a9f354 100644
--- a/arch/riscv/dts/th1520.dtsi
+++ b/arch/riscv/dts/th1520.dtsi
@@ -4,6 +4,7 @@
* Copyright (C) 2023 Jisheng Zhang <jszhang@kernel.org>
*/
+#include <dt-bindings/clock/thead,th1520-clk-ap.h>
#include <dt-bindings/interrupt-controller/irq.h>
/ {
@@ -14,6 +15,7 @@
cpus: cpus {
#address-cells = <1>;
#size-cells = <0>;
+ bootph-pre-ram;
timebase-frequency = <3000000>;
c910_0: cpu@0 {
@@ -21,6 +23,7 @@
device_type = "cpu";
riscv,isa = "rv64imafdc";
reg = <0>;
+ bootph-pre-ram;
i-cache-block-size = <64>;
i-cache-size = <65536>;
i-cache-sets = <512>;
@@ -42,6 +45,7 @@
device_type = "cpu";
riscv,isa = "rv64imafdc";
reg = <1>;
+ bootph-pre-ram;
i-cache-block-size = <64>;
i-cache-size = <65536>;
i-cache-sets = <512>;
@@ -63,6 +67,7 @@
device_type = "cpu";
riscv,isa = "rv64imafdc";
reg = <2>;
+ bootph-pre-ram;
i-cache-block-size = <64>;
i-cache-size = <65536>;
i-cache-sets = <512>;
@@ -84,6 +89,7 @@
device_type = "cpu";
riscv,isa = "rv64imafdc";
reg = <3>;
+ bootph-pre-ram;
i-cache-block-size = <64>;
i-cache-size = <65536>;
i-cache-sets = <512>;
@@ -122,25 +128,6 @@
#clock-cells = <0>;
};
- apb_clk: apb-clk-clock {
- compatible = "fixed-clock";
- clock-output-names = "apb_clk";
- #clock-cells = <0>;
- };
-
- uart_sclk: uart-sclk-clock {
- compatible = "fixed-clock";
- clock-output-names = "uart_sclk";
- #clock-cells = <0>;
- };
-
- sdhci_clk: sdhci-clock {
- compatible = "fixed-clock";
- clock-frequency = <198000000>;
- clock-output-names = "sdhci_clk";
- #clock-cells = <0>;
- };
-
soc {
compatible = "simple-bus";
interrupt-parent = <&plic>;
@@ -173,8 +160,10 @@
uart0: serial@ffe7014000 {
compatible = "snps,dw-apb-uart";
reg = <0xff 0xe7014000 0x0 0x100>;
+ bootph-pre-ram;
interrupts = <36 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&uart_sclk>;
+ clocks = <&clk CLK_UART_SCLK>, <&clk CLK_UART0_PCLK>;
+ clock-names = "buadclk", "apb_pclk";
reg-shift = <2>;
reg-io-width = <4>;
status = "disabled";
@@ -184,7 +173,7 @@
compatible = "thead,th1520-dwcmshc";
reg = <0xff 0xe7080000 0x0 0x10000>;
interrupts = <62 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&sdhci_clk>;
+ clocks = <&clk CLK_EMMC_SDIO>;
clock-names = "core";
status = "disabled";
};
@@ -193,7 +182,7 @@
compatible = "thead,th1520-dwcmshc";
reg = <0xff 0xe7090000 0x0 0x10000>;
interrupts = <64 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&sdhci_clk>;
+ clocks = <&clk CLK_EMMC_SDIO>;
clock-names = "core";
status = "disabled";
};
@@ -202,7 +191,7 @@
compatible = "thead,th1520-dwcmshc";
reg = <0xff 0xe70a0000 0x0 0x10000>;
interrupts = <71 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&sdhci_clk>;
+ clocks = <&clk CLK_EMMC_SDIO>;
clock-names = "core";
status = "disabled";
};
@@ -211,7 +200,8 @@
compatible = "snps,dw-apb-uart";
reg = <0xff 0xe7f00000 0x0 0x100>;
interrupts = <37 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&uart_sclk>;
+ clocks = <&clk CLK_UART_SCLK>, <&clk CLK_UART1_PCLK>;
+ clock-names = "buadclk", "apb_pclk";
reg-shift = <2>;
reg-io-width = <4>;
status = "disabled";
@@ -221,7 +211,8 @@
compatible = "snps,dw-apb-uart";
reg = <0xff 0xe7f04000 0x0 0x100>;
interrupts = <39 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&uart_sclk>;
+ clocks = <&clk CLK_UART_SCLK>, <&clk CLK_UART3_PCLK>;
+ clock-names = "buadclk", "apb_pclk";
reg-shift = <2>;
reg-io-width = <4>;
status = "disabled";
@@ -230,6 +221,8 @@
gpio2: gpio@ffe7f34000 {
compatible = "snps,dw-apb-gpio";
reg = <0xff 0xe7f34000 0x0 0x1000>;
+ clocks = <&clk CLK_GPIO2>;
+ clock-names = "bus";
#address-cells = <1>;
#size-cells = <0>;
@@ -248,6 +241,8 @@
gpio3: gpio@ffe7f38000 {
compatible = "snps,dw-apb-gpio";
reg = <0xff 0xe7f38000 0x0 0x1000>;
+ clocks = <&clk CLK_GPIO3>;
+ clock-names = "bus";
#address-cells = <1>;
#size-cells = <0>;
@@ -266,6 +261,8 @@
gpio0: gpio@ffec005000 {
compatible = "snps,dw-apb-gpio";
reg = <0xff 0xec005000 0x0 0x1000>;
+ clocks = <&clk CLK_GPIO0>;
+ clock-names = "bus";
#address-cells = <1>;
#size-cells = <0>;
@@ -284,6 +281,8 @@
gpio1: gpio@ffec006000 {
compatible = "snps,dw-apb-gpio";
reg = <0xff 0xec006000 0x0 0x1000>;
+ clocks = <&clk CLK_GPIO1>;
+ clock-names = "bus";
#address-cells = <1>;
#size-cells = <0>;
@@ -303,16 +302,24 @@
compatible = "snps,dw-apb-uart";
reg = <0xff 0xec010000 0x0 0x4000>;
interrupts = <38 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&uart_sclk>;
+ clocks = <&clk CLK_UART_SCLK>, <&clk CLK_UART2_PCLK>;
+ clock-names = "buadclk", "apb_pclk";
reg-shift = <2>;
reg-io-width = <4>;
status = "disabled";
};
+ clk: clock-controller@ffef010000 {
+ compatible = "thead,th1520-clk-ap";
+ reg = <0xff 0xef010000 0x0 0x1000>;
+ clocks = <&osc>;
+ #clock-cells = <1>;
+ };
+
timer0: timer@ffefc32000 {
compatible = "snps,dw-apb-timer";
reg = <0xff 0xefc32000 0x0 0x14>;
- clocks = <&apb_clk>;
+ clocks = <&clk CLK_PERI_APB_PCLK>;
clock-names = "timer";
interrupts = <16 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
@@ -321,7 +328,7 @@
timer1: timer@ffefc32014 {
compatible = "snps,dw-apb-timer";
reg = <0xff 0xefc32014 0x0 0x14>;
- clocks = <&apb_clk>;
+ clocks = <&clk CLK_PERI_APB_PCLK>;
clock-names = "timer";
interrupts = <17 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
@@ -330,7 +337,7 @@
timer2: timer@ffefc32028 {
compatible = "snps,dw-apb-timer";
reg = <0xff 0xefc32028 0x0 0x14>;
- clocks = <&apb_clk>;
+ clocks = <&clk CLK_PERI_APB_PCLK>;
clock-names = "timer";
interrupts = <18 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
@@ -339,7 +346,7 @@
timer3: timer@ffefc3203c {
compatible = "snps,dw-apb-timer";
reg = <0xff 0xefc3203c 0x0 0x14>;
- clocks = <&apb_clk>;
+ clocks = <&clk CLK_PERI_APB_PCLK>;
clock-names = "timer";
interrupts = <19 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
@@ -349,7 +356,8 @@
compatible = "snps,dw-apb-uart";
reg = <0xff 0xf7f08000 0x0 0x4000>;
interrupts = <40 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&uart_sclk>;
+ clocks = <&clk CLK_UART_SCLK>, <&clk CLK_UART4_PCLK>;
+ clock-names = "buadclk", "apb_pclk";
reg-shift = <2>;
reg-io-width = <4>;
status = "disabled";
@@ -359,16 +367,27 @@
compatible = "snps,dw-apb-uart";
reg = <0xff 0xf7f0c000 0x0 0x4000>;
interrupts = <41 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&uart_sclk>;
+ clocks = <&clk CLK_UART_SCLK>, <&clk CLK_UART5_PCLK>;
+ clock-names = "buadclk", "apb_pclk";
reg-shift = <2>;
reg-io-width = <4>;
status = "disabled";
};
+ ddrc: ddrc@fffd000000 {
+ compatible = "thead,th1520-ddrc";
+ reg = <0xff 0xfd000000 0x0 0x1000000>,
+ <0xff 0xfe000000 0x0 0x1000000>,
+ <0xff 0xff000000 0x0 0x4000>,
+ <0xff 0xff005000 0x0 0x1000>;
+ reg-names = "phy-0", "phy-1", "ctrl", "sys";
+ bootph-pre-ram;
+ };
+
timer4: timer@ffffc33000 {
compatible = "snps,dw-apb-timer";
reg = <0xff 0xffc33000 0x0 0x14>;
- clocks = <&apb_clk>;
+ clocks = <&clk CLK_PERI_APB_PCLK>;
clock-names = "timer";
interrupts = <20 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
@@ -377,7 +396,7 @@
timer5: timer@ffffc33014 {
compatible = "snps,dw-apb-timer";
reg = <0xff 0xffc33014 0x0 0x14>;
- clocks = <&apb_clk>;
+ clocks = <&clk CLK_PERI_APB_PCLK>;
clock-names = "timer";
interrupts = <21 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
@@ -386,7 +405,7 @@
timer6: timer@ffffc33028 {
compatible = "snps,dw-apb-timer";
reg = <0xff 0xffc33028 0x0 0x14>;
- clocks = <&apb_clk>;
+ clocks = <&clk CLK_PERI_APB_PCLK>;
clock-names = "timer";
interrupts = <22 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
@@ -395,7 +414,7 @@
timer7: timer@ffffc3303c {
compatible = "snps,dw-apb-timer";
reg = <0xff 0xffc3303c 0x0 0x14>;
- clocks = <&apb_clk>;
+ clocks = <&clk CLK_PERI_APB_PCLK>;
clock-names = "timer";
interrupts = <23 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
diff --git a/arch/riscv/dts/thead-th1520-binman.dtsi b/arch/riscv/dts/thead-th1520-binman.dtsi
new file mode 100644
index 00000000000..f060639e1c6
--- /dev/null
+++ b/arch/riscv/dts/thead-th1520-binman.dtsi
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2025 Yao Zi <ziyao@disroot.org>
+ */
+
+#include <config.h>
+
+/ {
+ binman: binman {
+ };
+};
+
+&binman {
+ filename = "u-boot-with-spl.bin";
+
+ u-boot-spl {
+ };
+
+ ddr-fw {
+ filename = "th1520-ddr-firmware.bin";
+ type = "blob-ext";
+ };
+
+ fit {
+ offset = <CONFIG_SPL_PAD_TO>;
+
+ description = "Configuration to load M-mode U-Boot";
+
+ #address-cells = <2>;
+ fit,fdt-list = "of-list";
+
+ images {
+ uboot {
+ description = "U-Boot";
+ type = "standalone";
+ os = "U-boot";
+ arch = "riscv";
+ compression = "none";
+ load = /bits/ 64 <CONFIG_TEXT_BASE>;
+
+ uboot_blob: u-boot {
+ };
+ };
+ };
+
+ configurations {
+ default = "conf-th1520-lichee-pi-4a";
+
+ conf-th1520-lichee-pi-4a {
+ description = "th1520-lichee-pi-4a";
+ loadables = "uboot";
+ };
+ };
+ };
+};
diff --git a/arch/riscv/include/asm/arch-th1520/cpu.h b/arch/riscv/include/asm/arch-th1520/cpu.h
new file mode 100644
index 00000000000..837f0b8d06b
--- /dev/null
+++ b/arch/riscv/include/asm/arch-th1520/cpu.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2025 Yao Zi <ziyao@disroot.org>
+ */
+
+#ifndef _ASM_TH1520_CPU_H_
+#define _ASM_TH1520_CPU_H_
+void th1520_invalidate_pmp(void);
+#endif /* _ASM_TH1520_CPU_H_ */
diff --git a/arch/riscv/include/asm/arch-th1520/iopmp.h b/arch/riscv/include/asm/arch-th1520/iopmp.h
new file mode 100644
index 00000000000..3dc766b5bff
--- /dev/null
+++ b/arch/riscv/include/asm/arch-th1520/iopmp.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2025 Yao Zi <ziyao@disroot.org>
+ */
+#ifndef _ASM_ARCH_TH1520_IOPMP_H_
+#define _ASM_ARCH_TH1520_IOPMP_H_
+
+#define TH1520_IOPMP_EMMC (void *)0xfffc0280c0
+#define TH1520_IOPMP_SDIO0 (void *)0xfffc0290c0
+#define TH1520_IOPMP_SDIO1 (void *)0xfffc02a0c0
+#define TH1520_IOPMP_USB0 (void *)0xfffc02e0c0
+#define TH1520_IOPMP_AO (void *)0xffffc210c0
+#define TH1520_IOPMP_AUD (void *)0xffffc220c0
+#define TH1520_IOPMP_CHIP_DBG (void *)0xffffc370c0
+#define TH1520_IOPMP_EIP120I (void *)0xffff2200c0
+#define TH1520_IOPMP_EIP120II (void *)0xffff2300c0
+#define TH1520_IOPMP_EIP120III (void *)0xffff2400c0
+#define TH1520_IOPMP_ISP0 (void *)0xfff40800c0
+#define TH1520_IOPMP_ISP1 (void *)0xfff40810c0
+#define TH1520_IOPMP_DW200 (void *)0xfff40820c0
+#define TH1520_IOPMP_VIPRE (void *)0xfff40830c0
+#define TH1520_IOPMP_VENC (void *)0xfffcc600c0
+#define TH1520_IOPMP_VDEC (void *)0xfffcc610c0
+#define TH1520_IOPMP_G2D (void *)0xfffcc620c0
+#define TH1520_IOPMP_FCE (void *)0xfffcc630c0
+#define TH1520_IOPMP_NPU (void *)0xffff01c0c0
+#define TH1520_IOPMP_DPU0 (void *)0xffff5200c0
+#define TH1520_IOPMP_DPU1 (void *)0xffff5210c0
+#define TH1520_IOPMP_GPU (void *)0xffff5220c0
+#define TH1520_IOPMP_GMAC1 (void *)0xfffc0010c0
+#define TH1520_IOPMP_GMAC2 (void *)0xfffc0020c0
+#define TH1520_IOPMP_DMAC (void *)0xffffc200c0
+#define TH1520_IOPMP_TEE_DMAC (void *)0xffff2500c0
+#define TH1520_IOPMP_DSP0 (void *)0xffff0580c0
+#define TH1520_IOPMP_DSP1 (void *)0xffff0590c0
+#define TH1520_IOPMP_AUDIO (void *)0xffffc220c0
+#define TH1520_IOPMP_AUDIO0 (void *)0xffcb02e0c0
+#define TH1520_IOPMP_AUDIO1 (void *)0xffcb02f0c0
+
+#define TH1520_IOPMP_DEFAULT_ATTR 0xffffffff
+
+#endif // _ASM_ARCH_TH1520_IOPMP_H_
diff --git a/arch/riscv/include/asm/arch-th1520/spl.h b/arch/riscv/include/asm/arch-th1520/spl.h
new file mode 100644
index 00000000000..59aed8cad62
--- /dev/null
+++ b/arch/riscv/include/asm/arch-th1520/spl.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2025 Yao Zi <ziyao@disroot.org>
+ */
+#ifndef _ASM_ARCH_TH1520_SPL_H_
+#define _ASM_ARCH_TH1520_SPL_H_
+
+void spl_dram_init(void);
+
+#endif // _ASM_ARCH_TH1520_SPL_H_
diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h
index d356752a56a..47b5e2cfc8f 100644
--- a/arch/riscv/include/asm/global_data.h
+++ b/arch/riscv/include/asm/global_data.h
@@ -14,6 +14,7 @@
#include <asm/smp.h>
#include <asm/u-boot.h>
#include <compiler.h>
+#include <config.h>
/* Architecture-specific global data */
struct arch_global_data {
@@ -47,8 +48,26 @@ struct arch_global_data {
#include <asm-generic/global_data.h>
+#if defined(__clang__) || CONFIG_IS_ENABLED(LTO)
+
+#define DECLARE_GLOBAL_DATA_PTR
+#define gd get_gd()
+
+static inline gd_t *get_gd(void)
+{
+ gd_t *gd_ptr;
+
+ __asm__ volatile ("mv %0, gp\n" : "=r" (gd_ptr));
+
+ return gd_ptr;
+}
+
+#else
+
#define DECLARE_GLOBAL_DATA_PTR register gd_t *gd asm ("gp")
+#endif
+
static inline void set_gd(volatile gd_t *gd_ptr)
{
#ifdef CONFIG_64BIT
diff --git a/arch/riscv/include/asm/insn-def.h b/arch/riscv/include/asm/insn-def.h
index 19a10cad84c..1869342b167 100644
--- a/arch/riscv/include/asm/insn-def.h
+++ b/arch/riscv/include/asm/insn-def.h
@@ -5,8 +5,8 @@
* Ported from linux insn-def.h.
*/
-#ifndef _ASM_RISCV_BARRIER_H
-#define _ASM_RISCV_BARRIER_H
+#ifndef _ASM_RISCV_INSN_DEF_H
+#define _ASM_RISCV_INSN_DEF_H
#define INSN_I_SIMM12_SHIFT 20
#define INSN_I_RS1_SHIFT 15
@@ -36,4 +36,4 @@
__INSN_I(RV_##opcode, RV_##func3, RV_##rd, \
RV_##rs1, RV_##simm12)
-#endif /* _ASM_RISCV_BARRIER_H */
+#endif /* _ASM_RISCV_INSN_DEF_H */
diff --git a/arch/riscv/include/asm/u-boot.h b/arch/riscv/include/asm/u-boot.h
index d5e1d5f3231..a90cc4c21cf 100644
--- a/arch/riscv/include/asm/u-boot.h
+++ b/arch/riscv/include/asm/u-boot.h
@@ -23,6 +23,10 @@
#include <asm/u-boot-riscv.h>
/* For image.h:image_check_target_arch() */
+#ifdef CONFIG_64BIT
+#define IH_ARCH_DEFAULT IH_ARCH_RISCV64
+#else
#define IH_ARCH_DEFAULT IH_ARCH_RISCV
+#endif
#endif /* _U_BOOT_H_ */
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index 189b35c24d3..db8d235c699 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_CMD_BOOTI) += bootm.o image.o
obj-$(CONFIG_CMD_GO) += boot.o
obj-y += cache.o
obj-$(CONFIG_SIFIVE_CACHE) += sifive_cache.o
+obj-$(CONFIG_SYS_CACHE_THEAD_CMO) += thead_cmo.o
ifeq ($(CONFIG_$(PHASE_)RISCV_MMODE),y)
obj-$(CONFIG_$(PHASE_)RISCV_ACLINT) += aclint_ipi.o
obj-$(CONFIG_ANDES_PLICSW) += andes_plicsw.o
diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c
index 9544907ab1e..c98c5e76633 100644
--- a/arch/riscv/lib/bootm.c
+++ b/arch/riscv/lib/bootm.c
@@ -90,6 +90,10 @@ static void boot_jump_linux(struct bootm_headers *images, int flag)
announce_and_cleanup(fake);
if (!fake) {
+ if (images->os.arch != IH_ARCH_DEFAULT) {
+ printf("Image arch not compatible with host arch.\n");
+ hang();
+ }
if (CONFIG_IS_ENABLED(OF_LIBFDT) && images->ft_len) {
#ifdef CONFIG_SMP
ret = smp_call_function(images->ep,
diff --git a/arch/riscv/cpu/cv1800b/cache.c b/arch/riscv/lib/thead_cmo.c
index b8051e29e02..b8051e29e02 100644
--- a/arch/riscv/cpu/cv1800b/cache.c
+++ b/arch/riscv/lib/thead_cmo.c