aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2024-04-09 14:18:55 -0600
committerTom Rini <trini@konsulko.com>2024-04-09 14:18:55 -0600
commit2d357e4dbea0dd2fd23002bdf2e18f901aec2d99 (patch)
tree877abee81b69a531fa33314f9361eda27d2d0c5c
parent069d07396e30aa9be396c1dd3fc158ac199e6843 (diff)
parentc1f78a4f632276bb4d77f8c79fe203709a9fa397 (diff)
downloadu-boot-WIP/09Apr2024.zip
u-boot-WIP/09Apr2024.tar.gz
u-boot-WIP/09Apr2024.tar.bz2
Merge branch 'master' of https://source.denx.de/u-boot/custodians/u-boot-riscvWIP/09Apr2024
CI: https://source.denx.de/u-boot/custodians/u-boot-riscv/-/pipelines/20256 - RISC-V: Support backtrace and improve isa extension parsing - cpu: Add cv1800b SoC support - board: Add Milk-V Mars board support - board: Add Milk-V Duo SD card support
-rw-r--r--arch/riscv/Kconfig22
-rw-r--r--arch/riscv/Makefile4
-rw-r--r--arch/riscv/cpu/cpu.c60
-rw-r--r--arch/riscv/cpu/cv1800b/Kconfig12
-rw-r--r--arch/riscv/cpu/cv1800b/Makefile7
-rw-r--r--arch/riscv/cpu/cv1800b/cache.c45
-rw-r--r--arch/riscv/cpu/cv1800b/cpu.c9
-rw-r--r--arch/riscv/cpu/cv1800b/dram.c21
-rw-r--r--arch/riscv/cpu/start.S1
-rw-r--r--arch/riscv/dts/cv1800b-milkv-duo.dts8
-rw-r--r--arch/riscv/dts/cv1800b.dtsi4
-rw-r--r--arch/riscv/dts/cv18xx.dtsi22
-rw-r--r--arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi2
-rw-r--r--arch/riscv/include/asm/arch-jh7110/eeprom.h9
-rw-r--r--arch/riscv/lib/interrupts.c35
-rw-r--r--board/emulation/qemu-riscv/qemu-riscv.c12
-rw-r--r--board/sophgo/milkv_duo/Kconfig4
-rw-r--r--board/starfive/visionfive2/spl.c100
-rw-r--r--board/starfive/visionfive2/starfive_visionfive2.c48
-rw-r--r--board/starfive/visionfive2/visionfive2-i2c-eeprom.c9
-rw-r--r--configs/milkv_duo_defconfig10
-rw-r--r--configs/starfive_visionfive2_defconfig1
-rw-r--r--doc/board/starfive/index.rst1
-rw-r--r--doc/board/starfive/milk-v_mars.rst111
-rw-r--r--doc/board/starfive/visionfive2.rst18
-rw-r--r--drivers/cpu/riscv_cpu.c8
-rw-r--r--drivers/mmc/Kconfig13
-rw-r--r--drivers/mmc/Makefile1
-rw-r--r--drivers/mmc/cv1800b_sdhci.c116
29 files changed, 649 insertions, 64 deletions
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 6c26f91f..7e20ef6 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -22,6 +22,7 @@ config TARGET_OPENPITON_RISCV64
config TARGET_QEMU_VIRT
bool "Support QEMU Virt Board"
+ select BOARD_LATE_INIT
config TARGET_SIFIVE_UNLEASHED
bool "Support SiFive Unleashed Board"
@@ -93,6 +94,7 @@ source "board/xilinx/mbv/Kconfig"
# platform-specific options below
source "arch/riscv/cpu/andesv5/Kconfig"
+source "arch/riscv/cpu/cv1800b/Kconfig"
source "arch/riscv/cpu/fu540/Kconfig"
source "arch/riscv/cpu/fu740/Kconfig"
source "arch/riscv/cpu/generic/Kconfig"
@@ -119,6 +121,26 @@ config ARCH_RV64I
endchoice
+config FRAMEPOINTER
+ bool "Build with frame pointer for stack unwinding"
+ 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
+ from as the source may be several functions back
+
+ If you say Y here, then the code size will be increased due to
+ having to store the fp.
+
+config SPL_FRAMEPOINTER
+ bool "Build SPL with frame pointer for stack unwinding"
+ 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
+ from as the source may be several functions back
+
+ If you say Y here, then the code size will be increased due to
+ having to store the fp.
+
choice
prompt "Code Model"
default CMODEL_MEDLOW
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index b3ef870..c36a853 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -48,6 +48,10 @@ endif
ARCH_FLAGS = -march=$(RISCV_MARCH) -mabi=$(ABI) \
-mcmodel=$(CMODEL)
+ifeq ($(CONFIG_$(SPL_)FRAMEPOINTER),y)
+ ARCH_FLAGS += -fno-omit-frame-pointer
+endif
+
PLATFORM_CPPFLAGS += $(ARCH_FLAGS)
CFLAGS_EFI += $(ARCH_FLAGS)
diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c
index ecfefa1..affe700 100644
--- a/arch/riscv/cpu/cpu.c
+++ b/arch/riscv/cpu/cpu.c
@@ -38,35 +38,51 @@ static inline bool supports_extension(char ext)
#if CONFIG_IS_ENABLED(RISCV_MMODE)
return csr_read(CSR_MISA) & (1 << (ext - 'a'));
#elif CONFIG_CPU
+ char sext[2] = {ext};
struct udevice *dev;
- char desc[32];
- int i;
+ const char *isa;
+ int ret, i;
uclass_find_first_device(UCLASS_CPU, &dev);
if (!dev) {
debug("unable to find the RISC-V cpu device\n");
return false;
}
- if (!cpu_get_desc(dev, desc, sizeof(desc))) {
- /*
- * skip the first 4 characters (rv32|rv64)
- */
- for (i = 4; i < sizeof(desc); i++) {
- switch (desc[i]) {
- case 's':
- case 'x':
- case 'z':
- case '_':
- case '\0':
- /*
- * Any of these characters mean the single
- * letter extensions have all been consumed.
- */
- return false;
- default:
- if (desc[i] == ext)
- return true;
- }
+
+ ret = dev_read_stringlist_search(dev, "riscv,isa-extensions", sext);
+ if (ret >= 0)
+ return true;
+
+ /*
+ * Only if the property is not found (ENODATA) is the fallback to
+ * riscv,isa used, otherwise the extension is not present in this
+ * CPU.
+ */
+ if (ret != -ENODATA)
+ return false;
+
+ isa = dev_read_string(dev, "riscv,isa");
+ if (!isa)
+ return false;
+
+ /*
+ * Skip the first 4 characters (rv32|rv64).
+ */
+ for (i = 4; i < sizeof(isa); i++) {
+ switch (isa[i]) {
+ case 's':
+ case 'x':
+ case 'z':
+ case '_':
+ case '\0':
+ /*
+ * Any of these characters mean the single
+ * letter extensions have all been consumed.
+ */
+ return false;
+ default:
+ if (isa[i] == ext)
+ return true;
}
}
diff --git a/arch/riscv/cpu/cv1800b/Kconfig b/arch/riscv/cpu/cv1800b/Kconfig
new file mode 100644
index 0000000..7225b12
--- /dev/null
+++ b/arch/riscv/cpu/cv1800b/Kconfig
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com>
+
+config SOPHGO_CV1800B
+ bool
+ select ARCH_EARLY_INIT_R
+ select SYS_CACHE_SHIFT_6
+ imply CPU
+ imply CPU_RISCV
+ imply RISCV_TIMER
+ imply CMD_CPU
diff --git a/arch/riscv/cpu/cv1800b/Makefile b/arch/riscv/cpu/cv1800b/Makefile
new file mode 100644
index 0000000..95beb34
--- /dev/null
+++ b/arch/riscv/cpu/cv1800b/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com>
+
+obj-y += dram.o
+obj-y += cpu.o
+obj-y += cache.o
diff --git a/arch/riscv/cpu/cv1800b/cache.c b/arch/riscv/cpu/cv1800b/cache.c
new file mode 100644
index 0000000..b8051e2
--- /dev/null
+++ b/arch/riscv/cpu/cv1800b/cache.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com>
+ */
+
+#include <cpu_func.h>
+
+/*
+ * dcache.ipa rs1 (invalidate)
+ * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 |
+ * 0000001 01010 rs1 000 00000 0001011
+ *
+ * dcache.cpa rs1 (clean)
+ * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 |
+ * 0000001 01001 rs1 000 00000 0001011
+ *
+ * dcache.cipa rs1 (clean then invalidate)
+ * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 |
+ * 0000001 01011 rs1 000 00000 0001011
+ *
+ * sync.s
+ * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 |
+ * 0000000 11001 00000 000 00000 0001011
+ */
+#define DCACHE_IPA_A0 ".long 0x02a5000b"
+#define DCACHE_CPA_A0 ".long 0x0295000b"
+#define DCACHE_CIPA_A0 ".long 0x02b5000b"
+
+#define SYNC_S ".long 0x0190000b"
+
+void invalidate_dcache_range(unsigned long start, unsigned long end)
+{
+ register unsigned long i asm("a0") = start & ~(CONFIG_SYS_CACHELINE_SIZE - 1);
+ for (; i < end; i += CONFIG_SYS_CACHELINE_SIZE)
+ __asm__ __volatile__(DCACHE_IPA_A0);
+ __asm__ __volatile__(SYNC_S);
+}
+
+void flush_dcache_range(unsigned long start, unsigned long end)
+{
+ register unsigned long i asm("a0") = start & ~(CONFIG_SYS_CACHELINE_SIZE - 1);
+ for (; i < end; i += CONFIG_SYS_CACHELINE_SIZE)
+ __asm__ __volatile__(DCACHE_CPA_A0);
+ __asm__ __volatile__(SYNC_S);
+}
diff --git a/arch/riscv/cpu/cv1800b/cpu.c b/arch/riscv/cpu/cv1800b/cpu.c
new file mode 100644
index 0000000..233a6a3
--- /dev/null
+++ b/arch/riscv/cpu/cv1800b/cpu.c
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com>
+ */
+
+int cleanup_before_linux(void)
+{
+ return 0;
+}
diff --git a/arch/riscv/cpu/cv1800b/dram.c b/arch/riscv/cpu/cv1800b/dram.c
new file mode 100644
index 0000000..91007c0
--- /dev/null
+++ b/arch/riscv/cpu/cv1800b/dram.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ */
+
+#include <fdtdec.h>
+#include <init.h>
+#include <asm/global_data.h>
+#include <linux/sizes.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+ return fdtdec_setup_mem_size_base();
+}
+
+int dram_init_banksize(void)
+{
+ return fdtdec_setup_memory_banksize();
+}
diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
index 6cecadf..a9e1935 100644
--- a/arch/riscv/cpu/start.S
+++ b/arch/riscv/cpu/start.S
@@ -418,6 +418,7 @@ call_board_init_r:
*/
mv a0, s3 /* gd_t */
mv a1, s4 /* dest_addr */
+ mv s0, zero /* fp == NULL */
/*
* jump to it ...
diff --git a/arch/riscv/dts/cv1800b-milkv-duo.dts b/arch/riscv/dts/cv1800b-milkv-duo.dts
index 3af9e34..94e64dd 100644
--- a/arch/riscv/dts/cv1800b-milkv-duo.dts
+++ b/arch/riscv/dts/cv1800b-milkv-duo.dts
@@ -33,6 +33,14 @@
clock-frequency = <25000000>;
};
+&sdhci0 {
+ status = "okay";
+ bus-width = <4>;
+ no-1-8-v;
+ no-mmc;
+ no-sdio;
+};
+
&uart0 {
status = "okay";
};
diff --git a/arch/riscv/dts/cv1800b.dtsi b/arch/riscv/dts/cv1800b.dtsi
index 165e9e3..baf6418 100644
--- a/arch/riscv/dts/cv1800b.dtsi
+++ b/arch/riscv/dts/cv1800b.dtsi
@@ -16,3 +16,7 @@
&clint {
compatible = "sophgo,cv1800b-clint", "thead,c900-clint";
};
+
+&clk {
+ compatible = "sophgo,cv1800-clk";
+};
diff --git a/arch/riscv/dts/cv18xx.dtsi b/arch/riscv/dts/cv18xx.dtsi
index 2d6f4a4..ec99c4d 100644
--- a/arch/riscv/dts/cv18xx.dtsi
+++ b/arch/riscv/dts/cv18xx.dtsi
@@ -45,6 +45,13 @@
#clock-cells = <0>;
};
+ sdhci_clk: sdhci-clock {
+ compatible = "fixed-clock";
+ clock-frequency = <375000000>;
+ clock-output-names = "sdhci_clk";
+ #clock-cells = <0>;
+ };
+
soc {
compatible = "simple-bus";
interrupt-parent = <&plic>;
@@ -53,6 +60,12 @@
dma-noncoherent;
ranges;
+ clk: clock-controller@3002000 {
+ reg = <0x03002000 0x1000>;
+ clocks = <&osc>;
+ #clock-cells = <1>;
+ };
+
gpio0: gpio@3020000 {
compatible = "snps,dw-apb-gpio";
reg = <0x3020000 0x1000>;
@@ -175,6 +188,15 @@
status = "disabled";
};
+ sdhci0: mmc@4310000 {
+ compatible = "sophgo,cv1800b-dwcmshc";
+ reg = <0x4310000 0x1000>;
+ interrupts = <36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sdhci_clk>;
+ clock-names = "core";
+ status = "disabled";
+ };
+
plic: interrupt-controller@70000000 {
reg = <0x70000000 0x4000000>;
interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 9>;
diff --git a/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi b/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi
index f2c6bec..e11babc 100644
--- a/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi
+++ b/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi
@@ -298,7 +298,7 @@
pinctrl-0 = <&mmc1_pins>;
no-sdio;
no-mmc;
- broken-cd;
+ cd-gpios = <&sysgpio 41 GPIO_ACTIVE_LOW>;
cap-sd-highspeed;
post-power-on-delay-ms = <200>;
status = "okay";
diff --git a/arch/riscv/include/asm/arch-jh7110/eeprom.h b/arch/riscv/include/asm/arch-jh7110/eeprom.h
index d2776d5..62d184a 100644
--- a/arch/riscv/include/asm/arch-jh7110/eeprom.h
+++ b/arch/riscv/include/asm/arch-jh7110/eeprom.h
@@ -12,4 +12,13 @@
u8 get_pcb_revision_from_eeprom(void);
u32 get_ddr_size_from_eeprom(void);
+/**
+ * get_product_id_from_eeprom - get product ID string
+ *
+ * A string like "VF7110A1-2228-D008E000-00000001" is returned.
+ *
+ * Return: product ID string
+ */
+const char *get_product_id_from_eeprom(void);
+
#endif /* _ASM_RISCV_EEPROM_H */
diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c
index a26ccc7..7350e2c 100644
--- a/arch/riscv/lib/interrupts.c
+++ b/arch/riscv/lib/interrupts.c
@@ -60,6 +60,40 @@ static void show_regs(struct pt_regs *regs)
#endif
}
+#if defined(CONFIG_FRAMEPOINTER) || defined(CONFIG_SPL_FRAMEPOINTER)
+static void show_backtrace(struct pt_regs *regs)
+{
+ uintptr_t *fp = (uintptr_t *)regs->s0;
+ unsigned count = 0;
+ ulong ra;
+
+ printf("backtrace:\n");
+
+ /* there are a few entry points where the s0 register is
+ * set to gd, so to avoid changing those, just abort if
+ * the value is the same */
+ while (fp != NULL && fp != (uintptr_t *)gd) {
+ ra = fp[-1];
+ printf("backtrace %2d: FP: " REG_FMT " RA: " REG_FMT,
+ count, (ulong)fp, ra);
+
+ if (gd && gd->flags & GD_FLG_RELOC)
+ printf(" - RA: " REG_FMT " reloc adjusted\n",
+ ra - gd->reloc_off);
+ else
+ printf("\n");
+
+ fp = (uintptr_t *)fp[-2];
+ count++;
+ }
+}
+#else
+static void show_backtrace(struct pt_regs *regs)
+{
+ printf("No backtrace support enabled\n");
+}
+#endif
+
/**
* instr_len() - get instruction length
*
@@ -131,6 +165,7 @@ static void _exit_trap(ulong code, ulong epc, ulong tval, struct pt_regs *regs)
epc - gd->reloc_off, regs->ra - gd->reloc_off);
show_regs(regs);
+ show_backtrace(regs);
show_code(epc);
show_efi_loaded_images(epc);
panic("\n");
diff --git a/board/emulation/qemu-riscv/qemu-riscv.c b/board/emulation/qemu-riscv/qemu-riscv.c
index 181abbb..173245b 100644
--- a/board/emulation/qemu-riscv/qemu-riscv.c
+++ b/board/emulation/qemu-riscv/qemu-riscv.c
@@ -31,12 +31,6 @@ int is_flash_available(void)
int board_init(void)
{
- /*
- * Make sure virtio bus is enumerated so that peripherals
- * on the virtio bus can be discovered by their drivers
- */
- virtio_init();
-
return 0;
}
@@ -46,6 +40,12 @@ int board_late_init(void)
if (CONFIG_IS_ENABLED(USB_KEYBOARD))
usb_init();
+ /*
+ * Make sure virtio bus is enumerated so that peripherals
+ * on the virtio bus can be discovered by their drivers
+ */
+ virtio_init();
+
return 0;
}
diff --git a/board/sophgo/milkv_duo/Kconfig b/board/sophgo/milkv_duo/Kconfig
index 2a458f2..040a748 100644
--- a/board/sophgo/milkv_duo/Kconfig
+++ b/board/sophgo/milkv_duo/Kconfig
@@ -7,7 +7,7 @@ config SYS_VENDOR
default "sophgo"
config SYS_CPU
- default "generic"
+ default "cv1800b"
config SYS_CONFIG_NAME
default "milkv_duo"
@@ -23,6 +23,6 @@ config ENV_SECT_SIZE
config BOARD_SPECIFIC_OPTIONS
def_bool y
- select GENERIC_RISCV
+ select SOPHGO_CV1800B
endif
diff --git a/board/starfive/visionfive2/spl.c b/board/starfive/visionfive2/spl.c
index 1b49945..45848db 100644
--- a/board/starfive/visionfive2/spl.c
+++ b/board/starfive/visionfive2/spl.c
@@ -4,7 +4,6 @@
* Author: Yanhong Wang<yanhong.wang@starfivetech.com>
*/
-#include <common.h>
#include <asm/arch/eeprom.h>
#include <asm/arch/gpio.h>
#include <asm/arch/regs.h>
@@ -27,6 +26,26 @@ struct starfive_vf2_pro {
const char *value;
};
+static const struct starfive_vf2_pro milk_v_mars[] = {
+ {"/soc/ethernet@16030000", "starfive,tx-use-rgmii-clk", NULL},
+ {"/soc/ethernet@16040000", "starfive,tx-use-rgmii-clk", NULL},
+
+ {"/soc/ethernet@16030000/mdio/ethernet-phy@0",
+ "motorcomm,tx-clk-adj-enabled", NULL},
+ {"/soc/ethernet@16030000/mdio/ethernet-phy@0",
+ "motorcomm,tx-clk-100-inverted", NULL},
+ {"/soc/ethernet@16030000/mdio/ethernet-phy@0",
+ "motorcomm,tx-clk-1000-inverted", NULL},
+ {"/soc/ethernet@16030000/mdio/ethernet-phy@0",
+ "motorcomm,rx-clk-drv-microamp", "3970"},
+ {"/soc/ethernet@16030000/mdio/ethernet-phy@0",
+ "motorcomm,rx-data-drv-microamp", "2910"},
+ {"/soc/ethernet@16030000/mdio/ethernet-phy@0",
+ "rx-internal-delay-ps", "1900"},
+ {"/soc/ethernet@16030000/mdio/ethernet-phy@0",
+ "tx-internal-delay-ps", "1500"},
+};
+
static const struct starfive_vf2_pro starfive_vera[] = {
{"/soc/ethernet@16030000/mdio/ethernet-phy@0", "rx-internal-delay-ps",
"1900"},
@@ -67,6 +86,49 @@ static const struct starfive_vf2_pro starfive_verb[] = {
"tx-internal-delay-ps", "0"},
};
+void spl_fdt_fixup_mars(void *fdt)
+{
+ static const char compat[] = "milkv,mars\0starfive,jh7110";
+ u32 phandle;
+ u8 i;
+ int offset;
+ int ret;
+
+ fdt_setprop(fdt, fdt_path_offset(fdt, "/"), "compatible", compat, sizeof(compat));
+ fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "model",
+ "Milk-V Mars");
+
+ /* gmac0 */
+ offset = fdt_path_offset(fdt, "/soc/clock-controller@17000000");
+ phandle = fdt_get_phandle(fdt, offset);
+ offset = fdt_path_offset(fdt, "/soc/ethernet@16030000");
+
+ fdt_setprop_u32(fdt, offset, "assigned-clocks", phandle);
+ fdt_appendprop_u32(fdt, offset, "assigned-clocks", JH7110_AONCLK_GMAC0_TX);
+ fdt_setprop_u32(fdt, offset, "assigned-clock-parents", phandle);
+ fdt_appendprop_u32(fdt, offset, "assigned-clock-parents",
+ JH7110_AONCLK_GMAC0_RMII_RTX);
+
+ /* gmac1 */
+ fdt_setprop_string(fdt, fdt_path_offset(fdt, "/soc/ethernet@16040000"),
+ "status", "disabled");
+
+ for (i = 0; i < ARRAY_SIZE(milk_v_mars); i++) {
+ offset = fdt_path_offset(fdt, milk_v_mars[i].path);
+
+ if (milk_v_mars[i].value)
+ ret = fdt_setprop_u32(fdt, offset, milk_v_mars[i].name,
+ dectoul(milk_v_mars[i].value, NULL));
+ else
+ ret = fdt_setprop_empty(fdt, offset, milk_v_mars[i].name);
+
+ if (ret) {
+ pr_err("%s set prop %s fail.\n", __func__, milk_v_mars[i].name);
+ break;
+ }
+ }
+}
+
void spl_fdt_fixup_version_a(void *fdt)
{
static const char compat[] = "starfive,visionfive-2-v1.2a\0starfive,jh7110";
@@ -167,22 +229,34 @@ void spl_fdt_fixup_version_b(void *fdt)
void spl_perform_fixups(struct spl_image_info *spl_image)
{
u8 version;
+ const char *product_id;
- version = get_pcb_revision_from_eeprom();
- switch (version) {
- case 'a':
- case 'A':
- spl_fdt_fixup_version_a(spl_image->fdt_addr);
- break;
-
- case 'b':
- case 'B':
- default:
- spl_fdt_fixup_version_b(spl_image->fdt_addr);
+ product_id = get_product_id_from_eeprom();
+ if (!product_id) {
+ pr_err("Can't read EEPROM\n");
+ return;
+ }
+ if (!strncmp(product_id, "MARS", 4)) {
+ spl_fdt_fixup_mars(spl_image->fdt_addr);
+ } else if (!strncmp(product_id, "VF7110", 6)) {
+ version = get_pcb_revision_from_eeprom();
+ switch (version) {
+ case 'a':
+ case 'A':
+ spl_fdt_fixup_version_a(spl_image->fdt_addr);
+ break;
+
+ case 'b':
+ case 'B':
+ default:
+ spl_fdt_fixup_version_b(spl_image->fdt_addr);
break;
+ };
+ } else {
+ pr_err("Unknown product %s\n", product_id);
};
- /* Update the memory size which read form eeprom or DT */
+ /* Update the memory size which read from eeprom or DT */
fdt_fixup_memory(spl_image->fdt_addr, 0x40000000, gd->ram_size);
}
diff --git a/board/starfive/visionfive2/starfive_visionfive2.c b/board/starfive/visionfive2/starfive_visionfive2.c
index 78e118d..a86bca5 100644
--- a/board/starfive/visionfive2/starfive_visionfive2.c
+++ b/board/starfive/visionfive2/starfive_visionfive2.c
@@ -4,11 +4,11 @@
* Author: Yanhong Wang<yanhong.wang@starfivetech.com>
*/
-#include <common.h>
#include <cpu_func.h>
#include <dm.h>
#include <fdt_support.h>
#include <env.h>
+#include <log.h>
#include <asm/arch/eeprom.h>
#include <asm/io.h>
#include <asm/sections.h>
@@ -17,6 +17,8 @@
DECLARE_GLOBAL_DATA_PTR;
#define JH7110_L2_PREFETCHER_BASE_ADDR 0x2030000
#define JH7110_L2_PREFETCHER_HART_OFFSET 0x2000
+#define FDTFILE_MILK_V_MARS \
+ "starfive/jh7110-milkv-mars.dtb"
#define FDTFILE_VISIONFIVE2_1_2A \
"starfive/jh7110-starfive-visionfive-2-v1.2a.dtb"
#define FDTFILE_VISIONFIVE2_1_3B \
@@ -48,20 +50,38 @@ static void set_fdtfile(void)
{
u8 version;
const char *fdtfile;
+ const char *product_id;
- version = get_pcb_revision_from_eeprom();
- switch (version) {
- case 'a':
- case 'A':
- fdtfile = FDTFILE_VISIONFIVE2_1_2A;
- break;
-
- case 'b':
- case 'B':
- default:
- fdtfile = FDTFILE_VISIONFIVE2_1_3B;
- break;
- };
+ fdtfile = env_get("fdtfile");
+ if (fdtfile)
+ return;
+
+ product_id = get_product_id_from_eeprom();
+ if (!product_id) {
+ log_err("Can't read EEPROM\n");
+ return;
+ }
+ if (!strncmp(product_id, "MARS", 4)) {
+ fdtfile = FDTFILE_MILK_V_MARS;
+ } else if (!strncmp(product_id, "VF7110", 6)) {
+ version = get_pcb_revision_from_eeprom();
+
+ switch (version) {
+ case 'a':
+ case 'A':
+ fdtfile = FDTFILE_VISIONFIVE2_1_2A;
+ break;
+
+ case 'b':
+ case 'B':
+ default:
+ fdtfile = FDTFILE_VISIONFIVE2_1_3B;
+ break;
+ }
+ } else {
+ log_err("Unknown product\n");
+ return;
+ }
env_set("fdtfile", fdtfile);
}
diff --git a/board/starfive/visionfive2/visionfive2-i2c-eeprom.c b/board/starfive/visionfive2/visionfive2-i2c-eeprom.c
index c36de1a..ddef7d6 100644
--- a/board/starfive/visionfive2/visionfive2-i2c-eeprom.c
+++ b/board/starfive/visionfive2/visionfive2-i2c-eeprom.c
@@ -4,7 +4,6 @@
* Author: Yanhong Wang<yanhong.wang@starfivetech.com>
*/
-#include <common.h>
#include <command.h>
#include <env.h>
#include <i2c.h>
@@ -405,6 +404,14 @@ static void set_product_id(char *string)
update_crc();
}
+const char *get_product_id_from_eeprom(void)
+{
+ if (read_eeprom())
+ return NULL;
+
+ return pbuf.eeprom.atom1.data.pstr;
+}
+
int do_mac(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
char *cmd;
diff --git a/configs/milkv_duo_defconfig b/configs/milkv_duo_defconfig
index 548adf1..e8413d7 100644
--- a/configs/milkv_duo_defconfig
+++ b/configs/milkv_duo_defconfig
@@ -17,6 +17,16 @@ CONFIG_SYS_CBSIZE=512
CONFIG_SYS_PBSIZE=544
CONFIG_HUSH_PARSER=y
CONFIG_SYS_PROMPT="milkv_duo# "
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
CONFIG_ENV_OVERWRITE=y
+CONFIG_MMC=y
+CONFIG_MMC_IO_VOLTAGE=y
+CONFIG_MMC_UHS_SUPPORT=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ADMA=y
+CONFIG_MMC_SDHCI_CV1800B=y
CONFIG_SYS_NS16550=y
CONFIG_SYS_NS16550_MEM32=y
diff --git a/configs/starfive_visionfive2_defconfig b/configs/starfive_visionfive2_defconfig
index 7a3f1d4..fa80d48 100644
--- a/configs/starfive_visionfive2_defconfig
+++ b/configs/starfive_visionfive2_defconfig
@@ -40,7 +40,6 @@ CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="console=ttyS0,115200 debug rootwait earlycon=sbi"
CONFIG_USE_PREBOOT=y
CONFIG_PREBOOT="nvme scan; usb start; setenv fdt_addr ${fdtcontroladdr}; fdt addr ${fdtcontroladdr};"
-CONFIG_DEFAULT_FDT_FILE="starfive/jh7110-starfive-visionfive-2.dtb"
CONFIG_SYS_CBSIZE=256
CONFIG_SYS_PBSIZE=276
CONFIG_DISPLAY_CPUINFO=y
diff --git a/doc/board/starfive/index.rst b/doc/board/starfive/index.rst
index 0c52dc7..2762bf7 100644
--- a/doc/board/starfive/index.rst
+++ b/doc/board/starfive/index.rst
@@ -6,4 +6,5 @@ StarFive
.. toctree::
:maxdepth: 1
+ milk-v_mars.rst
visionfive2
diff --git a/doc/board/starfive/milk-v_mars.rst b/doc/board/starfive/milk-v_mars.rst
new file mode 100644
index 0000000..554932e
--- /dev/null
+++ b/doc/board/starfive/milk-v_mars.rst
@@ -0,0 +1,111 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Milk-V Mars
+===========
+
+U-Boot for the Milk-V Mars uses the same U-Boot binaries as the VisionFive 2
+board. In U-Boot SPL the actual board is detected and the device-tree patched
+accordingly.
+
+Building
+~~~~~~~~
+
+1. Add the RISC-V toolchain to your PATH.
+2. Setup ARCH & cross compilation environment variable:
+
+.. code-block:: none
+
+ export CROSS_COMPILE=<riscv64 toolchain prefix>
+
+The M-mode software OpenSBI provides the supervisor binary interface (SBI) and
+is responsible for the switch to S-Mode. It is a prerequisite to build U-Boot.
+Support for the JH7110 was introduced in OpenSBI 1.2. It is recommended to use
+a current release.
+
+.. code-block:: console
+
+ git clone https://github.com/riscv/opensbi.git
+ cd opensbi
+ make PLATFORM=generic FW_TEXT_START=0x40000000 FW_OPTIONS=0
+
+Now build the U-Boot SPL and U-Boot proper.
+
+.. code-block:: console
+
+ cd <U-Boot-dir>
+ make starfive_visionfive2_defconfig
+ make OPENSBI=$(opensbi_dir)/build/platform/generic/firmware/fw_dynamic.bin
+
+This will generate the U-Boot SPL image (spl/u-boot-spl.bin.normal.out) as well
+as the FIT image (u-boot.itb) with OpenSBI and U-Boot.
+
+Device-tree selection
+~~~~~~~~~~~~~~~~~~~~~
+
+Depending on the board version U-Boot set variable $fdtfile to either
+starfive/jh7110-starfive-visionfive-2-v1.2a.dtb or
+starfive/jh7110-starfive-visionfive-2-v1.3b.dtb.
+
+To overrule this selection the variable can be set manually and saved in the
+environment
+
+::
+
+ setenv fdtfile my_device-tree.dtb
+ env save
+
+or the configuration variable CONFIG_DEFAULT_FDT_FILE can be used to set to
+provide a default value.
+
+Boot source selection
+~~~~~~~~~~~~~~~~~~~~~
+
+The board provides the DIP switches MSEL[1:0] to select the boot device out of
+SPI flash, eMMC, SD-card, UART. To select booting from SD-card set the DIP
+switches MSEL[1:0] to 10.
+
+Preparing the SD-Card
+~~~~~~~~~~~~~~~~~~~~~
+
+The device firmware loads U-Boot SPL (u-boot-spl.bin.normal.out) from the
+partition with type GUID 2E54B353-1271-4842-806F-E436D6AF6985. You are free
+to choose any partition number.
+
+With the default configuration U-Boot SPL loads the U-Boot FIT image
+(u-boot.itb) from partition 2 (CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=0x2).
+When formatting it is recommended to use GUID
+BC13C2FF-59E6-4262-A352-B275FD6F7172 for this partition.
+
+The FIT image (u-boot.itb) is a combination of OpenSBI's fw_dynamic.bin,
+u-boot-nodtb.bin and the device tree blob.
+
+Format the SD card (make sure the disk has GPT, otherwise use gdisk to switch)
+
+.. code-block:: bash
+
+ sudo sgdisk --clear \
+ --set-alignment=2 \
+ --new=1:4096:8191 --change-name=1:spl --typecode=1:2E54B353-1271-4842-806F-E436D6AF6985\
+ --new=2:8192:16383 --change-name=2:uboot --typecode=2:BC13C2FF-59E6-4262-A352-B275FD6F7172 \
+ --new=3:16384:1654784 --change-name=3:system --typecode=3:EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 \
+ /dev/sdb
+
+Copy U-Boot to the SD card
+
+.. code-block:: bash
+
+ sudo dd if=u-boot-spl.bin.normal.out of=/dev/sdb1
+ sudo dd if=u-boot.itb of=/dev/sdb2
+
+ sudo mount /dev/sdb3 /mnt/
+ sudo cp u-boot-spl.bin.normal.out /mnt/
+ sudo cp u-boot.itb /mnt/
+ sudo cp Image.gz /mnt/
+ sudo cp initramfs.cpio.gz /mnt/
+ sudo cp jh7110-starfive-visionfive-2.dtb /mnt/
+ sudo umount /mnt
+
+Booting
+~~~~~~~
+
+Once you plugin the sdcard and power up, you should see the U-Boot prompt.
diff --git a/doc/board/starfive/visionfive2.rst b/doc/board/starfive/visionfive2.rst
index abda8ac..2c68df3 100644
--- a/doc/board/starfive/visionfive2.rst
+++ b/doc/board/starfive/visionfive2.rst
@@ -71,6 +71,24 @@ Now build the U-Boot SPL and U-Boot proper
This will generate the U-Boot SPL image (spl/u-boot-spl.bin.normal.out) as well
as the FIT image (u-boot.itb) with OpenSBI and U-Boot.
+Device-tree selection
+~~~~~~~~~~~~~~~~~~~~~
+
+Depending on the board version U-Boot set variable $fdtfile to either
+starfive/jh7110-starfive-visionfive-2-v1.2a.dtb or
+starfive/jh7110-starfive-visionfive-2-v1.3b.dtb.
+
+To overrule this selection the variable can be set manually and saved in the
+environment
+
+::
+
+ setenv fdtfile my_device-tree.dtb
+ env save
+
+or the configuration variable CONFIG_DEFAULT_FDT_FILE can be used to provide
+a default value.
+
Flashing
~~~~~~~~
diff --git a/drivers/cpu/riscv_cpu.c b/drivers/cpu/riscv_cpu.c
index 5d1026b..9b1950e 100644
--- a/drivers/cpu/riscv_cpu.c
+++ b/drivers/cpu/riscv_cpu.c
@@ -21,13 +21,13 @@ DECLARE_GLOBAL_DATA_PTR;
static int riscv_cpu_get_desc(const struct udevice *dev, char *buf, int size)
{
- const char *isa;
+ const char *cpu;
- isa = dev_read_string(dev, "riscv,isa");
- if (size < (strlen(isa) + 1))
+ cpu = dev_read_string(dev, "compatible");
+ if (size < (strlen(cpu) + 1))
return -ENOSPC;
- strcpy(buf, isa);
+ strcpy(buf, cpu);
return 0;
}
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index cef0579..f7fe6d1 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -568,6 +568,19 @@ config MMC_SDHCI_CADENCE
If unsure, say N.
+config MMC_SDHCI_CV1800B
+ bool "SDHCI support for the CV1800B SD/SDIO/eMMC controller"
+ depends on BLK && DM_MMC
+ depends on MMC_SDHCI
+ depends on OF_CONTROL
+ help
+ This selects the CV1800B SD/SDIO/eMMC driver.
+
+ If you have a controller with this interface,
+ say Y here.
+
+ If unsure, say N.
+
config MMC_SDHCI_AM654
bool "SDHCI Controller on TI's Am654 devices"
depends on ARCH_K3
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index e9cf1fc..3374321 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -60,6 +60,7 @@ obj-$(CONFIG_MMC_SDHCI_ATMEL) += atmel_sdhci.o
obj-$(CONFIG_MMC_SDHCI_BCM2835) += bcm2835_sdhci.o
obj-$(CONFIG_MMC_SDHCI_BCMSTB) += bcmstb_sdhci.o
obj-$(CONFIG_MMC_SDHCI_CADENCE) += sdhci-cadence.o
+obj-$(CONFIG_MMC_SDHCI_CV1800B) += cv1800b_sdhci.o
obj-$(CONFIG_MMC_SDHCI_AM654) += am654_sdhci.o
obj-$(CONFIG_MMC_SDHCI_IPROC) += iproc_sdhci.o
obj-$(CONFIG_MMC_SDHCI_KONA) += kona_sdhci.o
diff --git a/drivers/mmc/cv1800b_sdhci.c b/drivers/mmc/cv1800b_sdhci.c
new file mode 100644
index 0000000..2275c53
--- /dev/null
+++ b/drivers/mmc/cv1800b_sdhci.c
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com>
+ */
+
+#include <dm.h>
+#include <mmc.h>
+#include <sdhci.h>
+#include <linux/delay.h>
+
+#define SDHCI_PHY_TX_RX_DLY 0x240
+#define MMC_MAX_CLOCK 375000000
+#define TUNE_MAX_PHCODE 128
+
+struct cv1800b_sdhci_plat {
+ struct mmc_config cfg;
+ struct mmc mmc;
+};
+
+static void cv1800b_set_tap_delay(struct sdhci_host *host, u16 tap)
+{
+ sdhci_writel(host, tap << 16, SDHCI_PHY_TX_RX_DLY);
+}
+
+static void cv1800b_sdhci_reset(struct sdhci_host *host, u8 mask)
+{
+ sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
+ while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask)
+ udelay(10);
+}
+
+static int cv1800b_execute_tuning(struct mmc *mmc, u8 opcode)
+{
+ struct sdhci_host *host = dev_get_priv(mmc->dev);
+
+ u16 tap;
+
+ int current_size = 0;
+ int max_size = 0;
+ int max_window = 0;
+
+ for (tap = 0; tap < TUNE_MAX_PHCODE; tap++) {
+ cv1800b_set_tap_delay(host, tap);
+
+ if (mmc_send_tuning(host->mmc, opcode, NULL)) {
+ current_size = 0;
+ } else {
+ current_size++;
+ if (current_size > max_size) {
+ max_size = current_size;
+ max_window = tap;
+ }
+ }
+ }
+
+ cv1800b_sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
+
+ cv1800b_set_tap_delay(host, max_window - max_size / 2);
+
+ return 0;
+}
+
+const struct sdhci_ops cv1800b_sdhci_sd_ops = {
+ .platform_execute_tuning = cv1800b_execute_tuning,
+};
+
+static int cv1800b_sdhci_bind(struct udevice *dev)
+{
+ struct cv1800b_sdhci_plat *plat = dev_get_plat(dev);
+
+ return sdhci_bind(dev, &plat->mmc, &plat->cfg);
+}
+
+static int cv1800b_sdhci_probe(struct udevice *dev)
+{
+ struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+ struct cv1800b_sdhci_plat *plat = dev_get_plat(dev);
+ struct sdhci_host *host = dev_get_priv(dev);
+ int ret;
+
+ host->name = dev->name;
+ host->ioaddr = devfdt_get_addr_ptr(dev);
+
+ upriv->mmc = &plat->mmc;
+ host->mmc = &plat->mmc;
+ host->mmc->priv = host;
+ host->mmc->dev = dev;
+ host->ops = &cv1800b_sdhci_sd_ops;
+ host->max_clk = MMC_MAX_CLOCK;
+
+ ret = mmc_of_parse(dev, &plat->cfg);
+ if (ret)
+ return ret;
+
+ ret = sdhci_setup_cfg(&plat->cfg, host, 0, 200000);
+ if (ret)
+ return ret;
+
+ return sdhci_probe(dev);
+}
+
+static const struct udevice_id cv1800b_sdhci_match[] = {
+ { .compatible = "sophgo,cv1800b-dwcmshc" },
+ { }
+};
+
+U_BOOT_DRIVER(cv1800b_sdhci) = {
+ .name = "sdhci-cv1800b",
+ .id = UCLASS_MMC,
+ .of_match = cv1800b_sdhci_match,
+ .bind = cv1800b_sdhci_bind,
+ .probe = cv1800b_sdhci_probe,
+ .priv_auto = sizeof(struct sdhci_host),
+ .plat_auto = sizeof(struct cv1800b_sdhci_plat),
+ .ops = &sdhci_ops,
+};