Merge https://gitlab.denx.de/u-boot/custodians/u-boot-riscv

CI: https://source.denx.de/u-boot/custodians/u-boot-riscv/-/pipelines/22292

- Add rdcycle to RISC-V exception command
- Some fixes and refactoring
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index fa3b016..876bec3 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -133,6 +133,7 @@
 
 config SPL_FRAMEPOINTER
 	bool "Build SPL with frame pointer for stack unwinding"
+	depends on SPL
 	help
 	  Choose this option to use the frame pointer so the stack can be
 	  unwound if needed. This is useful for tracing where faults came
@@ -437,7 +438,20 @@
 	  If disable this, it will send IPI by CPUs node numbers of device tree.
 
 config SHOW_REGS
+	default y
 	bool "Show registers on unhandled exception"
+	help
+	  By default only the program counter and the return address register
+	  are shown in crash dumps. Enable this symbol to show all registers in
+	  main U-Boot.
+
+config SPL_SHOW_REGS
+	bool "In SPL show registers on unhandled exception"
+	depends on SPL
+	help
+	  By default only the program counter and the return address register
+	  are shown in crash dumps. Enable this symbol to show all registers in
+	  SPL.
 
 config RISCV_PRIV_1_9
 	bool "Use version 1.9 of the RISC-V priviledged specification"
diff --git a/arch/riscv/include/asm/bitops.h b/arch/riscv/include/asm/bitops.h
index 35f1368..2f2994c 100644
--- a/arch/riscv/include/asm/bitops.h
+++ b/arch/riscv/include/asm/bitops.h
@@ -138,6 +138,43 @@
 	return k;
 }
 
+static inline int find_next_zero_bit(void *addr, int size, int offset)
+{
+	unsigned long *p = ((unsigned long *)addr) + (offset / BITS_PER_LONG);
+	unsigned long result = offset & ~(BITS_PER_LONG - 1);
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= (BITS_PER_LONG - 1);
+	if (offset) {
+		tmp = *(p++);
+		tmp |= ~0UL >> (BITS_PER_LONG - offset);
+		if (size < BITS_PER_LONG)
+			goto found_first;
+		if (~tmp)
+			goto found_middle;
+		size -= BITS_PER_LONG;
+		result += BITS_PER_LONG;
+	}
+	while (size & ~(BITS_PER_LONG - 1)) {
+		tmp = *(p++);
+		if (~tmp)
+			goto found_middle;
+		result += BITS_PER_LONG;
+		size -= BITS_PER_LONG;
+	}
+	if (!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	tmp |= ~0UL << size;
+found_middle:
+	return result + ffz(tmp);
+}
+
 /*
  * ffs: find first bit set. This is defined the same way as
  * the libc and compiler builtin ffs routines, therefore
@@ -158,6 +195,9 @@
 #define hweight16(x) generic_hweight16(x)
 #define hweight8(x) generic_hweight8(x)
 
+#define find_first_zero_bit(addr, size) \
+	find_next_zero_bit((addr), (size), 0)
+
 #define test_and_set_bit		__test_and_set_bit
 #define test_and_clear_bit		__test_and_clear_bit
 
diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c
index f9a1428..714cc92 100644
--- a/arch/riscv/lib/interrupts.c
+++ b/arch/riscv/lib/interrupts.c
@@ -34,9 +34,8 @@
 	efi_print_image_infos((void *)epc);
 }
 
-static void show_regs(struct pt_regs *regs)
+static void __maybe_unused show_regs(struct pt_regs *regs)
 {
-#ifdef CONFIG_SHOW_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",
@@ -57,7 +56,6 @@
 	       regs->s10, regs->s11, regs->t3);
 	printf("T4:  " REG_FMT " T5:  " REG_FMT " T6:  " REG_FMT "\n",
 	       regs->t4, regs->t5, regs->t6);
-#endif
 }
 
 static void __maybe_unused show_backtrace(struct pt_regs *regs)
@@ -157,7 +155,8 @@
 		printf("EPC: " REG_FMT " RA: " REG_FMT " reloc adjusted\n",
 		       epc - gd->reloc_off, regs->ra - gd->reloc_off);
 
-	show_regs(regs);
+	if (CONFIG_IS_ENABLED(SHOW_REGS))
+		show_regs(regs);
 	if (CONFIG_IS_ENABLED(FRAMEPOINTER))
 		show_backtrace(regs);
 	show_code(epc);
diff --git a/board/starfive/visionfive2/spl.c b/board/starfive/visionfive2/spl.c
index b794b73..f55c6b5 100644
--- a/board/starfive/visionfive2/spl.c
+++ b/board/starfive/visionfive2/spl.c
@@ -170,23 +170,32 @@
 {
 	const char *compat;
 	const char *model;
+	int compat_size;
 
 	spl_fdt_fixup_mars(fdt);
 
 	if (!get_mmc_size_from_eeprom()) {
 		int offset;
+		static const char
+		compat_cm_lite[] = "milkv,mars-cm-lite\0starfive,jh7110";
 
 		model = "Milk-V Mars CM Lite";
-		compat = "milkv,mars-cm-lite\0starfive,jh7110";
+		compat = compat_cm_lite;
+		compat_size = sizeof(compat_cm_lite);
 
 		offset = fdt_path_offset(fdt, "/soc/pinctrl/mmc0-pins/mmc0-pins-rest");
 		/* GPIOMUX(22, GPOUT_SYS_SDIO0_RST, GPOEN_ENABLE, GPI_NONE) */
 		fdt_setprop_u32(fdt, offset, "pinmux", 0xff130016);
 	} else {
+		static const char
+		compat_cm[] = "milkv,mars-cm\0starfive,jh7110";
+
 		model = "Milk-V Mars CM";
-		compat = "milkv,mars-cm\0starfive,jh7110";
+		compat = compat_cm;
+		compat_size = sizeof(compat_cm);
 	}
-	fdt_setprop(fdt, fdt_path_offset(fdt, "/"), "compatible", compat, sizeof(compat));
+	fdt_setprop(fdt, fdt_path_offset(fdt, "/"),
+		    "compatible", compat, compat_size);
 	fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "model", model);
 }
 
diff --git a/cmd/riscv/exception.c b/cmd/riscv/exception.c
index 2b58b1c..16e3353 100644
--- a/cmd/riscv/exception.c
+++ b/cmd/riscv/exception.c
@@ -36,6 +36,14 @@
 	return CMD_RET_SUCCESS;
 }
 
+static int do_rdcycle(struct cmd_tbl *cmdtp, int flag, int argc,
+		      char *const argv[])
+{
+	printf("cycle = 0x%lx\n", csr_read(CSR_CYCLE));
+
+	return CMD_RET_SUCCESS;
+}
+
 static int do_unaligned(struct cmd_tbl *cmdtp, int flag, int argc,
 			char *const argv[])
 {
@@ -62,6 +70,8 @@
 			 "", ""),
 	U_BOOT_CMD_MKENT(ialign16, CONFIG_SYS_MAXARGS, 1, do_ialign16,
 			 "", ""),
+	U_BOOT_CMD_MKENT(rdcycle, CONFIG_SYS_MAXARGS, 1, do_rdcycle,
+			 "", ""),
 	U_BOOT_CMD_MKENT(unaligned, CONFIG_SYS_MAXARGS, 1, do_unaligned,
 			 "", ""),
 	U_BOOT_CMD_MKENT(undefined, CONFIG_SYS_MAXARGS, 1, do_undefined,
@@ -74,7 +84,8 @@
 	"  compressed - compressed instruction\n"
 	"  ebreak     - breakpoint\n"
 	"  ialign16   - 16 bit aligned instruction\n"
-	"  undefined  - illegal instruction\n"
-	"  unaligned  - load address misaligned\n");
+	"  rdcycle    - read cycle CSR\n"
+	"  unaligned  - load address misaligned\n"
+	"  undefined  - illegal instruction\n");
 
 #include <exception.h>
diff --git a/drivers/clk/analogbits/wrpll-cln28hpc.c b/drivers/clk/analogbits/wrpll-cln28hpc.c
index a3cb109..537c696 100644
--- a/drivers/clk/analogbits/wrpll-cln28hpc.c
+++ b/drivers/clk/analogbits/wrpll-cln28hpc.c
@@ -81,7 +81,7 @@
 {
 	if (post_divr_freq < MIN_POST_DIVR_FREQ ||
 	    post_divr_freq > MAX_POST_DIVR_FREQ) {
-		WARN(1, "%s: post-divider reference freq out of range: %lu",
+		WARN(1, "%s: post-divider reference freq out of range: %lu\n",
 		     __func__, post_divr_freq);
 		return -ERANGE;
 	}
@@ -229,7 +229,7 @@
 	int range;
 
 	if (c->flags == 0) {
-		WARN(1, "%s called with uninitialized PLL config", __func__);
+		WARN(1, "%s called with uninitialized PLL config\n", __func__);
 		return -EINVAL;
 	}
 
@@ -335,7 +335,7 @@
 	u64 n;
 
 	if (c->flags & WRPLL_FLAGS_EXT_FEEDBACK_MASK) {
-		WARN(1, "external feedback mode not yet supported");
+		WARN(1, "external feedback mode not yet supported\n");
 		return ULONG_MAX;
 	}
 
diff --git a/drivers/clk/sifive/fu540-prci.c b/drivers/clk/sifive/fu540-prci.c
index ceb2c6f..e55a26a 100644
--- a/drivers/clk/sifive/fu540-prci.c
+++ b/drivers/clk/sifive/fu540-prci.c
@@ -58,7 +58,7 @@
 };
 
 /* List of clock controls provided by the PRCI */
-struct __prci_clock __prci_init_clocks_fu540[] = {
+static struct __prci_clock __prci_init_clocks_fu540[] = {
 	[PRCI_CLK_COREPLL] = {
 		.name = "corepll",
 		.parent_name = "hfclk",
@@ -83,3 +83,8 @@
 		.ops = &sifive_fu540_prci_tlclksel_clk_ops,
 	},
 };
+
+const struct prci_clk_desc prci_clk_fu540 = {
+	.clks = __prci_init_clocks_fu540,
+	.num_clks = ARRAY_SIZE(__prci_init_clocks_fu540),
+};
diff --git a/drivers/clk/sifive/fu540-prci.h b/drivers/clk/sifive/fu540-prci.h
deleted file mode 100644
index 1133011..0000000
--- a/drivers/clk/sifive/fu540-prci.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2020-2021 SiFive, Inc.
- * Zong Li
- * Pragnesh Patel
- */
-
-#ifndef __SIFIVE_CLK_FU540_PRCI_H
-#define __SIFIVE_CLK_FU540_PRCI_H
-
-#include "sifive-prci.h"
-
-#define NUM_CLOCK_FU540	4
-
-extern struct __prci_clock __prci_init_clocks_fu540[NUM_CLOCK_FU540];
-
-static const struct prci_clk_desc prci_clk_fu540 = {
-	.clks = __prci_init_clocks_fu540,
-	.num_clks = ARRAY_SIZE(__prci_init_clocks_fu540),
-};
-
-#endif /* __SIFIVE_CLK_FU540_PRCI_H */
diff --git a/drivers/clk/sifive/fu740-prci.c b/drivers/clk/sifive/fu740-prci.c
index 5edc864..4274b21 100644
--- a/drivers/clk/sifive/fu740-prci.c
+++ b/drivers/clk/sifive/fu740-prci.c
@@ -102,7 +102,7 @@
 };
 
 /* List of clock controls provided by the PRCI */
-struct __prci_clock __prci_init_clocks_fu740[] = {
+static struct __prci_clock __prci_init_clocks_fu740[] = {
 	[FU740_PRCI_CLK_COREPLL] = {
 		.name = "corepll",
 		.parent_name = "hfclk",
@@ -156,3 +156,8 @@
 		.pwd = &__prci_pcieaux_data,
 	}
 };
+
+const struct prci_clk_desc prci_clk_fu740 = {
+	.clks = __prci_init_clocks_fu740,
+	.num_clks = ARRAY_SIZE(__prci_init_clocks_fu740),
+};
diff --git a/drivers/clk/sifive/fu740-prci.h b/drivers/clk/sifive/fu740-prci.h
deleted file mode 100644
index b74f078..0000000
--- a/drivers/clk/sifive/fu740-prci.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2020-2021 SiFive, Inc.
- * Zong Li
- * Pragnesh Patel
- */
-
-#ifndef __SIFIVE_CLK_FU740_PRCI_H
-#define __SIFIVE_CLK_FU740_PRCI_H
-
-#include "sifive-prci.h"
-
-#define NUM_CLOCK_FU740		9
-
-extern struct __prci_clock __prci_init_clocks_fu740[NUM_CLOCK_FU740];
-
-static const struct prci_clk_desc prci_clk_fu740 = {
-	.clks = __prci_init_clocks_fu740,
-	.num_clks = ARRAY_SIZE(__prci_init_clocks_fu740),
-};
-
-#endif /* __SIFIVE_CLK_FU740_PRCI_H */
diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
index 5ea8606..aa26d3a 100644
--- a/drivers/clk/sifive/sifive-prci.c
+++ b/drivers/clk/sifive/sifive-prci.c
@@ -33,8 +33,7 @@
 #include <linux/math64.h>
 #include <dt-bindings/clock/sifive-fu740-prci.h>
 
-#include "fu540-prci.h"
-#include "fu740-prci.h"
+#include "sifive-prci.h"
 
 /*
  * Private functions
diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h
index 5ce33d6..b391698 100644
--- a/drivers/clk/sifive/sifive-prci.h
+++ b/drivers/clk/sifive/sifive-prci.h
@@ -320,4 +320,8 @@
 
 int sifive_prci_clock_enable(struct __prci_clock *pc, bool enable);
 
+/* Clock driver data */
+extern const struct prci_clk_desc prci_clk_fu540;
+extern const struct prci_clk_desc prci_clk_fu740;
+
 #endif /* __SIFIVE_CLK_SIFIVE_PRCI_H */