* [PATCH v2 01/29] clocksource: RISC-V: demote probe success messages to debug level
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 02/29] RISC-V: virt: select only one timer Ahmad Fatoum
` (28 subsequent siblings)
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
There's always some clocksource driver loaded, so reporting it probed
successfully doesn't add much value. timebase-frequency can be read
from the device tree if needed and which drivers were probed successfully
can be seen in drvinfo output, so demote both riscv and clint timer
messages to debug level.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
drivers/clocksource/timer-clint.c | 2 +-
drivers/clocksource/timer-riscv.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/clocksource/timer-clint.c b/drivers/clocksource/timer-clint.c
index b7360010bdb6..4eeb9cf7ffc9 100644
--- a/drivers/clocksource/timer-clint.c
+++ b/drivers/clocksource/timer-clint.c
@@ -72,7 +72,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 ef67cff47555..c2d32b36bbc5 100644
--- a/drivers/clocksource/timer-riscv.c
+++ b/drivers/clocksource/timer-riscv.c
@@ -59,7 +59,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);
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 02/29] RISC-V: virt: select only one timer
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 01/29] clocksource: RISC-V: demote probe success messages to debug level Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 03/29] RISC-V: extend multi-image to support both S- and M-Mode Ahmad Fatoum
` (27 subsequent siblings)
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
S-Mode should use the riscv timer, so no need to select CLINT timer for
virt.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/riscv/Kconfig.socs | 1 -
1 file changed, 1 deletion(-)
diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index c6875738d05c..fd36745755e0 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -16,7 +16,6 @@ config BOARD_ERIZO_GENERIC
config SOC_VIRT
bool "QEMU Virt Machine"
select BOARD_RISCV_GENERIC_DT
- select CLINT_TIMER
help
Generates an image tht can be be booted by QEMU. The image is called
barebox-dt-2nd.img
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 03/29] RISC-V: extend multi-image to support both S- and M-Mode
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 01/29] clocksource: RISC-V: demote probe success messages to debug level Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 02/29] RISC-V: virt: select only one timer Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 04/29] RISC-V: cpuinfo: return some output for non-SBI systems as well Ahmad Fatoum
` (26 subsequent siblings)
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
We can't currently mix S-Mode and M-Mode images in the same build
and there's no straight-forward way to determine which mode we are in.
Move the decision on which mode barebox is targeted at out of Kconfig
and into the PBL. PBL code can call either barebox_riscv_supervisor_entry
or barebox_riscv_machine_entry to signal to barebox proper which mode
it's running in. Currently the only user of this information is the
RISC-V timer clocksource driver.
Any new code that does IS_ENABLED(CONFIG_RISCV_SBI) or
IS_ENABLED(CONFIG_RISCV_M_MODE) should also be adapted to use riscv_mode().
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/riscv/Kconfig | 14 +++++----
arch/riscv/Kconfig.socs | 2 ++
arch/riscv/boards/erizo/lowlevel.c | 6 ++--
arch/riscv/boards/hifive/lowlevel.c | 17 ++++++-----
arch/riscv/boot/board-dt-2nd.c | 2 +-
arch/riscv/boot/entry.c | 5 ++--
arch/riscv/boot/entry.h | 6 ++--
arch/riscv/boot/start.c | 12 +++++---
arch/riscv/boot/uncompress.c | 6 ++--
arch/riscv/include/asm/barebox-riscv.h | 10 ++++++-
arch/riscv/include/asm/system.h | 41 ++++++++++++++++++++++++++
arch/riscv/lib/sbi.c | 4 +++
drivers/clocksource/timer-clint.c | 5 ++--
drivers/clocksource/timer-riscv.c | 3 +-
14 files changed, 102 insertions(+), 31 deletions(-)
create mode 100644 arch/riscv/include/asm/system.h
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index a4aa799acf01..bbafdea1b959 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -97,14 +97,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 fd36745755e0..f1b431555fcd 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -15,6 +15,7 @@ config BOARD_ERIZO_GENERIC
config SOC_VIRT
bool "QEMU Virt Machine"
+ select RISCV_S_MODE
select BOARD_RISCV_GENERIC_DT
help
Generates an image tht can be be booted by QEMU. The image is called
@@ -22,6 +23,7 @@ config SOC_VIRT
config SOC_SIFIVE
bool "SiFive SoCs"
+ select RISCV_S_MODE
select CLK_SIFIVE
select CLK_SIFIVE_PRCI
select RISCV_TIMER
diff --git a/arch/riscv/boards/erizo/lowlevel.c b/arch/riscv/boards/erizo/lowlevel.c
index 6acf15931cdf..fc262ed61b56 100644
--- a/arch/riscv/boards/erizo/lowlevel.c
+++ b/arch/riscv/boards/erizo/lowlevel.c
@@ -7,12 +7,14 @@
ENTRY_FUNCTION(start_erizo_generic, a0, a1, a2)
{
extern char __dtb_z_erizo_generic_start[];
+ void *fdt;
debug_ll_init();
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 1de13cac1688..8a20f3c51d40 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(void *fdt)
+{
+ putc_ll('>');
+
+ barebox_riscv_supervisor_entry(0x80000000, SZ_128M, 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(__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(__dtb_z_hifive_unleashed_a00_start + get_runtime_offset());
}
diff --git a/arch/riscv/boot/board-dt-2nd.c b/arch/riscv/boot/board-dt-2nd.c
index e9810f8add97..48cb23ae5e92 100644
--- a/arch/riscv/boot/board-dt-2nd.c
+++ b/arch/riscv/boot/board-dt-2nd.c
@@ -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, fdt);
}
diff --git a/arch/riscv/boot/entry.c b/arch/riscv/boot/entry.c
index eb286423d875..e4a5c2208df3 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 b3a24d2783f7..fb4af5eae558 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/start.c b/arch/riscv/boot/start.c
index 05f6c6231f7e..82bd02d0a0d0 100644
--- a/arch/riscv/boot/start.c
+++ b/arch/riscv/boot/start.c
@@ -26,6 +26,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 +108,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;
@@ -168,18 +170,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 b4e010998a4a..35a91e8cb62a 100644
--- a/arch/riscv/boot/uncompress.c
+++ b/arch/riscv/boot/uncompress.c
@@ -23,10 +23,10 @@ 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;
@@ -67,5 +67,5 @@ void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
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/include/asm/barebox-riscv.h b/arch/riscv/include/asm/barebox-riscv.h
index bb1d15308b48..f4081a71f00e 100644
--- a/arch/riscv/include/asm/barebox-riscv.h
+++ b/arch/riscv/include/asm/barebox-riscv.h
@@ -19,14 +19,22 @@
#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 __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, boarddata) \
+ barebox_riscv_entry(membase, memsize, boarddata, RISCV_S_MODE)
unsigned long riscv_mem_ramoops_get(void);
unsigned long riscv_mem_endmem_get(void);
diff --git a/arch/riscv/include/asm/system.h b/arch/riscv/include/asm/system.h
new file mode 100644
index 000000000000..3d57a7d191f6
--- /dev/null
+++ b/arch/riscv/include/asm/system.h
@@ -0,0 +1,41 @@
+/* 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;
+}
+
+#ifndef __PBL__
+extern unsigned barebox_riscv_pbl_flags;
+
+static inline enum riscv_mode riscv_mode(void)
+{
+ return __riscv_mode(barebox_riscv_pbl_flags);
+}
+
+#endif
+
+#endif
+
+#endif
diff --git a/arch/riscv/lib/sbi.c b/arch/riscv/lib/sbi.c
index 973c9d9d0f1e..45a04fb821a9 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/drivers/clocksource/timer-clint.c b/drivers/clocksource/timer-clint.c
index 4eeb9cf7ffc9..412ce3e1e985 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);
diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
index c2d32b36bbc5..5a517fe6b43d 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();
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 04/29] RISC-V: cpuinfo: return some output for non-SBI systems as well
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (2 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 03/29] RISC-V: extend multi-image to support both S- and M-Mode Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 05/29] RISC-V: S-Mode: propagate Hart ID Ahmad Fatoum
` (25 subsequent siblings)
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
If barebox managed to actually execute the cpuinfo command, it probably
means that it's assumption which instructon set is being used and
whether it runs in machine or supervisor mode is correct.
Add that output to cpuinfo, so it shows at least something for non-SBI
configurations.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/riscv/include/asm/sbi.h | 8 ++----
arch/riscv/lib/cpuinfo.c | 55 +++++++++++++++++++++++++-----------
commands/Kconfig | 4 +--
3 files changed, 43 insertions(+), 24 deletions(-)
diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index ab1fc9a128e5..eb4018de382e 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/lib/cpuinfo.c b/arch/riscv/lib/cpuinfo.c
index 21b99a990a1a..16305e6c4d96 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,56 @@ 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:
+ 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/commands/Kconfig b/commands/Kconfig
index 7bb36d6e417e..22375360885b 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
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 05/29] RISC-V: S-Mode: propagate Hart ID
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (3 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 04/29] RISC-V: cpuinfo: return some output for non-SBI systems as well Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 06/29] RISC-V: erizo: make it easier to reuse ns16550 debug_ll Ahmad Fatoum
` (24 subsequent siblings)
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
Unlike other architectures we support, Linux must apparently be
booted on all cores by the bootloader. To achieve this, the bootloaders
running on the multiple cores synchronize via IPIs.
We will get there eventually, but for now, let's restrict barebox
to boot Linux on a single core. S-Mode firmware is passed hart (core) id
in a0. This is propagated via the thread pointer register, which is
unused by GCC and made available as:
- cpuinfo output when running in S-Mode
- $global.hartid
- a0 when booting via bootm
- /chosen/boot-hartid fixup: will come in handy when we gain EFI
loading support
- single /cpus/*/reg: All other CPU nodes are deleted via fixup
For M-Mode, we can query hart id via CSR. It's unknown whether erizo
supports it and we don't yet have exception support to handle it not
being available, so changes are only done for S-Mode for now.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/riscv/boards/hifive/lowlevel.c | 8 +++----
arch/riscv/boot/board-dt-2nd.c | 4 ++--
arch/riscv/cpu/core.c | 33 +++++++++++++++++++++++++-
arch/riscv/include/asm/barebox-riscv.h | 6 +++--
arch/riscv/include/asm/system.h | 20 ++++++++++++++++
arch/riscv/lib/bootm.c | 4 +++-
arch/riscv/lib/cpuinfo.c | 1 +
common/globalvar.c | 21 ++++++++++++++++
common/oftree.c | 19 ++++++++++++++-
include/globalvar.h | 8 +++++++
10 files changed, 113 insertions(+), 11 deletions(-)
diff --git a/arch/riscv/boards/hifive/lowlevel.c b/arch/riscv/boards/hifive/lowlevel.c
index 8a20f3c51d40..5e8969bef1da 100644
--- a/arch/riscv/boards/hifive/lowlevel.c
+++ b/arch/riscv/boards/hifive/lowlevel.c
@@ -4,23 +4,23 @@
#include <asm/barebox-riscv.h>
#include <debug_ll.h>
-static __always_inline void start_hifive(void *fdt)
+static __always_inline void start_hifive(unsigned long hartid, void *fdt)
{
putc_ll('>');
- barebox_riscv_supervisor_entry(0x80000000, SZ_128M, fdt);
+ 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[];
- start_hifive(__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[];
- start_hifive(__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/board-dt-2nd.c b/arch/riscv/boot/board-dt-2nd.c
index 48cb23ae5e92..f31c48a906c2 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_supervisor_entry(membase, memsize, fdt);
+ barebox_riscv_supervisor_entry(membase, memsize, hartid, fdt);
}
diff --git a/arch/riscv/cpu/core.c b/arch/riscv/cpu/core.c
index 982d378eddec..62eb0ca87164 100644
--- a/arch/riscv/cpu/core.c
+++ b/arch/riscv/cpu/core.c
@@ -19,6 +19,8 @@
#include <linux/err.h>
#include <memory.h>
#include <asm-generic/memory_layout.h>
+#include <globalvar.h>
+#include <magicvar.h>
#include <io.h>
static int riscv_request_stack(void)
@@ -30,6 +32,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 +73,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[] = {
diff --git a/arch/riscv/include/asm/barebox-riscv.h b/arch/riscv/include/asm/barebox-riscv.h
index f4081a71f00e..bbe6cd040642 100644
--- a/arch/riscv/include/asm/barebox-riscv.h
+++ b/arch/riscv/include/asm/barebox-riscv.h
@@ -33,8 +33,10 @@ void __noreturn __naked barebox_riscv_entry(unsigned long membase, unsigned long
#define barebox_riscv_machine_entry(membase, memsize, boarddata) \
barebox_riscv_entry(membase, memsize, boarddata, RISCV_M_MODE)
-#define barebox_riscv_supervisor_entry(membase, memsize, boarddata) \
- barebox_riscv_entry(membase, memsize, boarddata, RISCV_S_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/system.h b/arch/riscv/include/asm/system.h
index 3d57a7d191f6..adf856f9e99b 100644
--- a/arch/riscv/include/asm/system.h
+++ b/arch/riscv/include/asm/system.h
@@ -26,6 +26,22 @@ static inline enum riscv_mode __riscv_mode(u32 flags)
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;
@@ -34,6 +50,10 @@ 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
diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c
index b3e41de4a890..835ff345e347 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();
fn = booti_load_image(data, &devicetree);
if (IS_ERR(fn))
@@ -15,7 +17,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 16305e6c4d96..2d9cee2a6270 100644
--- a/arch/riscv/lib/cpuinfo.c
+++ b/arch/riscv/lib/cpuinfo.c
@@ -34,6 +34,7 @@ static int do_cpuinfo(int argc, char *argv[])
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",
diff --git a/common/globalvar.c b/common/globalvar.c
index 8bb5015ce4e8..9e5a99f79353 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 5eaa63ad7ebc..1fcc5277c58d 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/include/globalvar.h b/include/globalvar.h
index 84bee9102cf3..476bb920f3e1 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)
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 06/29] RISC-V: erizo: make it easier to reuse ns16550 debug_ll
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (4 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 05/29] RISC-V: S-Mode: propagate Hart ID Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 07/29] RISC-V: socs: add Kconfig entry for StarFive JH7100 Ahmad Fatoum
` (23 subsequent siblings)
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
Incoming StarFive support also uses ns16550 compatibles as UART IP.
Make reuse easier by making the two most likely parameters to change
SoC-specific (base address and baud clock frequency) and move the rest
behind the new CONFIG_DEBUG_LL_NS16550.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/riscv/include/asm/debug_ll.h | 7 +++++--
common/Kconfig | 6 ++++++
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/include/asm/debug_ll.h b/arch/riscv/include/asm/debug_ll.h
index 6904460af98f..13609d25c559 100644
--- a/arch/riscv/include/asm/debug_ll.h
+++ b/arch/riscv/include/asm/debug_ll.h
@@ -12,13 +12,16 @@
#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)
+#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/common/Kconfig b/common/Kconfig
index 8b8f80bbb3ba..98be9b58abce 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -1376,6 +1376,7 @@ config DEBUG_RPI3_MINI_UART
config DEBUG_ERIZO
bool "Erizo ns16550 port"
depends on SOC_ERIZO
+ select DEBUG_LL_NS16550
config DEBUG_SIFIVE
bool "SiFive serial0 port"
@@ -1383,6 +1384,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 || \
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 07/29] RISC-V: socs: add Kconfig entry for StarFive JH7100
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (5 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 06/29] RISC-V: erizo: make it easier to reuse ns16550 debug_ll Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 08/29] nvmem: add StarFive OTP support Ahmad Fatoum
` (22 subsequent siblings)
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
The JH7100 is the StarFive SoC with SiFive CPUs in the pre-production
BeagleV. Th JH7110 in later boards will be cache-coherent, but the
JH7100 will need some workarounds.
Add Kconfig symbols, so newly introduced symbols can depend on them.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/riscv/Kconfig.socs | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index f1b431555fcd..8f955cd4d220 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -21,8 +21,12 @@ config SOC_VIRT
Generates an image tht can be be booted by QEMU. The image is called
barebox-dt-2nd.img
+config CPU_SIFIVE
+ bool
+
config SOC_SIFIVE
bool "SiFive SoCs"
+ select CPU_SIFIVE
select RISCV_S_MODE
select CLK_SIFIVE
select CLK_SIFIVE_PRCI
@@ -41,4 +45,22 @@ config BOARD_HIFIVE
endif
+config SOC_STARFIVE
+ bool "StarFive SoCs"
+ 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
+
+endif
+
+
endmenu
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 08/29] nvmem: add StarFive OTP support
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (6 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 07/29] RISC-V: socs: add Kconfig entry for StarFive JH7100 Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 09/29] RISC-V: dma: support multiple dma_alloc_coherent backends Ahmad Fatoum
` (21 subsequent siblings)
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
The OTP holds the ethernet MAC address. Add a driver, so barebox can
read it out.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
drivers/nvmem/Kconfig | 8 ++
drivers/nvmem/Makefile | 2 +
drivers/nvmem/starfive-otp.c | 201 +++++++++++++++++++++++++++++++++++
3 files changed, 211 insertions(+)
create mode 100644 drivers/nvmem/starfive-otp.c
diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 0d7c0b7b9e3d..3781f7a839fc 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 53c02dc7850c..55507f544126 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 000000000000..f9bf05ca87ec
--- /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);
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 09/29] RISC-V: dma: support multiple dma_alloc_coherent backends
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (7 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 08/29] nvmem: add StarFive OTP support Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 10/29] RISC-V: add exception support Ahmad Fatoum
` (20 subsequent siblings)
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
StarFive JH7100 is incoherent between CPU and dma masters like GMAC.
It has an uncached alias though similar to what we have on MIPS.
StarFive JH7110 will fix this and be cache coherent like other SiFive
SoCs. Support both by allowing driver to define their own
dma_alloc_coherent implementations.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/riscv/cpu/Makefile | 1 +
arch/riscv/cpu/dma.c | 74 ++++++++++++++++++++++++++++++++++++
arch/riscv/include/asm/dma.h | 48 +++++++----------------
3 files changed, 88 insertions(+), 35 deletions(-)
create mode 100644 arch/riscv/cpu/dma.c
diff --git a/arch/riscv/cpu/Makefile b/arch/riscv/cpu/Makefile
index f1312be699a1..9ce77ad869cd 100644
--- a/arch/riscv/cpu/Makefile
+++ b/arch/riscv/cpu/Makefile
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
obj-y += core.o time.o
+obj-$(CONFIG_HAS_DMA) += dma.o
diff --git a/arch/riscv/cpu/dma.c b/arch/riscv/cpu/dma.c
new file mode 100644
index 000000000000..5a4d714e5e71
--- /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/include/asm/dma.h b/arch/riscv/include/asm/dma.h
index 4204653984a3..56bcf06cc4af 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 */
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 10/29] RISC-V: add exception support
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (8 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 09/29] RISC-V: dma: support multiple dma_alloc_coherent backends Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 11/29] RISC-V: support incoherent I-Cache Ahmad Fatoum
` (19 subsequent siblings)
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
Add S- and M-Mode support for dumping registers when catching unexpected
CPU exceptions. Load access faults when data_abort_mask is active will
be skipped over. This allows outputting xxx when doing md /dev/mem for
non-accessible space.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/riscv/Kconfig | 5 +
arch/riscv/boot/start.c | 3 +
arch/riscv/boot/uncompress.c | 3 +
arch/riscv/cpu/Makefile | 3 +
arch/riscv/cpu/interrupts.c | 130 ++++++++++++++++++++++++
arch/riscv/cpu/mtrap.S | 30 ++++++
arch/riscv/cpu/strap.S | 30 ++++++
arch/riscv/include/asm/asm-offsets.h | 1 +
arch/riscv/include/asm/irq.h | 107 ++++++++++++++++++++
arch/riscv/include/asm/ptrace.h | 143 +++++++++++++++++++++++++++
arch/riscv/include/asm/unwind.h | 9 ++
arch/riscv/lib/asm-offsets.c | 46 +++++++++
12 files changed, 510 insertions(+)
create mode 100644 arch/riscv/cpu/interrupts.c
create mode 100644 arch/riscv/cpu/mtrap.S
create mode 100644 arch/riscv/cpu/strap.S
create mode 100644 arch/riscv/include/asm/asm-offsets.h
create mode 100644 arch/riscv/include/asm/irq.h
create mode 100644 arch/riscv/include/asm/ptrace.h
create mode 100644 arch/riscv/include/asm/unwind.h
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index bbafdea1b959..a814a1a45b1c 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
diff --git a/arch/riscv/boot/start.c b/arch/riscv/boot/start.c
index 82bd02d0a0d0..72ab93cb7691 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>
@@ -122,6 +123,8 @@ void barebox_non_pbl_start(unsigned long membase, unsigned long memsize,
barrier();
+ irq_init_vector(__riscv_mode(flags));
+
pr_debug("memory at 0x%08lx, size 0x%08lx\n", membase, memsize);
riscv_endmem = endmem;
diff --git a/arch/riscv/boot/uncompress.c b/arch/riscv/boot/uncompress.c
index 35a91e8cb62a..c6c20b38e390 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>
@@ -32,6 +33,8 @@ void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
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();
diff --git a/arch/riscv/cpu/Makefile b/arch/riscv/cpu/Makefile
index 9ce77ad869cd..717baaaaa727 100644
--- a/arch/riscv/cpu/Makefile
+++ b/arch/riscv/cpu/Makefile
@@ -2,3 +2,6 @@
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/interrupts.c b/arch/riscv/cpu/interrupts.c
new file mode 100644
index 000000000000..df6d3e6e010b
--- /dev/null
+++ b/arch/riscv/cpu/interrupts.c
@@ -0,0 +1,130 @@
+// 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;
+
+ 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 000000000000..e4aba7d69415
--- /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 000000000000..c1d684c19425
--- /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/include/asm/asm-offsets.h b/arch/riscv/include/asm/asm-offsets.h
new file mode 100644
index 000000000000..d370ee36a182
--- /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/irq.h b/arch/riscv/include/asm/irq.h
new file mode 100644
index 000000000000..fde7589baa80
--- /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 000000000000..b5e792f6669b
--- /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/unwind.h b/arch/riscv/include/asm/unwind.h
new file mode 100644
index 000000000000..9e5c8b542094
--- /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 22f382b71e7b..4b869690f198 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;
}
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 11/29] RISC-V: support incoherent I-Cache
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (9 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 10/29] RISC-V: add exception support Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 12/29] drivers: soc: sifive: add basic L2 cache controller driver Ahmad Fatoum
` (18 subsequent siblings)
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
SiFive SoCs have separate I-Caches that require self-modifying code
like barebox' relocation and PBL extraction code to do cache
maintenance. Implement sync_caches_for_execution and use it where
appropriate.
The underlying fence.i primitive is part of the Zifencei
(load/store fence) ISA extension. As we can't be sure it's always
available, the exception handler will skip over the instruction
if the CPU trips over it. Alternatively, if CONFIG_HAS_CACHE=n,
the instruction won't be emitted at all.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/riscv/Kconfig.socs | 2 ++
arch/riscv/boot/uncompress.c | 2 ++
arch/riscv/cpu/core.c | 7 +++++++
arch/riscv/cpu/interrupts.c | 9 +++++++++
arch/riscv/include/asm/barebox-riscv.h | 2 ++
arch/riscv/include/asm/cacheflush.h | 16 ++++++++++++++++
arch/riscv/lib/reloc.c | 8 ++++++++
arch/riscv/lib/setupc.S | 2 ++
8 files changed, 48 insertions(+)
create mode 100644 arch/riscv/include/asm/cacheflush.h
diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index 8f955cd4d220..6ec2315d4e70 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -17,12 +17,14 @@ config SOC_VIRT
bool "QEMU Virt Machine"
select RISCV_S_MODE
select BOARD_RISCV_GENERIC_DT
+ 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"
diff --git a/arch/riscv/boot/uncompress.c b/arch/riscv/boot/uncompress.c
index c6c20b38e390..4ed9b4d37192 100644
--- a/arch/riscv/boot/uncompress.c
+++ b/arch/riscv/boot/uncompress.c
@@ -66,6 +66,8 @@ 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);
diff --git a/arch/riscv/cpu/core.c b/arch/riscv/cpu/core.c
index 62eb0ca87164..b4727fe7449b 100644
--- a/arch/riscv/cpu/core.c
+++ b/arch/riscv/cpu/core.c
@@ -18,6 +18,7 @@
#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>
@@ -91,3 +92,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/interrupts.c b/arch/riscv/cpu/interrupts.c
index df6d3e6e010b..0e8951b61968 100644
--- a/arch/riscv/cpu/interrupts.c
+++ b/arch/riscv/cpu/interrupts.c
@@ -121,6 +121,15 @@ 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();
diff --git a/arch/riscv/include/asm/barebox-riscv.h b/arch/riscv/include/asm/barebox-riscv.h
index bbe6cd040642..abb320242769 100644
--- a/arch/riscv/include/asm/barebox-riscv.h
+++ b/arch/riscv/include/asm/barebox-riscv.h
@@ -27,6 +27,8 @@ 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, unsigned int flags);
diff --git a/arch/riscv/include/asm/cacheflush.h b/arch/riscv/include/asm/cacheflush.h
new file mode 100644
index 000000000000..9ff25740c66b
--- /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/lib/reloc.c b/arch/riscv/lib/reloc.c
index 2fc8818cd698..479d586afdee 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/setupc.S b/arch/riscv/lib/setupc.S
index 5fdd81c2c3ec..d225186c79fd 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:
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 12/29] drivers: soc: sifive: add basic L2 cache controller driver
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (10 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 11/29] RISC-V: support incoherent I-Cache Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 13/29] soc: starfive: add support for JH7100 incoherent interconnect Ahmad Fatoum
` (17 subsequent siblings)
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
SiFive SoCs are cache coherent with respect to other DMA masters,
so there is no need to explicitly flush cache lines.
Incoming StarFive SoC uses SiFive CPU and L2 cache controller,
but is cache-incoherent and thus needs the maintenance for DMA.
Add a basic driver that exports the cache flush function for
SoC-specific drivers to use.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/riscv/Kconfig.socs | 5 ++
arch/riscv/include/asm/barrier.h | 27 +++++++
drivers/Makefile | 2 +-
drivers/soc/Makefile | 4 +
drivers/soc/sifive/Makefile | 1 +
drivers/soc/sifive/sifive_l2_cache.c | 116 +++++++++++++++++++++++++++
include/soc/sifive/l2_cache.h | 10 +++
7 files changed, 164 insertions(+), 1 deletion(-)
create mode 100644 arch/riscv/include/asm/barrier.h
create mode 100644 drivers/soc/Makefile
create mode 100644 drivers/soc/sifive/Makefile
create mode 100644 drivers/soc/sifive/sifive_l2_cache.c
create mode 100644 include/soc/sifive/l2_cache.h
diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index 6ec2315d4e70..b4fdfd9741cd 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -64,5 +64,10 @@ config SOC_STARFIVE_JH7100
endif
+comment "CPU features"
+
+config SIFIVE_L2
+ bool "SiFive L2 cache controller"
+ depends on CPU_SIFIVE
endmenu
diff --git a/arch/riscv/include/asm/barrier.h b/arch/riscv/include/asm/barrier.h
new file mode 100644
index 000000000000..eff529307a15
--- /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/drivers/Makefile b/drivers/Makefile
index be5b0b3b04c9..aeb097e1f5ff 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -39,7 +39,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/soc/Makefile b/drivers/soc/Makefile
new file mode 100644
index 000000000000..b787379586ae
--- /dev/null
+++ b/drivers/soc/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += imx/
+obj-$(CONFIG_CPU_SIFIVE) += sifive/
diff --git a/drivers/soc/sifive/Makefile b/drivers/soc/sifive/Makefile
new file mode 100644
index 000000000000..e8113c66f576
--- /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 000000000000..96d6d4ec4773
--- /dev/null
+++ b/drivers/soc/sifive/sifive_l2_cache.c
@@ -0,0 +1,116 @@
+// 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>
+
+#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 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 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);
+
+ 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" },
+ { /* 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/include/soc/sifive/l2_cache.h b/include/soc/sifive/l2_cache.h
new file mode 100644
index 000000000000..0da655cd4e30
--- /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
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 13/29] soc: starfive: add support for JH7100 incoherent interconnect
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (11 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 12/29] drivers: soc: sifive: add basic L2 cache controller driver Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 14/29] soc: sifive: l2_cache: enable maximum available cache ways Ahmad Fatoum
` (16 subsequent siblings)
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
The preproduction JH7100 used in the BeagleV beta does not ensure cache
coherence between CPU and some DMA masters like the Ethernet MAC.
Fix this for streaming DMA mappings by implementing cache cleaning and
discarding. The Flush64 primitive can be used for both as it will
invalidate after flushing and not write-back clean lines.
Coherent DMA mapping will be implemented using allocation from uncached
SRAM in a follow-up commit.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/riscv/Kconfig.socs | 5 +++
drivers/soc/Makefile | 1 +
drivers/soc/sifive/sifive_l2_cache.c | 1 +
drivers/soc/starfive/Makefile | 1 +
drivers/soc/starfive/jh7100_dma.c | 55 ++++++++++++++++++++++++++++
5 files changed, 63 insertions(+)
create mode 100644 drivers/soc/starfive/Makefile
create mode 100644 drivers/soc/starfive/jh7100_dma.c
diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index b4fdfd9741cd..c112fcc82e1a 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -61,6 +61,11 @@ config SOC_STARFIVE_JH71XX
config SOC_STARFIVE_JH7100
bool
select SOC_STARFIVE_JH71XX
+ select SIFIVE_L2
+ help
+ Unlike JH7110 and later, CPU on the JH7100 are not cache-coherent
+ with respect to DMA masters like GMAC and DW MMC controller.
+ Select this if barebox needs to do DMA on this SoC.
endif
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index b787379586ae..c3499c0c7f30 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -2,3 +2,4 @@
obj-y += imx/
obj-$(CONFIG_CPU_SIFIVE) += sifive/
+obj-$(CONFIG_SOC_STARFIVE) += starfive/
diff --git a/drivers/soc/sifive/sifive_l2_cache.c b/drivers/soc/sifive/sifive_l2_cache.c
index 96d6d4ec4773..9e54474f7ae8 100644
--- a/drivers/soc/sifive/sifive_l2_cache.c
+++ b/drivers/soc/sifive/sifive_l2_cache.c
@@ -105,6 +105,7 @@ static int sifive_l2_probe(struct device_d *dev)
static const struct of_device_id sifive_l2_ids[] = {
{ .compatible = "sifive,fu540-c000-ccache" },
{ .compatible = "sifive,fu740-c000-ccache" },
+ { .compatible = "starfive,ccache0" },
{ /* end of table */ },
};
diff --git a/drivers/soc/starfive/Makefile b/drivers/soc/starfive/Makefile
new file mode 100644
index 000000000000..72504b3bef26
--- /dev/null
+++ b/drivers/soc/starfive/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_SOC_STARFIVE_JH7100) += jh7100_dma.o
diff --git a/drivers/soc/starfive/jh7100_dma.c b/drivers/soc/starfive/jh7100_dma.c
new file mode 100644
index 000000000000..a1dc48e73f6e
--- /dev/null
+++ b/drivers/soc/starfive/jh7100_dma.c
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 Ahmad Fatoum, Pengutronix
+ */
+
+#include <common.h>
+#include <asm/dma.h>
+#include <soc/sifive/l2_cache.h>
+
+#define SDRAM_CACHED_BASE 0x80000000
+#define SDRAM_UNCACHED_BASE 0x1000000000
+
+static inline void *jh7100_alloc_coherent(size_t size, dma_addr_t *dma_handle)
+{
+ dma_addr_t cpu_base;
+ void *ret;
+
+ ret = xmemalign(PAGE_SIZE, size);
+
+ memset(ret, 0, size);
+
+ cpu_base = (dma_addr_t)ret;
+
+ if (dma_handle)
+ *dma_handle = cpu_base;
+
+ sifive_l2_flush64_range(cpu_base, cpu_base + size);
+
+ return ret - SDRAM_CACHED_BASE + SDRAM_UNCACHED_BASE;
+
+}
+
+static inline void jh7100_free_coherent(void *vaddr, dma_addr_t dma_handle, size_t size)
+{
+ free((void *)dma_handle);
+}
+
+static const struct dma_ops jh7100_dma_ops = {
+ .alloc_coherent = jh7100_alloc_coherent,
+ .free_coherent = jh7100_free_coherent,
+ .flush_range = sifive_l2_flush64_range,
+ .inv_range = sifive_l2_flush64_range,
+};
+
+static int jh7100_dma_init(void)
+{
+ /* board drivers can claim the machine compatible, so no driver here */
+ if (!of_machine_is_compatible("starfive,jh7100"))
+ return 0;
+
+ dma_set_ops(&jh7100_dma_ops);
+
+ return 0;
+}
+mmu_initcall(jh7100_dma_init);
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 14/29] soc: sifive: l2_cache: enable maximum available cache ways
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (12 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 13/29] soc: starfive: add support for JH7100 incoherent interconnect Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 15/29] net: designware: fix non-1:1 mapped 64-bit systems Ahmad Fatoum
` (15 subsequent siblings)
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
Previous boot stages may not enable all cache ways, e.g. because they
are running from L2 cache. By the time barebox proper is running,
execution should be from main SDRAM, so it's ok now to enable the
maximum available count of cache ways.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
drivers/soc/sifive/sifive_l2_cache.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/drivers/soc/sifive/sifive_l2_cache.c b/drivers/soc/sifive/sifive_l2_cache.c
index 9e54474f7ae8..a1e9a1062204 100644
--- a/drivers/soc/sifive/sifive_l2_cache.c
+++ b/drivers/soc/sifive/sifive_l2_cache.c
@@ -15,6 +15,7 @@
#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
@@ -40,6 +41,9 @@
#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;
@@ -84,6 +88,19 @@ void sifive_l2_flush64_range(dma_addr_t start, dma_addr_t end)
}
}
+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;
@@ -97,6 +114,8 @@ static int sifive_l2_probe(struct device_d *dev)
l2_base = IOMEM(iores->start);
+ sifive_l2_enable_ways();
+
dev->info = sifive_l2_config_read;
return 0;
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 15/29] net: designware: fix non-1:1 mapped 64-bit systems
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (13 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 14/29] soc: sifive: l2_cache: enable maximum available cache ways Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-21 7:25 ` Sascha Hauer
2021-06-19 4:50 ` [PATCH v2 16/29] net: designware: add support for IP integrated into StarFive SoC Ahmad Fatoum
` (14 subsequent siblings)
29 siblings, 1 reply; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
drivers/net/designware.c handles the older Designware < 4.x MAC IPs,
which do not support DMA beyond 32-bit. They are still being integrated
into SoCs with 64-bit CPUs like the StarFive JH7100, which additionally
needs a non 1:1 mapping for coherent DMA.
Fix the driver to support such usage. The driver still has the assumption
that barebox core will only pass it 32-bit pointers. This is now made
explicit by returning error codes when the DMA mask is violated.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/riscv/include/asm/io.h | 10 +++++++
drivers/net/designware.c | 57 ++++++++++++++++++++++---------------
drivers/net/designware.h | 28 +++++++++++++++---
3 files changed, 68 insertions(+), 27 deletions(-)
diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h
index 3cdea7fcace1..795e670e3b9b 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/drivers/net/designware.c b/drivers/net/designware.c
index 0ee6d3d78ac7..559e202c29ce 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,6 +451,8 @@ 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);
@@ -481,12 +483,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 0a6a6bf1a497..5851187c0cf0 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;
@@ -38,6 +42,20 @@ struct dw_eth_drvdata {
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 +156,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
*/
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v2 15/29] net: designware: fix non-1:1 mapped 64-bit systems
2021-06-19 4:50 ` [PATCH v2 15/29] net: designware: fix non-1:1 mapped 64-bit systems Ahmad Fatoum
@ 2021-06-21 7:25 ` Sascha Hauer
2021-06-21 7:33 ` Ahmad Fatoum
0 siblings, 1 reply; 33+ messages in thread
From: Sascha Hauer @ 2021-06-21 7:25 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: barebox
On Sat, Jun 19, 2021 at 06:50:41AM +0200, Ahmad Fatoum wrote:
> drivers/net/designware.c handles the older Designware < 4.x MAC IPs,
> which do not support DMA beyond 32-bit. They are still being integrated
> into SoCs with 64-bit CPUs like the StarFive JH7100, which additionally
> needs a non 1:1 mapping for coherent DMA.
>
> Fix the driver to support such usage. The driver still has the assumption
> that barebox core will only pass it 32-bit pointers. This is now made
> explicit by returning error codes when the DMA mask is violated.
>
> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
> arch/riscv/include/asm/io.h | 10 +++++++
> drivers/net/designware.c | 57 ++++++++++++++++++++++---------------
> drivers/net/designware.h | 28 +++++++++++++++---
> 3 files changed, 68 insertions(+), 27 deletions(-)
>
> diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h
> index 3cdea7fcace1..795e670e3b9b 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/drivers/net/designware.c b/drivers/net/designware.c
> index 0ee6d3d78ac7..559e202c29ce 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]);
You have both the DMA and virtual addresses available when allocating
the memory. I think you should use this information rather than
introducing the need for a virt_to_phys() phys_to_virt() pair.
> @@ -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);
Rather use dma_map_single() here?
Sascha
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v2 15/29] net: designware: fix non-1:1 mapped 64-bit systems
2021-06-21 7:25 ` Sascha Hauer
@ 2021-06-21 7:33 ` Ahmad Fatoum
0 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-21 7:33 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
Hi,
On 21.06.21 09:25, Sascha Hauer wrote:
> On Sat, Jun 19, 2021 at 06:50:41AM +0200, Ahmad Fatoum wrote:
>> drivers/net/designware.c handles the older Designware < 4.x MAC IPs,
>> which do not support DMA beyond 32-bit. They are still being integrated
>> into SoCs with 64-bit CPUs like the StarFive JH7100, which additionally
>> needs a non 1:1 mapping for coherent DMA.
>>
>> Fix the driver to support such usage. The driver still has the assumption
>> that barebox core will only pass it 32-bit pointers. This is now made
>> explicit by returning error codes when the DMA mask is violated.
>>
>> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
>> ---
>> arch/riscv/include/asm/io.h | 10 +++++++
>> drivers/net/designware.c | 57 ++++++++++++++++++++++---------------
>> drivers/net/designware.h | 28 +++++++++++++++---
>> 3 files changed, 68 insertions(+), 27 deletions(-)
>>
>> diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h
>> index 3cdea7fcace1..795e670e3b9b 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/drivers/net/designware.c b/drivers/net/designware.c
>> index 0ee6d3d78ac7..559e202c29ce 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]);
>
> You have both the DMA and virtual addresses available when allocating
> the memory. I think you should use this information rather than
> introducing the need for a virt_to_phys() phys_to_virt() pair.
desc_p points at DMA coherent memory. desc_p->dmamac_addr is supposed to contain
the physical address of memory used for streaming DMA. I think virt_to_phys
is appropriate here.
>
>> @@ -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);
>
> Rather use dma_map_single() here?
There's is an unbalanced dma_sync_single_for_cpu in rx_descs_init().
I wasn't sure how to deal with it, had I wanted to move everything to dma_map_single.
I can supply a patch later for dma_map_single(), once I am told how, if that's
ok with you.
>
> Sascha
>
>
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 16/29] net: designware: add support for IP integrated into StarFive SoC
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (14 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 15/29] net: designware: fix non-1:1 mapped 64-bit systems Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 17/29] mci: allocate DMA-able memory Ahmad Fatoum
` (13 subsequent siblings)
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
The Designware MAC on the StarFive jh7100 needs some special speed
configuration. Match against a new starfive,stmmac compatible that
describes that.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
drivers/net/Kconfig | 8 +++
drivers/net/Makefile | 1 +
drivers/net/designware.c | 7 +-
drivers/net/designware.h | 1 +
drivers/net/designware_starfive.c | 110 ++++++++++++++++++++++++++++++
include/soc/starfive/sysmain.h | 15 ++++
6 files changed, 139 insertions(+), 3 deletions(-)
create mode 100644 drivers/net/designware_starfive.c
create mode 100644 include/soc/starfive/sysmain.h
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 18931211b54f..802169a86e8c 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 1674d53dffe8..fb3e3bdee46a 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 559e202c29ce..afc275e81ecb 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -459,11 +459,12 @@ struct dw_eth_dev *dwc_drv_probe(struct device_d *dev)
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;
diff --git a/drivers/net/designware.h b/drivers/net/designware.h
index 5851187c0cf0..8f6234aec5d1 100644
--- a/drivers/net/designware.h
+++ b/drivers/net/designware.h
@@ -39,6 +39,7 @@ struct dw_eth_dev {
struct dw_eth_drvdata {
bool enh_desc;
+ void (*fix_mac_speed)(int speed);
void *priv;
};
diff --git a/drivers/net/designware_starfive.c b/drivers/net/designware_starfive.c
new file mode 100644
index 000000000000..3dc9d14e11c1
--- /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/include/soc/starfive/sysmain.h b/include/soc/starfive/sysmain.h
new file mode 100644
index 000000000000..b58f8d9825fd
--- /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_
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 17/29] mci: allocate DMA-able memory
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (15 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 16/29] net: designware: add support for IP integrated into StarFive SoC Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 18/29] mci: allocate sector_buf on demand Ahmad Fatoum
` (12 subsequent siblings)
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
Doesn't yet make a difference, but in a future commit, RISC-V will use a
64-bit alignment for the sector buffers by defining a custom dma_alloc.
Prepare for this.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
drivers/mci/mci-core.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index a094f3cbf522..b174067a7fbc 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
@@ -1852,7 +1853,7 @@ static int mci_set_probe(struct param_d *param, void *priv)
static int mci_init(void)
{
- sector_buf = xmemalign(32, SECTOR_SIZE);
+ sector_buf = dma_alloc(SECTOR_SIZE);
return 0;
}
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 18/29] mci: allocate sector_buf on demand
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (16 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 17/29] mci: allocate DMA-able memory Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 19/29] dma: allocate 32-byte aligned buffers by default Ahmad Fatoum
` (11 subsequent siblings)
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
The MCI core uses a common bounce buffer for unaligned block
reads/writes as well as sd_change_freq. This buffer is allocated at
device initcall level, same as the MMC drivers themselves.
For CONFIG_MCI_STARTUP=y configurations this seems to imply that
sd_change_freq could attempt writing the NULL page. Avoid this
by just allocating the buffer when the first MMC device is registered.
This doesn't solve all issues; so add a comment noting that.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
drivers/mci/mci-core.c | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index b174067a7fbc..92a73c8f1dfe 100644
--- a/drivers/mci/mci-core.c
+++ b/drivers/mci/mci-core.c
@@ -1790,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);
@@ -1851,15 +1856,6 @@ static int mci_set_probe(struct param_d *param, void *priv)
return 0;
}
-static int mci_init(void)
-{
- sector_buf = dma_alloc(SECTOR_SIZE);
-
- return 0;
-}
-
-device_initcall(mci_init);
-
int mci_detect_card(struct mci_host *host)
{
int rc;
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 19/29] dma: allocate 32-byte aligned buffers by default
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (17 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 18/29] mci: allocate sector_buf on demand Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 20/29] mci: dw_mmc: add optional reset line Ahmad Fatoum
` (10 subsequent siblings)
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
If dma_alloc() is really used for streaming-dma between cache-incoherent
masters, it should return cache-line aligned buffers, so we don't risk
invalidating shared cache lines. Bump up the default alignment to 32-bytes.
This doesn't affect ARM, as it defines its own implementation with
64-byte buffers.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
include/dma.h | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/include/dma.h b/include/dma.h
index 1b1cb3a40796..90f9254ea80f 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
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 20/29] mci: dw_mmc: add optional reset line
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (18 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 19/29] dma: allocate 32-byte aligned buffers by default Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 21/29] mci: dw_mmc: match against StarFive MMC compatibles Ahmad Fatoum
` (9 subsequent siblings)
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Steffen Trumtrar, Ahmad Fatoum
The bindings describe a reset line for the MMC controller and we have
boards with device tree that contain a reset line that barebox has so
far never acted upon. For the StarFive, we need the reset, so have the
driver toggle it optionally if specified. This change wasn't tested
on existing users of the driver, like the SoCFPGA or the Rockchip
rk2928 and rk3288.
Cc: Steffen Trumtrar <s.trumtrar@pengutronix.de>
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
drivers/mci/dw_mmc.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/mci/dw_mmc.c b/drivers/mci/dw_mmc.c
index 930b538adc15..ad1d2a06b914 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>
@@ -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)) {
+ dev_warn(dev, "error claiming reset: %pe\n", 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);
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 21/29] mci: dw_mmc: match against StarFive MMC compatibles
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (19 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 20/29] mci: dw_mmc: add optional reset line Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 22/29] clk: add initial StarFive clock support Ahmad Fatoum
` (8 subsequent siblings)
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
The Linux driver in v5.13 doesn't determine min and max frequency from
clk_ciu, instead it consults the clock-frequency property in the device
tree. We will want to follow the Linux way for the StarFive, especially
because clk_get_rate returns bogus results for the JH7100, because the
clock tree doesn't yet describe enough information to calculate rates.
Add a compatible that does the necessary things as well as a generic
snps,dw-mshc compatible, like what the vendor device tree uses. The hope
is, that with complete clock tree described, we can drop the
starfive,jh7100-dw-mshc compatible check in future and use the generic
compatible instead.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
drivers/mci/dw_mmc.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/mci/dw_mmc.c b/drivers/mci/dw_mmc.c
index ad1d2a06b914..b402090ab3cb 100644
--- a/drivers/mci/dw_mmc.c
+++ b/drivers/mci/dw_mmc.c
@@ -32,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;
@@ -572,7 +572,7 @@ static int dw_mmc_probe(struct device_d *dev)
rst = reset_control_get(dev, "reset");
if (IS_ERR(rst)) {
- dev_warn(dev, "error claiming reset: %pe\n", rst);
+ return PTR_ERR(rst);
} else if (rst) {
reset_control_assert(rst);
udelay(10);
@@ -617,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;
@@ -635,6 +639,10 @@ static __maybe_unused struct of_device_id dw_mmc_compatible[] = {
.compatible = "rockchip,rk2928-dw-mshc",
}, {
.compatible = "rockchip,rk3288-dw-mshc",
+ }, {
+ .compatible = "snps,dw-mshc",
+ }, {
+ .compatible = "starfive,jh7100-dw-mshc",
}, {
/* sentinel */
}
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 22/29] clk: add initial StarFive clock support
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (20 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 21/29] mci: dw_mmc: match against StarFive MMC compatibles Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 23/29] reset: add StarFive reset controller driver Ahmad Fatoum
` (7 subsequent siblings)
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
All clocks seem to share a common format:
struct starfive_clk {
u32 divisor : 24; /* LSB */
u32 mux : 6;
u32 invert : 1;
u32 enable : 1; /* MSB */
};
There is no documentation, what the acceptable divisor values are, but
we could already register gates and muxes, do so for now until
documentation is available.
The bulk of this code has been machine-generated by parsing the macros
in the vendor U-Boot <asm/arch-vic7100/clkgen_ctrl_macro.h>.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
drivers/clk/Makefile | 1 +
drivers/clk/starfive/Makefile | 3 +
drivers/clk/starfive/clk.h | 64 ++++
drivers/clk/starfive/jh7100-clkgen.c | 363 ++++++++++++++++++++
include/dt-bindings/clock/starfive-jh7100.h | 203 +++++++++++
5 files changed, 634 insertions(+)
create mode 100644 drivers/clk/starfive/Makefile
create mode 100644 drivers/clk/starfive/clk.h
create mode 100644 drivers/clk/starfive/jh7100-clkgen.c
create mode 100644 include/dt-bindings/clock/starfive-jh7100.h
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index b0be8d1bd89a..499df2fe392b 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 000000000000..4e9bf7f2ba83
--- /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 000000000000..cfbf116dcb78
--- /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 000000000000..df5353e8e624
--- /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/include/dt-bindings/clock/starfive-jh7100.h b/include/dt-bindings/clock/starfive-jh7100.h
new file mode 100644
index 000000000000..9ad5e7f9bfd5
--- /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 35
+#define CLK_DMA2PNOC_AXI 37
+#define CLK_SGDMA2P_AHB 37
+#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
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 23/29] reset: add StarFive reset controller driver
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (21 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 22/29] clk: add initial StarFive clock support Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 24/29] watchdog: add StarFive watchdog driver Ahmad Fatoum
` (6 subsequent siblings)
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
The StarFive SoC has a single reset controller, which seems to control
reset of all clocks and peripherals. It differs from the ones supported
by the Linux reset-simple driver in that it has a dedicated status
registers that needs to be polled to verify the reset has completed.
Also special is that most resets (> 70) are synchronous. As the reset
status poll would just time out without the clock, have the reset
controller enable the clock as part of the reset. OS can decide later,
which clocks to disable again.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/riscv/Kconfig.socs | 1 +
drivers/reset/Kconfig | 6 +
drivers/reset/Makefile | 1 +
drivers/reset/reset-starfive-vic.c | 234 ++++++++++++++++++
.../reset-controller/starfive-jh7100.h | 126 ++++++++++
include/soc/starfive/rstgen.h | 41 +++
6 files changed, 409 insertions(+)
create mode 100644 drivers/reset/reset-starfive-vic.c
create mode 100644 include/dt-bindings/reset-controller/starfive-jh7100.h
create mode 100644 include/soc/starfive/rstgen.h
diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index c112fcc82e1a..e5603b001c74 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -49,6 +49,7 @@ endif
config SOC_STARFIVE
bool "StarFive SoCs"
+ select ARCH_HAS_RESET_CONTROLLER
help
This enables support for SiFive SoC platform hardware.
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 316ece9e7176..9429f107bb67 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 8460c4b154f5..ce494baae58e 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/reset-starfive-vic.c b/drivers/reset/reset-starfive-vic.c
new file mode 100644
index 000000000000..bcf615da0a13
--- /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/include/dt-bindings/reset-controller/starfive-jh7100.h b/include/dt-bindings/reset-controller/starfive-jh7100.h
new file mode 100644
index 000000000000..390a528576b9
--- /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/soc/starfive/rstgen.h b/include/soc/starfive/rstgen.h
new file mode 100644
index 000000000000..7a674aabe9f2
--- /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
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 24/29] watchdog: add StarFive watchdog driver
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (22 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 23/29] reset: add StarFive reset controller driver Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 25/29] hw_random: add driver for RNG on StarFive SoC Ahmad Fatoum
` (5 subsequent siblings)
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
drivers/watchdog/Kconfig | 7 +++
drivers/watchdog/Makefile | 1 +
drivers/watchdog/starfive_wdt.c | 106 ++++++++++++++++++++++++++++++++
3 files changed, 114 insertions(+)
create mode 100644 drivers/watchdog/starfive_wdt.c
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index b785181c59db..080bc91ff7f5 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 0b598af40218..4e784b5aaa30 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 000000000000..6779566fd6c1
--- /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);
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 25/29] hw_random: add driver for RNG on StarFive SoC
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (23 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 24/29] watchdog: add StarFive watchdog driver Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 26/29] reset: add device_reset_all helper Ahmad Fatoum
` (4 subsequent siblings)
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
Straight port from the vendor kernel with the difference that we
take the device out of reset. This allows to load older kernels that
don't yet do reset and clock handling.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
drivers/hw_random/Kconfig | 7 +
drivers/hw_random/Makefile | 1 +
drivers/hw_random/starfive-vic-rng.c | 208 +++++++++++++++++++++++++++
3 files changed, 216 insertions(+)
create mode 100644 drivers/hw_random/starfive-vic-rng.c
diff --git a/drivers/hw_random/Kconfig b/drivers/hw_random/Kconfig
index a84c03efef90..764911f4d35e 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 4bab3967fc4d..4cf33d2d93e6 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 000000000000..f7b7585884ac
--- /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");
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 26/29] reset: add device_reset_all helper
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (24 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 25/29] hw_random: add driver for RNG on StarFive SoC Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 27/29] gpio: add support for StarFive GPIO controller Ahmad Fatoum
` (3 subsequent siblings)
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
Some StarFive peripherals have 5 resets that need to be triggered in
order. Add a helper to simplify this. The Linux way of doing this would
be to import the reset_control_array API, but device_reset_all as
implemented here saves us from this boilerplate.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
drivers/reset/core.c | 78 +++++++++++++++++++++++++++++++++++++------
include/linux/reset.h | 7 ++++
2 files changed, 75 insertions(+), 10 deletions(-)
diff --git a/drivers/reset/core.c b/drivers/reset/core.c
index 26a54f21dff0..940b46d4b4bd 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.
*/
-static 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)
@@ -195,6 +200,26 @@ static 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.
+ */
+static 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)
{
@@ -302,6 +327,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/include/linux/reset.h b/include/linux/reset.h
index a166fe1cfe04..0a98ea6bacdf 100644
--- a/include/linux/reset.h
+++ b/include/linux/reset.h
@@ -17,6 +17,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)
@@ -54,6 +56,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
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 27/29] gpio: add support for StarFive GPIO controller
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (25 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 26/29] reset: add device_reset_all helper Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 28/29] misc: add power sequencing driver for initializing StarFive peripherals Ahmad Fatoum
` (2 subsequent siblings)
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
This imports support for the StarFive GPIO controller from the vendor's
kernel tree.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
drivers/gpio/Kconfig | 8 ++
drivers/gpio/Makefile | 1 +
drivers/gpio/gpio-starfive-vic.c | 177 +++++++++++++++++++++++++++++++
drivers/pinctrl/pinctrl-single.c | 4 +-
include/pinctrl.h | 6 ++
5 files changed, 194 insertions(+), 2 deletions(-)
create mode 100644 drivers/gpio/gpio-starfive-vic.c
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index a8ee9e58b84e..98a44fbbb578 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 25e12105d83d..638cbb19a328 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 000000000000..baa4f584d5e8
--- /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/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index c77466023216..cf2f724d187d 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/include/pinctrl.h b/include/pinctrl.h
index 0fd7f491189c..a628c3aac95b 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 */
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 28/29] misc: add power sequencing driver for initializing StarFive peripherals
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (26 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 27/29] gpio: add support for StarFive GPIO controller Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-19 4:50 ` [PATCH v2 29/29] RISC-V: StarFive: add board support for BeagleV Starlight Ahmad Fatoum
2021-06-21 9:11 ` [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Sascha Hauer
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
There will likely not be a use case for having neural network
accelerator driver support within barebox. Still the driver requires a
reset sequence, which is not yet supported by vendor kernel's or known
forks. Until Linux can take care of this itself, add a simple driver
that gets some of the peripherals out of reset.
There also enables unconditionally some of the clocks that the vendor
kernel may depend on. Hopefully, in future, the whole driver can be
dropped when the kernel starts to do clock and reset control itself.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
drivers/misc/Kconfig | 10 ++++
drivers/misc/Makefile | 1 +
drivers/misc/starfive-pwrseq.c | 92 ++++++++++++++++++++++++++++++++++
3 files changed, 103 insertions(+)
create mode 100644 drivers/misc/starfive-pwrseq.c
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 87674a2a29f9..7426dfc46398 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 4d92465a1e5e..36743e6ae6a3 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 000000000000..6236547bc568
--- /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);
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v2 29/29] RISC-V: StarFive: add board support for BeagleV Starlight
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (27 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 28/29] misc: add power sequencing driver for initializing StarFive peripherals Ahmad Fatoum
@ 2021-06-19 4:50 ` Ahmad Fatoum
2021-06-21 9:11 ` [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Sascha Hauer
29 siblings, 0 replies; 33+ messages in thread
From: Ahmad Fatoum @ 2021-06-19 4:50 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
With the different drivers now in place, we have everything to start a
barebox image.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
Documentation/boards/riscv.rst | 37 +
arch/riscv/Kconfig.socs | 18 +
arch/riscv/boards/Makefile | 1 +
arch/riscv/boards/beaglev/Makefile | 5 +
arch/riscv/boards/beaglev/board.c | 30 +
.../beaglev/defaultenv-beaglev/boot/buildroot | 13 +
.../beaglev/defaultenv-beaglev/boot/fedora | 16 +
.../defaultenv-beaglev/nv/boot.default | 1 +
arch/riscv/boards/beaglev/lowlevel.c | 18 +
arch/riscv/configs/starfive_defconfig | 131 +++
arch/riscv/dts/Makefile | 1 +
arch/riscv/dts/jh7100-beaglev-starlight.dts | 54 ++
arch/riscv/dts/jh7100-beaglev-starlight.dtsi | 369 ++++++++
arch/riscv/dts/jh7100.dtsi | 798 ++++++++++++++++++
arch/riscv/include/asm/debug_ll.h | 3 +
common/Kconfig | 5 +
images/Makefile.riscv | 4 +
17 files changed, 1504 insertions(+)
create mode 100644 arch/riscv/boards/beaglev/Makefile
create mode 100644 arch/riscv/boards/beaglev/board.c
create mode 100755 arch/riscv/boards/beaglev/defaultenv-beaglev/boot/buildroot
create mode 100755 arch/riscv/boards/beaglev/defaultenv-beaglev/boot/fedora
create mode 100644 arch/riscv/boards/beaglev/defaultenv-beaglev/nv/boot.default
create mode 100644 arch/riscv/boards/beaglev/lowlevel.c
create mode 100644 arch/riscv/configs/starfive_defconfig
create mode 100644 arch/riscv/dts/jh7100-beaglev-starlight.dts
create mode 100644 arch/riscv/dts/jh7100-beaglev-starlight.dtsi
create mode 100644 arch/riscv/dts/jh7100.dtsi
diff --git a/Documentation/boards/riscv.rst b/Documentation/boards/riscv.rst
index 53d13550f369..97f4d1deb7ba 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.socs b/arch/riscv/Kconfig.socs
index e5603b001c74..de74f216a215 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -50,6 +50,8 @@ endif
config SOC_STARFIVE
bool "StarFive SoCs"
select ARCH_HAS_RESET_CONTROLLER
+ select RISCV_S_MODE
+ select HAS_ASM_DEBUG_LL
help
This enables support for SiFive SoC platform hardware.
@@ -68,6 +70,22 @@ config SOC_STARFIVE_JH7100
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"
diff --git a/arch/riscv/boards/Makefile b/arch/riscv/boards/Makefile
index 99f22f32b470..cb28a25d8bc8 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 000000000000..23efc273ee0a
--- /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 000000000000..110754ea95fb
--- /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 000000000000..157223bbee45
--- /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 000000000000..4f9ab16f8233
--- /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 000000000000..880a6b1d8cf2
--- /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 000000000000..cccb928bc8e9
--- /dev/null
+++ b/arch/riscv/boards/beaglev/lowlevel.c
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <common.h>
+#include <debug_ll.h>
+#include <asm/barebox-riscv.h>
+
+ENTRY_FUNCTION(start_beaglev_starlight, a0, a1, a2)
+{
+ extern char __dtb_z_jh7100_beaglev_starlight_start[];
+ void *fdt;
+
+ debug_ll_init();
+ 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/configs/starfive_defconfig b/arch/riscv/configs/starfive_defconfig
new file mode 100644
index 000000000000..c4df2256f589
--- /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/dts/Makefile b/arch/riscv/dts/Makefile
index 17fdc9445bd0..4a15423b7fc7 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 000000000000..8b4c1ac0eaa4
--- /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 000000000000..13238f087f16
--- /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 = <ðaddr>;
+};
+
+&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 000000000000..e3990582af97
--- /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/debug_ll.h b/arch/riscv/include/asm/debug_ll.h
index 13609d25c559..b4caa0597a2d 100644
--- a/arch/riscv/include/asm/debug_ll.h
+++ b/arch/riscv/include/asm/debug_ll.h
@@ -17,6 +17,9 @@
#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
diff --git a/common/Kconfig b/common/Kconfig
index 98be9b58abce..d4e518bf8ade 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -1378,6 +1378,11 @@ config DEBUG_ERIZO
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"
depends on SOC_SIFIVE
diff --git a/images/Makefile.riscv b/images/Makefile.riscv
index c44c683431f7..4410765cf664 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
--
2.29.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PATCH v2 00/29] RISC-V: add BeagleV Beta board support
2021-06-19 4:50 [PATCH v2 00/29] RISC-V: add BeagleV Beta board support Ahmad Fatoum
` (28 preceding siblings ...)
2021-06-19 4:50 ` [PATCH v2 29/29] RISC-V: StarFive: add board support for BeagleV Starlight Ahmad Fatoum
@ 2021-06-21 9:11 ` Sascha Hauer
29 siblings, 0 replies; 33+ messages in thread
From: Sascha Hauer @ 2021-06-21 9:11 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: barebox
On Sat, Jun 19, 2021 at 06:50:26AM +0200, Ahmad Fatoum wrote:
> The changes allow barebox to run second stage (after ddrinit and second
> boot) on the BeagleV beta board. It does everything necessary to support
> Ethernet, MMC, GPIO, pinmux, pinconf, clock, reset, watchdog, HWRNG and
> DMA between CPU and the cache-incoherent DMA masters.
>
> The current vendor kernel doesn't care much for low-level
> initialization, depending on pinmux, pinconf, clock and reset to happen
> completely in the bootloader. This makes an initial bootloader port
> much more complex, because you need not only care about the peripherals
> you use yourself, but those that Linux may want to access to.
>
> For this reason, there is a starfive-pwrseq driver that binds against
> some nodes like the neural network accelerator, which we will probably
> never support, but at least tickles it resets and enables its clocks.
>
> Some peripherals require writing magic values into registers, which
> this series doesn't do. If your boot hangs, consider checking out:
>
> https://github.com/a3f/barebox/tree/beaglev
>
> instead, which imports some vendor boot code to support more
> peripherals. This series is sufficient to have barebox boot kernels that
> do their own initialization though. Problem is there are no such kernels
> yet ^^.
>
> Candidates for further steps:
>
> - Support more peripherals in starfive-pwrseq
> - Get Designware i2c controller working, so we can use PMIC for reset
> - Get Cadence QSPI working, so barebox can flash itself and use
> environment on flash
> - Figure out the ticket lottery stuff, so we can boot multi-core
> - Replace ddrinit and secondboot with PBL, load from there opensbi
> and then return to barebox proper
> - Complete missing clock tree info when Documentation is available
>
> I can use a hand impementing these, so patches are most certainly
> welcome (Antony, I am looking at you ;-).
>
> v1 was here:
> https://lore.barebox.org/barebox/20210531073821.15257-1-a.fatoum@pengutronix.de/
>
> v1 -> v2:
> - Dropped untested PMIC and flash chip commits. i2c and qspi controller
> drivers in tree don't yet work for BeagleV
> - remove clocksource clutter from console
> - import S-/M-Mode multi-image series, so we can build all images for
> the same ISA in one go
> - Drop barebox,provide-mac-address from OTP driver. This is now done
> via nvmem-cells reference
> - Replace coherent memory from SRAM allocator with non-1:1 mapping:
> Give devices the cached <= 32 bit address, as they are
> cache-incoherent anyway, and use the > 32 bit uncached address from
> CPU side. Works beautifully
> - Drop 64-bit-conversion for dw_mmc. Sascha did it for rk3568 and it
> works for BeagleV too
> - Check Designware ETH coherent memory allocation against mask
> - Rebase on newest clock changes
> - Disable clocks after resets (Sascha)
> - Move repsonsibility of keeping reset-synchronous clocks needed
> for normal operation enabled to drivers (Sascha, off-list)
> - Handle fence.i trap in exception handler to support SoCs without
> Zifencei ISA extension
> - Add some static clock initialization to starfive-pwrseq driver
> - Add pinctrl driver support
> - Add GPIO driver support
> - Add board support
>
>
> Ahmad Fatoum (29):
> clocksource: RISC-V: demote probe success messages to debug level
> RISC-V: virt: select only one timer
> RISC-V: extend multi-image to support both S- and M-Mode
> RISC-V: cpuinfo: return some output for non-SBI systems as well
> RISC-V: S-Mode: propagate Hart ID
> RISC-V: erizo: make it easier to reuse ns16550 debug_ll
> RISC-V: socs: add Kconfig entry for StarFive JH7100
> nvmem: add StarFive OTP support
> RISC-V: dma: support multiple dma_alloc_coherent backends
> RISC-V: add exception support
> RISC-V: support incoherent I-Cache
> drivers: soc: sifive: add basic L2 cache controller driver
> soc: starfive: add support for JH7100 incoherent interconnect
> soc: sifive: l2_cache: enable maximum available cache ways
> net: designware: fix non-1:1 mapped 64-bit systems
> net: designware: add support for IP integrated into StarFive SoC
> mci: allocate DMA-able memory
> mci: allocate sector_buf on demand
> dma: allocate 32-byte aligned buffers by default
> mci: dw_mmc: add optional reset line
> mci: dw_mmc: match against StarFive MMC compatibles
> clk: add initial StarFive clock support
> reset: add StarFive reset controller driver
> watchdog: add StarFive watchdog driver
> hw_random: add driver for RNG on StarFive SoC
> reset: add device_reset_all helper
> gpio: add support for StarFive GPIO controller
> misc: add power sequencing driver for initializing StarFive
> peripherals
> RISC-V: StarFive: add board support for BeagleV Starlight
Applied, thanks
Sascha
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 33+ messages in thread