Add support for the Milk-V Duo S, a development board based on the
Sophgo SG2000 SoC with 512 MiB of RAM.

The SG2000 differs from the CV1800B used on the Milk-V Duo 64M and the
SG2002 used on the Milk-V Duo 256M, but these SoCs share most of their
IP blocks, including the CPU core, so the existing CV1800B support can
be reused.

Add a separate board directory, target and defconfig for the Duo S,
based on the Milk-V Duo 256M ones. Like the Duo 256M, it reuses the
common Milk-V Duo board code. The defconfig uses the upstream devicetree
via OF_UPSTREAM.

Link: https://milkv.io/docs/duo/getting-started/duos
Signed-off-by: João Paulo Gonçalves <[email protected]>
Acked-by: Andrei Lalaev <[email protected]>
Acked-by: Hiago De Franco <[email protected]>
---
 arch/riscv/Kconfig                       |  4 ++
 board/sophgo/milkv_duo_s/Kconfig         | 30 +++++++++++
 board/sophgo/milkv_duo_s/MAINTAINERS     |  8 +++
 board/sophgo/milkv_duo_s/Makefile        |  6 +++
 board/sophgo/milkv_duo_s/milkv_duo_s.env |  8 +++
 configs/milkv_duo_s_defconfig            | 43 ++++++++++++++++
 doc/board/sophgo/index.rst               |  1 +
 doc/board/sophgo/milkv_duo_s.rst         | 86 ++++++++++++++++++++++++++++++++
 include/configs/milkv_duo_s.h            | 12 +++++
 9 files changed, 198 insertions(+)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 386241efd4a0..df10354e9aef 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -32,6 +32,9 @@ config TARGET_MILKV_DUO
 config TARGET_MILKV_DUO_256M
        bool "Support Milk-V Duo 256M Board"
 
+config TARGET_MILKV_DUO_S
+       bool "Support Milk-V Duo S Board"
+
 config TARGET_OPENPITON_RISCV64
        bool "Support RISC-V cores on OpenPiton SoC"
 
@@ -125,6 +128,7 @@ source "board/sifive/unmatched/Kconfig"
 source "board/sipeed/maix/Kconfig"
 source "board/sophgo/milkv_duo/Kconfig"
 source "board/sophgo/milkv_duo_256m/Kconfig"
+source "board/sophgo/milkv_duo_s/Kconfig"
 source "board/sophgo/licheerv_nano/Kconfig"
 source "board/spacemit/k1/Kconfig"
 source "board/spacemit/k3/Kconfig"
diff --git a/board/sophgo/milkv_duo_s/Kconfig b/board/sophgo/milkv_duo_s/Kconfig
new file mode 100644
index 000000000000..6ec6bd65d938
--- /dev/null
+++ b/board/sophgo/milkv_duo_s/Kconfig
@@ -0,0 +1,30 @@
+if TARGET_MILKV_DUO_S
+
+config SYS_BOARD
+       default "milkv_duo_s"
+
+config SYS_VENDOR
+       default "sophgo"
+
+config SYS_CPU
+       default "cv1800b"
+
+config SYS_CONFIG_NAME
+       default "milkv_duo_s"
+
+# The vendor FIP tool prepends a 32-byte loader header to u-boot.bin and loads
+# the result at 0x80200000, so the U-Boot code runs 0x20 bytes above that.
+config TEXT_BASE
+       default 0x80200020
+
+config ENV_SIZE
+       default 0x20000
+
+config ENV_SECT_SIZE
+       default 0x40000
+
+config BOARD_SPECIFIC_OPTIONS
+       def_bool y
+       select SOPHGO_CV1800B
+
+endif
diff --git a/board/sophgo/milkv_duo_s/MAINTAINERS 
b/board/sophgo/milkv_duo_s/MAINTAINERS
new file mode 100644
index 000000000000..86533c03fd9a
--- /dev/null
+++ b/board/sophgo/milkv_duo_s/MAINTAINERS
@@ -0,0 +1,8 @@
+Milk-V Duo S
+M:     Andrei Lalaev <[email protected]>
+M:     Hiago De Franco <[email protected]>
+S:     Maintained
+F:     board/sophgo/milkv_duo_s/
+F:     configs/milkv_duo_s_defconfig
+F:     doc/board/sophgo/milkv_duo_s.rst
+F:     include/configs/milkv_duo_s.h
diff --git a/board/sophgo/milkv_duo_s/Makefile 
b/board/sophgo/milkv_duo_s/Makefile
new file mode 100644
index 000000000000..a1b6aaee1489
--- /dev/null
+++ b/board/sophgo/milkv_duo_s/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2026, João Paulo Gonçalves <[email protected]>
+
+obj-y += ../milkv_duo/board.o
+obj-$(CONFIG_NET_LEGACY) += ../common/ethernet.o
diff --git a/board/sophgo/milkv_duo_s/milkv_duo_s.env 
b/board/sophgo/milkv_duo_s/milkv_duo_s.env
new file mode 100644
index 000000000000..4c9f53d08118
--- /dev/null
+++ b/board/sophgo/milkv_duo_s/milkv_duo_s.env
@@ -0,0 +1,8 @@
+fdt_addr_r=0x84000000
+fdtfile=DEFAULT_DEVICE_TREE.dtb
+kernel_addr_r=0x80200000
+kernel_comp_addr_r=0x88000000
+kernel_comp_size=0x4000000
+pxefile_addr_r=0x84300000
+ramdisk_addr_r=0x84400000
+scriptaddr=0x84200000
diff --git a/configs/milkv_duo_s_defconfig b/configs/milkv_duo_s_defconfig
new file mode 100644
index 000000000000..41a31c4ad46c
--- /dev/null
+++ b/configs/milkv_duo_s_defconfig
@@ -0,0 +1,43 @@
+CONFIG_RISCV=y
+CONFIG_SYS_MALLOC_LEN=0x820000
+CONFIG_SYS_MALLOC_F_LEN=0x8000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x82300000
+CONFIG_DEFAULT_DEVICE_TREE="sophgo/sg2000-milkv-duo-s"
+CONFIG_SYS_LOAD_ADDR=0x80080000
+CONFIG_IDENT_STRING=" milkv_duo_s"
+CONFIG_TARGET_MILKV_DUO_S=y
+CONFIG_ARCH_RV64I=y
+CONFIG_RISCV_SMODE=y
+CONFIG_FIT=y
+CONFIG_BOOTSTD_FULL=y
+# CONFIG_BOOTMETH_EFI_BOOTMGR is not set
+CONFIG_SD_BOOT=y
+CONFIG_SYS_CBSIZE=512
+CONFIG_SYS_PBSIZE=544
+CONFIG_SYS_PROMPT="milkv_duo_s# "
+# CONFIG_CMD_BOOTDEV is not set
+CONFIG_CMD_MBR=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_POWEROFF=y
+# CONFIG_CMD_MII is not set
+CONFIG_CMD_EXT4_WRITE=y
+# CONFIG_ISO_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+CONFIG_OF_UPSTREAM=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_CLK_SOPHGO_CV1800B=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_ETH_DESIGNWARE=y
+CONFIG_SYS_NS16550=y
+CONFIG_SYS_NS16550_MEM32=y
+CONFIG_SPI=y
+CONFIG_SYSRESET=y
+CONFIG_SYSRESET_CV1800B=y
diff --git a/doc/board/sophgo/index.rst b/doc/board/sophgo/index.rst
index 19c9a19b1d4b..61aceafceea3 100644
--- a/doc/board/sophgo/index.rst
+++ b/doc/board/sophgo/index.rst
@@ -7,4 +7,5 @@ Sophgo
 
    milkv_duo
    milkv_duo_256m
+   milkv_duo_s
    licheerv_nano
diff --git a/doc/board/sophgo/milkv_duo_s.rst b/doc/board/sophgo/milkv_duo_s.rst
new file mode 100644
index 000000000000..2ae749a08215
--- /dev/null
+++ b/doc/board/sophgo/milkv_duo_s.rst
@@ -0,0 +1,86 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Milk-V Duo S
+============
+
+SG2000 RISC-V SoC
+-----------------
+The SG2000 is a high-performance, low-power 64-bit RISC-V/ARM SoC from Sophgo.
+
+Mainline support
+----------------
+Support for the following drivers is already enabled:
+
+1. ns16550 UART Driver.
+2. Synopsys Designware MSHC Driver.
+3. Synopsys Designware Ethernet Controller.
+
+Building
+~~~~~~~~
+1. Add the RISC-V toolchain to your PATH.
+2. Setup ARCH & cross compilation environment variable:
+
+.. code-block:: console
+
+   export CROSS_COMPILE=<riscv64 toolchain prefix>
+   cd <U-Boot-dir>
+   make milkv_duo_s_defconfig
+   make
+
+This will generate u-boot.bin
+
+Booting
+~~~~~~~
+Currently, we rely on vendor FSBL (First Stage Boot Loader) to initialize the
+clock and load OpenSBI and the u-boot image, then bootup from it.
+
+To run u-boot.bin on top of FSBL, follow these steps:
+
+1. Generate a compatible u-boot.bin using U-Boot with the Milk-V Duo S
+   default configuration.
+
+2. Use mainline OpenSBI with a newer version than 1.5 to generate fw_dynamic.
+   Use FW_FDT_PATH to point to sg2000-milkv-duo-s.dtb device tree file while
+   compiling fw_dynamic. Example:
+
+.. code-block:: console
+
+   cd open-sbi
+   PLATFORM=generic 
FW_FDT_PATH=../u-boot/dts/upstream/src/riscv/sophgo/sg2000-milkv-duo-s.dtb make
+
+This will generate build/platform/generic/firmware/fw_dynamic.bin.
+
+3. Use the vendor-provided tool [1] to create a unified fip.bin file containing
+   FSBL, OpenSBI, and U-Boot.
+   Note that you will have to use the file cv181x.bin as the FSBL.
+
+4. Place the generated fip.bin file into the FAT partition of the SD card.
+
+5. Set the board's boot core selection switch to RISC-V.
+
+6. Insert the SD card into the board and power it on.
+
+The board will automatically execute the FSBL from the fip.bin file.
+Subsequently, it will transition to OpenSBI, and finally, OpenSBI will invoke
+U-Boot.
+
+[1]: https://github.com/sophgo/fiptool
+
+Sample boot log from Milk-V Duo S board
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. code-block:: none
+
+  U-Boot 2026.10-g3c39950264fd (Oct 16 2026 - 19:45:23 +0000) milkv_duo_s
+
+  DRAM:  512 MiB
+  Core:  28 devices, 13 uclasses, devicetree: separate
+  MMC:   mmc@4310000: 0, mmc@4320000: 2, mmc@4300000: 1
+  Loading Environment from nowhere... OK
+  In:    serial@4140000
+  Out:   serial@4140000
+  Err:   serial@4140000
+  Net:
+  Warning: ethernet@4070000 (eth0) using random MAC address - de:19:4d:5d:74:41
+  eth0: ethernet@4070000
+  Hit any key to stop autoboot: 0
+  milkv_duo_s#
diff --git a/include/configs/milkv_duo_s.h b/include/configs/milkv_duo_s.h
new file mode 100644
index 000000000000..f60aa23fc181
--- /dev/null
+++ b/include/configs/milkv_duo_s.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2026, João Paulo Gonçalves <[email protected]>
+ *
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define CFG_SYS_SDRAM_BASE     0x80000000
+
+#endif /* __CONFIG_H */

-- 
2.53.0

Reply via email to