summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2021-07-18 07:13:55 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2021-07-18 07:13:55 +0200
commit33f8f53317659cd2c61dd118bfa7150f33aa30fb (patch)
treecec893f4b273f4a78e1d84326d15e97b75a456df
parentca922d6044e49b1ed9782aa8eb28d1ed70931978 (diff)
parentb60bdac8a5870dc136c9b028771371dd123a2431 (diff)
downloadbarebox-33f8f53317659cd2c61dd118bfa7150f33aa30fb.tar.gz
barebox-33f8f53317659cd2c61dd118bfa7150f33aa30fb.tar.xz
Merge branch 'for-next/riscv'
-rw-r--r--Documentation/boards/riscv.rst37
-rw-r--r--arch/riscv/Kconfig19
-rw-r--r--arch/riscv/Kconfig.socs57
-rw-r--r--arch/riscv/boards/Makefile1
-rw-r--r--arch/riscv/boards/beaglev/Makefile5
-rw-r--r--arch/riscv/boards/beaglev/board.c30
-rwxr-xr-xarch/riscv/boards/beaglev/defaultenv-beaglev/boot/buildroot13
-rwxr-xr-xarch/riscv/boards/beaglev/defaultenv-beaglev/boot/fedora16
-rw-r--r--arch/riscv/boards/beaglev/defaultenv-beaglev/nv/boot.default1
-rw-r--r--arch/riscv/boards/beaglev/lowlevel.c20
-rw-r--r--arch/riscv/boards/erizo/lowlevel.c8
-rw-r--r--arch/riscv/boards/hifive/lowlevel.c17
-rw-r--r--arch/riscv/boot/Makefile1
-rw-r--r--arch/riscv/boot/board-dt-2nd.c4
-rw-r--r--arch/riscv/boot/entry.c5
-rw-r--r--arch/riscv/boot/entry.h6
-rw-r--r--arch/riscv/boot/nmon_entry.S13
-rw-r--r--arch/riscv/boot/start.c15
-rw-r--r--arch/riscv/boot/uncompress.c11
-rw-r--r--arch/riscv/configs/starfive_defconfig131
-rw-r--r--arch/riscv/cpu/Makefile4
-rw-r--r--arch/riscv/cpu/core.c41
-rw-r--r--arch/riscv/cpu/dma.c74
-rw-r--r--arch/riscv/cpu/interrupts.c139
-rw-r--r--arch/riscv/cpu/mtrap.S30
-rw-r--r--arch/riscv/cpu/strap.S30
-rw-r--r--arch/riscv/dts/Makefile1
-rw-r--r--arch/riscv/dts/jh7100-beaglev-starlight.dts54
-rw-r--r--arch/riscv/dts/jh7100-beaglev-starlight.dtsi369
-rw-r--r--arch/riscv/dts/jh7100.dtsi798
-rw-r--r--arch/riscv/include/asm/asm-offsets.h1
-rw-r--r--arch/riscv/include/asm/barebox-riscv.h14
-rw-r--r--arch/riscv/include/asm/barrier.h27
-rw-r--r--arch/riscv/include/asm/cacheflush.h16
-rw-r--r--arch/riscv/include/asm/debug_ll.h10
-rw-r--r--arch/riscv/include/asm/dma.h48
-rw-r--r--arch/riscv/include/asm/io.h10
-rw-r--r--arch/riscv/include/asm/irq.h107
-rw-r--r--arch/riscv/include/asm/ptrace.h143
-rw-r--r--arch/riscv/include/asm/riscv_nmon.h49
-rw-r--r--arch/riscv/include/asm/sbi.h8
-rw-r--r--arch/riscv/include/asm/system.h61
-rw-r--r--arch/riscv/include/asm/unwind.h9
-rw-r--r--arch/riscv/lib/asm-offsets.c46
-rw-r--r--arch/riscv/lib/bootm.c4
-rw-r--r--arch/riscv/lib/cpuinfo.c56
-rw-r--r--arch/riscv/lib/reloc.c8
-rw-r--r--arch/riscv/lib/sbi.c4
-rw-r--r--arch/riscv/lib/setupc.S2
-rw-r--r--commands/Kconfig4
-rw-r--r--common/Kconfig11
-rw-r--r--common/globalvar.c21
-rw-r--r--common/oftree.c19
-rw-r--r--drivers/Makefile2
-rw-r--r--drivers/clk/Makefile1
-rw-r--r--drivers/clk/starfive/Makefile3
-rw-r--r--drivers/clk/starfive/clk.h64
-rw-r--r--drivers/clk/starfive/jh7100-clkgen.c363
-rw-r--r--drivers/clocksource/timer-clint.c7
-rw-r--r--drivers/clocksource/timer-riscv.c5
-rw-r--r--drivers/gpio/Kconfig8
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/gpio-starfive-vic.c177
-rw-r--r--drivers/hw_random/Kconfig7
-rw-r--r--drivers/hw_random/Makefile1
-rw-r--r--drivers/hw_random/starfive-vic-rng.c208
-rw-r--r--drivers/mci/dw_mmc.c23
-rw-r--r--drivers/mci/mci-core.c15
-rw-r--r--drivers/misc/Kconfig10
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/starfive-pwrseq.c92
-rw-r--r--drivers/net/Kconfig8
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/designware.c64
-rw-r--r--drivers/net/designware.h29
-rw-r--r--drivers/net/designware_starfive.c110
-rw-r--r--drivers/nvmem/Kconfig8
-rw-r--r--drivers/nvmem/Makefile2
-rw-r--r--drivers/nvmem/starfive-otp.c201
-rw-r--r--drivers/pinctrl/pinctrl-single.c4
-rw-r--r--drivers/reset/Kconfig6
-rw-r--r--drivers/reset/Makefile1
-rw-r--r--drivers/reset/core.c78
-rw-r--r--drivers/reset/reset-starfive-vic.c234
-rw-r--r--drivers/soc/Makefile5
-rw-r--r--drivers/soc/sifive/Makefile1
-rw-r--r--drivers/soc/sifive/sifive_l2_cache.c136
-rw-r--r--drivers/soc/starfive/Makefile1
-rw-r--r--drivers/soc/starfive/jh7100_dma.c55
-rw-r--r--drivers/watchdog/Kconfig7
-rw-r--r--drivers/watchdog/Makefile1
-rw-r--r--drivers/watchdog/starfive_wdt.c106
-rw-r--r--images/Makefile.riscv4
-rw-r--r--include/dma.h7
-rw-r--r--include/dt-bindings/clock/starfive-jh7100.h203
-rw-r--r--include/dt-bindings/reset-controller/starfive-jh7100.h126
-rw-r--r--include/globalvar.h8
-rw-r--r--include/linux/reset.h7
-rw-r--r--include/pinctrl.h6
-rw-r--r--include/soc/sifive/l2_cache.h10
-rw-r--r--include/soc/starfive/rstgen.h41
-rw-r--r--include/soc/starfive/sysmain.h15
102 files changed, 4930 insertions, 171 deletions
diff --git a/Documentation/boards/riscv.rst b/Documentation/boards/riscv.rst
index 53d13550f3..97f4d1deb7 100644
--- a/Documentation/boards/riscv.rst
+++ b/Documentation/boards/riscv.rst
@@ -60,6 +60,43 @@ into the config file.
See https://barebox.org/jsbarebox/?graphic=1 for a live example.
+BeagleV
+-------
+
+barebox has second-stage support for the BeagleV Starlight::
+
+ make ARCH=riscv starfive_defconfig
+ make
+
+Thie resulting ``./images/barebox-beaglev-starlight.img`` can be used as payload
+to opensbi::
+
+ git clone https://github.com/starfive-tech/opensbi
+ cd opensbi
+ export ARCH=riscv
+ export PLATFORM=starfive/vic7100
+ export FW_PAYLOAD_PATH=$BAREBOX/build/images/barebox-beaglev-starlight.img
+
+ make ARCH=riscv
+ ./fsz.sh ./build/platform/starfive/vic7100/firmware/fw_payload.bin fw_payload.bin.out
+ ls -l $OPENSBI/build/platform/starfive/vic7100/firmware/fw_payload.bin.out
+
+The resulting ``./platform/starfive/vic7100/firmware/fw_payload.bin.out`` can then
+be flashed via Xmodem to the board::
+
+ picocom -b 115200 /dev/ttyUSB0 --send-cmd "sx -vv" --receive-cmd "rx -vv"
+ 0:update uboot
+ select the function: 0␤
+ send file by xmodem
+ ^A^S./platform/starfive/vic7100/firmware/fw_payload.bin.out␤
+
+After reset, barebox should then boot to shell and attempt booting kernel ``Image``
+and device tree ``jh7100-starlight.dtb`` from the first root partition with the same
+partition as rootfs. Note that while barebox does take over some initialization,
+because of lack of Linux drivers, it doesn't yet do everything. If you experience
+boot hangs, you may need to disable devices (or extend the starfive-pwrseq driver
+to initialize it for you).
+
Erizo
-----
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index a4aa799acf..a814a1a45b 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -77,6 +77,11 @@ config RISCV_OPTIMZED_STRING_FUNCTIONS
These functions work faster than the normal versions but increase
your binary size.
+config RISCV_EXCEPTIONS
+ bool "enable exception handling support"
+ default y
+ select ARCH_HAS_DATA_ABORT_MASK
+
config HAS_NMON
bool
@@ -97,14 +102,18 @@ config NMON_HELP
Say yes here to get the nmon commands message on
every nmon start.
-# set if we run in machine mode, cleared if we run in supervisor mode
+# selected by boards where barebox runs in machine mode
config RISCV_M_MODE
bool
-# set if we are running in S-mode and can use SBI calls
-config RISCV_SBI
+# selected by boards where barebox runs in supervisor mode
+config RISCV_S_MODE
bool
- depends on !RISCV_M_MODE
- default y
+
+config RISCV_MULTI_MODE
+ def_bool RISCV_S_MODE && RISCV_M_MODE
+
+config RISCV_SBI
+ def_bool RISCV_S_MODE
endmenu
diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index c6875738d0..221ea133d4 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -15,14 +15,21 @@ config BOARD_ERIZO_GENERIC
config SOC_VIRT
bool "QEMU Virt Machine"
+ select RISCV_S_MODE
select BOARD_RISCV_GENERIC_DT
- select CLINT_TIMER
+ select HAS_CACHE
help
Generates an image tht can be be booted by QEMU. The image is called
barebox-dt-2nd.img
+config CPU_SIFIVE
+ bool
+ select HAS_CACHE
+
config SOC_SIFIVE
bool "SiFive SoCs"
+ select CPU_SIFIVE
+ select RISCV_S_MODE
select CLK_SIFIVE
select CLK_SIFIVE_PRCI
select RISCV_TIMER
@@ -40,4 +47,52 @@ config BOARD_HIFIVE
endif
+config SOC_STARFIVE
+ bool "StarFive SoCs"
+ select ARCH_HAS_RESET_CONTROLLER
+ select RISCV_S_MODE
+ select HAS_ASM_DEBUG_LL
+ select HAS_NMON
+ help
+ This enables support for SiFive SoC platform hardware.
+
+if SOC_STARFIVE
+
+config SOC_STARFIVE_JH71XX
+ bool
+ select CPU_SIFIVE
+
+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.
+
+config BOARD_BEAGLEV
+ bool "BeagleV"
+ depends on ARCH_RV64I
+ select SOC_STARFIVE_JH71XX
+ select USE_COMPRESSED_DTB
+
+config BOARD_BEAGLEV_BETA
+ bool "BeagleV Beta (with JH7100)"
+ depends on BOARD_BEAGLEV
+ select SOC_STARFIVE_JH7100
+ help
+ Select this for hardware using the earlier JH7100 SoC. The JH7110
+ used with later production runs is cache-coherent and thus can do
+ without the special DMA handling enabled by this option. It's safe
+ to enable this option for other SoCs.
+
+endif
+
+comment "CPU features"
+
+config SIFIVE_L2
+ bool "SiFive L2 cache controller"
+ depends on CPU_SIFIVE
+
endmenu
diff --git a/arch/riscv/boards/Makefile b/arch/riscv/boards/Makefile
index 99f22f32b4..cb28a25d8b 100644
--- a/arch/riscv/boards/Makefile
+++ b/arch/riscv/boards/Makefile
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_BOARD_ERIZO_GENERIC) += erizo/
obj-$(CONFIG_BOARD_HIFIVE) += hifive/
+obj-$(CONFIG_BOARD_BEAGLEV) += beaglev/
diff --git a/arch/riscv/boards/beaglev/Makefile b/arch/riscv/boards/beaglev/Makefile
new file mode 100644
index 0000000000..23efc273ee
--- /dev/null
+++ b/arch/riscv/boards/beaglev/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+pbl-y += lowlevel.o
+obj-y += board.o
+bbenv-y += defaultenv-beaglev
diff --git a/arch/riscv/boards/beaglev/board.c b/arch/riscv/boards/beaglev/board.c
new file mode 100644
index 0000000000..110754ea95
--- /dev/null
+++ b/arch/riscv/boards/beaglev/board.c
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 Ahmad Fatoum, Pengutronix
+ */
+
+#include <common.h>
+#include <driver.h>
+#include <bbu.h>
+#include <envfs.h>
+
+static int beaglev_probe(struct device_d *dev)
+{
+ barebox_set_hostname("beaglev-starlight");
+
+ defaultenv_append_directory(defaultenv_beaglev);
+
+ return 0;
+}
+
+static const struct of_device_id beaglev_of_match[] = {
+ { .compatible = "beagle,beaglev-starlight-jh7100" },
+ { /* sentinel */ },
+};
+
+static struct driver_d beaglev_board_driver = {
+ .name = "board-beaglev",
+ .probe = beaglev_probe,
+ .of_compatible = beaglev_of_match,
+};
+device_platform_driver(beaglev_board_driver);
diff --git a/arch/riscv/boards/beaglev/defaultenv-beaglev/boot/buildroot b/arch/riscv/boards/beaglev/defaultenv-beaglev/boot/buildroot
new file mode 100755
index 0000000000..157223bbee
--- /dev/null
+++ b/arch/riscv/boards/beaglev/defaultenv-beaglev/boot/buildroot
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+BOOT=/mnt/mmc0.0/boot
+
+detect mmc0
+
+global.linux.bootargs.base="rhgb stmmaceth=chain_mode:1"
+
+global.bootm.oftree=$BOOT/jh7100-starlight.dtb
+global.bootm.image=$BOOT/Image
+global linux.bootargs.root=rootwait
+global linux.bootargs.earlycon=earlycon
+global.bootm.appendroot=1
diff --git a/arch/riscv/boards/beaglev/defaultenv-beaglev/boot/fedora b/arch/riscv/boards/beaglev/defaultenv-beaglev/boot/fedora
new file mode 100755
index 0000000000..4f9ab16f82
--- /dev/null
+++ b/arch/riscv/boards/beaglev/defaultenv-beaglev/boot/fedora
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+BOOT=/mnt/mmc0.0
+VERSION=5.10.6-210.0.riscv64.fc33.riscv64
+
+detect mmc0
+
+global.linux.bootargs.base="root=UUID=ae1e722a-d01b-4cdc-ab56-7b68abcdd0fe rhgb stmmaceth=chain_mode:1 selinux=0 LANG=en_US.UTF-8"
+
+global.bootm.oftree=${BOOT}/starfive_vic7100_beagle_v.dtb
+global.bootm.initrd=${BOOT}/initramfs-${VERSION}.img
+global.bootm.image=${BOOT}/vmlinuz-${VERSION}
+global linux.bootargs.root=rootwait
+global linux.bootargs.earlycon=earlycon
+#global.bootm.root_dev=mmc0.1
+#global.bootm.appendroot=1
diff --git a/arch/riscv/boards/beaglev/defaultenv-beaglev/nv/boot.default b/arch/riscv/boards/beaglev/defaultenv-beaglev/nv/boot.default
new file mode 100644
index 0000000000..880a6b1d8c
--- /dev/null
+++ b/arch/riscv/boards/beaglev/defaultenv-beaglev/nv/boot.default
@@ -0,0 +1 @@
+buildroot net
diff --git a/arch/riscv/boards/beaglev/lowlevel.c b/arch/riscv/boards/beaglev/lowlevel.c
new file mode 100644
index 0000000000..db884dc762
--- /dev/null
+++ b/arch/riscv/boards/beaglev/lowlevel.c
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <common.h>
+#include <debug_ll.h>
+#include <asm/barebox-riscv.h>
+#include <asm/riscv_nmon.h>
+
+ENTRY_FUNCTION(start_beaglev_starlight, a0, a1, a2)
+{
+ extern char __dtb_z_jh7100_beaglev_starlight_start[];
+ void *fdt;
+
+ debug_ll_init();
+ barebox_nmon_entry();
+ putc_ll('>');
+
+ fdt = __dtb_z_jh7100_beaglev_starlight_start + get_runtime_offset();
+
+ barebox_riscv_supervisor_entry(0x84000000, SZ_512M, a0, fdt);
+}
diff --git a/arch/riscv/boards/erizo/lowlevel.c b/arch/riscv/boards/erizo/lowlevel.c
index 6acf15931c..ab06634bdb 100644
--- a/arch/riscv/boards/erizo/lowlevel.c
+++ b/arch/riscv/boards/erizo/lowlevel.c
@@ -3,16 +3,20 @@
#include <common.h>
#include <asm/barebox-riscv.h>
#include <debug_ll.h>
+#include <asm/riscv_nmon.h>
ENTRY_FUNCTION(start_erizo_generic, a0, a1, a2)
{
extern char __dtb_z_erizo_generic_start[];
+ void *fdt;
debug_ll_init();
+ barebox_nmon_entry();
putc_ll('>');
/* On POR, we are running from read-only memory here. */
- barebox_riscv_entry(0x80000000, SZ_8M,
- __dtb_z_erizo_generic_start + get_runtime_offset());
+ fdt = __dtb_z_erizo_generic_start + get_runtime_offset();
+
+ barebox_riscv_machine_entry(0x80000000, SZ_8M, fdt);
}
diff --git a/arch/riscv/boards/hifive/lowlevel.c b/arch/riscv/boards/hifive/lowlevel.c
index 1de13cac16..5e8969bef1 100644
--- a/arch/riscv/boards/hifive/lowlevel.c
+++ b/arch/riscv/boards/hifive/lowlevel.c
@@ -4,22 +4,23 @@
#include <asm/barebox-riscv.h>
#include <debug_ll.h>
+static __always_inline void start_hifive(unsigned long hartid, void *fdt)
+{
+ putc_ll('>');
+
+ barebox_riscv_supervisor_entry(0x80000000, SZ_128M, hartid, fdt);
+}
+
ENTRY_FUNCTION(start_hifive_unmatched, a0, a1, a2)
{
extern char __dtb_z_hifive_unmatched_a00_start[];
- putc_ll('>');
-
- barebox_riscv_entry(0x80000000, SZ_128M,
- __dtb_z_hifive_unmatched_a00_start + get_runtime_offset());
+ start_hifive(a0, __dtb_z_hifive_unmatched_a00_start + get_runtime_offset());
}
ENTRY_FUNCTION(start_hifive_unleashed, a0, a1, a2)
{
extern char __dtb_z_hifive_unleashed_a00_start[];
- putc_ll('>');
-
- barebox_riscv_entry(0x80000000, SZ_128M,
- __dtb_z_hifive_unleashed_a00_start + get_runtime_offset());
+ start_hifive(a0, __dtb_z_hifive_unleashed_a00_start + get_runtime_offset());
}
diff --git a/arch/riscv/boot/Makefile b/arch/riscv/boot/Makefile
index 968a826d16..80f63a4a0a 100644
--- a/arch/riscv/boot/Makefile
+++ b/arch/riscv/boot/Makefile
@@ -1,4 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
obj-y += start.o
pbl-y += entry.o uncompress.o
+pbl-y += nmon_entry.o
pbl-$(CONFIG_BOARD_GENERIC_DT) += board-dt-2nd.o
diff --git a/arch/riscv/boot/board-dt-2nd.c b/arch/riscv/boot/board-dt-2nd.c
index e9810f8add..f31c48a906 100644
--- a/arch/riscv/boot/board-dt-2nd.c
+++ b/arch/riscv/boot/board-dt-2nd.c
@@ -40,7 +40,7 @@ static const struct fdt_device_id console_ids[] = {
{ /* sentinel */ }
};
-ENTRY_FUNCTION(start_dt_2nd, a0, _fdt, a2)
+ENTRY_FUNCTION(start_dt_2nd, hartid, _fdt, a2)
{
unsigned long membase, memsize, endmem, endfdt, uncompressed_len;
struct fdt_header *fdt = (void *)_fdt;
@@ -73,5 +73,5 @@ ENTRY_FUNCTION(start_dt_2nd, a0, _fdt, a2)
_fdt < riscv_mem_stack_top(membase, endmem))
memsize = ALIGN_DOWN(_fdt - membase, SZ_1M);
- barebox_riscv_entry(membase, memsize, fdt);
+ barebox_riscv_supervisor_entry(membase, memsize, hartid, fdt);
}
diff --git a/arch/riscv/boot/entry.c b/arch/riscv/boot/entry.c
index eb286423d8..e4a5c2208d 100644
--- a/arch/riscv/boot/entry.c
+++ b/arch/riscv/boot/entry.c
@@ -20,10 +20,11 @@
*/
void __noreturn __naked barebox_riscv_entry(unsigned long membase,
- unsigned long memsize, void *boarddata)
+ unsigned long memsize, void *boarddata,
+ unsigned flags)
{
unsigned long stack_top = riscv_mem_stack_top(membase, membase + memsize);
asm volatile ("move sp, %0" : : "r"(stack_top));
- barebox_pbl_start(membase, memsize, boarddata);
+ barebox_pbl_start(membase, memsize, boarddata, flags);
}
diff --git a/arch/riscv/boot/entry.h b/arch/riscv/boot/entry.h
index b3a24d2783..fb4af5eae5 100644
--- a/arch/riscv/boot/entry.h
+++ b/arch/riscv/boot/entry.h
@@ -6,10 +6,12 @@
void __noreturn barebox_non_pbl_start(unsigned long membase,
unsigned long memsize,
- void *boarddata);
+ void *boarddata,
+ unsigned flags);
void __noreturn barebox_pbl_start(unsigned long membase,
unsigned long memsize,
- void *boarddata);
+ void *boarddata,
+ unsigned flags);
#endif
diff --git a/arch/riscv/boot/nmon_entry.S b/arch/riscv/boot/nmon_entry.S
new file mode 100644
index 0000000000..ae017d2a1c
--- /dev/null
+++ b/arch/riscv/boot/nmon_entry.S
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <linux/linkage.h>
+#include <asm/sections.h>
+
+#include "asm/debug_ll.h"
+#include "asm/riscv_nmon.h"
+
+.section .text_bare_init
+
+ENTRY(__barebox_nmon_entry)
+ riscv_nmon
+ ret
+ENDPROC(__barebox_nmon_entry)
diff --git a/arch/riscv/boot/start.c b/arch/riscv/boot/start.c
index 05f6c6231f..72ab93cb76 100644
--- a/arch/riscv/boot/start.c
+++ b/arch/riscv/boot/start.c
@@ -16,6 +16,7 @@
#include <uncompress.h>
#include <malloc.h>
#include <compressed-dtb.h>
+#include <asm/irq.h>
#include <debug_ll.h>
@@ -26,6 +27,7 @@ static unsigned long riscv_barebox_size;
static unsigned long riscv_endmem;
static void *barebox_boarddata;
static unsigned long barebox_boarddata_size;
+unsigned barebox_riscv_pbl_flags;
void *barebox_riscv_boot_dtb(void)
{
@@ -107,7 +109,8 @@ device_initcall(barebox_memory_areas_init);
* the pbl. The stack already has been set up by the pbl.
*/
__noreturn __no_sanitize_address __section(.text_entry)
-void barebox_non_pbl_start(unsigned long membase, unsigned long memsize, void *boarddata)
+void barebox_non_pbl_start(unsigned long membase, unsigned long memsize,
+ void *boarddata, unsigned flags)
{
unsigned long endmem = membase + memsize;
unsigned long malloc_start, malloc_end;
@@ -120,6 +123,8 @@ void barebox_non_pbl_start(unsigned long membase, unsigned long memsize, void *b
barrier();
+ irq_init_vector(__riscv_mode(flags));
+
pr_debug("memory at 0x%08lx, size 0x%08lx\n", membase, memsize);
riscv_endmem = endmem;
@@ -168,18 +173,20 @@ void barebox_non_pbl_start(unsigned long membase, unsigned long memsize, void *b
mem_malloc_init((void *)malloc_start, (void *)malloc_end - 1);
+ barebox_riscv_pbl_flags = flags;
+
pr_debug("starting barebox...\n");
start_barebox();
}
-void start(unsigned long membase, unsigned long memsize, void *boarddata);
+void start(unsigned long membase, unsigned long memsize, void *boarddata, unsigned flags);
/*
* First function in the uncompressed image. We get here from
* the pbl. The stack already has been set up by the pbl.
*/
void __no_sanitize_address __section(.text_entry) start(unsigned long membase,
- unsigned long memsize, void *boarddata)
+ unsigned long memsize, void *boarddata, unsigned flags)
{
- barebox_non_pbl_start(membase, memsize, boarddata);
+ barebox_non_pbl_start(membase, memsize, boarddata, flags);
}
diff --git a/arch/riscv/boot/uncompress.c b/arch/riscv/boot/uncompress.c
index b4e010998a..4ed9b4d371 100644
--- a/arch/riscv/boot/uncompress.c
+++ b/arch/riscv/boot/uncompress.c
@@ -14,6 +14,7 @@
#include <asm-generic/memory_layout.h>
#include <asm/sections.h>
#include <asm/unaligned.h>
+#include <asm/irq.h>
#include <debug_ll.h>
@@ -23,15 +24,17 @@ unsigned long free_mem_ptr;
unsigned long free_mem_end_ptr;
void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
- void *fdt)
+ void *fdt, unsigned flags)
{
uint32_t pg_len, uncompressed_len;
- void __noreturn (*barebox)(unsigned long, unsigned long, void *);
+ void __noreturn (*barebox)(unsigned long, unsigned long, void *, unsigned);
unsigned long endmem = membase + memsize;
unsigned long barebox_base;
void *pg_start, *pg_end;
unsigned long pc = get_pc();
+ irq_init_vector(__riscv_mode(flags));
+
/* piggy data is not relocated, so determine the bounds now */
pg_start = input_data + get_runtime_offset();
pg_end = input_data_end + get_runtime_offset();
@@ -63,9 +66,11 @@ void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
pbl_barebox_uncompress((void*)barebox_base, pg_start, pg_len);
+ sync_caches_for_execution();
+
barebox = (void *)barebox_base;
pr_debug("jumping to uncompressed image at 0x%p. dtb=0x%p\n", barebox, fdt);
- barebox(membase, memsize, fdt);
+ barebox(membase, memsize, fdt, flags);
}
diff --git a/arch/riscv/configs/starfive_defconfig b/arch/riscv/configs/starfive_defconfig
new file mode 100644
index 0000000000..c4df2256f5
--- /dev/null
+++ b/arch/riscv/configs/starfive_defconfig
@@ -0,0 +1,131 @@
+CONFIG_ARCH_RV64I=y
+CONFIG_SOC_STARFIVE=y
+CONFIG_BOARD_BEAGLEV=y
+CONFIG_BOARD_BEAGLEV_BETA=y
+CONFIG_BOARD_RISCV_GENERIC_DT=y
+CONFIG_RISCV_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_STACK_SIZE=0x20000
+CONFIG_MALLOC_SIZE=0x0
+CONFIG_MALLOC_TLSF=y
+CONFIG_KALLSYMS=y
+CONFIG_RELOCATABLE=y
+CONFIG_PANIC_HANG=y
+CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_MENU=y
+CONFIG_BOOTM_INITRD=y
+CONFIG_SYSTEM_PARTITIONS=y
+CONFIG_IMD_TARGET=y
+CONFIG_CONSOLE_ALLOW_COLOR=y
+CONFIG_PBL_CONSOLE=y
+CONFIG_PARTITION_DISK_EFI=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
+CONFIG_BAREBOXENV_TARGET=y
+CONFIG_BAREBOXCRC32_TARGET=y
+CONFIG_STATE=y
+CONFIG_STATE_CRYPTO=y
+CONFIG_BOOTCHOOSER=y
+CONFIG_RESET_SOURCE=y
+CONFIG_MACHINE_ID=y
+CONFIG_CMD_DMESG=y
+CONFIG_LONGHELP=y
+CONFIG_CMD_IOMEM=y
+CONFIG_CMD_IMD=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_POLLER=y
+CONFIG_CMD_SLICE=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_LOADY=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_BOOTCHOOSER=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_MAGICVAR=y
+CONFIG_CMD_MAGICVAR_HELP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_CMP=y
+CONFIG_CMD_FILETYPE=y
+CONFIG_CMD_LN=y
+CONFIG_CMD_MD5SUM=y
+CONFIG_CMD_SHA1SUM=y
+CONFIG_CMD_SHA256SUM=y
+CONFIG_CMD_UNCOMPRESS=y
+CONFIG_CMD_MSLEEP=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_MM=y
+CONFIG_CMD_CLK=y
+CONFIG_CMD_DETECT=y
+CONFIG_CMD_FLASH=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_POWEROFF=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_WD=y
+CONFIG_CMD_2048=y
+CONFIG_CMD_BAREBOX_UPDATE=y
+CONFIG_CMD_OF_DIFF=y
+CONFIG_CMD_OF_NODE=y
+CONFIG_CMD_OF_PROPERTY=y
+CONFIG_CMD_OF_DISPLAY_TIMINGS=y
+CONFIG_CMD_OF_FIXUP_STATUS=y
+CONFIG_CMD_OF_OVERLAY=y
+CONFIG_CMD_OFTREE=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_DHRYSTONE=y
+CONFIG_NET=y
+CONFIG_NET_NFS=y
+CONFIG_DRIVER_SERIAL_NS16550=y
+CONFIG_DRIVER_NET_DESIGNWARE=y
+CONFIG_DRIVER_NET_DESIGNWARE_GENERIC=y
+CONFIG_DRIVER_NET_DESIGNWARE_STARFIVE=y
+CONFIG_MICREL_PHY=y
+CONFIG_SPI_MEM=y
+CONFIG_DRIVER_SPI_GPIO=y
+CONFIG_MCI=y
+CONFIG_MCI_DW=y
+CONFIG_CLOCKSOURCE_DUMMY_RATE=60000
+CONFIG_SRAM=y
+CONFIG_STARFIVE_PWRSEQ=y
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_LED_GPIO_OF=y
+CONFIG_LED_TRIGGERS=y
+CONFIG_WATCHDOG=y
+CONFIG_STARFIVE_WDT=y
+CONFIG_HWRNG=y
+CONFIG_HW_RANDOM_STARFIVE=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+CONFIG_GPIO_STARFIVE=y
+CONFIG_PINCTRL_SINGLE=y
+CONFIG_NVMEM=y
+CONFIG_NVMEM_RMEM=y
+CONFIG_STARFIVE_OTP=y
+CONFIG_SYSCON_REBOOT_MODE=y
+CONFIG_NVMEM_REBOOT_MODE=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_POWER_RESET_SYSCON_POWEROFF=y
+CONFIG_POWER_RESET_GPIO=y
+CONFIG_POWER_RESET_GPIO_RESTART=y
+# CONFIG_VIRTIO_MENU is not set
+CONFIG_FS_EXT4=y
+CONFIG_FS_TFTP=y
+CONFIG_FS_NFS=y
+CONFIG_FS_FAT=y
+CONFIG_FS_FAT_WRITE=y
+CONFIG_FS_FAT_LFN=y
+CONFIG_FS_UIMAGEFS=y
+CONFIG_FS_PSTORE=y
+CONFIG_FS_SQUASHFS=y
+CONFIG_ZLIB=y
+CONFIG_BZLIB=y
+CONFIG_LZ4_DECOMPRESS=y
+CONFIG_ZSTD_DECOMPRESS=y
+CONFIG_XZ_DECOMPRESS=y
+CONFIG_BASE64=y
+CONFIG_DIGEST_CRC32_GENERIC=y
diff --git a/arch/riscv/cpu/Makefile b/arch/riscv/cpu/Makefile
index f1312be699..717baaaaa7 100644
--- a/arch/riscv/cpu/Makefile
+++ b/arch/riscv/cpu/Makefile
@@ -1,3 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
obj-y += core.o time.o
+obj-$(CONFIG_HAS_DMA) += dma.o
+obj-pbl-$(CONFIG_RISCV_M_MODE) += mtrap.o
+obj-pbl-$(CONFIG_RISCV_S_MODE) += strap.o
+obj-pbl-y += interrupts.o
diff --git a/arch/riscv/cpu/core.c b/arch/riscv/cpu/core.c
index 982d378edd..80730c05b5 100644
--- a/arch/riscv/cpu/core.c
+++ b/arch/riscv/cpu/core.c
@@ -18,7 +18,11 @@
#include <linux/clk.h>
#include <linux/err.h>
#include <memory.h>
+#include <asm/barebox-riscv.h>
#include <asm-generic/memory_layout.h>
+#include <globalvar.h>
+#include <magicvar.h>
+#include <asm/system.h>
#include <io.h>
static int riscv_request_stack(void)
@@ -30,6 +34,31 @@ coredevice_initcall(riscv_request_stack);
static struct device_d timer_dev;
+static s64 hartid;
+
+BAREBOX_MAGICVAR(global.hartid, "RISC-V hartid");
+
+static int riscv_fixup_cpus(struct device_node *root, void *context)
+{
+ struct device_node *cpus_node, *np, *tmp;
+
+ cpus_node = of_find_node_by_name(root, "cpus");
+ if (!cpus_node)
+ return 0;
+
+ for_each_child_of_node_safe(cpus_node, tmp, np) {
+ u32 cpu_index;
+
+ if (of_property_read_u32(np, "reg", &cpu_index))
+ continue;
+
+ if (cpu_index != hartid)
+ of_delete_node(np);
+ }
+
+ return 0;
+}
+
static int riscv_probe(struct device_d *parent)
{
int ret;
@@ -46,7 +75,11 @@ static int riscv_probe(struct device_d *parent)
return ret;
}
- return 0;
+ hartid = riscv_hartid();
+ if (hartid >= 0)
+ globalvar_add_simple_uint64("hartid", &hartid, "%llu");
+
+ return of_register_fixup(riscv_fixup_cpus, NULL);
}
static struct of_device_id riscv_dt_ids[] = {
@@ -60,3 +93,9 @@ static struct driver_d riscv_driver = {
.of_compatible = riscv_dt_ids,
};
postcore_platform_driver(riscv_driver);
+
+static void arch_shutdown(void)
+{
+ sync_caches_for_execution();
+}
+archshutdown_exitcall(arch_shutdown);
diff --git a/arch/riscv/cpu/dma.c b/arch/riscv/cpu/dma.c
new file mode 100644
index 0000000000..5a4d714e5e
--- /dev/null
+++ b/arch/riscv/cpu/dma.c
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <common.h>
+#include <xfuncs.h>
+#include <asm/dma.h>
+#include <malloc.h>
+
+static void __dma_flush_range(dma_addr_t start, dma_addr_t end)
+{
+}
+
+static void *__dma_alloc_coherent(size_t size, dma_addr_t *dma_handle)
+{
+ void *ret;
+
+ ret = xmemalign(PAGE_SIZE, size);
+
+ memset(ret, 0, size);
+
+ if (dma_handle)
+ *dma_handle = (dma_addr_t)ret;
+
+ return ret;
+}
+
+static void __dma_free_coherent(void *vaddr, dma_addr_t dma_handle, size_t size)
+{
+ free(vaddr);
+}
+
+static const struct dma_ops coherent_dma_ops = {
+ .alloc_coherent = __dma_alloc_coherent,
+ .free_coherent = __dma_free_coherent,
+ .flush_range = __dma_flush_range,
+ .inv_range = __dma_flush_range,
+};
+
+static const struct dma_ops *dma_ops = &coherent_dma_ops;
+
+void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle)
+{
+ return dma_ops->alloc_coherent(size, dma_handle);
+}
+
+void dma_free_coherent(void *vaddr, dma_addr_t dma_handle, size_t size)
+{
+ dma_ops->free_coherent(vaddr, dma_handle, size);
+}
+
+void dma_set_ops(const struct dma_ops *ops)
+{
+ dma_ops = ops;
+}
+
+void dma_sync_single_for_cpu(dma_addr_t address, size_t size, enum dma_data_direction dir)
+{
+ /*
+ * FIXME: This function needs a device argument to support non 1:1 mappings
+ */
+ if (dir != DMA_TO_DEVICE)
+ dma_ops->inv_range(address, address + size);
+}
+
+void dma_sync_single_for_device(dma_addr_t address, size_t size, enum dma_data_direction dir)
+{
+ /*
+ * FIXME: This function needs a device argument to support non 1:1 mappings
+ */
+
+ if (dir == DMA_FROM_DEVICE)
+ dma_ops->inv_range(address, address + size);
+ else
+ dma_ops->flush_range(address, address + size);
+}
diff --git a/arch/riscv/cpu/interrupts.c b/arch/riscv/cpu/interrupts.c
new file mode 100644
index 0000000000..0e8951b619
--- /dev/null
+++ b/arch/riscv/cpu/interrupts.c
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2016-17 Microsemi Corporation.
+ * Padmarao Begari, Microsemi Corporation <padmarao.begari@microsemi.com>
+ *
+ * Copyright (C) 2017 Andes Technology Corporation
+ * Rick Chen, Andes Technology Corporation <rick@andestech.com>
+ *
+ * Copyright (C) 2019 Sean Anderson <seanga2@gmail.com>
+ */
+
+#include <common.h>
+#include <asm/system.h>
+#include <asm/ptrace.h>
+#include <asm/irq.h>
+#include <asm/csr.h>
+#include <abort.h>
+#include <pbl.h>
+
+#define MCAUSE32_INT 0x80000000
+#define MCAUSE64_INT 0x8000000000000000
+
+#ifdef CONFIG_64BIT
+# define MCAUSE_INT MCAUSE64_INT
+#else
+# define MCAUSE_INT MCAUSE32_INT
+#endif
+
+static void show_regs(const struct pt_regs *regs)
+{
+ printf("\nsp: " REG_FMT " gp: " REG_FMT " tp: " REG_FMT "\n",
+ regs->sp, regs->gp, regs->tp);
+ printf("t0: " REG_FMT " t1: " REG_FMT " t2: " REG_FMT "\n",
+ regs->t0, regs->t1, regs->t2);
+ printf("s0: " REG_FMT " s1: " REG_FMT " a0: " REG_FMT "\n",
+ regs->s0, regs->s1, regs->a0);
+ printf("a1: " REG_FMT " a2: " REG_FMT " a3: " REG_FMT "\n",
+ regs->a1, regs->a2, regs->a3);
+ printf("a4: " REG_FMT " a5: " REG_FMT " a6: " REG_FMT "\n",
+ regs->a4, regs->a5, regs->a6);
+ printf("a7: " REG_FMT " s2: " REG_FMT " s3: " REG_FMT "\n",
+ regs->a7, regs->s2, regs->s3);
+ printf("s4: " REG_FMT " s5: " REG_FMT " s6: " REG_FMT "\n",
+ regs->s4, regs->s5, regs->s6);
+ printf("s7: " REG_FMT " s8: " REG_FMT " s9: " REG_FMT "\n",
+ regs->s7, regs->s8, regs->s9);
+ printf("s10: " REG_FMT " s11: " REG_FMT " t3: " REG_FMT "\n",
+ regs->s10, regs->s11, regs->t3);
+ printf("t4: " REG_FMT " t5: " REG_FMT " t6: " REG_FMT "\n",
+ regs->t4, regs->t5, regs->t6);
+}
+
+static void report_trap(const struct pt_regs *regs)
+{
+ static const char * const exception_code[] = {
+ [0] = "Instruction address misaligned",
+ [1] = "Instruction access fault",
+ [2] = "Illegal instruction",
+ [3] = "Breakpoint",
+ [4] = "Load address misaligned",
+ [5] = "Load access fault",
+ [6] = "Store/AMO address misaligned",
+ [7] = "Store/AMO access fault",
+ [8] = "Environment call from U-mode",
+ [9] = "Environment call from S-mode",
+ [10] = "Reserved",
+ [11] = "Environment call from M-mode",
+ [12] = "Instruction page fault",
+ [13] = "Load page fault",
+ [14] = "Reserved",
+ [15] = "Store/AMO page fault",
+
+ };
+
+ printf("Unhandled exception: %ld", regs->cause);
+
+ if (regs->cause < ARRAY_SIZE(exception_code))
+ printf(" \"%s\"\n", exception_code[regs->cause]);
+
+ printf("E [<" REG_FMT ">] ra: [<" REG_FMT ">] tval: " REG_FMT "\n",
+ regs->epc, regs->ra, regs->badaddr);
+
+ show_regs(regs);
+}
+
+
+
+#ifdef __PBL__
+
+static inline bool skip_data_abort(struct pt_regs *regs)
+{
+ return false;
+}
+
+#else
+
+static volatile bool riscv_data_abort_occurred;
+static volatile bool riscv_ignore_data_abort;
+
+void data_abort_mask(void)
+{
+ riscv_data_abort_occurred = false;
+ riscv_ignore_data_abort = true;
+}
+
+int data_abort_unmask(void)
+{
+ riscv_ignore_data_abort = false;
+ return riscv_data_abort_occurred;
+}
+
+static inline bool skip_data_abort(struct pt_regs *regs)
+{
+ return regs->cause == EXC_LOAD_ACCESS && riscv_ignore_data_abort;
+}
+
+#endif
+
+unsigned long handle_trap(struct pt_regs *regs)
+{
+ if (skip_data_abort(regs))
+ goto skip;
+
+ if (regs->cause == 2) { /* illegal instruction */
+ switch(*(unsigned long *)regs->epc) {
+ case 0x0000100f: /* fence.i */
+ goto skip;
+ default:
+ break;
+ }
+ }
+
+ report_trap(regs);
+ hang();
+
+skip:
+ return regs->epc + 4;
+}
+
diff --git a/arch/riscv/cpu/mtrap.S b/arch/riscv/cpu/mtrap.S
new file mode 100644
index 0000000000..e4aba7d694
--- /dev/null
+++ b/arch/riscv/cpu/mtrap.S
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 FORTH-ICS/CARV
+ * Nick Kossifidis <mick@ics.forth.gr>
+ */
+
+#include <asm/asm.h>
+#include <asm/irq.h>
+#include <linux/linkage.h>
+
+.section .text.mtrap_entry
+ENTRY(mtrap_entry)
+ addi sp, sp, -PT_SIZE_ON_STACK
+ pt_regs_push sp
+ csrr t1, mstatus
+ csrr t2, mepc
+ csrr t3, mtval
+ csrr t4, mcause
+
+ REG_S t1, PT_STATUS(sp)
+ REG_S t2, PT_EPC(sp)
+ REG_S t3, PT_BADADDR(sp)
+ REG_S t4, PT_CAUSE(sp)
+ mv a0, sp
+ jal handle_trap
+ csrw mepc, a0
+ pt_regs_pop sp
+ addi sp, sp, PT_SIZE_ON_STACK
+ mret
+ENDPROC(mtrap_entry)
diff --git a/arch/riscv/cpu/strap.S b/arch/riscv/cpu/strap.S
new file mode 100644
index 0000000000..c1d684c194
--- /dev/null
+++ b/arch/riscv/cpu/strap.S
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 FORTH-ICS/CARV
+ * Nick Kossifidis <mick@ics.forth.gr>
+ */
+
+#include <asm/asm.h>
+#include <asm/irq.h>
+#include <linux/linkage.h>
+
+.section .text.strap_entry
+ENTRY(strap_entry)
+ addi sp, sp, -PT_SIZE_ON_STACK
+ pt_regs_push sp
+ csrr t1, sstatus
+ csrr t2, sepc
+ csrr t3, stval
+ csrr t4, scause
+
+ REG_S t1, PT_STATUS(sp)
+ REG_S t2, PT_EPC(sp)
+ REG_S t3, PT_BADADDR(sp)
+ REG_S t4, PT_CAUSE(sp)
+ mv a0, sp
+ jal handle_trap
+ csrw sepc, a0
+ pt_regs_pop sp
+ addi sp, sp, PT_SIZE_ON_STACK
+ sret
+ENDPROC(strap_entry)
diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile
index 17fdc9445b..4a15423b7f 100644
--- a/arch/riscv/dts/Makefile
+++ b/arch/riscv/dts/Makefile
@@ -7,5 +7,6 @@ obj- += dummy.o
pbl-$(CONFIG_BOARD_ERIZO_GENERIC) += erizo-generic.dtb.o
pbl-$(CONFIG_BOARD_HIFIVE) += hifive-unmatched-a00.dtb.o \
hifive-unleashed-a00.dtb.o
+pbl-$(CONFIG_BOARD_BEAGLEV) += jh7100-beaglev-starlight.dtb.o
clean-files := *.dtb *.dtb.S .*.dtc .*.pre .*.dts
diff --git a/arch/riscv/dts/jh7100-beaglev-starlight.dts b/arch/riscv/dts/jh7100-beaglev-starlight.dts
new file mode 100644
index 0000000000..8b4c1ac0ea
--- /dev/null
+++ b/arch/riscv/dts/jh7100-beaglev-starlight.dts
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/dts-v1/;
+
+#include "jh7100-beaglev-starlight.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "beagle,beaglev-starlight-jh7100", "starfive,jh7100";
+ model = "BeagleV Starlight Beta";
+
+ aliases {
+ serial0 = &uart3;
+ serial1 = &uart0;
+ };
+
+ chosen {
+ environment {
+ compatible = "barebox,environment";
+ device-path = &qpsi_env;
+ status = "disabled"; /* QSPI writes don't work yet */
+ };
+ };
+};
+
+&nor_flash {
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "secondboot";
+ reg = <0x0 0x10000>;
+ };
+
+ partition@10000 {
+ label = "ddrinit";
+ reg = <0x10000 0x10000>;
+ };
+
+ partition@20000 {
+ label = "sbi";
+ reg = <0x20000 0x1e0000>;
+ };
+
+ qpsi_env: partition@200000 {
+ label = "environment";
+ reg = <0x200000 0x1e00000>;
+ };
+ };
+};
diff --git a/arch/riscv/dts/jh7100-beaglev-starlight.dtsi b/arch/riscv/dts/jh7100-beaglev-starlight.dtsi
new file mode 100644
index 0000000000..13238f087f
--- /dev/null
+++ b/arch/riscv/dts/jh7100-beaglev-starlight.dtsi
@@ -0,0 +1,369 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include "jh7100.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "beagle,beaglev-starlight-jh7100", "starfive,jh7100";
+ model = "BeagleV Starlight Beta";
+
+ aliases {
+ serial0 = &uart3;
+ serial1 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200";
+ };
+
+ cpus {
+ timebase-frequency = <6250000>;
+ };
+
+ gpiopof: gpio-poweroff {
+ compatible = "gpio-poweroff";
+ gpios = <&gpio 63 GPIO_ACTIVE_HIGH>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ label = "beaglev:green:ack";
+ gpios = <&gpio 43 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0x2 0x0>;
+ };
+
+ memory@3000000000 {
+ device_type = "memory";
+ reg = <0x30 0x0 0x0 0x0>;
+ };
+};
+
+&gmac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rgmii>;
+ phy-mode = "rgmii-txid";
+ nvmem-cell-names = "mac-address";
+ nvmem-cells = <&ethaddr>;
+};
+
+&gpio {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio>;
+};
+
+&sdio0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sdio0>;
+ bus-width = <4>;
+ cap-sd-highspeed;
+ broken-cd;
+ no-sdio;
+ status = "okay";
+};
+
+&sdio1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sdio1>;
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart0>;
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&usb3 {
+ dr_mode = "host";
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0>;
+ status = "okay";
+
+ imx219@10 {
+ compatible = "imx219";
+ reg = <0x10>;
+ reset-gpio = <&gpio 58 0>;
+ };
+
+ tps65086@5e {
+ compatible = "ti,tps65086";
+ reg = <0x5e>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ tda998x@70 {
+ compatible = "nxp,tda998x";
+ reg = <0x70>;
+ };
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ seeed_plane_i2c@45 {
+ compatible = "seeed_panel";
+ reg = <0x45>;
+ };
+};
+
+&qspi {
+ nor_flash: nor-flash@0 {
+ compatible = "spi-flash";
+ reg = <0>;
+ spi-max-frequency = <31250000>;
+ cdns,page-size = <256>;
+ cdns,block-size = <16>;
+ cdns,read-delay = <4>;
+ cdns,tshsl-ns = <1>;
+ cdns,tsd2d-ns = <1>;
+ cdns,tchsh-ns = <1>;
+ cdns,tslch-ns = <1>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <1>;
+ };
+};
+
+&spi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi2>;
+ status = "okay";
+
+ spi_dev0: spi@0 {
+ compatible = "rohm,dh2228fv";
+ spi-max-frequency = <10000000>;
+ reg = <0>;
+ status = "okay";
+ };
+};
+
+&qspi {
+ status = "okay";
+};
+
+&spi2 {
+ status = "okay";
+};
+
+&otp {
+ power-gpios = <&gpio 56 GPIO_ACTIVE_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ethaddr: ethaddr@28 {
+ reg = <0x28 6>;
+ label = "mac-address";
+ };
+};
+
+&gpio {
+ pinctrl_uart0: uart0_pins {
+ pinctrl-single,pins = <
+ 0x358 0x2a /* GPIO40: uart0_pad_sin */
+ 0x194 0x1 /* GPIO40: doen_HIGH */
+ 0x198 0x7f /* GPIO41: dout_uart0_pad_sout */
+ 0x19c 0x0 /* GPIO41: doen_LOW */
+ 0x1a0 0x7e /* GPIO42: dout_uart0_pad_rtsn */
+ 0x1a4 0x0 /* GPIO42: doen_LOW */
+ 0x348 0x29 /* GPIO39: uart0_pad_ctsn */
+ 0x18c 0x1 /* GPIO39: doen_HIGH */
+ 0x16c 0x0 /* GPIO35: doen_LOW */
+ 0x168 0x1 /* GPIO35: dout_HIGH */
+ >;
+ };
+
+ pinctrl_i2c0: i2c0_pins {
+ pinctrl-single,pins = <
+ 0x240 0x0 /* GPIO62: dout_LOW */
+ 0x238 0x0 /* GPIO61: dout_LOW */
+ 0x244 0x80000008 /* GPIO62: doen_i2c0_pad_sck_oe
+ doen_reverse_(1) */
+ 0x23c 0x80000009 /* GPIO61: doen_i2c0_pad_sda_oe
+ doen_reverse_(1) */
+ 0x278 0x40 /* GPIO62: i2c0_pad_sck_in */
+ 0x27c 0x3f /* GPIO61: i2c0_pad_sda_in */
+ >;
+ };
+
+ pinctrl_i2c1: i2c1_pins {
+ pinctrl-single,pins = <
+ 0x1c8 0x0 /* GPIO47: dout_LOW */
+ 0x1d0 0x0 /* GPIO48: dout_LOW */
+ 0x1cc 0x8000000a /* GPIO47: doen_i2c1_pad_sck_oe
+ doen_reverse_(1) */
+ 0x1d4 0x8000000b /* GPIO48: doen_i2c1_pad_sda_oe
+ doen_reverse_(1) */
+ 0x280 0x31 /* GPIO47: i2c1_pad_sck_in */
+ 0x284 0x32 /* GPIO48: i2c1_pad_sda_in */
+ >;
+ };
+
+ pinctrl_i2c2: i2c2_pins {
+ pinctrl-single,pins = <
+ 0x230 0x0 /* GPIO60: dout_LOW */
+ 0x228 0x0 /* GPIO59: dout_LOW */
+ 0x234 0x8000000c /* GPIO60: doen_i2c2_pad_sck_oe
+ doen_reverse_(1) */
+ 0x22c 0x8000000d /* GPIO59: doen_i2c2_pad_sda_oe
+ doen_reverse_(1) */
+ 0x288 0x3e /* GPIO60: i2c2_pad_sck_in */
+ 0x28c 0x3d /* GPIO59: i2c2_pad_sda_in */
+ >;
+ };
+
+ pinctrl_spi2: spi2_pins {
+ pinctrl-single,pins = <
+ /* MISO */
+ 0xa8 0x6f /* GPIO11: dout_spi2_pad_txd */
+ 0xac 0x0 /* GPIO11: doen_LOW */
+ /* MOSI */
+ 0x320 0xe /* GPIO12: spi2_pad_rxd */
+ 0xb4 0x1 /* GPIO12: doen_HIGH */
+ /* SCLK */
+ 0xe0 0x6c /* GPIO18: dout_spi2_pad_sck_out */
+ 0xe4 0x0 /* GPIO18: doen_LOW */
+ /* CS */
+ 0xe8 0x6d /* GPIO19: dout_spi2_pad_ss_0_n */
+ 0xec 0x0 /* GPIO19: doen_LOW */
+ >;
+
+ };
+
+ pinctrl_sdio0: sdio0_pins {
+ pinctrl-single,pins = <
+ 0x2b4 0x39 /* GPIO55: sdio0_pad_card_detect_n */
+ 0x20c 0x1 /* GPIO55: doen_HIGH */
+ 0x200 0x36 /* GPIO54: dout_sdio0_pad_cclk_out */
+ 0x204 0x0 /* GPIO54: doen_LOW */
+ 0x1fc 0x80000037 /* GPIO53: doen_sdio0_pad_ccmd_oe
+ doen_reverse_(1) */
+ 0x1f8 0x38 /* GPIO53: dout_sdio0_pad_ccmd_out */
+ 0x2bc 0x37 /* GPIO53: _sdio0_pad_ccmd_in */
+ 0x1dc 0x80000039 /* GPIO49: doen_sdio0_pad_cdata_oe_bit0
+ doen_reverse_(1) */
+ 0x1d8 0x41 /* GPIO49: dout_sdio0_pad_cdata_out_bit0 */
+ 0x2c0 0x33 /* GPIO49: sdio0_pad_cdata_in_bit0 */
+ 0x1e4 0x8000003a /* GPIO50: doen_sdio0_pad_cdata_oe_bit1
+ doen_reverse_(1) */
+ 0x1e0 0x42 /* GPIO50: dout_sdio0_pad_cdata_out_bit1 */
+ 0x2c4 0x34 /* GPIO50: sdio0_pad_cdata_in_bit1 */
+ 0x1ec 0x8000003b /* GPIO51: doen_sdio0_pad_cdata_oe_bit2
+ doen_reverse_(1) */
+ 0x1e8 0x43 /* GPIO51: dout_sdio0_pad_cdata_out_bit2 */
+ 0x2c8 0x35 /* GPIO51: sdio0_pad_cdata_in_bit2 */
+ 0x1f4 0x8000003c /* GPIO52: doen_sdio0_pad_cdata_oe_bit3
+ doen_reverse_(1) */
+ 0x1f0 0x44 /* GPIO52: dout_sdio0_pad_cdata_out_bit3 */
+ 0x2cc 0x36 /* GPIO52: sdio0_pad_cdata_in_bit3(52) */
+ >;
+ };
+
+ pinctrl_sdio1: sdio1_pins {
+ pinctrl-single,pins = <
+ 0x158 0x4b /* GPIO33: dout_sdio1_pad_cclk_out */
+ 0x15c 0x0 /* GPIO33: doen_LOW */
+ 0x13c 0x8000004c /* GPIO29: doen_sdio1_pad_ccmd_oe
+ doen_reverse_(1) */
+ 0x138 0x4d /* GPIO29: dout_sdio1_pad_ccmd_out */
+ 0x2e8 0x1f /* GPIO29: sdio1_pad_ccmd_in */
+ 0x174 0x8000004e /* GPIO36: doen_sdio1_pad_cdata_oe_bit0
+ doen_reverse_(1) */
+ 0x170 0x56 /* GPIO36: dout_sdio1_pad_cdata_out_bit0 */
+ 0x2ec 0x26 /* GPIO36: sdio1_pad_cdata_in_bit0 */
+ 0x144 0x8000004f /* GPIO30: doen_sdio1_pad_cdata_oe_bit1
+ doen_reverse_(1) */
+ 0x140 0x57 /* GPIO30: dout_sdio1_pad_cdata_out_bit1 */
+ 0x2f0 0x20 /* GPIO30: sdio1_pad_cdata_in_bit1 */
+ 0x164 0x80000050 /* GPIO34: doen_sdio1_pad_cdata_oe_bit2
+ doen_reverse_(1) */
+ 0x160 0x58 /* GPIO34: dout_sdio1_pad_cdata_out_bit2 */
+ 0x2f4 0x24 /* GPIO34: sdio1_pad_cdata_in_bit2 */
+ 0x14c 0x80000051 /* GPIO31: doen_sdio1_pad_cdata_oe_bit3
+ doen_reverse_(1) */
+ 0x148 0x59 /* GPIO31: dout_sdio1_pad_cdata_out_bit3 */
+ 0x2f8 0x21 /* GPIO31: sdio1_pad_cdata_in_bit3 */
+ >;
+ };
+};
+
+&pinconf {
+ pinctrl_rgmii: rgmii_pins {
+ pinctrl-single,pins = <
+ 0x164 0xC30080
+ 0x168 0x30080
+
+ 0x16c 0x30003
+ 0x170 0x30003
+ 0x174 0x30003
+ 0x178 0x30003
+
+ 0x17c 0xC800003
+
+ 0x180 0x8000C0
+ 0x184 0xC000C0
+ 0x188 0xC000C0
+ 0x18c 0xC000C0
+ 0x190 0xC000C0
+ 0x194 0xC000C0
+ 0x198 0xC000C0
+ >;
+ };
+
+ /* Force most pins to input. Taken from vendor's sys_funcshare_io_input_en */
+ pinctrl_gpio: gpio_pins {
+ pinctrl-single,pins = <
+ 0x80 0xc000c0 /* gpio0 */
+ 0x90 0xc000c0 /* gpio8-9 */
+ 0x94 0xc000c0 /* gpio10-11 */
+ 0x98 0xc000c0 /* gpio12 */
+ 0xa0 0xc000c0 /* gpio16-17 */
+ 0xa4 0xc000c0 /* gpio18-19 */
+ 0xa8 0xc000c0 /* gpio20-21 */
+ 0xac 0xc000c0 /* gpio22-23 */
+ 0xb0 0xc000c0 /* gpio24-25 */
+ 0xb4 0xc000c0 /* gpio26-27 */
+ 0xb8 0xc000c0 /* gpio28-29 */
+ 0xbc 0xc000c0 /* gpio30-31 */
+ 0xc0 0xc000c0 /* gpio32-33 */
+ 0xc4 0xc000c0 /* gpio34-35 */
+ 0xcc 0xc000c0 /* gpio38-39 */
+ 0xd0 0xc000c0 /* gpio40-41 */
+ 0xd4 0xc000c0 /* gpio42-43 */
+ 0xd8 0xc000c0 /* gpio44-45 */
+ 0xdc 0xc000c0 /* gpio46-47 */
+ 0xe0 0xc000c0 /* gpio48-49 */
+ 0xe4 0xc000c0 /* gpio50-51 */
+ 0xe8 0xc000c0 /* gpio52-53 */
+ 0xec 0xc000c0 /* gpio54-55 */
+ 0xf0 0xc000c0 /* gpio56-57 */
+ 0xf4 0xc000c0 /* gpio58-59 */
+ 0xf8 0xc000c0 /* gpio60-61 */
+ 0xfc 0xc000c0 /* gpio62-63 */
+ >;
+ };
+};
diff --git a/arch/riscv/dts/jh7100.dtsi b/arch/riscv/dts/jh7100.dtsi
new file mode 100644
index 0000000000..e3990582af
--- /dev/null
+++ b/arch/riscv/dts/jh7100.dtsi
@@ -0,0 +1,798 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <dt-bindings/reset-controller/starfive-jh7100.h>
+#include <dt-bindings/clock/starfive-jh7100.h>
+
+/ {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "starfive,jh7100";
+
+ aliases {
+ spi0 = &qspi;
+ mmc0 = &sdio0;
+ mmc1 = &sdio1;
+ usb0 = &usb3;
+ };
+
+ chosen {
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu@0 {
+ compatible = "sifive,u74-mc", "riscv";
+ d-cache-block-size = <64>;
+ d-cache-sets = <64>;
+ d-cache-size = <32768>;
+ d-tlb-sets = <1>;
+ d-tlb-size = <32>;
+ device_type = "cpu";
+ i-cache-block-size = <64>;
+ i-cache-sets = <64>;
+ i-cache-size = <32768>;
+ i-tlb-sets = <1>;
+ i-tlb-size = <32>;
+ mmu-type = "riscv,sv39";
+ next-level-cache = <&ccache>;
+ reg = <0>;
+ riscv,isa = "rv64imafdc";
+ starfive,itim = <&itim0>;
+ status = "okay";
+ tlb-split;
+ cpu0_intc: interrupt-controller {
+ #interrupt-cells = <1>;
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ };
+ };
+
+ cpu@1 {
+ compatible = "sifive,u74-mc", "riscv";
+ d-cache-block-size = <64>;
+ d-cache-sets = <64>;
+ d-cache-size = <32768>;
+ d-tlb-sets = <1>;
+ d-tlb-size = <32>;
+ device_type = "cpu";
+ i-cache-block-size = <64>;
+ i-cache-sets = <64>;
+ i-cache-size = <32768>;
+ i-tlb-sets = <1>;
+ i-tlb-size = <32>;
+ mmu-type = "riscv,sv39";
+ next-level-cache = <&ccache>;
+ reg = <1>;
+ riscv,isa = "rv64imafdc";
+ starfive,itim = <&itim1>;
+ status = "okay";
+ tlb-split;
+ cpu1_intc: interrupt-controller {
+ #interrupt-cells = <1>;
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ };
+ };
+ };
+
+ osc_sys: clock-osc-sys {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ clock-output-names = "osc_sys";
+ };
+
+ osc_aud: clock-osc-audio {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <27000000>;
+ clock-output-names = "osc_aud";
+ };
+
+ i2c0clk: i2c0clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <49500000>;
+ clock-output-names = "i2c0clk";
+ };
+
+ i2c2clk: i2c2clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <49500000>;
+ clock-output-names = "i2c2clk";
+ };
+
+ axiclk: axiclk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <500000000>;
+ clock-output-names = "axiclk";
+ };
+
+ ahb0clk: ahb0clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <250000000>;
+ };
+
+ apb1clk: apb1clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <125000000>;
+ };
+
+ apb2clk: apb2clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <125000000>;
+ };
+
+ jpuclk: jpuclk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <333333333>;
+ };
+
+ vpuclk: vpuclk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <400000000>;
+ };
+
+ qspi_clk: qspi-clk@0 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <50000000>;
+ };
+
+ uartclk: uartclk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <100000000>;
+ };
+
+ hs_uartclk: hs_uartclk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <74250000>;
+ };
+
+ spiclk: spiclk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <50000000>;
+ };
+
+ pwmclk: pwmclk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <125000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0x0 0x28000000>;
+ alignment = <0x0 0x1000>;
+ alloc-ranges = <0x0 0xa0000000 0x0 0x28000000>;
+ linux,cma-default;
+ };
+
+ jpu_reserved: framebuffer@c9000000 {
+ reg = <0x0 0xc9000000 0x0 0x4000000>;
+ };
+
+ nvdla_reserved:framebuffer@d0000000 {
+ reg = <0x0 0xd0000000 0x0 0x28000000>;
+ };
+
+ vin_reserved: framebuffer@f9000000 {
+ compatible = "shared-dma-pool";
+ no-map;
+ reg = <0x0 0xf9000000 0x0 0x1000000>;
+ };
+
+ sffb_reserved: framebuffer@fb000000 {
+ compatible = "shared-dma-pool";
+ no-map;
+ reg = <0x0 0xfb000000 0x0 0x2000000>;
+ };
+ };
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ #clock-cells = <1>;
+ compatible = "simple-bus";
+ ranges;
+
+ intram0: sram@18000000 {
+ compatible = "mmio-sram";
+ reg = <0x0 0x18000000 0x0 0x20000>;
+ };
+
+ intram1: sram@18080000 {
+ compatible = "mmio-sram";
+ reg = <0x0 0x18080000 0x0 0x8000>;
+ };
+
+ ccache: cache-controller@2010000 {
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-sets = <2048>;
+ cache-size = <2097152>;
+ cache-unified;
+ compatible = "sifive,fu540-c000-ccache", "starfive,ccache0", "cache";
+ interrupt-parent = <&plic>;
+ interrupts = <128 131 129 130>;
+ /*next-level-cache = <&L40 &L36>;*/
+ reg = <0x0 0x2010000 0x0 0x1000 0x0 0x8000000 0x0 0x2000000>;
+ reg-names = "control", "sideband";
+ };
+
+ dtim: dtim@1000000 {
+ compatible = "starfive,dtim0";
+ reg = <0x0 0x1000000 0x0 0x2000>;
+ reg-names = "mem";
+ };
+
+ itim0: itim@1808000 {
+ compatible = "starfive,itim0";
+ reg = <0x0 0x1808000 0x0 0x8000>;
+ reg-names = "mem";
+ };
+
+ itim1: itim@1820000 {
+ compatible = "starfive,itim0";
+ reg = <0x0 0x1820000 0x0 0x8000>;
+ reg-names = "mem";
+ };
+
+ clint: clint@2000000 {
+ #interrupt-cells = <1>;
+ compatible = "riscv,clint0";
+ interrupts-extended = <&cpu0_intc 3 &cpu0_intc 7 &cpu1_intc 3 &cpu1_intc 7>;
+ reg = <0x0 0x2000000 0x0 0x10000>;
+ reg-names = "control";
+ };
+
+ plic: plic@c000000 {
+ #interrupt-cells = <1>;
+ compatible = "riscv,plic0";
+ interrupt-controller;
+ interrupts-extended = <&cpu0_intc 11 &cpu0_intc 9 &cpu1_intc 11 &cpu1_intc 9>;
+ reg = <0x0 0xc000000 0x0 0x4000000>;
+ reg-names = "control";
+ riscv,max-priority = <7>;
+ riscv,ndev = <127>;
+ };
+
+ sysmain: syscon@11850000 {
+ compatible = "syscon";
+ reg = <0x0 0x11850000 0x0 0x4000>;
+ };
+
+ pinconf: pinctrl@11858000 {
+ compatible = "pinctrl-single";
+ reg = <0x0 0x11858000 0x0 0x4000>;
+ #pinctrl-cells = <1>;
+ pinctrl-single,register-width = <32>;
+ pinctrl-single,function-mask = <0xffffffff>;
+ };
+
+ uart0: hs_serial@11870000 {
+ compatible = "snps,dw-apb-uart";
+ interrupt-parent = <&plic>;
+ interrupts = <92>;
+ reg = <0x0 0x11870000 0x0 0x10000>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ clocks = <&hs_uartclk>, <&apb1clk>;
+ clock-names = "baudclk", "apb_pclk";
+ current-clock = <74250000>;
+ current-speed = <115200>;
+ status = "disabled";
+ };
+
+ uart1: hs_serial@11880000 {
+ compatible = "snps,dw-apb-uart";
+ interrupt-parent = <&plic>;
+ interrupts = <93>;
+ reg = <0x0 0x11880000 0x0 0x10000>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ clocks = <&hs_uartclk>, <&apb1clk>;
+ clock-names = "baudclk", "apb_pclk";
+ current-clock = <74250000>;
+ current-speed = <115200>;
+ status = "disabled";
+ };
+
+ uart2: serial@12430000 {
+ compatible = "snps,dw-apb-uart";
+ interrupt-parent = <&plic>;
+ interrupts = <72>;
+ reg = <0x0 0x12430000 0x0 0x10000>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ clocks = <&uartclk>, <&apb2clk>;
+ clock-names = "baudclk", "apb_pclk";
+ current-clock = <100000000>;
+ current-speed = <115200>;
+ status = "disabled";
+ };
+
+ uart3: serial@12440000 {
+ compatible = "snps,dw-apb-uart", "starfive,uart0";
+ interrupt-parent = <&plic>;
+ interrupts = <73>;
+ reg = <0x0 0x12440000 0x0 0x10000>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ clocks = <&uartclk>, <&apb2clk>;
+ clock-names = "baudclk", "apb_pclk";
+ current-clock = <100000000>;
+ current-speed = <115200>;
+ status = "disabled";
+ };
+
+ nne50: nne@10800000 {
+ compatible = "starfive,nne50";
+ reg = <0x0 0x10800000 0x0 0x10000>;
+ resets = <&rstgen RSTN_DLA_AXI>,
+ <&rstgen RSTN_DLANOC_AXI>,
+ <&rstgen RSTN_DLA_APB>,
+ <&rstgen RSTN_NNENOC_AXI>,
+ <&rstgen RSTN_DLASLV_AXI>;
+
+ assigned-clocks = <&clkgen CLK_NNE_BUS>;
+ assigned-clocks-parents = <&clkgen CLK_CPU_AXI>;
+ status = "okay";
+ };
+
+ dma2p: sgdma2p@100b0000 {
+ compatible = "starfive,axi-dma", "snps,axi-dma-1.01a";
+ reg = <0x0 0x100b0000 0x0 0x10000>;
+ clocks = <&axiclk>, <&ahb0clk>;
+ clock-names = "core-clk", "cfgr-clk";
+ resets = <&rstgen RSTN_DMA2PNOC_AXI>, <&rstgen RSTN_SGDMA2P_AXI>, <&rstgen RSTN_SGDMA2P_AHB>;
+ reset-names = "noc", "axi", "ahb";
+ interrupt-parent = <&plic>;
+ interrupts = <2>;
+ dma-channels = <4>;
+ snps,dma-masters = <1>;
+ snps,data-width = <4>;
+ snps,block-size = <4096 4096 4096 4096>;
+ snps,priority = <0 1 2 3>;
+ snps,axi-max-burst-len = <128>;
+ status = "okay";
+ };
+
+ dma1p: sgdma1p@10500000 {
+ compatible = "starfive,axi-dma", "snps,axi-dma-1.01a";
+ reg = <0x0 0x10500000 0x0 0x10000>;
+ clocks = <&axiclk>, <&ahb0clk>;
+ clock-names = "core-clk", "cfgr-clk";
+ resets = <&rstgen RSTN_SGDMA1P_AXI>;
+ interrupt-parent = <&plic>;
+ interrupts = <1>;
+ dma-channels = <16>;
+ snps,dma-masters = <1>;
+ snps,data-width = <3>;
+ snps,block-size = <4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096>;
+ snps,priority = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15>;
+ snps,axi-max-burst-len = <64>;
+ status = "okay";
+ };
+
+ usb3: usb@104c0000 {
+ compatible = "cdns,usb3";
+ reg = <0x0 0x104c0000 0x0 0x10000>, // memory area for HOST registers
+ <0x0 0x104d0000 0x0 0x10000>, // memory area for DEVICE registers
+ <0x0 0x104e0000 0x0 0x10000>; // memory area for OTG/DRD registers
+ reg-names = "otg", "xhci", "dev";
+ interrupt-parent = <&plic>;
+ interrupts = <43>, <44>, <52>;
+ interrupt-names = "otg",
+ "host",
+ "peripheral";
+ phy-names = "cdns3,usb3-phy", "cdns3,usb2-phy";
+ maximum-speed = "super-speed";
+ status = "disabled";
+ };
+
+ gpio: gpio@11910000 {
+ compatible = "starfive,gpio0";
+ interrupt-parent = <&plic>;
+ interrupts = <32>;
+ resets = <&rstgen RSTN_GPIO_APB>;
+ clocks = <&clkgen CLK_GPIO_APB>;
+ reg = <0x0 0x11910000 0x0 0x10000>;
+ reg-names = "control";
+ interrupt-controller;
+ #gpio-cells = <2>;
+ #pinctrl-cells = <1>;
+ pinctrl-single,register-width = <32>;
+ pinctrl-single,function-mask = <0xffffffff>;
+ };
+
+ i2c0: i2c@118b0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #clock-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0x0 0x118b0000 0x0 0x10000>;
+ interrupt-parent = <&plic>;
+ interrupts = <96>;
+ clocks = <&i2c0clk>;
+ clock-frequency = <100000>;
+ i2c-sda-hold-time-ns = <300>;
+ i2c-sda-falling-time-ns = <500>;
+ i2c-scl-falling-time-ns = <500>;
+ scl-gpio = <&gpio 62 0>;
+ sda-gpio = <&gpio 61 0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@118c0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #clock-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0x0 0x118c0000 0x0 0x10000>;
+ interrupt-parent = <&plic>;
+ interrupts = <97>;
+ clocks = <&i2c0clk>;
+ clock-frequency = <400000>;
+ i2c-sda-hold-time-ns = <300>;
+ i2c-sda-falling-time-ns = <100>;
+ i2c-scl-falling-time-ns = <100>;
+ scl-gpio = <&gpio 47 0>;
+ sda-gpio = <&gpio 48 0>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@12450000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #clock-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0x0 0x12450000 0x0 0x10000>;
+ interrupt-parent = <&plic>;
+ interrupts = <74>;
+ clocks = <&i2c2clk>;
+ clock-frequency = <100000>;
+ i2c-sda-hold-time-ns = <300>;
+ i2c-sda-falling-time-ns = <500>;
+ i2c-scl-falling-time-ns = <500>;
+ scl-gpio = <&gpio 60 0>;
+ sda-gpio = <&gpio 59 0>;
+ status = "disabled";
+ };
+
+ trng: trng@118d0000 {
+ compatible = "starfive,vic-rng";
+ reg = <0x0 0x118d0000 0x0 0x10000>;
+ interrupt-parent = <&plic>;
+ interrupts = <98>;
+ clocks = <&clkgen CLK_TRNG_APB>;
+ resets = <&rstgen RSTN_TRNG_APB>;
+ };
+
+ crypto: crypto@100d0000 {
+ compatible = "starfive,vic-sec";
+ reg = <0x0 0x100d0000 0x0 0x20000>,
+ <0x0 0x11800234 0x0 0xc>;
+ reg-names = "secmem", "secclk";
+ resets = <&rstgen RSTN_SEC_AHB>, <&rstgen RSTN_AES>,
+ <&rstgen RSTN_PKA>, <&rstgen RSTN_SHA>;
+ interrupt-parent = <&plic>;
+ interrupts = <31>;
+ clocks = <&osc_sys>;
+ };
+
+ /* gmac device configuration */
+ stmmac_axi_setup: stmmac-axi-config {
+ snps,wr_osr_lmt = <0xf>;
+ snps,rd_osr_lmt = <0xf>;
+ snps,blen = <256 128 64 32 0 0 0>;
+ };
+
+ gmac: gmac@10020000 {
+ compatible = "starfive,stmmac";
+ reg = <0x0 0x10020000 0x0 0x10000>;
+ interrupt-parent = <&plic>;
+ interrupts = <6 7>;
+ interrupt-names = "macirq", "eth_wake_irq";
+ resets = <&rstgen RSTN_GMAC_AHB>;
+ reset-names = "stmmaceth";
+ clocks = <&clkgen CLK_GMAC_AHB>, <&clkgen CLK_GMAC_PTP_REF>,
+ <&clkgen CLK_GMAC_GTX>;
+ clock-names = "stmmaceth", "ptp_ref", "tx";
+ max-frame-size = <9000>;
+ snps,multicast-filter-bins = <256>;
+ snps,perfect-filter-entries = <128>;
+ rx-fifo-depth = <32768>;
+ tx-fifo-depth = <16384>;
+ snps,fixed-burst = <1>;
+ snps,no-pbl-x8 = <1>;
+ /*snps,force_sf_dma_mode;*/
+ snps,force_thresh_dma_mode;
+ snps,axi-config = <&stmmac_axi_setup>;
+ starfive,sysmain = <&sysmain>;
+ };
+
+ nbdla: nvdla@11940000 {
+ compatible = "nvidia,nvdla_os_initial";
+ interrupt-parent = <&plic>;
+ resets = <&rstgen RSTN_DLA_AXI>,
+ <&rstgen RSTN_DLANOC_AXI>,
+ <&rstgen RSTN_DLA_APB>,
+ <&rstgen RSTN_NNENOC_AXI>,
+ <&rstgen RSTN_DLASLV_AXI>;
+ interrupts = <22>;
+ memory-region = <&nvdla_reserved>;
+ reg = <0x0 0x11940000 0x0 0x40000>;
+ status = "okay";
+ };
+
+ jpu: coadj12@11900000 {
+ compatible = "cm,codaj12-jpu-1";
+ reg = <0x0 0x11900000 0x0 0x300>;
+ memory-region = <&jpu_reserved>;
+ interrupt-parent = <&plic>;
+ interrupts = <24>;
+ clocks = <&jpuclk>;
+ clock-names = "jpege";
+ reg-names = "control";
+ resets = <&rstgen RSTN_JPEG_AXI>, <&rstgen RSTN_JPEG_CCLK>,
+ <&rstgen RSTN_JPEG_APB>;
+ status = "okay";
+ };
+
+ clkgen: clock-controller@11800000 {
+ compatible = "starfive,jh7100-clkgen";
+ reg = <0x0 0x11800000 0x0 0x10000>;
+ clocks = <&osc_sys>, <&osc_aud>;
+ clock-names = "osc_sys", "osc_aud";
+ #clock-cells = <1>;
+ };
+
+ vpu_dec: vpu_dec@118f0000 {
+ compatible = "cm,cm511-vpu";
+ reg = <0 0x118f0000 0 0x10000>;
+ //memory-region = <&vpu_reserved>;
+ interrupt-parent = <&plic>;
+ interrupts = <23>;
+ clocks = <&vpuclk>;
+ clock-names = "vcodec";
+ resets = <&rstgen RSTN_VDEC_AXI>, <&rstgen RSTN_VDECBRG_MAIN>,
+ <&rstgen RSTN_VDEC_BCLK>, <&rstgen RSTN_VDEC_CCLK>,
+ <&rstgen RSTN_VDEC_APB>;
+ status = "okay";
+ };
+
+ vpu_enc: vpu_enc@118e0000 {
+ compatible = "cm,cm521-vpu";
+ reg = <0x0 0x118e0000 0x0 0x4000>;
+ interrupt-parent = <&plic>;
+ interrupts = <26>;
+ clocks = <&vpuclk>;
+ clock-names = "vcodec";
+ resets = <&rstgen RSTN_VENC_AXI>, <&rstgen RSTN_VENCBRG_MAIN>,
+ <&rstgen RSTN_VENC_BCLK>, <&rstgen RSTN_VENC_CCLK>,
+ <&rstgen RSTN_VENC_APB>;
+ reg-names = "control";
+ };
+
+ wdt: watchdogm@12480000 {
+ compatible = "starfive,wdt";
+ reg = <0x0 0x12480000 0x0 0x10000>;
+ clocks = <&clkgen CLK_WDTIMER_APB>,<&clkgen CLK_WDT_CORE>;
+ clock-names = "bus", "core";
+ resets = <&rstgen RSTN_WDTIMER_APB>, <&rstgen RSTN_WDT>;
+ reset-names = "bus", "core";
+ };
+
+ ptc: pwm@12490000 {
+ compatible = "starfive,pwm0";
+ reg = <0x0 0x12490000 0x0 0x10000>;
+ reg-names = "control";
+ sifive,approx-period = <100000000>;
+ clocks = <&pwmclk>;
+ #pwm-cells = <3>;
+ sifive,npwm = <8>;
+
+ };
+
+ rstgen: reset-controller@11840000 {
+ compatible = "starfive,jh7100-rstgen";
+ reg = <0x0 0x11840000 0x0 0x10000>;
+ #reset-cells = <1>;
+ };
+
+ spi2ahb {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ compatible = "starfive,spi2ahb";
+ resets = <&rstgen RSTN_SPI2AHB_AHB>, <&rstgen RSTN_SPI2AHB_CORE>;
+
+ qspi: spi@11860000 {
+ compatible = "cadence,qspi", "cdns,qspi-nor";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x11860000 0x0 0x10000 0x0 0x20000000 0x0 0x20000000>;
+ interrupts = <3>;
+ interrupt-parent = <&plic>;
+ clocks = <&qspi_clk>;
+ cdns,fifo-depth = <256>;
+ cdns,fifo-width = <4>;
+ cdns,trigger-address = <0x00000000>;
+ status = "disabled";
+ spi-max-frequency = <250000000>;
+ };
+
+ spi2: spi@12410000 {
+ compatible = "snps,dw-apb-ssi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupt-parent = <&plic>;
+ interrupts = <70>;
+ reg = <0x0 0x12410000 0x0 0x10000>;
+ clocks = <&spiclk>;
+ status = "disabled";
+ /*
+ num-cs = <1>;
+ cs-gpios = <&gpio 0 0>;
+ */
+ };
+ };
+
+ xrp@f0000000 {
+ compatible = "cdns,xrp";
+ reg = <0x0 0xf0000000 0x0 0x01ffffff
+ 0x10 0x72000000 0x0 0x00001000
+ 0x10 0x72001000 0x0 0x00fff000
+ 0x0 0x124b0000 0x0 0x00010000>;
+ clocks = <&osc_sys>;
+ interrupt-parent = <&plic>;
+ firmware-name = "vp6_elf";
+ resets = <&rstgen RSTN_VP6INTC_APB>;
+ dsp-irq = <19 20>;
+ dsp-irq-src = <0x20 0x21>;
+ intc-irq-mode = <1>;
+ intc-irq = <0 1>;
+ interrupts = <27 28>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x40000000 0x0 0x40000000 0x01000000
+ 0xb0000000 0x10 0x70000000 0x3000000>;
+ dsp@0 {
+ };
+ };
+
+ sdio0: sdio0@10000000 {
+ compatible = "starfive,jh7100-dw-mshc", "snps,dw-mshc";
+ reg = <0x0 0x10000000 0x0 0x10000>;
+ interrupts = <4>;
+ interrupt-parent = <&plic>;
+ clocks = <&clkgen CLK_SDIO0_AHB>, <&clkgen CLK_SDIO0_CCLKINT>;
+ clock-names = "biu", "ciu";
+ resets = <&rstgen RSTN_SDIO0_AHB>;
+ reset-names = "reset";
+ clock-frequency = <100000000>;
+ max-frequency = <10000000>;
+ fifo-depth = <32>;
+ card-detect-delay = <300>;
+ fifo-watermark-aligned;
+ data-addr = <0>;
+ post-power-on-delay-ms = <200>;
+ status = "disabled";
+ };
+
+ sdio1: sdio1@10010000 {
+ compatible = "starfive,jh7100-dw-mshc", "snps,dw-mshc";
+ reg = <0x0 0x10010000 0x0 0x10000>;
+ interrupts = <5>;
+ interrupt-parent = <&plic>;
+ clocks = <&clkgen CLK_SDIO1_AHB>, <&clkgen CLK_SDIO1_CCLKINT>;
+ clock-names = "biu", "ciu";
+ resets = <&rstgen RSTN_SDIO1_AHB>;
+ reset-names = "reset";
+ clock-frequency = <100000000>;
+ max-frequency = <10000000>;
+ fifo-depth = <32>;
+ card-detect-delay = <300>;
+ fifo-watermark-aligned;
+ data-addr = <0>;
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ cap-mmc-hw-reset;
+ enable-sdio-wakeup;
+ keep-power-in-suspend;
+ cap-mmc-highspeed;
+ post-power-on-delay-ms = <200>;
+ status = "disabled";
+ };
+
+ sfivefb: sfivefb@12000000 {
+ compatible = "starfive,vpp-lcdc";
+ interrupt-parent = <&plic>;
+ interrupts = <101>, <103>;
+ interrupt-names = "lcdc_irq", "vpp1_irq";
+ reg = <0x0 0x12000000 0x0 0x10000>,
+ <0x0 0x12100000 0x0 0x10000>,
+ <0x0 0x12040000 0x0 0x10000>,
+ <0x0 0x12080000 0x0 0x10000>,
+ <0x0 0x120c0000 0x0 0x10000>,
+ <0x0 0x12240000 0x0 0x10000>,
+ <0x0 0x12250000 0x0 0x10000>,
+ <0x0 0x12260000 0x0 0x10000>;
+ reg-names = "lcdc", "dsitx", "vpp0", "vpp1", "vpp2", "clk", "rst", "sys";
+ memory-region = <&sffb_reserved>;
+ clocks = <&uartclk>, <&apb2clk>;
+ clock-names = "baudclk", "apb_pclk";
+ status = "okay";
+ ddr-format = <4>;/* LCDC win_format WIN_FMT_RGB565 */
+ };
+
+ vin_sysctl: vin_sysctl@19800000 {
+ compatible = "starfive,stf-vin";
+ reg = <0x0 0x19800000 0x0 0x10000>,
+ <0x0 0x19810000 0x0 0x10000>,
+ <0x0 0x19820000 0x0 0x10000>,
+ <0x0 0x19830000 0x0 0x10000>,
+ <0x0 0x19840000 0x0 0x10000>,
+ <0x0 0x19870000 0x0 0x30000>,
+ <0x0 0x198a0000 0x0 0x30000>,
+ <0x0 0x11800000 0x0 0x10000>,
+ <0x0 0x11840000 0x0 0x10000>,
+ <0x0 0x11858000 0x0 0x10000>;
+ reg-names = "mipi0", "vclk", "vrst", "mipi1", "sctrl",
+ "isp0", "isp1", "tclk", "trst", "iopad";
+ interrupt-parent = <&plic>;
+ interrupts = <119 109>;
+ memory-region = <&vin_reserved>;
+ /*defaule config for imx219 vin&isp*/
+ format = <3>; /* SRC_CSI2RX_VIN_ISP */
+ frame-width = <800>;
+ frame-height =<480>;
+ isp0_enable;
+ csi-lane = <2>;
+ csi-dlane-swaps = /bits/ 8 <1>,/bits/ 8 <2>,/bits/ 8 <3>,/bits/ 8 <4>;
+ csi-dlane-pn-swaps = /bits/ 8 <0>,/bits/ 8 <0>,/bits/ 8 <0>,/bits/ 8 <0>;
+ csi-clane-swap = /bits/ 8 <0>;
+ csi-clane-pn-swap = /bits/ 8 <0>;
+ csi-mipiID = <0>;
+ csi-width = <1920>;
+ csi-height = <1080>;
+ csi-dt = <0x2b>;
+ };
+
+ sfc_tmp: tmpsensor@124a0000 {
+ compatible = "sfc,tempsensor";
+ reg = <0x0 0x124a0000 0x0 0x1000>;
+ interrupt-parent = <&plic>;
+ interrupts = <122>;
+ resets = <&rstgen RSTN_TEMP_APB>, <&rstgen RSTN_TEMP_SENSE>;
+ status = "okay";
+ };
+
+ otp: otp@11810000 {
+ compatible = "starfive,fu740-otp";
+ reg = <0x0 0x11810000 0x0 0x10000>;
+ fuse-count = <0x200>;
+ resets = <&rstgen RSTN_OTP_APB>;
+ clocks = <&clkgen CLK_OTP_APB>;
+ };
+ };
+};
diff --git a/arch/riscv/include/asm/asm-offsets.h b/arch/riscv/include/asm/asm-offsets.h
new file mode 100644
index 0000000000..d370ee36a1
--- /dev/null
+++ b/arch/riscv/include/asm/asm-offsets.h
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff --git a/arch/riscv/include/asm/barebox-riscv.h b/arch/riscv/include/asm/barebox-riscv.h
index bb1d15308b..abb3202427 100644
--- a/arch/riscv/include/asm/barebox-riscv.h
+++ b/arch/riscv/include/asm/barebox-riscv.h
@@ -19,14 +19,26 @@
#include <linux/compiler.h>
#include <asm/sections.h>
#include <asm/barebox-riscv-head.h>
+#include <asm/system.h>
unsigned long get_runtime_offset(void);
void setup_c(void);
void relocate_to_current_adr(void);
void relocate_to_adr(unsigned long target);
+
+void sync_caches_for_execution(void);
+
void __noreturn __naked barebox_riscv_entry(unsigned long membase, unsigned long memsize,
- void *boarddata);
+ void *boarddata, unsigned int flags);
+
+#define barebox_riscv_machine_entry(membase, memsize, boarddata) \
+ barebox_riscv_entry(membase, memsize, boarddata, RISCV_M_MODE)
+
+#define barebox_riscv_supervisor_entry(membase, memsize, hartid, boarddata) do { \
+ __asm__ volatile("mv tp, %0\n" : : "r"(hartid)); \
+ barebox_riscv_entry(membase, memsize, boarddata, RISCV_S_MODE); \
+} while (0)
unsigned long riscv_mem_ramoops_get(void);
unsigned long riscv_mem_endmem_get(void);
diff --git a/arch/riscv/include/asm/barrier.h b/arch/riscv/include/asm/barrier.h
new file mode 100644
index 0000000000..eff529307a
--- /dev/null
+++ b/arch/riscv/include/asm/barrier.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Based on arch/arm/include/asm/barrier.h
+ *
+ * Copyright (C) 2012 ARM Ltd.
+ * Copyright (C) 2013 Regents of the University of California
+ * Copyright (C) 2017 SiFive
+ */
+
+#ifndef _ASM_RISCV_BARRIER_H
+#define _ASM_RISCV_BARRIER_H
+
+#ifndef __ASSEMBLY__
+
+#define nop() __asm__ __volatile__ ("nop")
+
+#define RISCV_FENCE(p, s) \
+ __asm__ __volatile__ ("fence " #p "," #s : : : "memory")
+
+/* These barriers need to enforce ordering on both devices or memory. */
+#define mb() RISCV_FENCE(iorw,iorw)
+#define rmb() RISCV_FENCE(ir,ir)
+#define wmb() RISCV_FENCE(ow,ow)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_RISCV_BARRIER_H */
diff --git a/arch/riscv/include/asm/cacheflush.h b/arch/riscv/include/asm/cacheflush.h
new file mode 100644
index 0000000000..9ff25740c6
--- /dev/null
+++ b/arch/riscv/include/asm/cacheflush.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2015 Regents of the University of California
+ */
+
+#ifndef _ASM_RISCV_CACHEFLUSH_H
+#define _ASM_RISCV_CACHEFLUSH_H
+
+static inline void local_flush_icache_all(void)
+{
+#ifdef HAS_CACHE
+ asm volatile ("fence.i" ::: "memory");
+#endif
+}
+
+#endif /* _ASM_RISCV_CACHEFLUSH_H */
diff --git a/arch/riscv/include/asm/debug_ll.h b/arch/riscv/include/asm/debug_ll.h
index 6904460af9..b4caa0597a 100644
--- a/arch/riscv/include/asm/debug_ll.h
+++ b/arch/riscv/include/asm/debug_ll.h
@@ -12,13 +12,19 @@
#include <linux/kconfig.h>
-#ifdef CONFIG_DEBUG_ERIZO
+#ifdef CONFIG_DEBUG_LL_NS16550
+#if defined CONFIG_DEBUG_ERIZO
#define DEBUG_LL_UART_ADDR 0x90000000
+#define DEBUG_LL_UART_CLK (24000000 / 16)
+#elif defined CONFIG_DEBUG_STARFIVE
+#define DEBUG_LL_UART_ADDR 0x12440000
+#define DEBUG_LL_UART_CLK (100000000 / 16)
+#endif
+
#define DEBUG_LL_UART_SHIFT 2
#define DEBUG_LL_UART_IOSIZE32
-#define DEBUG_LL_UART_CLK (24000000 / 16)
#define DEBUG_LL_UART_BPS CONFIG_BAUDRATE
#define DEBUG_LL_UART_DIVISOR (DEBUG_LL_UART_CLK / DEBUG_LL_UART_BPS)
diff --git a/arch/riscv/include/asm/dma.h b/arch/riscv/include/asm/dma.h
index 4204653984..56bcf06cc4 100644
--- a/arch/riscv/include/asm/dma.h
+++ b/arch/riscv/include/asm/dma.h
@@ -1,44 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_DMA_MAPPING_H
-#define _ASM_DMA_MAPPING_H
+#ifndef _RISCV_ASM_DMA_H
+#define _RISCV_ASM_DMA_H
-#include <common.h>
-#include <xfuncs.h>
-#include <linux/build_bug.h>
-#include <malloc.h>
+#include <linux/types.h>
-#ifdef CONFIG_MMU
-#error DMA stubs need be replaced when using MMU and caches
-#endif
+struct dma_ops {
+ void *(*alloc_coherent)(size_t size, dma_addr_t *dma_handle);
+ void (*free_coherent)(void *vaddr, dma_addr_t dma_handle, size_t size);
-static inline void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle)
-{
- void *ret;
+ void (*flush_range)(dma_addr_t start, dma_addr_t end);
+ void (*inv_range)(dma_addr_t start, dma_addr_t end);
+};
- ret = xmemalign(PAGE_SIZE, size);
+/* Override for SoCs with cache-incoherent DMA masters */
+void dma_set_ops(const struct dma_ops *ops);
- memset(ret, 0, size);
+#define DMA_ALIGNMENT 64
- if (dma_handle)
- *dma_handle = (dma_addr_t)ret;
-
- return ret;
-}
-
-static inline void dma_free_coherent(void *vaddr, dma_addr_t dma_handle,
- size_t size)
-{
- free(vaddr);
-}
-
-static inline void dma_sync_single_for_cpu(dma_addr_t address, size_t size,
- enum dma_data_direction dir)
-{
-}
-
-static inline void dma_sync_single_for_device(dma_addr_t address, size_t size,
- enum dma_data_direction dir)
-{
-}
+#include <dma.h>
#endif /* _ASM_DMA_MAPPING_H */
diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h
index 3cdea7fcac..795e670e3b 100644
--- a/arch/riscv/include/asm/io.h
+++ b/arch/riscv/include/asm/io.h
@@ -5,4 +5,14 @@
#include <asm-generic/io.h>
+static inline void *phys_to_virt(unsigned long phys)
+{
+ return (void *)phys;
+}
+
+static inline unsigned long virt_to_phys(volatile void *mem)
+{
+ return (unsigned long)mem;
+}
+
#endif /* __ASM_RISCV_IO_H */
diff --git a/arch/riscv/include/asm/irq.h b/arch/riscv/include/asm/irq.h
new file mode 100644
index 0000000000..fde7589baa
--- /dev/null
+++ b/arch/riscv/include/asm/irq.h
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef RISCV_ASM_IRQ_H__
+#define RISCV_ASM_IRQ_H__
+
+#include <asm/csr.h>
+#include <asm/system.h>
+#include <asm/asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/ptrace.h>
+
+#ifndef __ASSEMBLY__
+#include <asm/barebox-riscv.h>
+void strap_entry(void);
+void mtrap_entry(void);
+unsigned long handle_trap(struct pt_regs *regs);
+
+static inline void irq_init_vector(enum riscv_mode mode)
+{
+ switch (mode) {
+#ifdef CONFIG_RISCV_EXCEPTIONS
+ case RISCV_S_MODE:
+ asm volatile ("csrw stvec, %0; csrw sie, zero" : :
+ "r"(strap_entry + get_runtime_offset()));
+ break;
+ case RISCV_M_MODE:
+ asm volatile ("csrw mtvec, %0; csrw mie, zero" : :
+ "r"(mtrap_entry + get_runtime_offset()));
+ break;
+#endif
+ default:
+ break;
+ }
+}
+
+#else
+
+.macro pt_regs_push ptr
+ REG_S ra, PT_RA(\ptr) /* x1 */
+ REG_S sp, PT_SP(\ptr) /* x2 */
+ REG_S gp, PT_GP(\ptr) /* x3 */
+ REG_S tp, PT_TP(\ptr) /* x4 */
+ REG_S t0, PT_T0(\ptr) /* x5 */
+ REG_S t1, PT_T1(\ptr) /* x6 */
+ REG_S t2, PT_T2(\ptr) /* x7 */
+ REG_S s0, PT_S0(\ptr) /* x8/fp */
+ REG_S s1, PT_S1(\ptr) /* x9 */
+ REG_S a0, PT_A0(\ptr) /* x10 */
+ REG_S a1, PT_A1(\ptr) /* x11 */
+ REG_S a2, PT_A2(\ptr) /* x12 */
+ REG_S a3, PT_A3(\ptr) /* x13 */
+ REG_S a4, PT_A4(\ptr) /* x14 */
+ REG_S a5, PT_A5(\ptr) /* x15 */
+ REG_S a6, PT_A6(\ptr) /* x16 */
+ REG_S a7, PT_A7(\ptr) /* x17 */
+ REG_S s2, PT_S2(\ptr) /* x18 */
+ REG_S s3, PT_S3(\ptr) /* x19 */
+ REG_S s4, PT_S4(\ptr) /* x20 */
+ REG_S s5, PT_S5(\ptr) /* x21 */
+ REG_S s6, PT_S6(\ptr) /* x22 */
+ REG_S s7, PT_S7(\ptr) /* x23 */
+ REG_S s8, PT_S8(\ptr) /* x24 */
+ REG_S s9, PT_S9(\ptr) /* x25 */
+ REG_S s10, PT_S10(\ptr) /* x26 */
+ REG_S s11, PT_S11(\ptr) /* x27 */
+ REG_S t3, PT_T3(\ptr) /* x28 */
+ REG_S t4, PT_T4(\ptr) /* x29 */
+ REG_S t5, PT_T5(\ptr) /* x30 */
+ REG_S t6, PT_T6(\ptr) /* x31 */
+.endm
+
+.macro pt_regs_pop ptr
+ REG_L ra, PT_RA(\ptr) /* x1 */
+ REG_L sp, PT_SP(\ptr) /* x2 */
+ REG_L gp, PT_GP(\ptr) /* x3 */
+ REG_L tp, PT_TP(\ptr) /* x4 */
+ REG_L t0, PT_T0(\ptr) /* x5 */
+ REG_L t1, PT_T1(\ptr) /* x6 */
+ REG_L t2, PT_T2(\ptr) /* x7 */
+ REG_L s0, PT_S0(\ptr) /* x8/fp */
+ REG_L s1, PT_S1(\ptr) /* x9 */
+ REG_L a0, PT_A0(\ptr) /* x10 */
+ REG_L a1, PT_A1(\ptr) /* x11 */
+ REG_L a2, PT_A2(\ptr) /* x12 */
+ REG_L a3, PT_A3(\ptr) /* x13 */
+ REG_L a4, PT_A4(\ptr) /* x14 */
+ REG_L a5, PT_A5(\ptr) /* x15 */
+ REG_L a6, PT_A6(\ptr) /* x16 */
+ REG_L a7, PT_A7(\ptr) /* x17 */
+ REG_L s2, PT_S2(\ptr) /* x18 */
+ REG_L s3, PT_S3(\ptr) /* x19 */
+ REG_L s4, PT_S4(\ptr) /* x20 */
+ REG_L s5, PT_S5(\ptr) /* x21 */
+ REG_L s6, PT_S6(\ptr) /* x22 */
+ REG_L s7, PT_S7(\ptr) /* x23 */
+ REG_L s8, PT_S8(\ptr) /* x24 */
+ REG_L s9, PT_S9(\ptr) /* x25 */
+ REG_L s10, PT_S10(\ptr) /* x26 */
+ REG_L s11, PT_S11(\ptr) /* x27 */
+ REG_L t3, PT_T3(\ptr) /* x28 */
+ REG_L t4, PT_T4(\ptr) /* x29 */
+ REG_L t5, PT_T5(\ptr) /* x30 */
+ REG_L t6, PT_T6(\ptr) /* x31 */
+.endm
+
+#endif
+
+#endif
diff --git a/arch/riscv/include/asm/ptrace.h b/arch/riscv/include/asm/ptrace.h
new file mode 100644
index 0000000000..b5e792f666
--- /dev/null
+++ b/arch/riscv/include/asm/ptrace.h
@@ -0,0 +1,143 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2012 Regents of the University of California
+ */
+
+#ifndef _ASM_RISCV_PTRACE_H
+#define _ASM_RISCV_PTRACE_H
+
+#include <asm/csr.h>
+#include <linux/compiler.h>
+
+#ifndef __ASSEMBLY__
+
+struct pt_regs {
+ unsigned long epc;
+ unsigned long ra;
+ unsigned long sp;
+ unsigned long gp;
+ unsigned long tp;
+ unsigned long t0;
+ unsigned long t1;
+ unsigned long t2;
+ unsigned long s0;
+ unsigned long s1;
+ unsigned long a0;
+ unsigned long a1;
+ unsigned long a2;
+ unsigned long a3;
+ unsigned long a4;
+ unsigned long a5;
+ unsigned long a6;
+ unsigned long a7;
+ unsigned long s2;
+ unsigned long s3;
+ unsigned long s4;
+ unsigned long s5;
+ unsigned long s6;
+ unsigned long s7;
+ unsigned long s8;
+ unsigned long s9;
+ unsigned long s10;
+ unsigned long s11;
+ unsigned long t3;
+ unsigned long t4;
+ unsigned long t5;
+ unsigned long t6;
+ /* Supervisor/Machine CSRs */
+ unsigned long status;
+ unsigned long badaddr;
+ unsigned long cause;
+};
+
+#ifdef CONFIG_64BIT
+#define REG_FMT "%016lx"
+#else
+#define REG_FMT "%08lx"
+#endif
+
+#define user_mode(regs) (((regs)->status & SR_PP) == 0)
+
+#define MAX_REG_OFFSET offsetof(struct pt_regs, cause)
+
+/* Helpers for working with the instruction pointer */
+static inline unsigned long instruction_pointer(struct pt_regs *regs)
+{
+ return regs->epc;
+}
+static inline void instruction_pointer_set(struct pt_regs *regs,
+ unsigned long val)
+{
+ regs->epc = val;
+}
+
+#define profile_pc(regs) instruction_pointer(regs)
+
+/* Helpers for working with the user stack pointer */
+static inline unsigned long user_stack_pointer(struct pt_regs *regs)
+{
+ return regs->sp;
+}
+static inline void user_stack_pointer_set(struct pt_regs *regs,
+ unsigned long val)
+{
+ regs->sp = val;
+}
+
+/* Valid only for Kernel mode traps. */
+static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
+{
+ return regs->sp;
+}
+
+/* Helpers for working with the frame pointer */
+static inline unsigned long frame_pointer(struct pt_regs *regs)
+{
+ return regs->s0;
+}
+static inline void frame_pointer_set(struct pt_regs *regs,
+ unsigned long val)
+{
+ regs->s0 = val;
+}
+
+static inline unsigned long regs_return_value(struct pt_regs *regs)
+{
+ return regs->a0;
+}
+
+static inline void regs_set_return_value(struct pt_regs *regs,
+ unsigned long val)
+{
+ regs->a0 = val;
+}
+
+extern int regs_query_register_offset(const char *name);
+extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
+ unsigned int n);
+
+void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
+ unsigned long frame_pointer);
+int do_syscall_trace_enter(struct pt_regs *regs);
+void do_syscall_trace_exit(struct pt_regs *regs);
+
+/**
+ * regs_get_register() - get register value from its offset
+ * @regs: pt_regs from which register value is gotten
+ * @offset: offset of the register.
+ *
+ * regs_get_register returns the value of a register whose offset from @regs.
+ * The @offset is the offset of the register in struct pt_regs.
+ * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
+ */
+static inline unsigned long regs_get_register(struct pt_regs *regs,
+ unsigned int offset)
+{
+ if (unlikely(offset > MAX_REG_OFFSET))
+ return 0;
+
+ return *(unsigned long *)((unsigned long)regs + offset);
+}
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_RISCV_PTRACE_H */
diff --git a/arch/riscv/include/asm/riscv_nmon.h b/arch/riscv/include/asm/riscv_nmon.h
index caf213cdd8..8a44e216d7 100644
--- a/arch/riscv/include/asm/riscv_nmon.h
+++ b/arch/riscv/include/asm/riscv_nmon.h
@@ -16,13 +16,26 @@
#ifndef __ASM_RISCV_NMON_H
#define __ASM_RISCV_NMON_H
+#include <linux/kconfig.h>
+
#define CODE_ESC 0x1b
-.macro nmon_outs msg
+#ifndef __ASSEMBLY__
- la a1, \msg
+extern void __barebox_nmon_entry(void);
- jal _nmon_outs
+static inline void barebox_nmon_entry(void)
+{
+ if (IS_ENABLED(CONFIG_NMON))
+ __barebox_nmon_entry();
+}
+
+#else
+
+.macro nmon_outs msg
+
+ lla a1, \msg
+ jal a2, _nmon_outs
.endm
@@ -73,7 +86,7 @@ nmon_main:
li a0, 'q'
bne s0, a0, 3f
- jal _nmon_outc_a0
+ jal a2, _nmon_outc_a0
j nmon_exit
@@ -90,12 +103,12 @@ nmon_main:
j nmon_main_help
nmon_cmd_d:
- jal _nmon_outc_a0
+ jal a2, _nmon_outc_a0
li a0, ' '
- jal _nmon_outc_a0
+ jal a2, _nmon_outc_a0
- jal _nmon_gethexw
+ jal a2, _nmon_gethexw
nmon_outs msg_nl
@@ -105,28 +118,28 @@ nmon_cmd_d:
j nmon_main
nmon_cmd_w:
- jal _nmon_outc_a0
+ jal a2, _nmon_outc_a0
li a0, ' '
- jal _nmon_outc_a0
+ jal a2, _nmon_outc_a0
- jal _nmon_gethexw
+ jal a2, _nmon_gethexw
move s2, s0
li a0, ' '
- jal _nmon_outc_a0
- jal _nmon_gethexw
+ jal a2, _nmon_outc_a0
+ jal a2, _nmon_gethexw
sw s0, 0(s2)
j nmon_main
nmon_cmd_g:
- jal _nmon_outc_a0
+ jal a2, _nmon_outc_a0
li a0, ' '
- jal _nmon_outc_a0
+ jal a2, _nmon_outc_a0
- jal _nmon_gethexw
+ jal a2, _nmon_gethexw
move s2, s0
nmon_outs msg_nl
@@ -136,7 +149,7 @@ nmon_cmd_g:
_nmon_outc_a0:
debug_ll_outc_a0
- jr ra
+ jr a2
_nmon_outs:
@@ -202,7 +215,7 @@ _get_hex_digit:
move s0, t2
_nmon_jr_ra_exit:
- jr ra
+ jr a2
msg_prompt:
.asciz "\r\nnmon> "
@@ -231,4 +244,6 @@ nmon_exit:
.endm
+#endif /* __ASSEMBLY__ */
+
#endif /* __ASM_RISCV_NMON_H */
diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index ab1fc9a128..eb4018de38 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -9,9 +9,7 @@
#include <linux/types.h>
-#ifdef CONFIG_RISCV_SBI
enum sbi_ext_id {
-#ifdef CONFIG_RISCV_SBI_V01
SBI_EXT_0_1_SET_TIMER = 0x0,
SBI_EXT_0_1_CONSOLE_PUTCHAR = 0x1,
SBI_EXT_0_1_CONSOLE_GETCHAR = 0x2,
@@ -21,7 +19,7 @@ enum sbi_ext_id {
SBI_EXT_0_1_REMOTE_SFENCE_VMA = 0x6,
SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID = 0x7,
SBI_EXT_0_1_SHUTDOWN = 0x8,
-#endif
+
SBI_EXT_BASE = 0x10,
SBI_EXT_TIME = 0x54494D45,
SBI_EXT_IPI = 0x735049,
@@ -167,7 +165,5 @@ static inline unsigned long sbi_minor_version(void)
}
int sbi_err_map_linux_errno(int err);
-#else /* CONFIG_RISCV_SBI */
-static inline int sbi_remote_fence_i(const unsigned long *hart_mask) { return -1; }
-#endif /* CONFIG_RISCV_SBI */
+
#endif /* _ASM_RISCV_SBI_H */
diff --git a/arch/riscv/include/asm/system.h b/arch/riscv/include/asm/system.h
new file mode 100644
index 0000000000..adf856f9e9
--- /dev/null
+++ b/arch/riscv/include/asm/system.h
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __ASM_SYSTEM_H_
+#define __ASM_SYSTEM_H_
+
+#ifndef __ASSEMBLY__
+
+#define RISCV_MODE_MASK 0x3
+enum riscv_mode {
+ RISCV_U_MODE = 0,
+ RISCV_S_MODE = 1,
+ RISCV_HS_MODE = 2,
+ RISCV_M_MODE = 3,
+};
+
+static inline enum riscv_mode __riscv_mode(u32 flags)
+{
+ /* allow non-LTO builds to discard code for unused modes */
+ if (!IS_ENABLED(CONFIG_RISCV_MULTI_MODE)) {
+ if (IS_ENABLED(CONFIG_RISCV_M_MODE))
+ return RISCV_M_MODE;
+ if (IS_ENABLED(CONFIG_RISCV_S_MODE))
+ return RISCV_S_MODE;
+ }
+
+ return flags & RISCV_MODE_MASK;
+}
+
+static inline long __riscv_hartid(u32 flags)
+{
+ long hartid = -1;
+
+ switch (__riscv_mode(flags)) {
+ case RISCV_S_MODE:
+ __asm__ volatile("mv %0, tp\n" : "=r"(hartid) :);
+ break;
+ default:
+ /* unimplemented */
+ break;
+ }
+
+ return hartid;
+}
+
+#ifndef __PBL__
+extern unsigned barebox_riscv_pbl_flags;
+
+static inline enum riscv_mode riscv_mode(void)
+{
+ return __riscv_mode(barebox_riscv_pbl_flags);
+}
+
+static inline long riscv_hartid(void)
+{
+ return __riscv_hartid(barebox_riscv_pbl_flags);
+}
+#endif
+
+#endif
+
+#endif
diff --git a/arch/riscv/include/asm/unwind.h b/arch/riscv/include/asm/unwind.h
new file mode 100644
index 0000000000..9e5c8b5420
--- /dev/null
+++ b/arch/riscv/include/asm/unwind.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef RISCV_ASM_UNWIND_H__
+#define RISCV_ASM_UNWIND_H__
+
+struct pt_regs;
+
+void unwind_backtrace(struct pt_regs *regs);
+
+#endif
diff --git a/arch/riscv/lib/asm-offsets.c b/arch/riscv/lib/asm-offsets.c
index 22f382b71e..4b869690f1 100644
--- a/arch/riscv/lib/asm-offsets.c
+++ b/arch/riscv/lib/asm-offsets.c
@@ -5,8 +5,54 @@
*/
#include <linux/kbuild.h>
+#include <linux/kernel.h>
+#include <asm/ptrace.h>
+
+#define STACK_ALIGN 16
int main(void)
{
+ DEFINE(PT_SIZE, sizeof(struct pt_regs));
+ OFFSET(PT_EPC, pt_regs, epc);
+ OFFSET(PT_RA, pt_regs, ra);
+ OFFSET(PT_FP, pt_regs, s0);
+ OFFSET(PT_S0, pt_regs, s0);
+ OFFSET(PT_S1, pt_regs, s1);
+ OFFSET(PT_S2, pt_regs, s2);
+ OFFSET(PT_S3, pt_regs, s3);
+ OFFSET(PT_S4, pt_regs, s4);
+ OFFSET(PT_S5, pt_regs, s5);
+ OFFSET(PT_S6, pt_regs, s6);
+ OFFSET(PT_S7, pt_regs, s7);
+ OFFSET(PT_S8, pt_regs, s8);
+ OFFSET(PT_S9, pt_regs, s9);
+ OFFSET(PT_S10, pt_regs, s10);
+ OFFSET(PT_S11, pt_regs, s11);
+ OFFSET(PT_SP, pt_regs, sp);
+ OFFSET(PT_TP, pt_regs, tp);
+ OFFSET(PT_A0, pt_regs, a0);
+ OFFSET(PT_A1, pt_regs, a1);
+ OFFSET(PT_A2, pt_regs, a2);
+ OFFSET(PT_A3, pt_regs, a3);
+ OFFSET(PT_A4, pt_regs, a4);
+ OFFSET(PT_A5, pt_regs, a5);
+ OFFSET(PT_A6, pt_regs, a6);
+ OFFSET(PT_A7, pt_regs, a7);
+ OFFSET(PT_T0, pt_regs, t0);
+ OFFSET(PT_T1, pt_regs, t1);
+ OFFSET(PT_T2, pt_regs, t2);
+ OFFSET(PT_T3, pt_regs, t3);
+ OFFSET(PT_T4, pt_regs, t4);
+ OFFSET(PT_T5, pt_regs, t5);
+ OFFSET(PT_T6, pt_regs, t6);
+ OFFSET(PT_GP, pt_regs, gp);
+ OFFSET(PT_STATUS, pt_regs, status);
+ OFFSET(PT_BADADDR, pt_regs, badaddr);
+ OFFSET(PT_CAUSE, pt_regs, cause);
+
+ /*
+ * We allocate a pt_regs on the stack. This ensures the alignment is sane.
+ */
+ DEFINE(PT_SIZE_ON_STACK, ALIGN(sizeof(struct pt_regs), STACK_ALIGN));
return 0;
}
diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c
index 1b96edcd1b..6984f282be 100644
--- a/arch/riscv/lib/bootm.c
+++ b/arch/riscv/lib/bootm.c
@@ -3,11 +3,13 @@
#include <common.h>
#include <bootm.h>
+#include <asm/system.h>
static int do_bootm_linux(struct image_data *data)
{
void (*fn)(unsigned long a0, unsigned long dtb, unsigned long a2);
phys_addr_t devicetree;
+ long hartid = riscv_hartid();
int ret;
fn = booti_load_image(data, &devicetree);
@@ -23,7 +25,7 @@ static int do_bootm_linux(struct image_data *data)
shutdown_barebox();
- fn(0, devicetree, 0);
+ fn(hartid >= 0 ? hartid : 0, devicetree, 0);
return -EINVAL;
}
diff --git a/arch/riscv/lib/cpuinfo.c b/arch/riscv/lib/cpuinfo.c
index 21b99a990a..2d9cee2a62 100644
--- a/arch/riscv/lib/cpuinfo.c
+++ b/arch/riscv/lib/cpuinfo.c
@@ -2,6 +2,7 @@
#include <common.h>
#include <command.h>
#include <asm/sbi.h>
+#include <asm/system.h>
static const char *implementations[] = {
[0] = "\"Berkeley Boot Loader (BBL)\" ",
@@ -12,34 +13,57 @@ static const char *implementations[] = {
[5] = "\"Diosix\" ",
};
+static const char *modes[] = {
+ [RISCV_U_MODE] = "U",
+ [RISCV_S_MODE] = "S",
+ [RISCV_HS_MODE] = "HS",
+ [RISCV_M_MODE] = "M",
+};
+
static int do_cpuinfo(int argc, char *argv[])
{
const char *implementation = "";
+ enum riscv_mode mode;
unsigned long impid;
- printf("SBI specification v%lu.%lu detected\n",
- sbi_major_version(), sbi_minor_version());
+ mode = riscv_mode() & RISCV_MODE_MASK;
+
+ printf("%s barebox for %s-Mode\n",
+ IS_ENABLED(CONFIG_ARCH_RV64I) ? "RV64I" : "RV32I",
+ modes[mode]);
+
+ switch (mode) {
+ case RISCV_S_MODE:
+ printf("Hart ID=%lu\n", riscv_hartid());
+ if (!IS_ENABLED(CONFIG_RISCV_SBI))
+ break;
+ printf("SBI specification v%lu.%lu detected\n",
+ sbi_major_version(), sbi_minor_version());
- if (sbi_spec_is_0_1())
- return 0;
+ if (sbi_spec_is_0_1())
+ return 0;
- impid = __sbi_base_ecall(SBI_EXT_BASE_GET_IMP_ID);
- if (impid < ARRAY_SIZE(implementations))
- implementation = implementations[impid];
+ impid = __sbi_base_ecall(SBI_EXT_BASE_GET_IMP_ID);
+ if (impid < ARRAY_SIZE(implementations))
+ implementation = implementations[impid];
- printf("SBI implementation ID=0x%lx %sVersion=0x%lx\n",
- impid, implementation, __sbi_base_ecall(SBI_EXT_BASE_GET_IMP_VERSION));
+ printf("SBI implementation ID=0x%lx %sVersion=0x%lx\n",
+ impid, implementation, __sbi_base_ecall(SBI_EXT_BASE_GET_IMP_VERSION));
- printf("SBI Machine VENDORID=0x%lx ARCHID=0x%lx MIMPID=0x%lx\n",
- __sbi_base_ecall(SBI_EXT_BASE_GET_MVENDORID),
- __sbi_base_ecall(SBI_EXT_BASE_GET_MARCHID),
- __sbi_base_ecall(SBI_EXT_BASE_GET_MIMPID));
+ printf("SBI Machine VENDORID=0x%lx ARCHID=0x%lx MIMPID=0x%lx\n",
+ __sbi_base_ecall(SBI_EXT_BASE_GET_MVENDORID),
+ __sbi_base_ecall(SBI_EXT_BASE_GET_MARCHID),
+ __sbi_base_ecall(SBI_EXT_BASE_GET_MIMPID));
+ break;
+ default:
+ break;
+ }
return 0;
}
BAREBOX_CMD_START(cpuinfo)
.cmd = do_cpuinfo,
-BAREBOX_CMD_DESC("show CPU information")
-BAREBOX_CMD_GROUP(CMD_GRP_INFO)
- BAREBOX_CMD_END
+ BAREBOX_CMD_DESC("show CPU information")
+ BAREBOX_CMD_GROUP(CMD_GRP_INFO)
+BAREBOX_CMD_END
diff --git a/arch/riscv/lib/reloc.c b/arch/riscv/lib/reloc.c
index 2fc8818cd6..479d586afd 100644
--- a/arch/riscv/lib/reloc.c
+++ b/arch/riscv/lib/reloc.c
@@ -5,6 +5,7 @@
#include <linux/linkage.h>
#include <asm/sections.h>
#include <asm/barebox-riscv.h>
+#include <asm/cacheflush.h>
#include <debug_ll.h>
#include <asm-generic/module.h>
@@ -24,6 +25,11 @@
#define RISC_R_TYPE(x) ((x) & 0xFF)
+void sync_caches_for_execution(void)
+{
+ local_flush_icache_all();
+}
+
void relocate_to_current_adr(void)
{
unsigned long offset;
@@ -63,4 +69,6 @@ void relocate_to_current_adr(void)
panic("");
}
}
+
+ sync_caches_for_execution();
}
diff --git a/arch/riscv/lib/sbi.c b/arch/riscv/lib/sbi.c
index 973c9d9d0f..45a04fb821 100644
--- a/arch/riscv/lib/sbi.c
+++ b/arch/riscv/lib/sbi.c
@@ -6,6 +6,7 @@
*/
#include <asm/sbi.h>
+#include <asm/system.h>
#include <linux/export.h>
#include <errno.h>
#include <init.h>
@@ -53,6 +54,9 @@ static int sbi_init(void)
{
int ret;
+ if (riscv_mode() != RISCV_S_MODE)
+ return 0;
+
ret = sbi_get_spec_version();
if (ret > 0)
sbi_spec_version = ret;
diff --git a/arch/riscv/lib/setupc.S b/arch/riscv/lib/setupc.S
index 5fdd81c2c3..d225186c79 100644
--- a/arch/riscv/lib/setupc.S
+++ b/arch/riscv/lib/setupc.S
@@ -46,6 +46,8 @@ ENTRY(relocate_to_adr)
jal __memcpy
+ jal sync_caches_for_execution
+
REG_L a0, (SZREG * 1)(sp)
jr a0 /* jump to relocated address */
copied:
diff --git a/commands/Kconfig b/commands/Kconfig
index 7bb36d6e41..2237536088 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -47,9 +47,9 @@ config CMD_ARM_CPUINFO
config CMD_RISCV_CPUINFO
bool "cpuinfo command"
default y
- depends on RISCV_SBI
+ depends on RISCV
help
- Show SBI info about RISC-V CPU
+ Show info about RISC-V CPU
config CMD_DEVINFO
tristate
diff --git a/common/Kconfig b/common/Kconfig
index 1ece3f7318..2d7888b9fa 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -1376,6 +1376,12 @@ config DEBUG_RPI3_MINI_UART
config DEBUG_ERIZO
bool "Erizo ns16550 port"
depends on SOC_ERIZO
+ select DEBUG_LL_NS16550
+
+config DEBUG_STARFIVE
+ bool "Starfive ns16550 serial0 port"
+ depends on SOC_STARFIVE
+ select DEBUG_LL_NS16550
config DEBUG_SIFIVE
bool "SiFive serial0 port"
@@ -1383,6 +1389,11 @@ config DEBUG_SIFIVE
endchoice
+config DEBUG_LL_NS16550
+ bool
+ help
+ Selected by RISC-V platforms that use ns16550 for debug_ll
+
config DEBUG_IMX_UART_PORT
int "i.MX Debug UART Port Selection" if DEBUG_IMX1_UART || \
DEBUG_IMX21_UART || \
diff --git a/common/globalvar.c b/common/globalvar.c
index 8bb5015ce4..9e5a99f793 100644
--- a/common/globalvar.c
+++ b/common/globalvar.c
@@ -565,6 +565,27 @@ int globalvar_add_simple_int(const char *name, int *value,
return 0;
}
+int globalvar_add_simple_uint64(const char *name, u64 *value,
+ const char *format)
+{
+ struct param_d *p;
+ int ret;
+
+ ret = globalvar_remove_unqualified(name);
+ if (ret)
+ return ret;
+
+ p = dev_add_param_uint64(&global_device, name, NULL, NULL,
+ value, format, NULL);
+
+ if (IS_ERR(p))
+ return PTR_ERR(p);
+
+ globalvar_nv_sync(name);
+
+ return 0;
+}
+
int globalvar_add_bool(const char *name,
int (*set)(struct param_d *, void *),
int *value, void *priv)
diff --git a/common/oftree.c b/common/oftree.c
index 7028c49aca..962fff244d 100644
--- a/common/oftree.c
+++ b/common/oftree.c
@@ -232,7 +232,24 @@ static int of_fixup_bootargs(struct device_node *root, void *unused)
return err;
}
- return of_fixup_bootargs_bootsource(root, node);
+ err = of_fixup_bootargs_bootsource(root, node);
+ if (err)
+ return err;
+
+ if (IS_ENABLED(CONFIG_RISCV)) {
+ const char *hartid;
+
+ hartid = getenv("global.hartid");
+ if (hartid) {
+ unsigned long id;
+
+ err = kstrtoul(hartid, 10, &id);
+ if (!err)
+ err = of_property_write_u32(node, "boot-hartid", id);
+ }
+ }
+
+ return err;
}
static int of_register_bootargs_fixup(void)
diff --git a/drivers/Makefile b/drivers/Makefile
index e21ac7095c..9958b748eb 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -40,7 +40,7 @@ obj-$(CONFIG_HAB) += hab/
obj-$(CONFIG_CRYPTO_HW) += crypto/
obj-$(CONFIG_AIODEV) += aiodev/
obj-y += memory/
-obj-y += soc/imx/
+obj-y += soc/
obj-y += nvme/
obj-y += ddr/
obj-y += power/
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index b0be8d1bd8..499df2fe39 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -23,3 +23,4 @@ obj-$(CONFIG_MACH_MIPS_LOONGSON)+= loongson/
obj-$(CONFIG_ARCH_LAYERSCAPE) += clk-qoric.o
obj-y += analogbits/
obj-$(CONFIG_CLK_SIFIVE) += sifive/
+obj-$(CONFIG_SOC_STARFIVE) += starfive/
diff --git a/drivers/clk/starfive/Makefile b/drivers/clk/starfive/Makefile
new file mode 100644
index 0000000000..4e9bf7f2ba
--- /dev/null
+++ b/drivers/clk/starfive/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_SOC_STARFIVE_JH71XX) += jh7100-clkgen.o
diff --git a/drivers/clk/starfive/clk.h b/drivers/clk/starfive/clk.h
new file mode 100644
index 0000000000..cfbf116dcb
--- /dev/null
+++ b/drivers/clk/starfive/clk.h
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2021 Ahmad Fatoum, Pengutronix
+ */
+
+#ifndef STARFIVE_CLK_H_
+#define STARFIVE_CLK_H_
+
+#include <linux/clk.h>
+
+#define STARFIVE_CLK_ENABLE_SHIFT 31
+#define STARFIVE_CLK_INVERT_SHIFT 30
+#define STARFIVE_CLK_MUX_SHIFT 24
+
+static inline struct clk *starfive_clk_underspecifid(const char *name, const char *parent)
+{
+ /*
+ * TODO With documentation available, all users of this functions can be
+ * migrated to one of the above or to a clk_fixed_factor with
+ * appropriate factor
+ */
+ return clk_fixed_factor(name, parent, 1, 1, 0);
+}
+
+static inline struct clk *starfive_clk_divider(const char *name, const char *parent,
+ void __iomem *reg, u8 width)
+{
+ return starfive_clk_underspecifid(name, parent);
+}
+
+static inline struct clk *starfive_clk_gate(const char *name, const char *parent,
+ void __iomem *reg)
+{
+ return clk_gate(name, parent, reg, STARFIVE_CLK_ENABLE_SHIFT, CLK_SET_RATE_PARENT, 0);
+}
+
+static inline struct clk *starfive_clk_divider_table(const char *name,
+ const char *parent, void __iomem *reg, u8 width,
+ const struct clk_div_table *table)
+{
+ return clk_divider_table(name, parent, CLK_SET_RATE_PARENT, reg, 0,
+ width, table, 0);
+}
+
+static inline struct clk *starfive_clk_gated_divider(const char *name,
+ const char *parent, void __iomem *reg, u8 width)
+{
+ /* TODO divider part */
+ return clk_gate(name, parent, reg, STARFIVE_CLK_ENABLE_SHIFT, CLK_SET_RATE_PARENT, 0);
+}
+
+static inline struct clk *starfive_clk_gate_dis(const char *name, const char *parent,
+ void __iomem *reg)
+{
+ return clk_gate_inverted(name, parent, reg, STARFIVE_CLK_INVERT_SHIFT, CLK_SET_RATE_PARENT);
+}
+
+static inline struct clk *starfive_clk_mux(const char *name, void __iomem *reg,
+ u8 width, const char * const *parents, u8 num_parents)
+{
+ return clk_mux(name, 0, reg, STARFIVE_CLK_MUX_SHIFT, width, parents, num_parents, 0);
+}
+
+#endif
diff --git a/drivers/clk/starfive/jh7100-clkgen.c b/drivers/clk/starfive/jh7100-clkgen.c
new file mode 100644
index 0000000000..df5353e8e6
--- /dev/null
+++ b/drivers/clk/starfive/jh7100-clkgen.c
@@ -0,0 +1,363 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2021 Ahmad Fatoum, Pengutronix
+ */
+
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <linux/clk.h>
+#include <io.h>
+#include <of.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <dt-bindings/clock/starfive-jh7100.h>
+
+#include "clk.h"
+
+
+static const char *cpundbus_root_sels[4] = {
+ [0] = "osc_sys",
+ [1] = "pll0_out",
+ [2] = "pll1_out",
+ [3] = "pll2_out",
+};
+
+static const char *dla_root_sels[4] = {
+ [0] = "osc_sys",
+ [1] = "pll1_out",
+ [2] = "pll2_out",
+ [3] = "dummy",
+};
+
+static const char *dsp_root_sels[4] = {
+ [0] = "osc_sys",
+ [1] = "pll0_out",
+ [2] = "pll1_out",
+ [3] = "pll2_out",
+};
+
+static const char *gmacusb_root_sels[4] = {
+ [0] = "osc_sys",
+ [1] = "pll0_out",
+ [2] = "pll2_out",
+ [3] = "dummy",
+};
+
+static const char *perh0_root_sels[2] = {
+ [0] = "osc_sys",
+ [1] = "pll0_out",
+};
+
+static const char *perh1_root_sels[2] = {
+ [0] = "osc_sys",
+ [1] = "pll2_out",
+};
+
+static const char *vin_root_sels[4] = {
+ [0] = "osc_sys",
+ [1] = "pll1_out",
+ [2] = "pll2_out",
+ [3] = "dummy",
+};
+
+static const char *vout_root_sels[4] = {
+ [0] = "osc_aud",
+ [1] = "pll0_out",
+ [2] = "pll2_out",
+ [3] = "dummy",
+};
+
+static const char *cdechifi4_root_sels[4] = {
+ [0] = "osc_sys",
+ [1] = "pll1_out",
+ [2] = "pll2_out",
+ [3] = "dummy",
+};
+
+static const char *cdec_root_sels[4] = {
+ [0] = "osc_sys",
+ [1] = "pll0_out",
+ [2] = "pll1_out",
+ [3] = "dummy",
+};
+
+static const char *voutbus_root_sels[4] = {
+ [0] = "osc_aud",
+ [1] = "pll0_out",
+ [2] = "pll2_out",
+ [3] = "dummy",
+};
+
+static const char *pll2_refclk_sels[2] = {
+ [0] = "osc_sys",
+ [1] = "osc_aud",
+};
+
+static const char *ddrc0_sels[4] = {
+ [0] = "ddrosc_div2",
+ [1] = "ddrpll_div2",
+ [2] = "ddrpll_div4",
+ [3] = "ddrpll_div8",
+};
+
+static const char *ddrc1_sels[4] = {
+ [0] = "ddrosc_div2",
+ [1] = "ddrpll_div2",
+ [2] = "ddrpll_div4",
+ [3] = "ddrpll_div8",
+};
+
+static const char *nne_bus_sels[2] = {
+ [0] = "cpu_axi",
+ [1] = "nnebus_src1",
+};
+
+static const char *usbphy_25m_sels[2] = {
+ [0] = "osc_sys",
+ [1] = "usbphy_plldiv25m",
+};
+
+static const char *gmac_tx_sels[4] = {
+ [0] = "gmac_gtxclk",
+ [1] = "gmac_mii_txclk",
+ [2] = "gmac_rmii_txclk",
+ [3] = "dummy",
+};
+
+static const char *gmac_rx_pre_sels[2] = {
+ [0] = "gmac_gr_mii_rxclk",
+ [1] = "gmac_rmii_rxclk",
+};
+
+static struct clk *clks[CLK_END];
+
+/* assume osc_sys as direct parent for clocks of yet unknown lineage */
+#define UNKNOWN "osc_sys"
+
+static void starfive_clkgen_init(struct device_node *np, void __iomem *base)
+{
+ clks[CLK_OSC_SYS] = of_clk_get_by_name(np, "osc_sys");
+ clks[CLK_OSC_AUD] = of_clk_get_by_name(np, "osc_aud");
+ clks[CLK_PLL0_OUT] = starfive_clk_underspecifid("pll0_out", "osc_sys");
+ clks[CLK_PLL1_OUT] = starfive_clk_underspecifid("pll1_out", "osc_sys");
+ clks[CLK_PLL2_OUT] = starfive_clk_underspecifid("pll2_out", "pll2_refclk");
+ clks[CLK_CPUNDBUS_ROOT] = starfive_clk_mux("cpundbus_root", base + 0x0, 2, cpundbus_root_sels, ARRAY_SIZE(cpundbus_root_sels));
+ clks[CLK_DLA_ROOT] = starfive_clk_mux("dla_root", base + 0x4, 2, dla_root_sels, ARRAY_SIZE(dla_root_sels));
+ clks[CLK_DSP_ROOT] = starfive_clk_mux("dsp_root", base + 0x8, 2, dsp_root_sels, ARRAY_SIZE(dsp_root_sels));
+ clks[CLK_GMACUSB_ROOT] = starfive_clk_mux("gmacusb_root", base + 0xC, 2, gmacusb_root_sels, ARRAY_SIZE(gmacusb_root_sels));
+ clks[CLK_PERH0_ROOT] = starfive_clk_mux("perh0_root", base + 0x10, 1, perh0_root_sels, ARRAY_SIZE(perh0_root_sels));
+ clks[CLK_PERH1_ROOT] = starfive_clk_mux("perh1_root", base + 0x14, 1, perh1_root_sels, ARRAY_SIZE(perh1_root_sels));
+ clks[CLK_VIN_ROOT] = starfive_clk_mux("vin_root", base + 0x18, 2, vin_root_sels, ARRAY_SIZE(vin_root_sels));
+ clks[CLK_VOUT_ROOT] = starfive_clk_mux("vout_root", base + 0x1C, 2, vout_root_sels, ARRAY_SIZE(vout_root_sels));
+ clks[CLK_AUDIO_ROOT] = starfive_clk_gated_divider("audio_root", UNKNOWN, base + 0x20, 4);
+ clks[CLK_CDECHIFI4_ROOT] = starfive_clk_mux("cdechifi4_root", base + 0x24, 2, cdechifi4_root_sels, ARRAY_SIZE(cdechifi4_root_sels));
+ clks[CLK_CDEC_ROOT] = starfive_clk_mux("cdec_root", base + 0x28, 2, cdec_root_sels, ARRAY_SIZE(cdec_root_sels));
+ clks[CLK_VOUTBUS_ROOT] = starfive_clk_mux("voutbus_root", base + 0x2C, 2, voutbus_root_sels, ARRAY_SIZE(voutbus_root_sels));
+ clks[CLK_CPUNBUS_ROOT_DIV] = starfive_clk_divider("cpunbus_root_div", "cpunbus_root", base + 0x30, 2);
+ clks[CLK_DSP_ROOT_DIV] = starfive_clk_divider("dsp_root_div", "dsp_root", base + 0x34, 3);
+ clks[CLK_PERH0_SRC] = starfive_clk_divider("perh0_src", "perh0_root", base + 0x38, 3);
+ clks[CLK_PERH1_SRC] = starfive_clk_divider("perh1_src", "perh1_root", base + 0x3C, 3);
+ clks[CLK_PLL0_TESTOUT] = starfive_clk_gated_divider("pll0_testout", "pll0_out", base + 0x40, 5);
+ clks[CLK_PLL1_TESTOUT] = starfive_clk_gated_divider("pll1_testout", "pll1_out", base + 0x44, 5);
+ clks[CLK_PLL2_TESTOUT] = starfive_clk_gated_divider("pll2_testout", "pll2_out", base + 0x48, 5);
+ clks[CLK_PLL2_REF] = starfive_clk_mux("pll2_refclk", base + 0x4C, 1, pll2_refclk_sels, ARRAY_SIZE(pll2_refclk_sels));
+ clks[CLK_CPU_CORE] = starfive_clk_divider("cpu_core", UNKNOWN, base + 0x50, 4);
+ clks[CLK_CPU_AXI] = starfive_clk_divider("cpu_axi", UNKNOWN, base + 0x54, 4);
+ clks[CLK_AHB_BUS] = starfive_clk_divider("ahb_bus", UNKNOWN, base + 0x58, 4);
+ clks[CLK_APB1_BUS] = starfive_clk_divider("apb1_bus", UNKNOWN, base + 0x5C, 4);
+ clks[CLK_APB2_BUS] = starfive_clk_divider("apb2_bus", UNKNOWN, base + 0x60, 4);
+ clks[CLK_DOM3AHB_BUS] = starfive_clk_gate("dom3ahb_bus", UNKNOWN, base + 0x64);
+ clks[CLK_DOM7AHB_BUS] = starfive_clk_gate("dom7ahb_bus", UNKNOWN, base + 0x68);
+ clks[CLK_U74_CORE0] = starfive_clk_gate("u74_core0", UNKNOWN, base + 0x6C);
+ clks[CLK_U74_CORE1] = starfive_clk_gated_divider("u74_core1", "", base + 0x70, 4);
+ clks[CLK_U74_AXI] = starfive_clk_gate("u74_axi", UNKNOWN, base + 0x74);
+ clks[CLK_U74RTC_TOGGLE] = starfive_clk_gate("u74rtc_toggle", UNKNOWN, base + 0x78);
+ clks[CLK_SGDMA2P_AXI] = starfive_clk_gate("sgdma2p_axi", UNKNOWN, base + 0x7C);
+ clks[CLK_DMA2PNOC_AXI] = starfive_clk_gate("dma2pnoc_axi", UNKNOWN, base + 0x80);
+ clks[CLK_SGDMA2P_AHB] = starfive_clk_gate("sgdma2p_ahb", UNKNOWN, base + 0x84);
+ clks[CLK_DLA_BUS] = starfive_clk_divider("dla_bus", UNKNOWN, base + 0x88, 3);
+ clks[CLK_DLA_AXI] = starfive_clk_gate("dla_axi", UNKNOWN, base + 0x8C);
+ clks[CLK_DLANOC_AXI] = starfive_clk_gate("dlanoc_axi", UNKNOWN, base + 0x90);
+ clks[CLK_DLA_APB] = starfive_clk_gate("dla_apb", UNKNOWN, base + 0x94);
+ clks[CLK_VP6_CORE] = starfive_clk_gated_divider("vp6_core", UNKNOWN, base + 0x98, 3);
+ clks[CLK_VP6BUS_SRC] = starfive_clk_divider("vp6bus_src", UNKNOWN, base + 0x9C, 3);
+ clks[CLK_VP6_AXI] = starfive_clk_gated_divider("vp6_axi", UNKNOWN, base + 0xA0, 3);
+ clks[CLK_VCDECBUS_SRC] = starfive_clk_divider("vcdecbus_src", UNKNOWN, base + 0xA4, 3);
+ clks[CLK_VDEC_BUS] = starfive_clk_divider("vdec_bus", UNKNOWN, base + 0xA8, 4);
+ clks[CLK_VDEC_AXI] = starfive_clk_gate("vdec_axi", UNKNOWN, base + 0xAC);
+ clks[CLK_VDECBRG_MAIN] = starfive_clk_gate("vdecbrg_mainclk", UNKNOWN, base + 0xB0);
+ clks[CLK_VDEC_BCLK] = starfive_clk_gated_divider("vdec_bclk", UNKNOWN, base + 0xB4, 4);
+ clks[CLK_VDEC_CCLK] = starfive_clk_gated_divider("vdec_cclk", UNKNOWN, base + 0xB8, 4);
+ clks[CLK_VDEC_APB] = starfive_clk_gate("vdec_apb", UNKNOWN, base + 0xBC);
+ clks[CLK_JPEG_AXI] = starfive_clk_gated_divider("jpeg_axi", UNKNOWN, base + 0xC0, 4);
+ clks[CLK_JPEG_CCLK] = starfive_clk_gated_divider("jpeg_cclk", UNKNOWN, base + 0xC4, 4);
+ clks[CLK_JPEG_APB] = starfive_clk_gate("jpeg_apb", UNKNOWN, base + 0xC8);
+ clks[CLK_GC300_2X] = starfive_clk_gated_divider("gc300_2x", UNKNOWN, base + 0xCC, 4);
+ clks[CLK_GC300_AHB] = starfive_clk_gate("gc300_ahb", UNKNOWN, base + 0xD0);
+ clks[CLK_JPCGC300_AXIBUS] = starfive_clk_divider("jpcgc300_axibus", UNKNOWN, base + 0xD4, 4);
+ clks[CLK_GC300_AXI] = starfive_clk_gate("gc300_axi", UNKNOWN, base + 0xD8);
+ clks[CLK_JPCGC300_MAIN] = starfive_clk_gate("jpcgc300_mainclk", UNKNOWN, base + 0xDC);
+ clks[CLK_VENC_BUS] = starfive_clk_divider("venc_bus", UNKNOWN, base + 0xE0, 4);
+ clks[CLK_VENC_AXI] = starfive_clk_gate("venc_axi", UNKNOWN, base + 0xE4);
+ clks[CLK_VENCBRG_MAIN] = starfive_clk_gate("vencbrg_mainclk", UNKNOWN, base + 0xE8);
+ clks[CLK_VENC_BCLK] = starfive_clk_gated_divider("venc_bclk", UNKNOWN, base + 0xEC, 4);
+ clks[CLK_VENC_CCLK] = starfive_clk_gated_divider("venc_cclk", UNKNOWN, base + 0xF0, 4);
+ clks[CLK_VENC_APB] = starfive_clk_gate("venc_apb", UNKNOWN, base + 0xF4);
+ clks[CLK_DDRPLL_DIV2] = starfive_clk_gated_divider("ddrpll_div2", UNKNOWN, base + 0xF8, 2);
+ clks[CLK_DDRPLL_DIV4] = starfive_clk_gated_divider("ddrpll_div4", UNKNOWN, base + 0xFC, 2);
+ clks[CLK_DDRPLL_DIV8] = starfive_clk_gated_divider("ddrpll_div8", UNKNOWN, base + 0x100, 2);
+ clks[CLK_DDROSC_DIV2] = starfive_clk_gated_divider("ddrosc_div2", UNKNOWN, base + 0x104, 2);
+ clks[CLK_DDRC0] = starfive_clk_mux("ddrc0", base + 0x108, 2, ddrc0_sels, ARRAY_SIZE(ddrc0_sels));
+ clks[CLK_DDRC1] = starfive_clk_mux("ddrc1", base + 0x10C, 2, ddrc1_sels, ARRAY_SIZE(ddrc1_sels));
+ clks[CLK_DDRPHY_APB] = starfive_clk_gate("ddrphy_apb", UNKNOWN, base + 0x110);
+ clks[CLK_NOC_ROB] = starfive_clk_divider("noc_rob", UNKNOWN, base + 0x114, 4);
+ clks[CLK_NOC_COG] = starfive_clk_divider("noc_cog", UNKNOWN, base + 0x118, 4);
+ clks[CLK_NNE_AHB] = starfive_clk_gate("nne_ahb", UNKNOWN, base + 0x11C);
+ clks[CLK_NNEBUS_SRC1] = starfive_clk_divider("nnebus_src1", UNKNOWN, base + 0x120, 3);
+ clks[CLK_NNE_BUS] = starfive_clk_mux("nne_bus", base + 0x124, 2, nne_bus_sels, ARRAY_SIZE(nne_bus_sels));
+ clks[CLK_NNE_AXI] = starfive_clk_gate("nne_axi", UNKNOWN, base + 0x128);
+ clks[CLK_NNENOC_AXI] = starfive_clk_gate("nnenoc_axi", UNKNOWN, base + 0x12C);
+ clks[CLK_DLASLV_AXI] = starfive_clk_gate("dlaslv_axi", UNKNOWN, base + 0x130);
+ clks[CLK_DSPX2C_AXI] = starfive_clk_gate("dspx2c_axi", UNKNOWN, base + 0x134);
+ clks[CLK_HIFI4_SRC] = starfive_clk_divider("hifi4_src", UNKNOWN, base + 0x138, 3);
+ clks[CLK_HIFI4_COREFREE] = starfive_clk_divider("hifi4_corefree", UNKNOWN, base + 0x13C, 4);
+ clks[CLK_HIFI4_CORE] = starfive_clk_gate("hifi4_core", UNKNOWN, base + 0x140);
+ clks[CLK_HIFI4_BUS] = starfive_clk_divider("hifi4_bus", UNKNOWN, base + 0x144, 4);
+ clks[CLK_HIFI4_AXI] = starfive_clk_gate("hifi4_axi", UNKNOWN, base + 0x148);
+ clks[CLK_HIFI4NOC_AXI] = starfive_clk_gate("hifi4noc_axi", UNKNOWN, base + 0x14C);
+ clks[CLK_SGDMA1P_BUS] = starfive_clk_divider("sgdma1p_bus", UNKNOWN, base + 0x150, 4);
+ clks[CLK_SGDMA1P_AXI] = starfive_clk_gate("sgdma1p_axi", UNKNOWN, base + 0x154);
+ clks[CLK_DMA1P_AXI] = starfive_clk_gate("dma1p_axi", UNKNOWN, base + 0x158);
+ clks[CLK_X2C_AXI] = starfive_clk_gated_divider("x2c_axi", UNKNOWN, base + 0x15C, 4);
+ clks[CLK_USB_BUS] = starfive_clk_divider("usb_bus", UNKNOWN, base + 0x160, 4);
+ clks[CLK_USB_AXI] = starfive_clk_gate("usb_axi", UNKNOWN, base + 0x164);
+ clks[CLK_USBNOC_AXI] = starfive_clk_gate("usbnoc_axi", UNKNOWN, base + 0x168);
+ clks[CLK_USBPHY_ROOTDIV] = starfive_clk_divider("usbphy_rootdiv", UNKNOWN, base + 0x16C, 3);
+ clks[CLK_USBPHY_125M] = starfive_clk_gated_divider("usbphy_125m", UNKNOWN, base + 0x170, 4);
+ clks[CLK_USBPHY_PLLDIV25M] = starfive_clk_gated_divider("usbphy_plldiv25m", UNKNOWN, base + 0x174, 6);
+ clks[CLK_USBPHY_25M] = starfive_clk_mux("usbphy_25m", base + 0x178, 1, usbphy_25m_sels, ARRAY_SIZE(usbphy_25m_sels));
+ clks[CLK_AUDIO_DIV] = starfive_clk_divider("audio_div", UNKNOWN, base + 0x17C, 18);
+ clks[CLK_AUDIO_SRC] = starfive_clk_gate("audio_src", UNKNOWN, base + 0x180);
+ clks[CLK_AUDIO_12288] = starfive_clk_gate("audio_12288", UNKNOWN, base + 0x184);
+ clks[CLK_VIN_SRC] = starfive_clk_gated_divider("vin_src", UNKNOWN, base + 0x188, 3);
+ clks[CLK_ISP0_BUS] = starfive_clk_divider("isp0_bus", UNKNOWN, base + 0x18C, 4);
+ clks[CLK_ISP0_AXI] = starfive_clk_gate("isp0_axi", UNKNOWN, base + 0x190);
+ clks[CLK_ISP0NOC_AXI] = starfive_clk_gate("isp0noc_axi", UNKNOWN, base + 0x194);
+ clks[CLK_ISPSLV_AXI] = starfive_clk_gate("ispslv_axi", UNKNOWN, base + 0x198);
+ clks[CLK_ISP1_BUS] = starfive_clk_divider("isp1_bus", UNKNOWN, base + 0x19C, 4);
+ clks[CLK_ISP1_AXI] = starfive_clk_gate("isp1_axi", UNKNOWN, base + 0x1A0);
+ clks[CLK_ISP1NOC_AXI] = starfive_clk_gate("isp1noc_axi", UNKNOWN, base + 0x1A4);
+ clks[CLK_VIN_BUS] = starfive_clk_divider("vin_bus", UNKNOWN, base + 0x1A8, 4);
+ clks[CLK_VIN_AXI] = starfive_clk_gate("vin_axi", UNKNOWN, base + 0x1AC);
+ clks[CLK_VINNOC_AXI] = starfive_clk_gate("vinnoc_axi", UNKNOWN, base + 0x1B0);
+ clks[CLK_VOUT_SRC] = starfive_clk_gated_divider("vout_src", UNKNOWN, base + 0x1B4, 3);
+ clks[CLK_DISPBUS_SRC] = starfive_clk_divider("dispbus_src", UNKNOWN, base + 0x1B8, 3);
+ clks[CLK_DISP_BUS] = starfive_clk_divider("disp_bus", UNKNOWN, base + 0x1BC, 3);
+ clks[CLK_DISP_AXI] = starfive_clk_gate("disp_axi", UNKNOWN, base + 0x1C0);
+ clks[CLK_DISPNOC_AXI] = starfive_clk_gate("dispnoc_axi", UNKNOWN, base + 0x1C4);
+ clks[CLK_SDIO0_AHB] = starfive_clk_gate("sdio0_ahb", UNKNOWN, base + 0x1C8);
+ clks[CLK_SDIO0_CCLKINT] = starfive_clk_gated_divider("sdio0_cclkint", UNKNOWN, base + 0x1CC, 5);
+ clks[CLK_SDIO0_CCLKINT_INV] = starfive_clk_gate_dis("sdio0_cclkint_inv", UNKNOWN, base + 0x1D0);
+ clks[CLK_SDIO1_AHB] = starfive_clk_gate("sdio1_ahb", UNKNOWN, base + 0x1D4);
+ clks[CLK_SDIO1_CCLKINT] = starfive_clk_gated_divider("sdio1_cclkint", UNKNOWN, base + 0x1D8, 5);
+ clks[CLK_SDIO1_CCLKINT_INV] = starfive_clk_gate_dis("sdio1_cclkint_inv", UNKNOWN, base + 0x1DC);
+ clks[CLK_GMAC_AHB] = starfive_clk_gate("gmac_ahb", UNKNOWN, base + 0x1E0);
+ clks[CLK_GMAC_ROOT_DIV] = starfive_clk_divider("gmac_root_div", UNKNOWN, base + 0x1E4, 4);
+ clks[CLK_GMAC_PTP_REF] = starfive_clk_gated_divider("gmac_ptp_refclk", UNKNOWN, base + 0x1E8, 5);
+ clks[CLK_GMAC_GTX] = starfive_clk_gated_divider("gmac_gtxclk", UNKNOWN, base + 0x1EC, 8);
+ clks[CLK_GMAC_RMII_TX] = starfive_clk_gated_divider("gmac_rmii_txclk", UNKNOWN, base + 0x1F0, 4);
+ clks[CLK_GMAC_RMII_RX] = starfive_clk_gated_divider("gmac_rmii_rxclk", UNKNOWN, base + 0x1F4, 4);
+ clks[CLK_GMAC_TX] = starfive_clk_mux("gmac_tx", base + 0x1F8, 2, gmac_tx_sels, ARRAY_SIZE(gmac_tx_sels));
+ clks[CLK_GMAC_TX_INV] = starfive_clk_gate_dis("gmac_tx_inv", UNKNOWN, base + 0x1FC);
+ clks[CLK_GMAC_RX_PRE] = starfive_clk_mux("gmac_rx_pre", base + 0x200, 1, gmac_rx_pre_sels, ARRAY_SIZE(gmac_rx_pre_sels));
+ clks[CLK_GMAC_RX_INV] = starfive_clk_gate_dis("gmac_rx_inv", UNKNOWN, base + 0x204);
+ clks[CLK_GMAC_RMII] = starfive_clk_gate("gmac_rmii", UNKNOWN, base + 0x208);
+ clks[CLK_GMAC_TOPHYREF] = starfive_clk_gated_divider("gmac_tophyref", UNKNOWN, base + 0x20C, 7);
+ clks[CLK_SPI2AHB_AHB] = starfive_clk_gate("spi2ahb_ahb", UNKNOWN, base + 0x210);
+ clks[CLK_SPI2AHB_CORE] = starfive_clk_gated_divider("spi2ahb_core", UNKNOWN, base + 0x214, 5);
+ clks[CLK_EZMASTER_AHB] = starfive_clk_gate("ezmaster_ahb", UNKNOWN, base + 0x218);
+ clks[CLK_E24_AHB] = starfive_clk_gate("e24_ahb", UNKNOWN, base + 0x21C);
+ clks[CLK_E24RTC_TOGGLE] = starfive_clk_gate("e24rtc_toggle", UNKNOWN, base + 0x220);
+ clks[CLK_QSPI_AHB] = starfive_clk_gate("qspi_ahb", UNKNOWN, base + 0x224);
+ clks[CLK_QSPI_APB] = starfive_clk_gate("qspi_apb", UNKNOWN, base + 0x228);
+ clks[CLK_QSPI_REF] = starfive_clk_gated_divider("qspi_refclk", UNKNOWN, base + 0x22C, 5);
+ clks[CLK_SEC_AHB] = starfive_clk_gate("sec_ahb", UNKNOWN, base + 0x230);
+ clks[CLK_AES] = starfive_clk_gate("aes_clk", UNKNOWN, base + 0x234);
+ clks[CLK_SHA] = starfive_clk_gate("sha_clk", UNKNOWN, base + 0x238);
+ clks[CLK_PKA] = starfive_clk_gate("pka_clk", UNKNOWN, base + 0x23C);
+ clks[CLK_TRNG_APB] = starfive_clk_gate("trng_apb", UNKNOWN, base + 0x240);
+ clks[CLK_OTP_APB] = starfive_clk_gate("otp_apb", UNKNOWN, base + 0x244);
+ clks[CLK_UART0_APB] = starfive_clk_gate("uart0_apb", UNKNOWN, base + 0x248);
+ clks[CLK_UART0_CORE] = starfive_clk_gated_divider("uart0_core", UNKNOWN, base + 0x24C, 6);
+ clks[CLK_UART1_APB] = starfive_clk_gate("uart1_apb", UNKNOWN, base + 0x250);
+ clks[CLK_UART1_CORE] = starfive_clk_gated_divider("uart1_core", UNKNOWN, base + 0x254, 6);
+ clks[CLK_SPI0_APB] = starfive_clk_gate("spi0_apb", UNKNOWN, base + 0x258);
+ clks[CLK_SPI0_CORE] = starfive_clk_gated_divider("spi0_core", UNKNOWN, base + 0x25C, 6);
+ clks[CLK_SPI1_APB] = starfive_clk_gate("spi1_apb", UNKNOWN, base + 0x260);
+ clks[CLK_SPI1_CORE] = starfive_clk_gated_divider("spi1_core", UNKNOWN, base + 0x264, 6);
+ clks[CLK_I2C0_APB] = starfive_clk_gate("i2c0_apb", UNKNOWN, base + 0x268);
+ clks[CLK_I2C0_CORE] = starfive_clk_gated_divider("i2c0_core", UNKNOWN, base + 0x26C, 6);
+ clks[CLK_I2C1_APB] = starfive_clk_gate("i2c1_apb", UNKNOWN, base + 0x270);
+ clks[CLK_I2C1_CORE] = starfive_clk_gated_divider("i2c1_core", UNKNOWN, base + 0x274, 6);
+ clks[CLK_GPIO_APB] = starfive_clk_gate("gpio_apb", UNKNOWN, base + 0x278);
+ clks[CLK_UART2_APB] = starfive_clk_gate("uart2_apb", UNKNOWN, base + 0x27C);
+ clks[CLK_UART2_CORE] = starfive_clk_gated_divider("uart2_core", UNKNOWN, base + 0x280, 6);
+ clks[CLK_UART3_APB] = starfive_clk_gate("uart3_apb", UNKNOWN, base + 0x284);
+ clks[CLK_UART3_CORE] = starfive_clk_gated_divider("uart3_core", UNKNOWN, base + 0x288, 6);
+ clks[CLK_SPI2_APB] = starfive_clk_gate("spi2_apb", UNKNOWN, base + 0x28C);
+ clks[CLK_SPI2_CORE] = starfive_clk_gated_divider("spi2_core", UNKNOWN, base + 0x290, 6);
+ clks[CLK_SPI3_APB] = starfive_clk_gate("spi3_apb", UNKNOWN, base + 0x294);
+ clks[CLK_SPI3_CORE] = starfive_clk_gated_divider("spi3_core", UNKNOWN, base + 0x298, 6);
+ clks[CLK_I2C2_APB] = starfive_clk_gate("i2c2_apb", UNKNOWN, base + 0x29C);
+ clks[CLK_I2C2_CORE] = starfive_clk_gated_divider("i2c2_core", UNKNOWN, base + 0x2A0, 6);
+ clks[CLK_I2C3_APB] = starfive_clk_gate("i2c3_apb", UNKNOWN, base + 0x2A4);
+ clks[CLK_I2C3_CORE] = starfive_clk_gated_divider("i2c3_core", UNKNOWN, base + 0x2A8, 6);
+ clks[CLK_WDTIMER_APB] = starfive_clk_gate("wdtimer_apb", UNKNOWN, base + 0x2AC);
+ clks[CLK_WDT_CORE] = starfive_clk_gated_divider("wdt_coreclk", UNKNOWN, base + 0x2B0, 6);
+ clks[CLK_TIMER0_CORE] = starfive_clk_gated_divider("timer0_coreclk", UNKNOWN, base + 0x2B4, 6);
+ clks[CLK_TIMER1_CORE] = starfive_clk_gated_divider("timer1_coreclk", UNKNOWN, base + 0x2B8, 6);
+ clks[CLK_TIMER2_CORE] = starfive_clk_gated_divider("timer2_coreclk", UNKNOWN, base + 0x2BC, 6);
+ clks[CLK_TIMER3_CORE] = starfive_clk_gated_divider("timer3_coreclk", UNKNOWN, base + 0x2C0, 6);
+ clks[CLK_TIMER4_CORE] = starfive_clk_gated_divider("timer4_coreclk", UNKNOWN, base + 0x2C4, 6);
+ clks[CLK_TIMER5_CORE] = starfive_clk_gated_divider("timer5_coreclk", UNKNOWN, base + 0x2C8, 6);
+ clks[CLK_TIMER6_CORE] = starfive_clk_gated_divider("timer6_coreclk", UNKNOWN, base + 0x2CC, 6);
+ clks[CLK_VP6INTC_APB] = starfive_clk_gate("vp6intc_apb", UNKNOWN, base + 0x2D0);
+ clks[CLK_PWM_APB] = starfive_clk_gate("pwm_apb", UNKNOWN, base + 0x2D4);
+ clks[CLK_MSI_APB] = starfive_clk_gate("msi_apb", UNKNOWN, base + 0x2D8);
+ clks[CLK_TEMP_APB] = starfive_clk_gate("temp_apb", UNKNOWN, base + 0x2DC);
+ clks[CLK_TEMP_SENSE] = starfive_clk_gated_divider("temp_sense", UNKNOWN, base + 0x2E0, 5);
+ clks[CLK_SYSERR_APB] = starfive_clk_gate("syserr_apb", UNKNOWN, base + 0x2E4);
+}
+
+static struct clk_onecell_data clk_data;
+
+static int starfive_clkgen_clk_probe(struct device_d *dev)
+{
+ struct resource *iores;
+
+ iores = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(iores))
+ return PTR_ERR(iores);
+
+ starfive_clkgen_init(dev->device_node, IOMEM(iores->start));
+
+ clk_data.clks = clks;
+ clk_data.clk_num = ARRAY_SIZE(clks);
+ of_clk_add_provider(dev->device_node, of_clk_src_onecell_get,
+ &clk_data);
+
+ return 0;
+}
+
+static __maybe_unused struct of_device_id starfive_clkgen_clk_dt_ids[] = {
+ { .compatible = "starfive,jh7100-clkgen" },
+ { /* sentinel */ }
+};
+
+static struct driver_d starfive_clkgen_clk_driver = {
+ .probe = starfive_clkgen_clk_probe,
+ .name = "starfive-clkgen",
+ .of_compatible = starfive_clkgen_clk_dt_ids,
+};
+core_platform_driver(starfive_clkgen_clk_driver);
diff --git a/drivers/clocksource/timer-clint.c b/drivers/clocksource/timer-clint.c
index b7360010bd..412ce3e1e9 100644
--- a/drivers/clocksource/timer-clint.c
+++ b/drivers/clocksource/timer-clint.c
@@ -17,6 +17,7 @@
#include <linux/err.h>
#include <io.h>
#include <asm/timer.h>
+#include <asm/system.h>
#define CLINT_TIMER_VAL_OFF 0xbff8
@@ -63,8 +64,8 @@ static int clint_timer_init_dt(struct device_d* dev)
{
struct resource *iores;
- /* one timer is enough */
- if (clint_timer_val)
+ /* one timer is enough. Only M-Mode */
+ if (clint_timer_val || riscv_mode() != RISCV_M_MODE)
return 0;
iores = dev_request_mem_resource(dev, 0);
@@ -72,7 +73,7 @@ static int clint_timer_init_dt(struct device_d* dev)
return PTR_ERR(iores);
clint_timer_val = IOMEM(iores->start) + CLINT_TIMER_VAL_OFF;
- dev_info(dev, "running at %lu Hz\n", riscv_timebase);
+ dev_dbg(dev, "running at %lu Hz\n", riscv_timebase);
clint_clocksource.mult = clocksource_hz2mult(riscv_timebase, clint_clocksource.shift);
diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
index ef67cff475..5a517fe6b4 100644
--- a/drivers/clocksource/timer-riscv.c
+++ b/drivers/clocksource/timer-riscv.c
@@ -12,6 +12,7 @@
#include <clock.h>
#include <asm/timer.h>
#include <asm/csr.h>
+#include <asm/system.h>
static u64 notrace riscv_timer_get_count_sbi(void)
{
@@ -45,7 +46,7 @@ static u64 notrace riscv_timer_get_count_rdcycle(void)
static u64 notrace riscv_timer_get_count(void)
{
- if (IS_ENABLED(CONFIG_RISCV_SBI))
+ if (riscv_mode() == RISCV_S_MODE)
return riscv_timer_get_count_sbi();
else
return riscv_timer_get_count_rdcycle();
@@ -59,7 +60,7 @@ static struct clocksource riscv_clocksource = {
static int riscv_timer_init(struct device_d* dev)
{
- dev_info(dev, "running at %lu Hz\n", riscv_timebase);
+ dev_dbg(dev, "running at %lu Hz\n", riscv_timebase);
riscv_clocksource.mult = clocksource_hz2mult(riscv_timebase, riscv_clocksource.shift);
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index a8ee9e58b8..98a44fbbb5 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -171,6 +171,14 @@ config GPIO_SIFIVE
help
Say yes here to support the GPIO device on SiFive SoCs.
+config GPIO_STARFIVE
+ bool "StarFive GPIO support"
+ depends on SOC_STARFIVE || CROSS_COMPILE
+ depends on OF_GPIO
+ select GPIO_GENERIC
+ help
+ Say yes here to support the GPIO device on StarFive SoCs.
+
config GPIO_LIBFTDI1
bool "libftdi1 driver"
depends on SANDBOX
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 25e12105d8..638cbb19a3 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -24,3 +24,4 @@ obj-$(CONFIG_GPIO_SX150X) += gpio-sx150x.o
obj-$(CONFIG_GPIO_VF610) += gpio-vf610.o
obj-$(CONFIG_GPIO_RASPBERRYPI_EXP) += gpio-raspberrypi-exp.o
obj-$(CONFIG_GPIO_SIFIVE) += gpio-sifive.o
+obj-$(CONFIG_GPIO_STARFIVE) += gpio-starfive-vic.o
diff --git a/drivers/gpio/gpio-starfive-vic.c b/drivers/gpio/gpio-starfive-vic.c
new file mode 100644
index 0000000000..baa4f584d5
--- /dev/null
+++ b/drivers/gpio/gpio-starfive-vic.c
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * COPYRIGHT 2020 Shanghai StarFive Technology Co., Ltd.
+ */
+
+#include <linux/basic_mmio_gpio.h>
+#include <linux/reset.h>
+#include <linux/clk.h>
+#include <printk.h>
+#include <driver.h>
+#include <errno.h>
+#include <pinctrl.h>
+
+#define GPIO_EN 0x0
+#define GPIO_IS_LOW 0x10
+#define GPIO_IS_HIGH 0x14
+#define GPIO_IBE_LOW 0x18
+#define GPIO_IBE_HIGH 0x1c
+#define GPIO_IEV_LOW 0x20
+#define GPIO_IEV_HIGH 0x24
+#define GPIO_IE_LOW 0x28
+#define GPIO_IE_HIGH 0x2c
+#define GPIO_IC_LOW 0x30
+#define GPIO_IC_HIGH 0x34
+//read only
+#define GPIO_RIS_LOW 0x38
+#define GPIO_RIS_HIGH 0x3c
+#define GPIO_MIS_LOW 0x40
+#define GPIO_MIS_HIGH 0x44
+#define GPIO_DIN_LOW 0x48
+#define GPIO_DIN_HIGH 0x4c
+
+#define GPIO_DOUT_X_REG 0x50
+#define GPIO_DOEN_X_REG 0x54
+
+#define MAX_GPIO 64
+
+struct starfive_gpio {
+ void __iomem *base;
+ struct gpio_chip gc;
+};
+
+#define to_starfive_gpio(gc) container_of(gc, struct starfive_gpio, gc)
+
+static int starfive_direction_input(struct gpio_chip *gc, unsigned offset)
+{
+ struct starfive_gpio *chip = to_starfive_gpio(gc);
+
+ if (offset >= gc->ngpio)
+ return -EINVAL;
+
+ writel(0x1, chip->base + GPIO_DOEN_X_REG + offset * 8);
+
+ return 0;
+}
+
+static int starfive_direction_output(struct gpio_chip *gc, unsigned offset, int value)
+{
+ struct starfive_gpio *chip = to_starfive_gpio(gc);
+
+ if (offset >= gc->ngpio)
+ return -EINVAL;
+ writel(0x0, chip->base + GPIO_DOEN_X_REG + offset * 8);
+ writel(value, chip->base + GPIO_DOUT_X_REG + offset * 8);
+
+ return 0;
+}
+
+static int starfive_get_direction(struct gpio_chip *gc, unsigned offset)
+{
+ struct starfive_gpio *chip = to_starfive_gpio(gc);
+
+ if (offset >= gc->ngpio)
+ return -EINVAL;
+
+ return readl(chip->base + GPIO_DOEN_X_REG + offset * 8) & 0x1;
+}
+
+static int starfive_get_value(struct gpio_chip *gc, unsigned offset)
+{
+ struct starfive_gpio *chip = to_starfive_gpio(gc);
+ int value;
+
+ if (offset >= gc->ngpio)
+ return -EINVAL;
+
+ if(offset < 32){
+ value = readl(chip->base + GPIO_DIN_LOW);
+ return (value >> offset) & 0x1;
+ } else {
+ value = readl(chip->base + GPIO_DIN_HIGH);
+ return (value >> (offset - 32)) & 0x1;
+ }
+}
+
+static void starfive_set_value(struct gpio_chip *gc, unsigned offset, int value)
+{
+ struct starfive_gpio *chip = to_starfive_gpio(gc);
+
+ if (offset >= gc->ngpio)
+ return;
+
+ writel(value, chip->base + GPIO_DOUT_X_REG + offset * 8);
+}
+
+static struct gpio_ops starfive_gpio_ops = {
+ .direction_input = starfive_direction_input,
+ .direction_output = starfive_direction_output,
+ .get_direction = starfive_get_direction,
+ .get = starfive_get_value,
+ .set = starfive_set_value,
+};
+
+static int starfive_gpio_probe(struct device_d *dev)
+{
+ struct starfive_gpio *chip;
+ struct resource *res;
+ struct clk *clk;
+ int ret;
+
+ clk = clk_get(dev, NULL);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ clk_enable(clk);
+
+ ret = device_reset(dev);
+ if (ret)
+ return ret;
+
+ ret = pinctrl_single_probe(dev);
+ if (ret)
+ return ret;
+
+ res = dev_get_resource(dev, IORESOURCE_MEM, 0);
+ if (IS_ERR(res))
+ return PTR_ERR(res);
+
+ chip = xzalloc(sizeof(*chip));
+ chip->base = IOMEM(res->start);
+
+ chip->gc.base = -1;
+ chip->gc.ngpio = MAX_GPIO;
+ chip->gc.dev = dev;
+ chip->gc.ops = &starfive_gpio_ops;
+
+ /* Disable all GPIO interrupts */
+ iowrite32(0, chip->base + GPIO_IE_HIGH);
+ iowrite32(0, chip->base + GPIO_IE_LOW);
+
+ ret = gpiochip_add(&chip->gc);
+ if (ret) {
+ dev_err(dev, "could not add gpiochip\n");
+ gpiochip_remove(&chip->gc);
+ return ret;
+ }
+
+ writel(1, chip->base + GPIO_EN);
+
+ return 0;
+}
+
+static const struct of_device_id starfive_gpio_match[] = {
+ { .compatible = "starfive,gpio0", },
+ { },
+};
+
+static struct driver_d starfive_gpio_driver = {
+ .probe = starfive_gpio_probe,
+ .name = "starfive_gpio",
+ .of_compatible = starfive_gpio_match,
+};
+postcore_platform_driver(starfive_gpio_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Huan Feng <huan.feng@starfivetech.com>");
+MODULE_DESCRIPTION("Starfive VIC GPIO generator driver");
diff --git a/drivers/hw_random/Kconfig b/drivers/hw_random/Kconfig
index a84c03efef..764911f4d3 100644
--- a/drivers/hw_random/Kconfig
+++ b/drivers/hw_random/Kconfig
@@ -36,4 +36,11 @@ config HW_RANDOM_VIRTIO
This driver provides guest-side support for the virtual Random Number
Generator hardware.
+config HW_RANDOM_STARFIVE
+ tristate "StarFive Random Number Generator"
+ depends on SOC_STARFIVE || COMPILE_TEST
+ help
+ This driver provides barebox support for the Random Number
+ Generator hardware found on the StarFive family of SoCs.
+
endif
diff --git a/drivers/hw_random/Makefile b/drivers/hw_random/Makefile
index 4bab3967fc..4cf33d2d93 100644
--- a/drivers/hw_random/Makefile
+++ b/drivers/hw_random/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_HWRNG_MXC_RNGC) += mxc-rngc.o
obj-$(CONFIG_HWRNG_STM32) += stm32-rng.o
obj-$(CONFIG_HWRNG_DEV_RANDOM) += dev-random.o
obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o
+obj-$(CONFIG_HW_RANDOM_STARFIVE) += starfive-vic-rng.o
diff --git a/drivers/hw_random/starfive-vic-rng.c b/drivers/hw_random/starfive-vic-rng.c
new file mode 100644
index 0000000000..f7b7585884
--- /dev/null
+++ b/drivers/hw_random/starfive-vic-rng.c
@@ -0,0 +1,208 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * COPYRIGHT 2020 Shanghai StarFive Technology Co., Ltd.
+ */
+#include <common.h>
+#include <linux/err.h>
+#include <io.h>
+#include <of.h>
+#include <driver.h>
+#include <linux/hw_random.h>
+#include <linux/reset.h>
+#include <linux/clk.h>
+
+#define VIC_RAND_LEN 4
+
+#define VIC_CTRL 0x00
+#define VIC_MODE 0x04
+#define VIC_SMODE 0x08
+#define VIC_STAT 0x0C
+#define VIC_IE 0x10
+#define VIC_ISTAT 0x14
+#define VIC_ALARM 0x18
+#define VIC_BUILD_ID 0x1C
+#define VIC_FEATURES 0x20
+#define VIC_RAND0 0x24
+#define VIC_NPA_DATA0 0x34
+#define VIC_SEED0 0x74
+#define VIC_IA_RDATA 0xA4
+#define VIC_IA_WDATA 0xA8
+#define VIC_IA_ADDR 0xAC
+#define VIC_IA_CMD 0xB0
+
+/* CTRL */
+#define VIC_CTRL_CMD_NOP 0
+#define VIC_CTRL_CMD_GEN_NOISE 1
+#define VIC_CTRL_CMD_GEN_NONCE 2
+#define VIC_CTRL_CMD_CREATE_STATE 3
+#define VIC_CTRL_CMD_RENEW_STATE 4
+#define VIC_CTRL_CMD_REFRESH_ADDIN 5
+#define VIC_CTRL_CMD_GEN_RANDOM 6
+#define VIC_CTRL_CMD_ADVANCE_STATE 7
+#define VIC_CTRL_CMD_KAT 8
+#define VIC_CTRL_CMD_ZEROIZE 15
+
+/* SMODE */
+#define _VIC_SMODE_SECURE_EN 1
+
+#define VIC_SMODE_SECURE_EN(x) ((x) << _VIC_SMODE_SECURE_EN)
+
+/* STAT */
+#define _VIC_STAT_BUSY 31
+
+#define VIC_STAT_BUSY (1UL << _VIC_STAT_BUSY)
+
+/* IE */
+#define _VIC_IE_GLBL 31
+#define _VIC_IE_DONE 4
+#define _VIC_IE_ALARMS 3
+#define _VIC_IE_NOISE_RDY 2
+#define _VIC_IE_KAT_COMPLETE 1
+#define _VIC_IE_ZEROIZE 0
+
+#define VIC_IE_GLBL (1UL << _VIC_IE_GLBL)
+#define VIC_IE_DONE (1UL << _VIC_IE_DONE)
+#define VIC_IE_ALARMS (1UL << _VIC_IE_ALARMS)
+#define VIC_IE_NOISE_RDY (1UL << _VIC_IE_NOISE_RDY)
+#define VIC_IE_KAT_COMPLETE (1UL << _VIC_IE_KAT_COMPLETE)
+#define VIC_IE_ZEROIZE (1UL << _VIC_IE_ZEROIZE)
+#define VIC_IE_ALL (VIC_IE_GLBL | VIC_IE_DONE | VIC_IE_ALARMS | \
+ VIC_IE_NOISE_RDY | VIC_IE_KAT_COMPLETE | VIC_IE_ZEROIZE)
+
+#define to_vic_rng(p) container_of(p, struct vic_rng, rng)
+
+struct vic_rng {
+ struct device_d *dev;
+ void __iomem *base;
+ struct hwrng rng;
+};
+
+static inline void vic_wait_till_idle(struct vic_rng *hrng)
+{
+ while(readl(hrng->base + VIC_STAT) & VIC_STAT_BUSY)
+ ;
+}
+
+static inline void vic_rng_irq_mask_clear(struct vic_rng *hrng)
+{
+ u32 data = readl(hrng->base + VIC_ISTAT);
+ writel(data, hrng->base + VIC_ISTAT);
+ writel(0, hrng->base + VIC_ALARM);
+}
+
+static int vic_trng_cmd(struct vic_rng *hrng, u32 cmd)
+{
+ vic_wait_till_idle(hrng);
+
+ switch (cmd) {
+ case VIC_CTRL_CMD_NOP:
+ case VIC_CTRL_CMD_GEN_NOISE:
+ case VIC_CTRL_CMD_GEN_NONCE:
+ case VIC_CTRL_CMD_CREATE_STATE:
+ case VIC_CTRL_CMD_RENEW_STATE:
+ case VIC_CTRL_CMD_REFRESH_ADDIN:
+ case VIC_CTRL_CMD_GEN_RANDOM:
+ case VIC_CTRL_CMD_ADVANCE_STATE:
+ case VIC_CTRL_CMD_KAT:
+ case VIC_CTRL_CMD_ZEROIZE:
+ writel(cmd, hrng->base + VIC_CTRL);
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int vic_rng_init(struct hwrng *rng)
+{
+ struct vic_rng *hrng = to_vic_rng(rng);
+ struct clk *clk;
+ int ret;
+
+ clk = clk_get(rng->dev, NULL);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ clk_enable(clk);
+
+ ret = device_reset(rng->dev);
+ if (ret)
+ return ret;
+
+ // clear register: ISTAT
+ vic_rng_irq_mask_clear(hrng);
+
+ // set mission mode
+ writel(VIC_SMODE_SECURE_EN(1), hrng->base + VIC_SMODE);
+
+ vic_trng_cmd(hrng, VIC_CTRL_CMD_GEN_NOISE);
+ vic_wait_till_idle(hrng);
+
+ // set interrupt
+ writel(VIC_IE_ALL, hrng->base + VIC_IE);
+
+ // zeroize
+ vic_trng_cmd(hrng, VIC_CTRL_CMD_ZEROIZE);
+
+ vic_wait_till_idle(hrng);
+
+ return 0;
+}
+
+static int vic_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
+{
+ struct vic_rng *hrng = to_vic_rng(rng);
+
+ vic_trng_cmd(hrng, VIC_CTRL_CMD_ZEROIZE);
+ vic_trng_cmd(hrng, VIC_CTRL_CMD_GEN_NOISE);
+ vic_trng_cmd(hrng, VIC_CTRL_CMD_CREATE_STATE);
+
+ vic_wait_till_idle(hrng);
+ max = min_t(size_t, max, VIC_RAND_LEN * 4);
+
+ writel(0x0, hrng->base + VIC_MODE);
+ vic_trng_cmd(hrng, VIC_CTRL_CMD_GEN_RANDOM);
+
+ vic_wait_till_idle(hrng);
+ memcpy_fromio(buf, hrng->base + VIC_RAND0, max);
+ vic_trng_cmd(hrng, VIC_CTRL_CMD_ZEROIZE);
+
+ vic_wait_till_idle(hrng);
+ return max;
+}
+
+static int vic_rng_probe(struct device_d *dev)
+{
+ struct vic_rng *hrng;
+ struct resource *res;
+
+ hrng = xzalloc(sizeof(*hrng));
+
+ res = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(res))
+ return PTR_ERR(res);
+
+ hrng->base = IOMEM(res->start);
+ hrng->dev = dev;
+
+ hrng->rng.name = dev_name(dev);
+ hrng->rng.init = vic_rng_init;
+ hrng->rng.read = vic_rng_read;
+
+ return hwrng_register(dev, &hrng->rng);
+}
+
+static const struct of_device_id vic_rng_dt_ids[] = {
+ { .compatible = "starfive,vic-rng" },
+ { /* sentinel */ }
+};
+
+static struct driver_d vic_rng_driver = {
+ .name = "vic-rng",
+ .probe = vic_rng_probe,
+ .of_compatible = vic_rng_dt_ids,
+};
+device_platform_driver(vic_rng_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Huan Feng <huan.feng@starfivetech.com>");
+MODULE_DESCRIPTION("Starfive VIC random number generator driver");
diff --git a/drivers/mci/dw_mmc.c b/drivers/mci/dw_mmc.c
index 930b538adc..b402090ab3 100644
--- a/drivers/mci/dw_mmc.c
+++ b/drivers/mci/dw_mmc.c
@@ -17,6 +17,7 @@
#include <io.h>
#include <platform_data/dw_mmc.h>
#include <linux/bitops.h>
+#include <linux/reset.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <errno.h>
@@ -31,7 +32,7 @@ struct dwmci_host {
unsigned int fifo_size_bytes;
struct dwmci_idmac *idmac;
- unsigned long clkrate;
+ u32 clkrate;
int ciu_div;
u32 fifoth_val;
u32 pwren_value;
@@ -548,6 +549,7 @@ static int dwmci_init(struct mci_host *mci, struct device_d *dev)
static int dw_mmc_probe(struct device_d *dev)
{
+ struct reset_control *rst;
struct resource *iores;
struct dwmci_host *host;
struct dw_mmc_platform_data *pdata = dev->platform_data;
@@ -568,6 +570,15 @@ static int dw_mmc_probe(struct device_d *dev)
clk_enable(host->clk_biu);
clk_enable(host->clk_ciu);
+ rst = reset_control_get(dev, "reset");
+ if (IS_ERR(rst)) {
+ return PTR_ERR(rst);
+ } else if (rst) {
+ reset_control_assert(rst);
+ udelay(10);
+ reset_control_deassert(rst);
+ }
+
iores = dev_request_mem_resource(dev, 0);
if (IS_ERR(iores))
return PTR_ERR(iores);
@@ -606,7 +617,11 @@ static int dw_mmc_probe(struct device_d *dev)
else
host->pwren_value = 1;
- host->clkrate = clk_get_rate(host->clk_ciu);
+ if (of_device_is_compatible(dev->device_node, "starfive,jh7100-dw-mshc"))
+ of_property_read_u32(dev->device_node, "clock-frequency", &host->clkrate);
+ if (!host->clkrate)
+ host->clkrate = clk_get_rate(host->clk_ciu);
+
host->mci.f_min = host->clkrate / 510 / host->ciu_div;
if (host->mci.f_min < 200000)
host->mci.f_min = 200000;
@@ -625,6 +640,10 @@ static __maybe_unused struct of_device_id dw_mmc_compatible[] = {
}, {
.compatible = "rockchip,rk3288-dw-mshc",
}, {
+ .compatible = "snps,dw-mshc",
+ }, {
+ .compatible = "starfive,jh7100-dw-mshc",
+ }, {
/* sentinel */
}
};
diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index a094f3cbf5..92a73c8f1d 100644
--- a/drivers/mci/mci-core.c
+++ b/drivers/mci/mci-core.c
@@ -21,6 +21,7 @@
#include <of.h>
#include <linux/err.h>
#include <linux/sizes.h>
+#include <dma.h>
#define MAX_BUFFER_NUMBER 0xffffffff
@@ -1789,6 +1790,11 @@ static int mci_card_probe(struct mci *mci)
mci->cdevname = basprintf("disk%d", disknum);
}
+ if (!sector_buf)
+ sector_buf = dma_alloc(SECTOR_SIZE);
+
+ /* FIXME we don't check sector_buf against the device dma mask here */
+
rc = mci_startup(mci);
if (rc) {
dev_warn(&mci->dev, "Card's startup fails with %d\n", rc);
@@ -1850,15 +1856,6 @@ static int mci_set_probe(struct param_d *param, void *priv)
return 0;
}
-static int mci_init(void)
-{
- sector_buf = xmemalign(32, SECTOR_SIZE);
-
- return 0;
-}
-
-device_initcall(mci_init);
-
int mci_detect_card(struct mci_host *host)
{
int rc;
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 87674a2a29..7426dfc463 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -42,4 +42,14 @@ config ACPI_TEST
help
This is a simple Test driver to test the ACPI bus.
+config STARFIVE_PWRSEQ
+ bool "StarFive power sequencing driver"
+ depends on SOC_STARFIVE
+ help
+ This driver sets up a number of StarFive peripherals not matched
+ by more specific barebox drivers by deasserting reset lines, muxing
+ pins and/or enabling clocks. Peripherals set up by this can then
+ be accessed over /dev/mem or used from kernels which still depend
+ on bootloader for initialization.
+
endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 4d92465a1e..36743e6ae6 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_STATE_DRV) += state.o
obj-$(CONFIG_DEV_MEM) += mem.o
obj-$(CONFIG_UBOOTVAR) += ubootvar.o
obj-$(CONFIG_ACPI_TEST) += acpi-test.o
+obj-$(CONFIG_STARFIVE_PWRSEQ) += starfive-pwrseq.o
diff --git a/drivers/misc/starfive-pwrseq.c b/drivers/misc/starfive-pwrseq.c
new file mode 100644
index 0000000000..6236547bc5
--- /dev/null
+++ b/drivers/misc/starfive-pwrseq.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 Ahmad Fatoum, Pengutronix
+ */
+
+#include <driver.h>
+#include <init.h>
+#include <linux/reset.h>
+#include <dt-bindings/clock/starfive-jh7100.h>
+#include <linux/clk.h>
+
+struct starfive_pwrseq {
+ const char **names;
+};
+
+static int starfive_pwrseq_probe(struct device_d *dev)
+{
+ int ret;
+
+ ret = device_reset_all(dev);
+ if (ret)
+ return ret;
+
+ return of_platform_populate(dev->device_node, NULL, dev);
+}
+
+static struct of_device_id starfive_pwrseq_dt_ids[] = {
+ { .compatible = "starfive,axi-dma" },
+ { .compatible = "cm,cm521-vpu" },
+ { .compatible = "starfive,vic-sec" },
+ { .compatible = "sfc,tempsensor" },
+ { .compatible = "cm,codaj12-jpu-1" },
+ { .compatible = "cdns,xrp" },
+ { .compatible = "starfive,nne50" },
+ { .compatible = "nvidia,nvdla_os_initial" },
+ { .compatible = "starfive,spi2ahb" },
+ { /* sentinel */ }
+};
+
+static struct driver_d starfive_pwrseq_driver = {
+ .name = "starfive_pwrseq",
+ .probe = starfive_pwrseq_probe,
+ .of_compatible = starfive_pwrseq_dt_ids,
+};
+
+static const int clks[] = {
+ CLK_VDEC_AXI, CLK_VDECBRG_MAIN, CLK_VDEC_BCLK, CLK_VDEC_CCLK, CLK_VDEC_APB,
+ CLK_JPEG_AXI, CLK_JPEG_CCLK, CLK_JPEG_APB,
+ CLK_DLA_AXI, CLK_DLANOC_AXI, CLK_DLA_APB, CLK_NNENOC_AXI, CLK_DLASLV_AXI,
+ CLK_VENC_AXI, CLK_VENCBRG_MAIN, CLK_VENC_BCLK, CLK_VENC_CCLK, CLK_VENC_APB,
+ CLK_SGDMA1P_AXI,
+ CLK_DMA2PNOC_AXI, CLK_SGDMA2P_AXI, CLK_SGDMA2P_AHB,
+ CLK_SDIO0_AHB,
+ CLK_SDIO1_AHB,
+ CLK_SPI2AHB_AHB, CLK_SPI2AHB_CORE,
+ CLK_EZMASTER_AHB,
+ CLK_SEC_AHB, CLK_AES, CLK_SHA, CLK_PKA,
+ CLK_UART0_APB, CLK_UART0_CORE,
+ CLK_UART1_APB, CLK_UART1_CORE,
+ CLK_UART2_APB, CLK_UART2_CORE,
+ CLK_UART3_APB, CLK_UART3_CORE,
+ CLK_SPI0_APB, CLK_SPI0_CORE,
+ CLK_SPI1_APB, CLK_SPI1_CORE,
+ CLK_SPI2_APB, CLK_SPI2_CORE,
+ CLK_SPI3_APB, CLK_SPI3_CORE,
+ CLK_I2C0_APB, CLK_I2C0_CORE,
+ CLK_I2C1_APB, CLK_I2C1_CORE,
+ CLK_I2C2_APB, CLK_I2C2_CORE,
+ CLK_I2C3_APB, CLK_I2C3_CORE,
+ CLK_VP6INTC_APB,
+ CLK_TEMP_APB, CLK_TEMP_SENSE,
+
+ CLK_END
+};
+
+static int __init starfive_pwrseq_driver_register(void)
+{
+ struct of_phandle_args clkspec;
+ int i;
+
+ clkspec.args_count = 1;
+ clkspec.np = of_find_compatible_node(NULL, NULL, "starfive,jh7100-clkgen");
+ if (clkspec.np) {
+ for (i = 0; clks[i] != CLK_END; i++) {
+ clkspec.args[0] = clks[i];
+ clk_enable(of_clk_get_from_provider(&clkspec));
+ }
+ }
+
+ return platform_driver_register(&starfive_pwrseq_driver);
+}
+device_initcall(starfive_pwrseq_driver_register);
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 18931211b5..802169a86e 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -82,6 +82,14 @@ config DRIVER_NET_DESIGNWARE_SOCFPGA
This option enables support for the Synopsys
Designware Core Univesal MAC 10M/100M/1G ethernet IP on SoCFPGA.
+config DRIVER_NET_DESIGNWARE_STARFIVE
+ bool "Designware Universal MAC ethernet driver for StarFive platforms"
+ depends on SOC_STARFIVE || COMPILE_TEST
+ select MFD_SYSCON
+ help
+ This option enables support for the Synopsys
+ Designware Core Univesal MAC 10M/100M/1G ethernet IP on StarFive.
+
endif
config DRIVER_NET_DESIGNWARE_EQOS
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 1674d53dff..fb3e3bdee4 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_DRIVER_NET_DAVINCI_EMAC) += davinci_emac.o
obj-$(CONFIG_DRIVER_NET_DESIGNWARE) += designware.o
obj-$(CONFIG_DRIVER_NET_DESIGNWARE_GENERIC) += designware_generic.o
obj-$(CONFIG_DRIVER_NET_DESIGNWARE_SOCFPGA) += designware_socfpga.o
+obj-$(CONFIG_DRIVER_NET_DESIGNWARE_STARFIVE) += designware_starfive.o
obj-$(CONFIG_DRIVER_NET_DESIGNWARE_EQOS) += designware_eqos.o
obj-$(CONFIG_DRIVER_NET_DESIGNWARE_STM32) += designware_stm32.o
obj-$(CONFIG_DRIVER_NET_DESIGNWARE_TEGRA186) += designware_tegra186.o
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index 0ee6d3d78a..afc275e81e 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -104,15 +104,15 @@ static void tx_descs_init(struct eth_device *dev)
{
struct dw_eth_dev *priv = dev->priv;
struct eth_dma_regs *dma_p = priv->dma_regs_p;
- struct dmamacdescr *desc_table_p = &priv->tx_mac_descrtable[0];
+ struct dmamacdescr *desc_table_p = &priv->tx_mac_descrtable_cpu[0];
char *txbuffs = &priv->txbuffs[0];
struct dmamacdescr *desc_p;
u32 idx;
for (idx = 0; idx < CONFIG_TX_DESCR_NUM; idx++) {
desc_p = &desc_table_p[idx];
- desc_p->dmamac_addr = &txbuffs[idx * CONFIG_ETH_BUFSIZE];
- desc_p->dmamac_next = &desc_table_p[idx + 1];
+ desc_p->dmamac_addr = virt_to_phys(&txbuffs[idx * CONFIG_ETH_BUFSIZE]);
+ desc_p->dmamac_next = tx_dma_addr(priv, &desc_table_p[idx + 1]);
if (priv->enh_desc) {
desc_p->txrx_status &= ~(DESC_ENH_TXSTS_TXINT | DESC_ENH_TXSTS_TXLAST |
@@ -130,9 +130,9 @@ static void tx_descs_init(struct eth_device *dev)
}
/* Correcting the last pointer of the chain */
- desc_p->dmamac_next = &desc_table_p[0];
+ desc_p->dmamac_next = tx_dma_addr(priv, &desc_table_p[0]);
- writel((ulong)&desc_table_p[0], &dma_p->txdesclistaddr);
+ writel(desc_p->dmamac_next, &dma_p->txdesclistaddr);
priv->tx_currdescnum = 0;
}
@@ -140,15 +140,15 @@ static void rx_descs_init(struct eth_device *dev)
{
struct dw_eth_dev *priv = dev->priv;
struct eth_dma_regs *dma_p = priv->dma_regs_p;
- struct dmamacdescr *desc_table_p = &priv->rx_mac_descrtable[0];
+ struct dmamacdescr *desc_table_p = &priv->rx_mac_descrtable_cpu[0];
char *rxbuffs = &priv->rxbuffs[0];
struct dmamacdescr *desc_p;
u32 idx;
for (idx = 0; idx < CONFIG_RX_DESCR_NUM; idx++) {
desc_p = &desc_table_p[idx];
- desc_p->dmamac_addr = &rxbuffs[idx * CONFIG_ETH_BUFSIZE];
- desc_p->dmamac_next = &desc_table_p[idx + 1];
+ desc_p->dmamac_addr = virt_to_phys(&rxbuffs[idx * CONFIG_ETH_BUFSIZE]);
+ desc_p->dmamac_next = rx_dma_addr(priv, &desc_table_p[idx + 1]);
desc_p->dmamac_cntl = MAC_MAX_FRAME_SZ;
if (priv->enh_desc)
@@ -156,15 +156,15 @@ static void rx_descs_init(struct eth_device *dev)
else
desc_p->dmamac_cntl |= DESC_RXCTRL_RXCHAIN;
- dma_sync_single_for_cpu((unsigned long)desc_p->dmamac_addr,
+ dma_sync_single_for_cpu(desc_p->dmamac_addr,
CONFIG_ETH_BUFSIZE, DMA_FROM_DEVICE);
desc_p->txrx_status = DESC_RXSTS_OWNBYDMA;
}
/* Correcting the last pointer of the chain */
- desc_p->dmamac_next = &desc_table_p[0];
+ desc_p->dmamac_next = rx_dma_addr(priv, &desc_table_p[0]);
- writel((ulong)&desc_table_p[0], &dma_p->rxdesclistaddr);
+ writel(desc_p->dmamac_next, &dma_p->rxdesclistaddr);
priv->rx_currdescnum = 0;
}
@@ -276,7 +276,7 @@ static int dwc_ether_send(struct eth_device *dev, void *packet, int length)
struct dw_eth_dev *priv = dev->priv;
struct eth_dma_regs *dma_p = priv->dma_regs_p;
u32 owndma, desc_num = priv->tx_currdescnum;
- struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num];
+ struct dmamacdescr *desc_p = &priv->tx_mac_descrtable_cpu[desc_num];
owndma = priv->enh_desc ? DESC_ENH_TXSTS_OWNBYDMA : DESC_TXSTS_OWNBYDMA;
/* Check if the descriptor is owned by CPU */
@@ -285,8 +285,8 @@ static int dwc_ether_send(struct eth_device *dev, void *packet, int length)
return -1;
}
- memcpy((void *)desc_p->dmamac_addr, packet, length);
- dma_sync_single_for_device((unsigned long)desc_p->dmamac_addr, length,
+ memcpy(dmamac_addr(desc_p), packet, length);
+ dma_sync_single_for_device(desc_p->dmamac_addr, length,
DMA_TO_DEVICE);
if (priv->enh_desc) {
@@ -314,7 +314,7 @@ static int dwc_ether_send(struct eth_device *dev, void *packet, int length)
/* Start the transmission */
writel(POLL_DATA, &dma_p->txpolldemand);
- dma_sync_single_for_cpu((unsigned long)desc_p->dmamac_addr, length,
+ dma_sync_single_for_cpu(desc_p->dmamac_addr, length,
DMA_TO_DEVICE);
return 0;
@@ -324,7 +324,7 @@ static int dwc_ether_rx(struct eth_device *dev)
{
struct dw_eth_dev *priv = dev->priv;
u32 desc_num = priv->rx_currdescnum;
- struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num];
+ struct dmamacdescr *desc_p = &priv->rx_mac_descrtable_cpu[desc_num];
u32 status = desc_p->txrx_status;
int length = 0;
@@ -358,10 +358,10 @@ static int dwc_ether_rx(struct eth_device *dev)
length = (status & DESC_RXSTS_FRMLENMSK) >>
DESC_RXSTS_FRMLENSHFT;
- dma_sync_single_for_cpu((unsigned long)desc_p->dmamac_addr,
+ dma_sync_single_for_cpu(desc_p->dmamac_addr,
length, DMA_FROM_DEVICE);
- net_receive(dev, desc_p->dmamac_addr, length);
- dma_sync_single_for_device((unsigned long)desc_p->dmamac_addr,
+ net_receive(dev, dmamac_addr(desc_p), length);
+ dma_sync_single_for_device(desc_p->dmamac_addr,
length, DMA_FROM_DEVICE);
ret = length;
}
@@ -451,17 +451,20 @@ struct dw_eth_dev *dwc_drv_probe(struct device_d *dev)
int ret;
struct dw_eth_drvdata *drvdata;
+ dma_set_mask(dev, DMA_BIT_MASK(32));
+
priv = xzalloc(sizeof(struct dw_eth_dev));
ret = dev_get_drvdata(dev, (const void **)&drvdata);
if (ret)
return ERR_PTR(ret);
- if (drvdata && drvdata->enh_desc)
+ if (drvdata) {
priv->enh_desc = drvdata->enh_desc;
- else
+ priv->fix_mac_speed = drvdata->fix_mac_speed;
+ } else {
dev_warn(dev, "No drvdata specified\n");
-
+ }
if (pdata) {
priv->phy_addr = pdata->phy_addr;
@@ -481,12 +484,21 @@ struct dw_eth_dev *dwc_drv_probe(struct device_d *dev)
priv->mac_regs_p = base;
dwc_version(dev, readl(&priv->mac_regs_p->version));
priv->dma_regs_p = base + DW_DMA_BASE_OFFSET;
- priv->tx_mac_descrtable = dma_alloc_coherent(
+
+ priv->tx_mac_descrtable_cpu = dma_alloc_coherent(
CONFIG_TX_DESCR_NUM * sizeof(struct dmamacdescr),
- DMA_ADDRESS_BROKEN);
- priv->rx_mac_descrtable = dma_alloc_coherent(
+ &priv->tx_mac_descrtable_dev);
+
+ if (dma_mapping_error(dev, priv->tx_mac_descrtable_dev))
+ return ERR_PTR(-EFAULT);
+
+ priv->rx_mac_descrtable_cpu = dma_alloc_coherent(
CONFIG_RX_DESCR_NUM * sizeof(struct dmamacdescr),
- DMA_ADDRESS_BROKEN);
+ &priv->rx_mac_descrtable_dev);
+
+ if (dma_mapping_error(dev, priv->rx_mac_descrtable_dev))
+ return ERR_PTR(-EFAULT);
+
priv->txbuffs = dma_alloc(TX_TOTAL_BUFSIZE);
priv->rxbuffs = dma_alloc(RX_TOTAL_BUFSIZE);
diff --git a/drivers/net/designware.h b/drivers/net/designware.h
index 0a6a6bf1a4..8f6234aec5 100644
--- a/drivers/net/designware.h
+++ b/drivers/net/designware.h
@@ -8,6 +8,7 @@
#define __DESIGNWARE_ETH_H
#include <net.h>
+#include <linux/types.h>
struct dw_eth_dev {
struct eth_device netdev;
@@ -18,8 +19,11 @@ struct dw_eth_dev {
u32 tx_currdescnum;
u32 rx_currdescnum;
- struct dmamacdescr *tx_mac_descrtable;
- struct dmamacdescr *rx_mac_descrtable;
+ struct dmamacdescr *tx_mac_descrtable_cpu;
+ struct dmamacdescr *rx_mac_descrtable_cpu;
+
+ dma_addr_t tx_mac_descrtable_dev;
+ dma_addr_t rx_mac_descrtable_dev;
u8 *txbuffs;
u8 *rxbuffs;
@@ -35,9 +39,24 @@ struct dw_eth_dev {
struct dw_eth_drvdata {
bool enh_desc;
+ void (*fix_mac_speed)(int speed);
void *priv;
};
+static inline dma_addr_t tx_dma_addr(struct dw_eth_dev *priv,
+ struct dmamacdescr *desc)
+{
+ return priv->tx_mac_descrtable_dev
+ + ((u8 *)desc - (u8 *)priv->tx_mac_descrtable_cpu);
+}
+
+static inline dma_addr_t rx_dma_addr(struct dw_eth_dev *priv,
+ struct dmamacdescr *desc)
+{
+ return priv->rx_mac_descrtable_dev
+ + ((u8 *)desc - (u8 *)priv->rx_mac_descrtable_cpu);
+}
+
struct dw_eth_dev *dwc_drv_probe(struct device_d *dev);
void dwc_drv_remove(struct device_d *dev);
@@ -138,10 +157,12 @@ struct eth_dma_regs {
struct dmamacdescr {
u32 txrx_status;
u32 dmamac_cntl;
- void *dmamac_addr;
- struct dmamacdescr *dmamac_next;
+ u32 dmamac_addr;
+ u32 dmamac_next;
};
+#define dmamac_addr(descr) (phys_to_virt((descr)->dmamac_addr))
+
/*
* txrx_status definitions
*/
diff --git a/drivers/net/designware_starfive.c b/drivers/net/designware_starfive.c
new file mode 100644
index 0000000000..3dc9d14e11
--- /dev/null
+++ b/drivers/net/designware_starfive.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2021 Ahmad Fatoum, Pengutronix
+ */
+
+#include <common.h>
+#include <init.h>
+#include <linux/reset.h>
+#include <linux/clk.h>
+#include <mfd/syscon.h>
+#include <soc/starfive/sysmain.h>
+#include "designware.h"
+
+/*
+ * GMAC_GTXCLK
+ * bit name access default description
+ * [31] _gmac_gtxclk enable RW 0x0 "1:enable; 0:disable"
+ * [30] reserved - 0x0 reserved
+ * [29:8] reserved - 0x0 reserved
+ * [7:0] gmac_gtxclk ratio RW 0x4 divider value
+ *
+ * 1000M: gtxclk@125M => 500/125 = 0x4
+ * 100M: gtxclk@25M => 500/25 = 0x14
+ * 10M: gtxclk@2.5M => 500/2.5 = 0xc8
+ */
+
+#define CLKGEN_BASE 0x11800000
+#define CLKGEN_GMAC_GTXCLK_OFFSET 0x1EC
+#define CLKGEN_GMAC_GTXCLK_ADDR (CLKGEN_BASE + CLKGEN_GMAC_GTXCLK_OFFSET)
+
+
+#define CLKGEN_125M_DIV 0x4
+#define CLKGEN_25M_DIV 0x14
+#define CLKGEN_2_5M_DIV 0xc8
+
+static void dwmac_fixed_speed(int speed)
+{
+ /* TODO: move this into clk driver */
+ void __iomem *addr = IOMEM(CLKGEN_GMAC_GTXCLK_ADDR);
+ u32 value;
+
+ value = readl(addr) & (~0x000000FF);
+
+ switch (speed) {
+ case SPEED_1000: value |= CLKGEN_125M_DIV; break;
+ case SPEED_100: value |= CLKGEN_25M_DIV; break;
+ case SPEED_10: value |= CLKGEN_2_5M_DIV; break;
+ default: return;
+ }
+
+ writel(value, addr);
+}
+
+static struct dw_eth_drvdata starfive_drvdata = {
+ .enh_desc = 1,
+ .fix_mac_speed = dwmac_fixed_speed,
+};
+
+static int starfive_dwc_ether_probe(struct device_d *dev)
+{
+ struct dw_eth_dev *dwc;
+ struct regmap *regmap;
+ int ret;
+ struct clk_bulk_data clks[] = {
+ { .id = "stmmaceth" },
+ { .id = "ptp_ref" },
+ { .id = "tx" },
+ };
+
+ regmap = syscon_regmap_lookup_by_phandle(dev->device_node, "starfive,sysmain");
+ if (IS_ERR(regmap)) {
+ dev_err(dev, "Could not get starfive,sysmain node\n");
+ return PTR_ERR(regmap);
+ }
+
+ ret = clk_bulk_get(dev, ARRAY_SIZE(clks), clks);
+ if (ret)
+ return ret;
+
+ ret = clk_bulk_enable(ARRAY_SIZE(clks), clks);
+ if (ret < 0)
+ return ret;
+
+ ret = device_reset(dev);
+ if (ret)
+ return ret;
+
+ dwc = dwc_drv_probe(dev);
+ if (IS_ERR(dwc))
+ return PTR_ERR(dwc);
+
+ if (phy_interface_mode_is_rgmii(dwc->interface)) {
+ regmap_update_bits(regmap, SYSMAIN_GMAC_PHY_INTF_SEL, 0x7, 0x1);
+ regmap_write(regmap, SYSMAIN_GMAC_GTXCLK_DLYCHAIN_SEL, 0x4);
+ }
+
+ return 0;
+}
+
+static struct of_device_id starfive_dwc_ether_compatible[] = {
+ { .compatible = "starfive,stmmac", .data = &starfive_drvdata },
+ { /* sentinel */ }
+};
+
+static struct driver_d starfive_dwc_ether_driver = {
+ .name = "starfive-designware_eth",
+ .probe = starfive_dwc_ether_probe,
+ .of_compatible = starfive_dwc_ether_compatible,
+};
+device_platform_driver(starfive_dwc_ether_driver);
diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 0d7c0b7b9e..3781f7a839 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -65,4 +65,12 @@ config STM32_BSEC
This adds support for the STM32 OTP controller. Reads and writes
to will go to the shadow RAM, not the OTP fuses themselvers.
+config STARFIVE_OTP
+ tristate "Starfive OTP Supprot"
+ depends on SOC_STARFIVE
+ depends on OFDEVICE
+ help
+ This adds support for the StarFive OTP controller. Only reading
+ is currently supported.
+
endif
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index 53c02dc785..55507f5441 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -22,3 +22,5 @@ nvmem_eeprom_93xx46-y := eeprom_93xx46.o
obj-$(CONFIG_STM32_BSEC) += nvmem_bsec.o
nvmem_bsec-y := bsec.o
+
+obj-$(CONFIG_STARFIVE_OTP) += starfive-otp.o
diff --git a/drivers/nvmem/starfive-otp.c b/drivers/nvmem/starfive-otp.c
new file mode 100644
index 0000000000..f9bf05ca87
--- /dev/null
+++ b/drivers/nvmem/starfive-otp.c
@@ -0,0 +1,201 @@
+// SPDX_License-Identifier: GPL-2.0
+/*
+ * Copyright 2021 StarFive, Inc
+ */
+
+#include <common.h>
+#include <driver.h>
+#include <malloc.h>
+#include <xfuncs.h>
+#include <errno.h>
+#include <gpiod.h>
+#include <init.h>
+#include <net.h>
+#include <io.h>
+#include <of.h>
+#include <regmap.h>
+#include <machine_id.h>
+#include <linux/reset.h>
+#include <linux/clk.h>
+#include <linux/nvmem-provider.h>
+
+// otp reg offset
+#define OTP_CFGR 0x00
+#define OTPC_IER 0x04
+#define OTPC_SRR 0x08
+#define OTP_OPRR 0x0c
+#define OTPC_CTLR 0x10
+#define OTPC_ADDRR 0x14
+#define OTPC_DINR 0x18
+#define OTPC_DOUTR 0x1c
+
+#define OTP_EMPTY_CELL_VALUE 0xffffffffUL
+
+// cfgr (offset 0x00)
+#define OTP_CFGR_PRG_CNT_MASK 0xff
+#define OTP_CFGR_PRG_CNT_SHIFT 0
+#define OTP_CFGR_DIV_1US_MASK 0xff
+#define OTP_CFGR_DIV_1US_SHIFT 8
+#define OTP_CFGR_RD_CYC_MASK 0x0f
+#define OTP_CFGR_RD_CYC_SHIFT 16
+
+// ier (offset 0x04)
+#define OTPC_IER_DONE_IE BIT(0)
+#define OTPC_IER_BUSY_OPR_IE BIT(1)
+
+// srr (offset 0x08)
+#define OTPC_SRR_DONE BIT(0)
+#define OTPC_SRR_BUSY_OPR BIT(1)
+#define OTPC_SRR_INFO_RD_LOCK BIT(29)
+#define OTPC_SRR_INFO_WR_LOCK BIT(30)
+#define OTPC_SRR_BUSY BIT(31)
+
+// oprr (offset 0x0c)
+#define OTP_OPRR_OPR_MASK 0x00000007
+#define OTP_OPRR_OPR_SHIFT 0
+
+#define OTP_OPR_STANDBY 0x0 // user mode
+#define OTP_OPR_READ 0x1 // user mode
+#define OTP_OPR_MARGIN_READ_PROG 0x2 // testing mode
+#define OTP_OPR_MARGIN_READ_INIT 0x3 // testing mode
+#define OTP_OPR_PROGRAM 0x4 // user mode
+#define OTP_OPR_DEEP_STANDBY 0x5 // user mode
+#define OTP_OPR_DEBUG 0x6 // user mode
+
+// ctlr (offset 0x10, see EG512X32TH028CW01_v1.0.pdf "Pin Description")
+#define OTPC_CTLR_PCE BIT(0)
+#define OTPC_CTLR_PTM_MASK 0x0000000e
+#define OTPC_CTLR_PTM_SHIFT 1
+#define OTPC_CTLR_PDSTB BIT(4)
+#define OTPC_CTLR_PTR BIT(5)
+#define OTPC_CTLR_PPROG BIT(6)
+#define OTPC_CTLR_PWE BIT(7)
+#define OTPC_CTLR_PCLK BIT(8)
+
+// addrr (offset 0x14)
+#define OTPC_ADDRR_PA_MASK 0x000001ff
+#define OTPC_ADDRR_PA_SHIFT 0
+
+/*
+ * data format:
+ * struct starfive_otp_data{
+ * char vendor[32];
+ * uint64_t sn;
+ * uint8_t mac_addr[6];
+ * uint8_t padding_0[2];
+ * }
+ */
+
+struct starfive_otp {
+ int power_gpio;
+ struct starfive_otp_regs __iomem *regs;
+};
+
+struct starfive_otp_regs {
+ /* TODO: add otp ememory_eg512x32 registers define */
+ u32 otp_cfg; /* timing Register */
+ u32 otpc_ie; /* interrupt Enable */
+ u32 otpc_sr; /* status Register */
+ u32 otp_opr; /* operation mode select Register */
+ u32 otpc_ctl; /* otp control port */
+ u32 otpc_addr; /* otp pa port */
+ u32 otpc_din; /* otp pdin port */
+ u32 otpc_dout; /* otp pdout */
+ u32 reserved[504];
+ u32 mem[512];
+};
+
+/*
+ * offset and size are assumed aligned to the size of the fuses (32-bit).
+ */
+static int starfive_otp_read(void *ctx, unsigned offset, unsigned *val)
+{
+ struct starfive_otp *priv = ctx;
+
+ gpio_set_active(priv->power_gpio, true);
+ mdelay(10);
+
+ //otp set to read mode
+ writel(OTP_OPR_READ, &priv->regs->otp_opr);
+ mdelay(5);
+
+ /* read all requested fuses */
+ *val = readl(&priv->regs->mem[offset / 4]);
+
+ gpio_set_active(priv->power_gpio, false);
+ mdelay(5);
+
+ return 0;
+}
+
+static int starfive_otp_write(void *ctx, unsigned offset, unsigned val)
+{
+ return -EOPNOTSUPP;
+}
+
+static struct regmap_bus starfive_otp_regmap_bus = {
+ .reg_read = starfive_otp_read,
+ .reg_write = starfive_otp_write,
+};
+
+static int starfive_otp_probe(struct device_d *dev)
+{
+ struct starfive_otp *priv;
+ struct regmap_config config = {};
+ struct resource *iores;
+ struct regmap *map;
+ struct clk *clk;
+ u32 total_fuses;
+ int ret;
+
+ clk = clk_get(dev, NULL);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ clk_enable(clk);
+
+ ret = device_reset(dev);
+ if (ret)
+ return ret;
+
+ iores = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(iores))
+ return PTR_ERR(iores);
+
+ ret = of_property_read_u32(dev->device_node, "fuse-count", &total_fuses);
+ if (ret < 0) {
+ dev_err(dev, "missing required fuse-count property\n");
+ return ret;
+ }
+
+ config.name = "starfive-otp";
+ config.reg_bits = 32;
+ config.val_bits = 32;
+ config.reg_stride = 4;
+ config.max_register = total_fuses;
+
+ priv = xzalloc(sizeof(*priv));
+
+ priv->regs = IOMEM(iores->start);
+ priv->power_gpio = gpiod_get(dev, "power", GPIOD_OUT_LOW);
+ if (priv->power_gpio < 0)
+ return priv->power_gpio;
+
+ map = regmap_init(dev, &starfive_otp_regmap_bus, priv, &config);
+ if (IS_ERR(map))
+ return PTR_ERR(map);
+
+ return PTR_ERR_OR_ZERO(nvmem_regmap_register(map, "starfive-otp"));
+}
+
+static struct of_device_id starfive_otp_dt_ids[] = {
+ { .compatible = "starfive,fu740-otp" },
+ { /* sentinel */ }
+};
+
+static struct driver_d starfive_otp_driver = {
+ .name = "starfive_otp",
+ .probe = starfive_otp_probe,
+ .of_compatible = starfive_otp_dt_ids,
+};
+device_platform_driver(starfive_otp_driver);
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index c774660232..cf2f724d18 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -128,7 +128,7 @@ static struct pinctrl_ops pcs_ops = {
.set_state = pcs_set_state,
};
-static int pcs_probe(struct device_d *dev)
+int pinctrl_single_probe(struct device_d *dev)
{
struct resource *iores;
struct pinctrl_single *pcs;
@@ -215,7 +215,7 @@ static __maybe_unused struct of_device_id pcs_dt_ids[] = {
static struct driver_d pcs_driver = {
.name = "pinctrl-single",
- .probe = pcs_probe,
+ .probe = pinctrl_single_probe,
.of_compatible = DRV_OF_COMPAT(pcs_dt_ids),
};
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 316ece9e71..9429f107bb 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -27,4 +27,10 @@ config RESET_STM32
help
This enables the reset controller driver for STM32MP and STM32 MCUs.
+config RESET_STARFIVE
+ bool "StarFive Controller Driver" if COMPILE_TEST
+ default SOC_STARFIVE
+ help
+ This enables the reset controller driver for the StarFive JH7100.
+
endif
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 8460c4b154..ce494baae5 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_RESET_CONTROLLER) += core.o
obj-$(CONFIG_ARCH_SOCFPGA) += reset-socfpga.o
obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
obj-$(CONFIG_RESET_STM32) += reset-stm32.o
+obj-$(CONFIG_RESET_STARFIVE) += reset-starfive-vic.o
diff --git a/drivers/reset/core.c b/drivers/reset/core.c
index 1dd071635f..9f5a642539 100644
--- a/drivers/reset/core.c
+++ b/drivers/reset/core.c
@@ -139,30 +139,35 @@ int reset_control_deassert(struct reset_control *rstc)
EXPORT_SYMBOL_GPL(reset_control_deassert);
/**
- * of_reset_control_get - Lookup and obtain a reference to a reset controller.
+ * of_reset_control_count - Count reset lines
+ * @node: device node
+ *
+ * Returns number of resets, 0 if none specified
+ */
+static int of_reset_control_count(struct device_node *node)
+{
+ return of_count_phandle_with_args(node, "resets", "#reset-cells");
+}
+
+/**
+ * of_reset_control_get_by_index - Lookup and obtain a reference to a reset controller.
* @node: device to be reset by the controller
- * @id: reset line name
+ * @index: reset line index
*
* Returns a struct reset_control or IS_ERR() condition containing errno.
- *
- * Use of id names is optional.
*/
-struct reset_control *of_reset_control_get(struct device_node *node,
- const char *id)
+static struct reset_control *of_reset_control_get_by_index(struct device_node *node,
+ int index)
{
struct reset_control *rstc;
struct reset_controller_dev *r, *rcdev;
struct of_phandle_args args;
- int index = 0;
int rstc_id;
int ret;
if (!of_get_property(node, "resets", NULL))
return NULL;
- if (id)
- index = of_property_match_string(node,
- "reset-names", id);
ret = of_parse_phandle_with_args(node, "resets", "#reset-cells",
index, &args);
if (ret)
@@ -199,6 +204,26 @@ struct reset_control *of_reset_control_get(struct device_node *node,
return rstc;
}
+/**
+ * of_reset_control_get - Lookup and obtain a reference to a reset controller.
+ * @node: device to be reset by the controller
+ * @id: reset line name
+ *
+ * Returns a struct reset_control or IS_ERR() condition containing errno.
+ *
+ * Use of id names is optional.
+ */
+struct reset_control *of_reset_control_get(struct device_node *node,
+ const char *id)
+{
+ int index = 0;
+
+ if (id)
+ index = of_property_match_string(node, "reset-names", id);
+
+ return of_reset_control_get_by_index(node, index);
+}
+
static struct reset_control *
gpio_reset_control_get(struct device_d *dev, const char *id)
{
@@ -306,6 +331,39 @@ int device_reset(struct device_d *dev)
}
EXPORT_SYMBOL_GPL(device_reset);
+int device_reset_all(struct device_d *dev)
+{
+ struct reset_control *rstc;
+ int ret, i;
+
+ for (i = 0; i < of_reset_control_count(dev->device_node); i++) {
+ int ret;
+
+ rstc = of_reset_control_get_by_index(dev->device_node, i);
+ if (IS_ERR(rstc))
+ return PTR_ERR(rstc);
+
+ ret = reset_control_reset(rstc);
+ if (ret)
+ return ret;
+
+ reset_control_put(rstc);
+ }
+
+ if (i == 0) {
+ rstc = gpio_reset_control_get(dev, NULL);
+
+ ret = reset_control_reset(rstc);
+ if (ret)
+ return ret;
+
+ reset_control_put(rstc);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(device_reset_all);
+
int device_reset_us(struct device_d *dev, int us)
{
struct reset_control *rstc;
diff --git a/drivers/reset/reset-starfive-vic.c b/drivers/reset/reset-starfive-vic.c
new file mode 100644
index 0000000000..bcf615da0a
--- /dev/null
+++ b/drivers/reset/reset-starfive-vic.c
@@ -0,0 +1,234 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 Ahmad Fatoum, Pengutronix
+ *
+ * StarFive Reset Controller driver
+ */
+#define pr_fmt(fmt) "reset-starfive: " fmt
+
+#include <common.h>
+#include <init.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/reset-controller.h>
+#include <soc/starfive/rstgen.h>
+#include <dt-bindings/reset-controller/starfive-jh7100.h>
+#include <dt-bindings/clock/starfive-jh7100.h>
+
+struct starfive_rstgen {
+ void __iomem *base;
+ struct reset_controller_dev rcdev;
+ const struct starfive_rstgen_ops *ops;
+ struct device_node *clknp;
+ const int *sync_resets;
+};
+
+static struct starfive_rstgen *to_starfive_rstgen(struct reset_controller_dev *rcdev)
+{
+ return container_of(rcdev, struct starfive_rstgen, rcdev);
+}
+
+static const int jh7110_rstgen_sync_resets[RSTN_END] = {
+ [RSTN_SGDMA2P_AHB] = CLK_SGDMA2P_AHB,
+ [RSTN_SGDMA2P_AXI] = CLK_SGDMA2P_AXI,
+ [RSTN_DMA2PNOC_AXI] = CLK_DMA2PNOC_AXI,
+ [RSTN_DLA_AXI] = CLK_DLA_AXI,
+ [RSTN_DLANOC_AXI] = CLK_DLANOC_AXI,
+ [RSTN_DLA_APB] = CLK_DLA_APB,
+ [RSTN_VDECBRG_MAIN] = CLK_VDECBRG_MAIN,
+ [RSTN_VDEC_AXI] = CLK_VDEC_AXI,
+ [RSTN_VDEC_BCLK] = CLK_VDEC_BCLK,
+ [RSTN_VDEC_CCLK] = CLK_VDEC_CCLK,
+ [RSTN_VDEC_APB] = CLK_VDEC_APB,
+ [RSTN_JPEG_AXI] = CLK_JPEG_AXI,
+ [RSTN_JPEG_CCLK] = CLK_JPEG_CCLK,
+ [RSTN_JPEG_APB] = CLK_JPEG_APB,
+ [RSTN_JPCGC300_MAIN] = CLK_JPCGC300_MAIN,
+ [RSTN_GC300_2X] = CLK_GC300_2X,
+ [RSTN_GC300_AXI] = CLK_GC300_AXI,
+ [RSTN_GC300_AHB] = CLK_GC300_AHB,
+ [RSTN_VENC_AXI] = CLK_VENC_AXI,
+ [RSTN_VENCBRG_MAIN] = CLK_VENCBRG_MAIN,
+ [RSTN_VENC_BCLK] = CLK_VENC_BCLK,
+ [RSTN_VENC_CCLK] = CLK_VENC_CCLK,
+ [RSTN_VENC_APB] = CLK_VENC_APB,
+ [RSTN_DDRPHY_APB] = CLK_DDRPHY_APB,
+ [RSTN_USB_AXI] = CLK_USB_AXI,
+ [RSTN_SGDMA1P_AXI] = CLK_SGDMA1P_AXI,
+ [RSTN_DMA1P_AXI] = CLK_DMA1P_AXI,
+ [RSTN_NNE_AHB] = CLK_NNE_AHB,
+ [RSTN_NNE_AXI] = CLK_NNE_AXI,
+ [RSTN_NNENOC_AXI] = CLK_NNENOC_AXI,
+ [RSTN_DLASLV_AXI] = CLK_DLASLV_AXI,
+ [RSTN_VOUT_SRC] = CLK_VOUT_SRC,
+ [RSTN_DISP_AXI] = CLK_DISP_AXI,
+ [RSTN_DISPNOC_AXI] = CLK_DISPNOC_AXI,
+ [RSTN_SDIO0_AHB] = CLK_SDIO0_AHB,
+ [RSTN_SDIO1_AHB] = CLK_SDIO1_AHB,
+ [RSTN_GMAC_AHB] = CLK_GMAC_AHB,
+ [RSTN_SPI2AHB_AHB] = CLK_SPI2AHB_AHB,
+ [RSTN_SPI2AHB_CORE] = CLK_SPI2AHB_CORE,
+ [RSTN_EZMASTER_AHB] = CLK_EZMASTER_AHB,
+ [RSTN_SEC_AHB] = CLK_SEC_AHB,
+ [RSTN_AES] = CLK_AES,
+ [RSTN_PKA] = CLK_PKA,
+ [RSTN_SHA] = CLK_SHA,
+ [RSTN_TRNG_APB] = CLK_TRNG_APB,
+ [RSTN_OTP_APB] = CLK_OTP_APB,
+ [RSTN_UART0_APB] = CLK_UART0_APB,
+ [RSTN_UART0_CORE] = CLK_UART0_CORE,
+ [RSTN_UART1_APB] = CLK_UART1_APB,
+ [RSTN_UART1_CORE] = CLK_UART1_CORE,
+ [RSTN_SPI0_APB] = CLK_SPI0_APB,
+ [RSTN_SPI0_CORE] = CLK_SPI0_CORE,
+ [RSTN_SPI1_APB] = CLK_SPI1_APB,
+ [RSTN_SPI1_CORE] = CLK_SPI1_CORE,
+ [RSTN_I2C0_APB] = CLK_I2C0_APB,
+ [RSTN_I2C0_CORE] = CLK_I2C0_CORE,
+ [RSTN_I2C1_APB] = CLK_I2C1_APB,
+ [RSTN_I2C1_CORE] = CLK_I2C1_CORE,
+ [RSTN_GPIO_APB] = CLK_GPIO_APB,
+ [RSTN_UART2_APB] = CLK_UART2_APB,
+ [RSTN_UART2_CORE] = CLK_UART2_CORE,
+ [RSTN_UART3_APB] = CLK_UART3_APB,
+ [RSTN_UART3_CORE] = CLK_UART3_CORE,
+ [RSTN_SPI2_APB] = CLK_SPI2_APB,
+ [RSTN_SPI2_CORE] = CLK_SPI2_CORE,
+ [RSTN_SPI3_APB] = CLK_SPI3_APB,
+ [RSTN_SPI3_CORE] = CLK_SPI3_CORE,
+ [RSTN_I2C2_APB] = CLK_I2C2_APB,
+ [RSTN_I2C2_CORE] = CLK_I2C2_CORE,
+ [RSTN_I2C3_APB] = CLK_I2C3_APB,
+ [RSTN_I2C3_CORE] = CLK_I2C3_CORE,
+ [RSTN_WDTIMER_APB] = CLK_WDTIMER_APB,
+ [RSTN_WDT] = CLK_WDT_CORE,
+ [RSTN_VP6INTC_APB] = CLK_VP6INTC_APB,
+ [RSTN_TEMP_APB] = CLK_TEMP_APB,
+ [RSTN_TEMP_SENSE] = CLK_TEMP_SENSE,
+};
+
+static struct clk *starfive_reset_clk_get(struct starfive_rstgen *priv, unsigned id)
+{
+ struct of_phandle_args clkspec = {
+ .np = priv->clknp,
+ .args_count = 1,
+ };
+
+ if (!priv->sync_resets || !priv->sync_resets[id])
+ return 0;
+
+ clkspec.args[0] = priv->sync_resets[id];
+
+ pr_debug("synchronous reset=%u clk=%u\n", id, priv->sync_resets[id]);
+
+ return of_clk_get_from_provider(&clkspec);
+}
+
+static int starfive_reset_clk_enable(struct starfive_rstgen *priv, unsigned id)
+{
+ return clk_enable(starfive_reset_clk_get(priv, id));
+}
+
+static void starfive_reset_clk_disable(struct starfive_rstgen *priv, unsigned id)
+{
+ clk_disable(starfive_reset_clk_get(priv, id));
+}
+
+static int starfive_rstgen(struct starfive_rstgen *priv, unsigned id, bool assert)
+{
+ void __iomem *base = priv->base;
+
+ __starfive_rstgen(base, id, assert);
+
+ return wait_on_timeout(NSEC_PER_MSEC, __starfive_rstgen_asserted(base, id) == assert);
+}
+
+static int starfive_rstgen_assert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct starfive_rstgen *priv = to_starfive_rstgen(rcdev);
+ int ret;
+
+ starfive_reset_clk_enable(priv, id);
+ ret = starfive_rstgen(priv, id, true);
+ starfive_reset_clk_disable(priv, id);
+
+ return ret;
+}
+
+static int starfive_rstgen_deassert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct starfive_rstgen *priv = to_starfive_rstgen(rcdev);
+ int ret;
+
+ starfive_reset_clk_enable(priv, id);
+ ret = starfive_rstgen(priv, id, false);
+ starfive_reset_clk_disable(priv, id);
+
+ return ret;
+}
+
+static int starfive_reset(struct reset_controller_dev *rcdev, unsigned long id)
+{
+ struct starfive_rstgen *priv = to_starfive_rstgen(rcdev);
+ int ret;
+
+ starfive_reset_clk_enable(priv, id);
+
+ ret = starfive_rstgen(priv, id, true);
+ if (ret)
+ goto out;
+
+ udelay(2);
+
+ ret = starfive_rstgen(priv, id, false);
+
+out:
+ starfive_reset_clk_disable(priv, id);
+
+ return ret;
+}
+
+static const struct reset_control_ops starfive_rstgen_ops = {
+ .assert = starfive_rstgen_assert,
+ .deassert = starfive_rstgen_deassert,
+ .reset = starfive_reset,
+};
+
+static int starfive_rstgen_probe(struct device_d *dev)
+{
+ struct starfive_rstgen *priv;
+ struct resource *iores;
+
+ priv = xzalloc(sizeof(*priv));
+
+ iores = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(iores))
+ return PTR_ERR(iores);
+
+ if ((priv->sync_resets = device_get_match_data(dev))) {
+ priv->clknp = of_find_compatible_node(NULL, NULL, "starfive,jh7100-clkgen");
+ if (!priv->clknp)
+ return -ENODEV;
+ }
+
+ priv->base = IOMEM(iores->start);
+ priv->rcdev.nr_resets = RSTN_END;
+ priv->rcdev.ops = &starfive_rstgen_ops;
+ priv->rcdev.of_node = dev->device_node;
+
+ return reset_controller_register(&priv->rcdev);
+}
+
+static const struct of_device_id starfive_rstgen_reset_dt_ids[] = {
+ { .compatible = "starfive,jh7100-rstgen", .data = jh7110_rstgen_sync_resets },
+ { /* sentinel */ },
+};
+
+static struct driver_d starfive_rstgen_reset_driver = {
+ .name = "starfive_rstgen",
+ .probe = starfive_rstgen_probe,
+ .of_compatible = starfive_rstgen_reset_dt_ids,
+};
+core_platform_driver(starfive_rstgen_reset_driver);
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
new file mode 100644
index 0000000000..c3499c0c7f
--- /dev/null
+++ b/drivers/soc/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += imx/
+obj-$(CONFIG_CPU_SIFIVE) += sifive/
+obj-$(CONFIG_SOC_STARFIVE) += starfive/
diff --git a/drivers/soc/sifive/Makefile b/drivers/soc/sifive/Makefile
new file mode 100644
index 0000000000..e8113c66f5
--- /dev/null
+++ b/drivers/soc/sifive/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_SIFIVE_L2) += sifive_l2_cache.o
diff --git a/drivers/soc/sifive/sifive_l2_cache.c b/drivers/soc/sifive/sifive_l2_cache.c
new file mode 100644
index 0000000000..a1e9a10622
--- /dev/null
+++ b/drivers/soc/sifive/sifive_l2_cache.c
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SiFive L2 cache controller Driver
+ *
+ * Copyright (C) 2018-2019 SiFive, Inc.
+ *
+ */
+
+#define pr_fmt(fmt) "sifive-l2: " fmt
+
+#include <io.h>
+#include <printk.h>
+#include <stdio.h>
+#include <driver.h>
+#include <init.h>
+#include <soc/sifive/l2_cache.h>
+#include <asm/barrier.h>
+#include <linux/bitops.h>
+
+#define SIFIVE_L2_DIRECCFIX_LOW 0x100
+#define SIFIVE_L2_DIRECCFIX_HIGH 0x104
+#define SIFIVE_L2_DIRECCFIX_COUNT 0x108
+
+#define SIFIVE_L2_DIRECCFAIL_LOW 0x120
+#define SIFIVE_L2_DIRECCFAIL_HIGH 0x124
+#define SIFIVE_L2_DIRECCFAIL_COUNT 0x128
+
+#define SIFIVE_L2_DATECCFIX_LOW 0x140
+#define SIFIVE_L2_DATECCFIX_HIGH 0x144
+#define SIFIVE_L2_DATECCFIX_COUNT 0x148
+
+#define SIFIVE_L2_DATECCFAIL_LOW 0x160
+#define SIFIVE_L2_DATECCFAIL_HIGH 0x164
+#define SIFIVE_L2_DATECCFAIL_COUNT 0x168
+
+#define SIFIVE_L2_FLUSH64 0x200
+
+#define SIFIVE_L2_CONFIG 0x00
+#define SIFIVE_L2_WAYENABLE 0x08
+#define SIFIVE_L2_ECCINJECTERR 0x40
+
+#define SIFIVE_L2_MAX_ECCINTR 4
+
+#define MASK_NUM_WAYS GENMASK(15, 8)
+#define NUM_WAYS_SHIFT 8
+
+#define SIFIVE_L2_FLUSH64_LINE_LEN 64
+
+static void __iomem *l2_base = NULL;
+
+static void sifive_l2_config_read(struct device_d *dev)
+{
+ u32 regval, val;
+
+ printf("Cache configuration:\n");
+
+ regval = readl(l2_base + SIFIVE_L2_CONFIG);
+ val = regval & 0xFF;
+ printf(" #Banks: %d\n", val);
+ val = (regval & 0xFF00) >> 8;
+ printf(" #Ways per bank: %d\n", val);
+ val = (regval & 0xFF0000) >> 16;
+ printf(" #Sets per bank: %llu\n", 1llu << val);
+ val = (regval & 0xFF000000) >> 24;
+ printf(" #Bytes per cache block: %llu\n", 1llu << val);
+
+ regval = readl(l2_base + SIFIVE_L2_WAYENABLE);
+ printf(" #Index of the largest way enabled: %d\n", regval);
+}
+
+void sifive_l2_flush64_range(dma_addr_t start, dma_addr_t end)
+{
+ unsigned long line;
+
+ start = ALIGN_DOWN(start, 64);
+ end = ALIGN(end, 64);
+
+ if (WARN_ON(!l2_base))
+ return;
+
+ if (start == end)
+ return;
+
+ mb();
+ for (line = start; line < end; line += SIFIVE_L2_FLUSH64_LINE_LEN) {
+ writeq(line, l2_base + SIFIVE_L2_FLUSH64);
+ mb();
+ }
+}
+
+static void sifive_l2_enable_ways(void)
+{
+ u32 config;
+ u32 ways;
+
+ config = readl(l2_base + SIFIVE_L2_CONFIG);
+ ways = (config & MASK_NUM_WAYS) >> NUM_WAYS_SHIFT;
+
+ mb();
+ writel(ways - 1, l2_base + SIFIVE_L2_WAYENABLE);
+ mb();
+}
+
+static int sifive_l2_probe(struct device_d *dev)
+{
+ struct resource *iores;
+
+ if (l2_base)
+ return -EBUSY;
+
+ iores = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(iores))
+ return PTR_ERR(iores);
+
+ l2_base = IOMEM(iores->start);
+
+ sifive_l2_enable_ways();
+
+ dev->info = sifive_l2_config_read;
+
+ return 0;
+}
+
+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 */ },
+};
+
+static struct driver_d sifive_l2_driver = {
+ .name = "sfive-l2cache",
+ .probe = sifive_l2_probe,
+ .of_compatible = sifive_l2_ids,
+};
+postcore_platform_driver(sifive_l2_driver);
diff --git a/drivers/soc/starfive/Makefile b/drivers/soc/starfive/Makefile
new file mode 100644
index 0000000000..72504b3bef
--- /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 0000000000..a1dc48e73f
--- /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);
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index b785181c59..080bc91ff7 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -141,4 +141,11 @@ config ITCO_WDT
NO_REBOOT flag which prevents the watchdog from rebooting the
machine.
+config STARFIVE_WDT
+ tristate "StarFive Watchdog Timer"
+ depends on SOC_STARFIVE && OFDEVICE
+ help
+ If you say yes here you get support for the watchdog device
+ on StarFive SoCs.
+
endif
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 0b598af402..4e784b5aaa 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -18,3 +18,4 @@ obj-$(CONFIG_STPMIC1_WATCHDOG) += stpmic1_wdt.o
obj-$(CONFIG_F71808E_WDT) += f71808e_wdt.o
obj-$(CONFIG_GPIO_WATCHDOG) += gpio_wdt.o
obj-$(CONFIG_ITCO_WDT) += itco_wdt.o
+obj-$(CONFIG_STARFIVE_WDT) += starfive_wdt.o
diff --git a/drivers/watchdog/starfive_wdt.c b/drivers/watchdog/starfive_wdt.c
new file mode 100644
index 0000000000..6779566fd6
--- /dev/null
+++ b/drivers/watchdog/starfive_wdt.c
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2018 Kalray Inc.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <of.h>
+#include <watchdog.h>
+#include <linux/reset.h>
+
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#define WDT_REG_RESET_EN 0x104
+#define WDT_REG_TIMEOUT 0x108
+#define WDT_REG_CONTROL 0x110
+#define WDT_REG_UNLOCK 0x13c
+
+#define WDT_UNLOCK_KEY 0x378f0765
+
+#define WDT_TICKS_PER_SEC 50000000
+
+struct starfive_wdt {
+ u32 clk_rate;
+ struct watchdog wdd;
+ void __iomem *base;
+ bool setup;
+};
+
+static int starfive_wdt_set_timeout(struct watchdog *wdd, unsigned int timeout)
+{
+ struct starfive_wdt *wd = container_of(wdd, struct starfive_wdt, wdd);
+
+ writel(0, wd->base + WDT_REG_CONTROL);
+
+ if (timeout > 0) {
+ timeout *= wd->clk_rate;
+ writel(timeout, wd->base + WDT_REG_TIMEOUT);
+ writel(1, wd->base + WDT_REG_CONTROL);
+ }
+
+ return 0;
+}
+
+static int starfive_wdt_drv_probe(struct device_d *dev)
+{
+ struct starfive_wdt *wd;
+ struct resource *iores;
+ struct watchdog *wdd;
+ struct clk_bulk_data clks[] = {
+ { .id = "bus" },
+ { .id = "core" },
+ };
+ int ret;
+
+ ret = clk_bulk_get(dev, ARRAY_SIZE(clks), clks);
+ if (ret)
+ return ret;
+
+ ret = clk_bulk_enable(ARRAY_SIZE(clks), clks);
+ if (ret < 0)
+ return ret;
+
+ ret = device_reset_all(dev);
+ if (ret)
+ return ret;
+
+ iores = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(iores))
+ return PTR_ERR(iores);
+
+ wd = xzalloc(sizeof(*wd));
+ wd->base = IOMEM(iores->start);
+
+ wd->clk_rate = WDT_TICKS_PER_SEC;
+
+ writel(WDT_UNLOCK_KEY, wd->base + WDT_REG_UNLOCK);
+ wd->base = IOMEM(iores->start);
+ /* reset, not interrupt, on timer expiry */
+ writel(1, wd->base + WDT_REG_RESET_EN);
+
+ wdd = &wd->wdd;
+ wdd->name = "starfive_wdt";
+ wdd->hwdev = dev;
+ wdd->set_timeout = starfive_wdt_set_timeout;
+ wdd->timeout_max = U32_MAX / wd->clk_rate;
+
+ wdd->running = readl(wd->base + WDT_REG_CONTROL) & 1 ?
+ WDOG_HW_RUNNING : WDOG_HW_NOT_RUNNING;
+
+ return watchdog_register(wdd);
+}
+
+static struct of_device_id starfive_wdt_of_match[] = {
+ { .compatible = "starfive,wdt", },
+ { /* sentinel */ }
+};
+
+static struct driver_d starfive_wdt_driver = {
+ .name = "starfive-wdt",
+ .probe = starfive_wdt_drv_probe,
+ .of_compatible = starfive_wdt_of_match,
+};
+device_platform_driver(starfive_wdt_driver);
diff --git a/images/Makefile.riscv b/images/Makefile.riscv
index c44c683431..4410765cf6 100644
--- a/images/Makefile.riscv
+++ b/images/Makefile.riscv
@@ -15,3 +15,7 @@ pblb-$(CONFIG_BOARD_HIFIVE) += start_hifive_unmatched start_hifive_unleashed
FILE_barebox-hifive-unmatched.img = start_hifive_unmatched.pblb
FILE_barebox-hifive-unleashed.img = start_hifive_unleashed.pblb
image-$(CONFIG_BOARD_HIFIVE) += barebox-hifive-unmatched.img barebox-hifive-unleashed.img
+
+pblb-$(CONFIG_BOARD_BEAGLEV) += start_beaglev_starlight
+FILE_barebox-beaglev-starlight.img = start_beaglev_starlight.pblb
+image-$(CONFIG_BOARD_BEAGLEV) += barebox-beaglev-starlight.img
diff --git a/include/dma.h b/include/dma.h
index 1b1cb3a407..90f9254ea8 100644
--- a/include/dma.h
+++ b/include/dma.h
@@ -8,6 +8,7 @@
#include <malloc.h>
#include <xfuncs.h>
+#include <linux/kernel.h>
#include <dma-dir.h>
#include <asm/dma.h>
@@ -15,10 +16,14 @@
#define DMA_ADDRESS_BROKEN NULL
+#ifndef DMA_ALIGNMENT
+#define DMA_ALIGNMENT 32
+#endif
+
#ifndef dma_alloc
static inline void *dma_alloc(size_t size)
{
- return xmalloc(size);
+ return xmemalign(DMA_ALIGNMENT, ALIGN(size, DMA_ALIGNMENT));
}
#endif
diff --git a/include/dt-bindings/clock/starfive-jh7100.h b/include/dt-bindings/clock/starfive-jh7100.h
new file mode 100644
index 0000000000..2512bb810e
--- /dev/null
+++ b/include/dt-bindings/clock/starfive-jh7100.h
@@ -0,0 +1,203 @@
+/* SPDX-License-Identifier: GPL-2.0 OR X11 */
+/*
+ * Copyright (C) 2021 Ahmad Fatoum, Pengutronix
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7100_H
+#define __DT_BINDINGS_CLOCK_STARFIVE_JH7100_H
+
+#define CLK_OSC_SYS 0
+#define CLK_OSC_AUD 1
+#define CLK_PLL0_OUT 2
+#define CLK_PLL1_OUT 3
+#define CLK_PLL2_OUT 4
+#define CLK_CPUNDBUS_ROOT 5
+#define CLK_DLA_ROOT 6
+#define CLK_DSP_ROOT 7
+#define CLK_GMACUSB_ROOT 8
+#define CLK_PERH0_ROOT 9
+#define CLK_PERH1_ROOT 10
+#define CLK_VIN_ROOT 11
+#define CLK_VOUT_ROOT 12
+#define CLK_AUDIO_ROOT 13
+#define CLK_CDECHIFI4_ROOT 14
+#define CLK_CDEC_ROOT 15
+#define CLK_VOUTBUS_ROOT 16
+#define CLK_CPUNBUS_ROOT_DIV 17
+#define CLK_DSP_ROOT_DIV 18
+#define CLK_PERH0_SRC 19
+#define CLK_PERH1_SRC 20
+#define CLK_PLL0_TESTOUT 21
+#define CLK_PLL1_TESTOUT 22
+#define CLK_PLL2_TESTOUT 23
+#define CLK_PLL2_REF 24
+#define CLK_CPU_CORE 25
+#define CLK_CPU_AXI 26
+#define CLK_AHB_BUS 27
+#define CLK_APB1_BUS 28
+#define CLK_APB2_BUS 29
+#define CLK_DOM3AHB_BUS 30
+#define CLK_DOM7AHB_BUS 31
+#define CLK_U74_CORE0 32
+#define CLK_U74_CORE1 33
+#define CLK_U74_AXI 34
+#define CLK_U74RTC_TOGGLE 35
+#define CLK_SGDMA2P_AXI 36
+#define CLK_DMA2PNOC_AXI 37
+#define CLK_SGDMA2P_AHB 38
+#define CLK_DLA_BUS 39
+#define CLK_DLA_AXI 40
+#define CLK_DLANOC_AXI 41
+#define CLK_DLA_APB 42
+#define CLK_VP6_CORE 43
+#define CLK_VP6BUS_SRC 44
+#define CLK_VP6_AXI 45
+#define CLK_VCDECBUS_SRC 46
+#define CLK_VDEC_BUS 47
+#define CLK_VDEC_AXI 48
+#define CLK_VDECBRG_MAIN 49
+#define CLK_VDEC_BCLK 50
+#define CLK_VDEC_CCLK 51
+#define CLK_VDEC_APB 52
+#define CLK_JPEG_AXI 53
+#define CLK_JPEG_CCLK 54
+#define CLK_JPEG_APB 55
+#define CLK_GC300_2X 56
+#define CLK_GC300_AHB 57
+#define CLK_JPCGC300_AXIBUS 58
+#define CLK_GC300_AXI 59
+#define CLK_JPCGC300_MAIN 60
+#define CLK_VENC_BUS 61
+#define CLK_VENC_AXI 62
+#define CLK_VENCBRG_MAIN 63
+#define CLK_VENC_BCLK 64
+#define CLK_VENC_CCLK 65
+#define CLK_VENC_APB 66
+#define CLK_DDRPLL_DIV2 67
+#define CLK_DDRPLL_DIV4 68
+#define CLK_DDRPLL_DIV8 69
+#define CLK_DDROSC_DIV2 70
+#define CLK_DDRC0 71
+#define CLK_DDRC1 72
+#define CLK_DDRPHY_APB 73
+#define CLK_NOC_ROB 74
+#define CLK_NOC_COG 75
+#define CLK_NNE_AHB 76
+#define CLK_NNEBUS_SRC1 77
+#define CLK_NNE_BUS 78
+#define CLK_NNE_AXI 79
+#define CLK_NNENOC_AXI 80
+#define CLK_DLASLV_AXI 81
+#define CLK_DSPX2C_AXI 82
+#define CLK_HIFI4_SRC 83
+#define CLK_HIFI4_COREFREE 84
+#define CLK_HIFI4_CORE 85
+#define CLK_HIFI4_BUS 86
+#define CLK_HIFI4_AXI 87
+#define CLK_HIFI4NOC_AXI 88
+#define CLK_SGDMA1P_BUS 89
+#define CLK_SGDMA1P_AXI 90
+#define CLK_DMA1P_AXI 91
+#define CLK_X2C_AXI 92
+#define CLK_USB_BUS 93
+#define CLK_USB_AXI 94
+#define CLK_USBNOC_AXI 95
+#define CLK_USBPHY_ROOTDIV 96
+#define CLK_USBPHY_125M 97
+#define CLK_USBPHY_PLLDIV25M 98
+#define CLK_USBPHY_25M 99
+#define CLK_AUDIO_DIV 100
+#define CLK_AUDIO_SRC 101
+#define CLK_AUDIO_12288 102
+#define CLK_VIN_SRC 103
+#define CLK_ISP0_BUS 104
+#define CLK_ISP0_AXI 105
+#define CLK_ISP0NOC_AXI 106
+#define CLK_ISPSLV_AXI 107
+#define CLK_ISP1_BUS 108
+#define CLK_ISP1_AXI 109
+#define CLK_ISP1NOC_AXI 110
+#define CLK_VIN_BUS 111
+#define CLK_VIN_AXI 112
+#define CLK_VINNOC_AXI 113
+#define CLK_VOUT_SRC 114
+#define CLK_DISPBUS_SRC 115
+#define CLK_DISP_BUS 116
+#define CLK_DISP_AXI 117
+#define CLK_DISPNOC_AXI 118
+#define CLK_SDIO0_AHB 119
+#define CLK_SDIO0_CCLKINT 120
+#define CLK_SDIO0_CCLKINT_INV 121
+#define CLK_SDIO1_AHB 122
+#define CLK_SDIO1_CCLKINT 123
+#define CLK_SDIO1_CCLKINT_INV 124
+#define CLK_GMAC_AHB 125
+#define CLK_GMAC_ROOT_DIV 126
+#define CLK_GMAC_PTP_REF 127
+#define CLK_GMAC_GTX 128
+#define CLK_GMAC_RMII_TX 129
+#define CLK_GMAC_RMII_RX 130
+#define CLK_GMAC_TX 131
+#define CLK_GMAC_TX_INV 132
+#define CLK_GMAC_RX_PRE 133
+#define CLK_GMAC_RX_INV 134
+#define CLK_GMAC_RMII 135
+#define CLK_GMAC_TOPHYREF 136
+#define CLK_SPI2AHB_AHB 137
+#define CLK_SPI2AHB_CORE 138
+#define CLK_EZMASTER_AHB 139
+#define CLK_E24_AHB 140
+#define CLK_E24RTC_TOGGLE 141
+#define CLK_QSPI_AHB 142
+#define CLK_QSPI_APB 143
+#define CLK_QSPI_REF 144
+#define CLK_SEC_AHB 145
+#define CLK_AES 146
+#define CLK_SHA 147
+#define CLK_PKA 148
+#define CLK_TRNG_APB 149
+#define CLK_OTP_APB 150
+#define CLK_UART0_APB 151
+#define CLK_UART0_CORE 152
+#define CLK_UART1_APB 153
+#define CLK_UART1_CORE 154
+#define CLK_SPI0_APB 155
+#define CLK_SPI0_CORE 156
+#define CLK_SPI1_APB 157
+#define CLK_SPI1_CORE 158
+#define CLK_I2C0_APB 159
+#define CLK_I2C0_CORE 160
+#define CLK_I2C1_APB 161
+#define CLK_I2C1_CORE 162
+#define CLK_GPIO_APB 163
+#define CLK_UART2_APB 164
+#define CLK_UART2_CORE 165
+#define CLK_UART3_APB 166
+#define CLK_UART3_CORE 167
+#define CLK_SPI2_APB 168
+#define CLK_SPI2_CORE 169
+#define CLK_SPI3_APB 170
+#define CLK_SPI3_CORE 171
+#define CLK_I2C2_APB 172
+#define CLK_I2C2_CORE 173
+#define CLK_I2C3_APB 174
+#define CLK_I2C3_CORE 175
+#define CLK_WDTIMER_APB 176
+#define CLK_WDT_CORE 177
+#define CLK_TIMER0_CORE 178
+#define CLK_TIMER1_CORE 179
+#define CLK_TIMER2_CORE 180
+#define CLK_TIMER3_CORE 181
+#define CLK_TIMER4_CORE 182
+#define CLK_TIMER5_CORE 183
+#define CLK_TIMER6_CORE 184
+#define CLK_VP6INTC_APB 185
+#define CLK_PWM_APB 186
+#define CLK_MSI_APB 187
+#define CLK_TEMP_APB 188
+#define CLK_TEMP_SENSE 189
+#define CLK_SYSERR_APB 190
+
+#define CLK_END 191
+
+#endif
diff --git a/include/dt-bindings/reset-controller/starfive-jh7100.h b/include/dt-bindings/reset-controller/starfive-jh7100.h
new file mode 100644
index 0000000000..390a528576
--- /dev/null
+++ b/include/dt-bindings/reset-controller/starfive-jh7100.h
@@ -0,0 +1,126 @@
+/* SPDX-License-Identifier: GPL-2.0 OR X11 */
+/*
+ * Copyright (c) 2021 Ahmad Fatoum, Pengutronix
+ */
+
+#ifndef _DT_BINDINGS_RESET_CONTROLLER_STARFIVE_JH7100
+#define _DT_BINDINGS_RESET_CONTROLLER_STARFIVE_JH7100
+
+#define RSTN_DOM3AHB_BUS 0
+#define RSTN_DOM7AHB_BUS 1
+#define RST_U74 2
+#define RSTN_U74_AXI 3
+#define RSTN_SGDMA2P_AHB 4
+#define RSTN_SGDMA2P_AXI 5
+#define RSTN_DMA2PNOC_AXI 6
+#define RSTN_DLA_AXI 7
+#define RSTN_DLANOC_AXI 8
+#define RSTN_DLA_APB 9
+#define RST_VP6_DRESET 10
+#define RST_VP6_BRESET 11
+#define RSTN_VP6_AXI 12
+#define RSTN_VDECBRG_MAIN 13
+#define RSTN_VDEC_AXI 14
+#define RSTN_VDEC_BCLK 15
+#define RSTN_VDEC_CCLK 16
+#define RSTN_VDEC_APB 17
+#define RSTN_JPEG_AXI 18
+#define RSTN_JPEG_CCLK 19
+#define RSTN_JPEG_APB 20
+#define RSTN_JPCGC300_MAIN 21
+#define RSTN_GC300_2X 22
+#define RSTN_GC300_AXI 23
+#define RSTN_GC300_AHB 24
+#define RSTN_VENC_AXI 25
+#define RSTN_VENCBRG_MAIN 26
+#define RSTN_VENC_BCLK 27
+#define RSTN_VENC_CCLK 28
+#define RSTN_VENC_APB 29
+#define RSTN_DDRPHY_APB 30
+#define RSTN_NOC_ROB 31
+#define RSTN_NOC_COG 32
+#define RSTN_HIFI4_AXI 33
+#define RSTN_HIFI4NOC_AXI 34
+#define RST_HIFI4_drESET 35
+#define RST_HIFI4_bRESET 36
+#define RSTN_USB_AXI 37
+#define RSTN_USBNOC_AXI 38
+#define RSTN_SGDMA1P_AXI 39
+#define RSTN_DMA1P_AXI 40
+#define RSTN_X2C_AXI 41
+#define RSTN_NNE_AHB 42
+#define RSTN_NNE_AXI 43
+#define RSTN_NNENOC_AXI 44
+#define RSTN_DLASLV_AXI 45
+#define RSTN_DSPX2C_AXI 46
+#define RSTN_VIN_SRC 47
+#define RSTN_ISPSLV_AXI 48
+#define RSTN_VIN_AXI 49
+#define RSTN_VINNOC_AXI 50
+#define RSTN_ISP0_AXI 51
+#define RSTN_ISP0NOC_AXI 52
+#define RSTN_ISP1_AXI 53
+#define RSTN_ISP1NOC_AXI 54
+#define RSTN_VOUT_SRC 55
+#define RSTN_DISP_AXI 56
+#define RSTN_DISPNOC_AXI 57
+#define RSTN_SDIO0_AHB 58
+#define RSTN_SDIO1_AHB 59
+#define RSTN_GMAC_AHB 60
+#define RSTN_SPI2AHB_AHB 61
+#define RSTN_SPI2AHB_CORE 62
+#define RSTN_EZMASTER_AHB 63
+#define RST_E24 64
+#define RSTN_QSPI_AHB 65
+#define RSTN_QSPI_CORE 66
+#define RSTN_QSPI_APB 67
+#define RSTN_SEC_AHB 68
+#define RSTN_AES 69
+#define RSTN_PKA 70
+#define RSTN_SHA 71
+#define RSTN_TRNG_APB 72
+#define RSTN_OTP_APB 73
+#define RSTN_UART0_APB 74
+#define RSTN_UART0_CORE 75
+#define RSTN_UART1_APB 76
+#define RSTN_UART1_CORE 77
+#define RSTN_SPI0_APB 78
+#define RSTN_SPI0_CORE 79
+#define RSTN_SPI1_APB 80
+#define RSTN_SPI1_CORE 81
+#define RSTN_I2C0_APB 82
+#define RSTN_I2C0_CORE 83
+#define RSTN_I2C1_APB 84
+#define RSTN_I2C1_CORE 85
+#define RSTN_GPIO_APB 86
+#define RSTN_UART2_APB 87
+#define RSTN_UART2_CORE 88
+#define RSTN_UART3_APB 89
+#define RSTN_UART3_CORE 90
+#define RSTN_SPI2_APB 91
+#define RSTN_SPI2_CORE 92
+#define RSTN_SPI3_APB 93
+#define RSTN_SPI3_CORE 94
+#define RSTN_I2C2_APB 95
+#define RSTN_I2C2_CORE 96
+#define RSTN_I2C3_APB 97
+#define RSTN_I2C3_CORE 98
+#define RSTN_WDTIMER_APB 99
+#define RSTN_WDT 100
+#define RSTN_TIMER0 101
+#define RSTN_TIMER1 102
+#define RSTN_TIMER2 103
+#define RSTN_TIMER3 104
+#define RSTN_TIMER4 105
+#define RSTN_TIMER5 106
+#define RSTN_TIMER6 107
+#define RSTN_VP6INTC_APB 108
+#define RSTN_PWM_APB 109
+#define RSTN_MSI_APB 110
+#define RSTN_TEMP_APB 111
+#define RSTN_TEMP_SENSE 112
+#define RSTN_SYSERR_APB 113
+
+#define RSTN_END 114
+
+#endif
diff --git a/include/globalvar.h b/include/globalvar.h
index 84bee9102c..476bb920f3 100644
--- a/include/globalvar.h
+++ b/include/globalvar.h
@@ -20,6 +20,8 @@ void globalvar_set(const char *name, const char *val);
int globalvar_add_simple_string(const char *name, char **value);
int globalvar_add_simple_int(const char *name, int *value,
const char *format);
+int globalvar_add_simple_uint64(const char *name, u64 *value,
+ const char *format);
int globalvar_add_bool(const char *name,
int (*set)(struct param_d *, void *),
int *value, void *priv);
@@ -55,6 +57,12 @@ static inline int globalvar_add_simple_int(const char *name,
return 0;
}
+static inline int globalvar_add_simple_uint64(const char *name,
+ u64 *value, const char *format)
+{
+ return 0;
+}
+
static inline int globalvar_add_bool(const char *name,
int (*set)(struct param_d *, void *),
int *value, void *priv)
diff --git a/include/linux/reset.h b/include/linux/reset.h
index 726cb5c205..818b06412f 100644
--- a/include/linux/reset.h
+++ b/include/linux/reset.h
@@ -19,6 +19,8 @@ int __must_check device_reset(struct device_d *dev);
int __must_check device_reset_us(struct device_d *dev, int us);
+int __must_check device_reset_all(struct device_d *dev);
+
#else
static inline int reset_control_reset(struct reset_control *rstc)
@@ -56,6 +58,11 @@ static inline int device_reset(struct device_d *dev)
return 0;
}
+static inline int device_reset_all(struct device_d *dev)
+{
+ return 0;
+}
+
#endif /* CONFIG_RESET_CONTROLLER */
#endif
diff --git a/include/pinctrl.h b/include/pinctrl.h
index 0fd7f49118..a628c3aac9 100644
--- a/include/pinctrl.h
+++ b/include/pinctrl.h
@@ -29,6 +29,7 @@ int of_pinctrl_select_state_default(struct device_node *np);
int pinctrl_gpio_direction_input(unsigned pin);
int pinctrl_gpio_direction_output(unsigned int pin);
int pinctrl_gpio_get_direction(unsigned pin);
+int pinctrl_single_probe(struct device_d *dev);
#else
static inline int pinctrl_select_state(struct device_d *dev, const char *state)
{
@@ -64,6 +65,11 @@ static inline int pinctrl_gpio_get_direction(unsigned pin)
{
return -ENOTSUPP;
}
+
+static inline int pinctrl_single_probe(struct device_d *dev)
+{
+ return -ENOSYS;
+}
#endif
#endif /* PINCTRL_H */
diff --git a/include/soc/sifive/l2_cache.h b/include/soc/sifive/l2_cache.h
new file mode 100644
index 0000000000..0da655cd4e
--- /dev/null
+++ b/include/soc/sifive/l2_cache.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __SOC_SIFIVE_L2_CACHE_H_
+#define __SOC_SIFIVE_L2_CACHE_H_
+
+#include <linux/types.h>
+
+void sifive_l2_flush64_range(dma_addr_t start, dma_addr_t end);
+
+#endif
diff --git a/include/soc/starfive/rstgen.h b/include/soc/starfive/rstgen.h
new file mode 100644
index 0000000000..7a674aabe9
--- /dev/null
+++ b/include/soc/starfive/rstgen.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __SOC_STARFIVE_RSTGEN_H_
+#define __SOC_STARFIVE_RSTGEN_H_
+
+#include <dt-bindings/reset-controller/starfive-jh7100.h>
+#include <linux/bitops.h>
+#include <linux/types.h>
+
+#define STARFIVE_RSTGEN_STATUS 0x10
+
+static inline void __iomem *starfive_rstgen_bank(void __iomem *base, unsigned long *id)
+{
+ void __iomem *bank = base + *id / (4 * BITS_PER_BYTE) * 4;
+ *id %= 4 * BITS_PER_BYTE;
+ return bank;
+}
+
+static inline void __starfive_rstgen(void __iomem *base, unsigned long id, bool assert)
+{
+ void __iomem *bank = starfive_rstgen_bank(base, &id);
+ u32 val;
+
+ val = readl(bank);
+
+ if (assert)
+ val |= BIT(id);
+ else
+ val &= ~BIT(id);
+
+ writel(val, bank);
+}
+
+static bool __starfive_rstgen_asserted(void __iomem *base, unsigned long id)
+{
+ void __iomem *bank = starfive_rstgen_bank(base, &id);
+
+ return !(readl(bank + STARFIVE_RSTGEN_STATUS) & BIT(id));
+}
+
+#endif
diff --git a/include/soc/starfive/sysmain.h b/include/soc/starfive/sysmain.h
new file mode 100644
index 0000000000..b58f8d9825
--- /dev/null
+++ b/include/soc/starfive/sysmain.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _STARFIVE_SYSMAIN_H_
+#define _STARFIVE_SYSMAIN_H_
+
+#define SYSMAIN_PLL0_REG 0x00
+#define SYSMAIN_PLL1_REG 0x04
+#define SYSMAIN_PLL2_REG 0x08
+#define SYSMAIN_PLLS_STAT 0x0c
+
+#define SYSMAIN_GMAC_PHY_INTF_SEL 0x70
+#define SYSMAIN_GMAC_GTXCLK_DLYCHAIN_SEL 0xC8
+
+
+#endif //_SYSCON_SYSMAIN_CTRL_MACRO_H_