* Add RISC-V falcon mode documentation
* Add Clang build support
* Add cmd to detect Debug Trigger Extension support

* Add PWM setting for Unmatched board
* Add Milk-V Duo board support
* Add new device node and enable new config option for VisionFive2 board
* Add second virtio device for RISC-V QEMU
This commit is contained in:
Tom Rini 2024-01-31 08:49:35 -05:00
commit 625e68ef65
33 changed files with 811 additions and 28 deletions

View file

@ -14,6 +14,9 @@ config TARGET_ANDES_AE350
config TARGET_MICROCHIP_ICICLE
bool "Support Microchip PolarFire-SoC Icicle Board"
config TARGET_MILKV_DUO
bool "Support Milk-v Duo Board"
config TARGET_OPENPITON_RISCV64
bool "Support RISC-V cores on OpenPiton SoC"
@ -83,6 +86,7 @@ source "board/openpiton/riscv64/Kconfig"
source "board/sifive/unleashed/Kconfig"
source "board/sifive/unmatched/Kconfig"
source "board/sipeed/maix/Kconfig"
source "board/sophgo/milkv_duo/Kconfig"
source "board/starfive/visionfive2/Kconfig"
source "board/thead/th1520_lpi4a/Kconfig"
source "board/xilinx/mbv/Kconfig"

View file

@ -25,7 +25,7 @@ EFI_LDS := elf_riscv64_efi.lds
PLATFORM_ELFFLAGS += -B riscv -O elf64-littleriscv
endif
PLATFORM_CPPFLAGS += -ffixed-gp -fpic
PLATFORM_CPPFLAGS += -ffixed-x3 -fpic
PLATFORM_RELFLAGS += -fno-common -ffunction-sections -fdata-sections
LDFLAGS_u-boot += --gc-sections -static -pie

View file

@ -2,6 +2,7 @@
dtb-$(CONFIG_TARGET_ANDES_AE350) += ae350_32.dtb ae350_64.dtb
dtb-$(CONFIG_TARGET_MICROCHIP_ICICLE) += mpfs-icicle-kit.dtb
dtb-$(CONFIG_TARGET_MILKV_DUO) += cv1800b-milkv-duo.dtb
dtb-$(CONFIG_TARGET_QEMU_VIRT) += qemu-virt32.dtb qemu-virt64.dtb
dtb-$(CONFIG_TARGET_OPENPITON_RISCV64) += openpiton-riscv64.dtb
dtb-$(CONFIG_TARGET_SIFIVE_UNLEASHED) += hifive-unleashed-a00.dtb

View file

@ -0,0 +1,38 @@
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
* Copyright (C) 2023 Jisheng Zhang <jszhang@kernel.org>
*/
/dts-v1/;
#include "cv1800b.dtsi"
/ {
model = "Milk-V Duo";
compatible = "milkv,duo", "sophgo,cv1800b";
aliases {
serial0 = &uart0;
serial1 = &uart1;
serial2 = &uart2;
serial3 = &uart3;
serial4 = &uart4;
};
chosen {
stdout-path = "serial0:115200n8";
};
memory@80000000 {
device_type = "memory";
reg = <0x80000000 0x3f40000>;
};
};
&osc {
clock-frequency = <25000000>;
};
&uart0 {
status = "okay";
};

View file

@ -0,0 +1,18 @@
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
* Copyright (C) 2023 Jisheng Zhang <jszhang@kernel.org>
*/
#include "cv18xx.dtsi"
/ {
compatible = "sophgo,cv1800b";
};
&plic {
compatible = "sophgo,cv1800b-plic", "thead,c900-plic";
};
&clint {
compatible = "sophgo,cv1800b-clint", "thead,c900-clint";
};

192
arch/riscv/dts/cv18xx.dtsi Normal file
View file

@ -0,0 +1,192 @@
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
* Copyright (C) 2023 Jisheng Zhang <jszhang@kernel.org>
* Copyright (C) 2023 Inochi Amaoto <inochiama@outlook.com>
*/
#include <dt-bindings/interrupt-controller/irq.h>
/ {
#address-cells = <1>;
#size-cells = <1>;
cpus: cpus {
#address-cells = <1>;
#size-cells = <0>;
timebase-frequency = <25000000>;
cpu0: cpu@0 {
compatible = "thead,c906", "riscv";
device_type = "cpu";
reg = <0>;
d-cache-block-size = <64>;
d-cache-sets = <512>;
d-cache-size = <65536>;
i-cache-block-size = <64>;
i-cache-sets = <128>;
i-cache-size = <32768>;
mmu-type = "riscv,sv39";
riscv,isa = "rv64imafdc";
riscv,isa-base = "rv64i";
riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr",
"zifencei", "zihpm";
cpu0_intc: interrupt-controller {
compatible = "riscv,cpu-intc";
interrupt-controller;
#interrupt-cells = <1>;
};
};
};
osc: oscillator {
compatible = "fixed-clock";
clock-output-names = "osc_25m";
#clock-cells = <0>;
};
soc {
compatible = "simple-bus";
interrupt-parent = <&plic>;
#address-cells = <1>;
#size-cells = <1>;
dma-noncoherent;
ranges;
gpio0: gpio@3020000 {
compatible = "snps,dw-apb-gpio";
reg = <0x3020000 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
porta: gpio-controller@0 {
compatible = "snps,dw-apb-gpio-port";
gpio-controller;
#gpio-cells = <2>;
ngpios = <32>;
reg = <0>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <60 IRQ_TYPE_LEVEL_HIGH>;
};
};
gpio1: gpio@3021000 {
compatible = "snps,dw-apb-gpio";
reg = <0x3021000 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
portb: gpio-controller@0 {
compatible = "snps,dw-apb-gpio-port";
gpio-controller;
#gpio-cells = <2>;
ngpios = <32>;
reg = <0>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <61 IRQ_TYPE_LEVEL_HIGH>;
};
};
gpio2: gpio@3022000 {
compatible = "snps,dw-apb-gpio";
reg = <0x3022000 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
portc: gpio-controller@0 {
compatible = "snps,dw-apb-gpio-port";
gpio-controller;
#gpio-cells = <2>;
ngpios = <32>;
reg = <0>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <62 IRQ_TYPE_LEVEL_HIGH>;
};
};
gpio3: gpio@3023000 {
compatible = "snps,dw-apb-gpio";
reg = <0x3023000 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
portd: gpio-controller@0 {
compatible = "snps,dw-apb-gpio-port";
gpio-controller;
#gpio-cells = <2>;
ngpios = <32>;
reg = <0>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <63 IRQ_TYPE_LEVEL_HIGH>;
};
};
uart0: serial@4140000 {
compatible = "snps,dw-apb-uart";
reg = <0x04140000 0x100>;
interrupts = <44 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&osc>;
reg-shift = <2>;
reg-io-width = <4>;
status = "disabled";
};
uart1: serial@4150000 {
compatible = "snps,dw-apb-uart";
reg = <0x04150000 0x100>;
interrupts = <45 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&osc>;
reg-shift = <2>;
reg-io-width = <4>;
status = "disabled";
};
uart2: serial@4160000 {
compatible = "snps,dw-apb-uart";
reg = <0x04160000 0x100>;
interrupts = <46 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&osc>;
reg-shift = <2>;
reg-io-width = <4>;
status = "disabled";
};
uart3: serial@4170000 {
compatible = "snps,dw-apb-uart";
reg = <0x04170000 0x100>;
interrupts = <47 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&osc>;
reg-shift = <2>;
reg-io-width = <4>;
status = "disabled";
};
uart4: serial@41c0000 {
compatible = "snps,dw-apb-uart";
reg = <0x041c0000 0x100>;
interrupts = <48 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&osc>;
reg-shift = <2>;
reg-io-width = <4>;
status = "disabled";
};
plic: interrupt-controller@70000000 {
reg = <0x70000000 0x4000000>;
interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 9>;
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <2>;
riscv,ndev = <101>;
};
clint: timer@74000000 {
reg = <0x74000000 0x10000>;
interrupts-extended = <&cpu0_intc 3>, <&cpu0_intc 7>;
};
};
};

View file

@ -127,6 +127,11 @@
pinctrl-0 = <&i2c5_pins>;
status = "okay";
pmic@36 {
compatible = "x-powers,axp15060";
reg = <0x36>;
};
eeprom@50 {
compatible = "atmel,24c04";
reg = <0x50>;

View file

@ -473,6 +473,12 @@
status = "disabled";
};
power-controller@17030000 {
compatible = "starfive,jh7110-pmu";
reg = <0x0 0x17030000 0x0 0x10000>;
interrupts = <111>;
};
qspi: spi@13010000 {
compatible = "cdns,qspi-nor";
reg = <0x0 0x13010000 0x0 0x10000

View file

@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2024 SiFive, Inc.
*
* Zong Li <zong.li@sifve.com>
*/
#ifndef _ASM_RISCV_EEPROM_H
#define _ASM_RISCV_EEPROM_H
#define PCB_REVISION_REV3 0x3
u8 get_pcb_revision_from_eeprom(void);
#endif /* _ASM_RISCV_EEPROM_H */

View file

@ -33,6 +33,7 @@ enum sbi_ext_id {
SBI_EXT_CPPC = 0x43505043,
SBI_EXT_NACL = 0x4E41434C,
SBI_EXT_STA = 0x535441,
SBI_EXT_DBTR = 0x44425452,
};
enum sbi_ext_base_fid {

View file

@ -21,8 +21,6 @@
#include <fdtdec.h>
#include <dm.h>
#include <spl.h>
#include <mapmem.h>
#include <hang.h>
DECLARE_GLOBAL_DATA_PTR;
@ -51,29 +49,6 @@ int misc_init_r(void)
}
#endif
#if CONFIG_IS_ENABLED(LOAD_FIT) || CONFIG_IS_ENABLED(LOAD_FIT_FULL)
#define ANDES_SPL_FDT_ADDR (CONFIG_TEXT_BASE - 0x100000)
void spl_perform_fixups(struct spl_image_info *spl_image)
{
/*
* Originally, u-boot-spl will place DTB directly after the kernel,
* but the size of the kernel did not include the BSS section, which
* means u-boot-spl will place the DTB in the kernel BSS section
* causing the DTB to be cleared by kernel BSS initializtion.
* Moving DTB in front of the kernel can avoid the error.
*/
if (ANDES_SPL_FDT_ADDR < 0) {
printf("%s: CONFIG_TEXT_BASE needs to be larger than 0x100000\n",
__func__);
hang();
}
memcpy((void *)ANDES_SPL_FDT_ADDR, spl_image->fdt_addr,
fdt_totalsize(spl_image->fdt_addr));
spl_image->fdt_addr = map_sysmem(ANDES_SPL_FDT_ADDR, 0);
}
#endif
int board_init(void)
{
gd->bd->bi_boot_params = PHYS_SDRAM_0 + 0x400;

View file

@ -15,6 +15,29 @@
#include <asm/gpio.h>
#include <asm/arch/gpio.h>
#include <asm/arch/spl.h>
#include <linux/io.h>
#include <asm/arch/eeprom.h>
struct pwm_sifive_regs {
unsigned int cfg; /* PWM configuration register */
unsigned int pad0; /* Reserved */
unsigned int cnt; /* PWM count register */
unsigned int pad1; /* Reserved */
unsigned int pwms; /* Scaled PWM count register */
unsigned int pad2; /* Reserved */
unsigned int pad3; /* Reserved */
unsigned int pad4; /* Reserved */
unsigned int cmp0; /* PWM 0 compare register */
unsigned int cmp1; /* PWM 1 compare register */
unsigned int cmp2; /* PWM 2 compare register */
unsigned int cmp3; /* PWM 3 compare register */
};
#define PWM0_BASE 0x10020000
#define PWM1_BASE 0x10021000
#define PWM_CFG_INIT 0x1000
#define PWM_CMP_ENABLE_VAL 0x0
#define PWM_CMP_DISABLE_VAL 0xffff
#define UBRDG_RESET SIFIVE_GENERIC_GPIO_NR(0, 7)
#define ULPI_RESET SIFIVE_GENERIC_GPIO_NR(0, 9)
@ -26,6 +49,33 @@
#define MODE_SELECT_SD 0xb
#define MODE_SELECT_MASK GENMASK(3, 0)
void spl_pwm_device_init(void)
{
struct pwm_sifive_regs *pwm0, *pwm1;
pwm0 = (struct pwm_sifive_regs *)PWM0_BASE;
pwm1 = (struct pwm_sifive_regs *)PWM1_BASE;
writel(PWM_CMP_DISABLE_VAL, (void *)&pwm0->cmp0);
/* Set the 3-color PWM LEDs to yellow in SPL */
writel(PWM_CMP_ENABLE_VAL, (void *)&pwm0->cmp1);
writel(PWM_CMP_ENABLE_VAL, (void *)&pwm0->cmp2);
writel(PWM_CMP_DISABLE_VAL, (void *)&pwm0->cmp3);
writel(PWM_CFG_INIT, (void *)&pwm0->cfg);
/* Turn on all the fans, (J21), (J23) and (J24), on the unmatched board */
/* The SoC fan(J21) on the rev3 board cannot be controlled by PWM_COMP0,
* so here sets the initial value of PWM_COMP0 as DISABLE */
if (get_pcb_revision_from_eeprom() == PCB_REVISION_REV3)
writel(PWM_CMP_DISABLE_VAL, (void *)&pwm1->cmp1);
else
writel(PWM_CMP_ENABLE_VAL, (void *)&pwm1->cmp1);
writel(PWM_CMP_ENABLE_VAL, (void *)&pwm1->cmp2);
writel(PWM_CMP_ENABLE_VAL, (void *)&pwm1->cmp3);
writel(PWM_CFG_INIT, (void *)&pwm1->cfg);
}
static inline int spl_reset_device_by_gpio(const char *label, int pin, int low_width)
{
int ret;
@ -90,6 +140,8 @@ int spl_board_init_f(void)
goto end;
}
spl_pwm_device_init();
ret = spl_gemgxl_init();
if (ret) {
debug("Gigabit ethernet PHY (VSC8541) init failed: %d\n", ret);

View file

@ -0,0 +1,28 @@
if TARGET_MILKV_DUO
config SYS_BOARD
default "milkv_duo"
config SYS_VENDOR
default "sophgo"
config SYS_CPU
default "generic"
config SYS_CONFIG_NAME
default "milkv_duo"
config TEXT_BASE
default 0x80200000
config ENV_SIZE
default 0x20000
config ENV_SECT_SIZE
default 0x40000
config BOARD_SPECIFIC_OPTIONS
def_bool y
select GENERIC_RISCV
endif

View file

@ -0,0 +1,6 @@
Milk-V Duo
M: Kongyang Liu <seashell11234455@gmail.com>
S: Maintained
F: board/sophgo/milkv_duo/
F: configs/milkv_duo_defconfig
F: doc/board/sophgo/milkv_duo.rst

View file

@ -0,0 +1,5 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com>
obj-y := board.o

View file

@ -0,0 +1,9 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com>
*/
int board_init(void)
{
return 0;
}

View file

@ -44,6 +44,10 @@ static const struct starfive_vf2_pro starfive_verb[] = {
"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",
@ -53,6 +57,10 @@ static const struct starfive_vf2_pro starfive_verb[] = {
"motorcomm,tx-clk-adj-enabled", NULL},
{ "/soc/ethernet@16040000/mdio/ethernet-phy@1",
"motorcomm,tx-clk-100-inverted", NULL},
{"/soc/ethernet@16040000/mdio/ethernet-phy@1",
"motorcomm,rx-clk-drv-microamp", "3970"},
{"/soc/ethernet@16040000/mdio/ethernet-phy@1",
"motorcomm,rx-data-drv-microamp", "2910"},
{"/soc/ethernet@16040000/mdio/ethernet-phy@1",
"rx-internal-delay-ps", "0"},
{"/soc/ethernet@16040000/mdio/ethernet-phy@1",
@ -61,11 +69,13 @@ static const struct starfive_vf2_pro starfive_verb[] = {
void spl_fdt_fixup_version_a(void *fdt)
{
static const char compat[] = "starfive,visionfive-2-v1.2a\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",
"StarFive VisionFive 2 v1.2A");
@ -106,11 +116,13 @@ void spl_fdt_fixup_version_a(void *fdt)
void spl_fdt_fixup_version_b(void *fdt)
{
static const char compat[] = "starfive,visionfive-2-v1.3b\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",
"StarFive VisionFive 2 v1.3B");

View file

@ -53,6 +53,7 @@ static struct sbi_ext extensions[] = {
{ SBI_EXT_CPPC, "Collaborative Processor Performance Control Extension" },
{ SBI_EXT_NACL, "Nested Acceleration Extension" },
{ SBI_EXT_STA, "Steal-time Accounting Extension" },
{ SBI_EXT_DBTR, "Debug Trigger Extension" },
};
static int do_sbi(struct cmd_tbl *cmdtp, int flag, int argc,

View file

@ -1113,7 +1113,7 @@ config SPL_OS_BOOT
config SPL_PAYLOAD_ARGS_ADDR
hex "Address in memory to load 'args' file for Falcon Mode to"
depends on SPL_OS_BOOT
depends on SPL_OS_BOOT || SPL_LOAD_FIT_OPENSBI_OS_BOOT
default 0x88000000 if ARCH_OMAP2PLUS
help
Address in memory where the 'args' file, typically a device tree

View file

@ -16,6 +16,7 @@
#include <opensbi.h>
#include <linux/libfdt.h>
#include <linux/printk.h>
#include <mapmem.h>
DECLARE_GLOBAL_DATA_PTR;
@ -57,6 +58,20 @@ void __noreturn spl_invoke_opensbi(struct spl_image_info *spl_image)
hang();
}
/*
* Originally, u-boot-spl will place DTB directly after the kernel,
* but the size of the kernel did not include the BSS section, which
* means u-boot-spl will place the DTB in the kernel BSS section
* causing the DTB to be cleared by kernel BSS initializtion.
* Moving DTB in front of the kernel can avoid the error.
*/
#if CONFIG_IS_ENABLED(LOAD_FIT_OPENSBI_OS_BOOT) && \
CONFIG_IS_ENABLED(PAYLOAD_ARGS_ADDR)
memcpy((void *)CONFIG_SPL_PAYLOAD_ARGS_ADDR, spl_image->fdt_addr,
fdt_totalsize(spl_image->fdt_addr));
spl_image->fdt_addr = map_sysmem(CONFIG_SPL_PAYLOAD_ARGS_ADDR, 0);
#endif
/*
* Find next os image in /fit-images
* The next os image default is u-boot proper, once enable

View file

@ -14,6 +14,7 @@ CONFIG_TARGET_ANDES_AE350=y
CONFIG_RISCV_SMODE=y
# CONFIG_AVAILABLE_HARTS is not set
CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT=y
CONFIG_SPL_PAYLOAD_ARGS_ADDR=0x01700000
CONFIG_SYS_MONITOR_BASE=0x88000000
CONFIG_FIT=y
CONFIG_SPL_LOAD_FIT_ADDRESS=0x10000000

View file

@ -15,6 +15,7 @@ CONFIG_TARGET_ANDES_AE350=y
CONFIG_RISCV_SMODE=y
CONFIG_SPL_XIP=y
CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT=y
CONFIG_SPL_PAYLOAD_ARGS_ADDR=0x01700000
CONFIG_SYS_MONITOR_BASE=0x88000000
CONFIG_FIT=y
CONFIG_SPL_LOAD_FIT_ADDRESS=0x80010000

View file

@ -14,6 +14,7 @@ CONFIG_ARCH_RV64I=y
CONFIG_RISCV_SMODE=y
# CONFIG_AVAILABLE_HARTS is not set
CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT=y
CONFIG_SPL_PAYLOAD_ARGS_ADDR=0x01700000
CONFIG_SYS_MONITOR_BASE=0x88000000
CONFIG_FIT=y
CONFIG_SPL_LOAD_FIT_ADDRESS=0x10000000

View file

@ -15,6 +15,7 @@ CONFIG_ARCH_RV64I=y
CONFIG_RISCV_SMODE=y
CONFIG_SPL_XIP=y
CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT=y
CONFIG_SPL_PAYLOAD_ARGS_ADDR=0x01700000
CONFIG_SYS_MONITOR_BASE=0x88000000
CONFIG_FIT=y
CONFIG_SPL_LOAD_FIT_ADDRESS=0x80010000

View file

@ -0,0 +1,23 @@
CONFIG_RISCV=y
CONFIG_SYS_MALLOC_LEN=0x820000
CONFIG_SYS_MALLOC_F_LEN=0x2000
CONFIG_NR_DRAM_BANKS=1
CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x82300000
CONFIG_DEFAULT_DEVICE_TREE="cv1800b-milkv-duo"
CONFIG_IDENT_STRING="milkv_duo"
CONFIG_SYS_LOAD_ADDR=0x80080000
CONFIG_TARGET_MILKV_DUO=y
CONFIG_ARCH_RV64I=y
CONFIG_RISCV_SMODE=y
CONFIG_FIT=y
CONFIG_SUPPORT_RAW_INITRD=y
CONFIG_HUSH_PARSER=y
CONFIG_SYS_PROMPT="milkv_duo# "
CONFIG_SYS_MAXARGS=64
CONFIG_SYS_CBSIZE=512
CONFIG_SYS_PBSIZE=544
CONFIG_SYS_BOOTM_LEN=0x4000000
CONFIG_ENV_OVERWRITE=y
CONFIG_SYS_NS16550=y
CONFIG_SYS_NS16550_MEM32=y

View file

@ -77,7 +77,6 @@ CONFIG_CMD_TFTPPUT=y
CONFIG_CMD_BOOTSTAGE=y
CONFIG_OF_BOARD=y
CONFIG_ENV_OVERWRITE=y
CONFIG_ENV_IS_NOWHERE=y
CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_ENV_SECT_SIZE_AUTO=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y

View file

@ -46,6 +46,7 @@ Board-specific doc
sifive/index
sipeed/index
socionext/index
sophgo/index
st/index
starfive/index
ste/index

View file

@ -0,0 +1,8 @@
.. SPDX-License-Identifier: GPL-2.0+
Sophgo
======
.. toctree::
:maxdepth: 1
milkv_duo

View file

@ -0,0 +1,64 @@
.. SPDX-License-Identifier: GPL-2.0+
Milk-V Duo
==========
CV1800B RISC-V SoC
------------------
The CV1800B is a high-performance, low-power 1+1 64-bit RISC-V SoC from Sophgo.
Mainline support
----------------
The support for following drivers are already enabled:
1. ns16550 UART Driver.
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_defconfig
make
This will generate u-boot-dtb.bin
Booting
~~~~~~~
Currently, we rely on vendor FSBL(First Stage Boot Loader) to initialize the
clock and load the u-boot image, then bootup from it.
Alternatively, to run u-boot-dtb.bin on top of FSBL, follow these steps:
1. Use the vendor-provided tool to create a unified fip.bin file containing
FSBL, OpenSBI, and U-Boot.
2. Place the generated fip.bin file into the FAT partition of the SD card.
3. 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.
Sample boot log from Milk-V Duo board
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: none
U-Boot 2024.01-rc5-00010-g51965baa36 (Dec 28 2023 - 13:15:53 +0800)milkv_duo
DRAM: 63.3 MiB
Core: 10 devices, 8 uclasses, devicetree: separate
Loading Environment from nowhere... OK
In: serial@4140000
Out: serial@4140000
Err: serial@4140000
Net: No ethernet found.
milkv_duo# cpu detail
0: cpu@0 rv64imafdc
ID = 0, freq = 0 Hz: L1 cache, MMU
milkv_duo#

View file

@ -256,3 +256,161 @@ the following command:
Falcon Mode was presented at the RMLL 2012. Slides are available at:
http://schedule2012.rmll.info/IMG/pdf/LSM2012_UbootFalconMode_Babic.pdf
Falcon Mode Boot on RISC-V
--------------------------
Introduction
~~~~~~~~~~~~
In the RISC-V environment, OpenSBI is required to enable a supervisor mode
binary to execute certain privileged operations. The typical boot sequence on
RISC-V is SPL -> OpenSBI -> U-Boot -> Linux kernel. SPL will load and start
the OpenSBI initializations, then OpenSBI will bring up the next image, U-Boot
proper. The OpenSBI binary must be prepared in advance of the U-Boot build
process and it will be packed together with U-Boot into a file called
u-boot.itb.
The Falcon Mode on RISC-V platforms is a distinct boot sequence. Borrowing
ideas from the U-Boot Falcon Mode on ARM, it skips the U-Boot proper phase
in the normal boot process and allows OpenSBI to load and start the Linux
kernel. Its boot sequence is SPL -> OpenSBI -> Linux kernel. The OpenSBI
binary and Linux kernel binary must be prepared prior to the U-Boot build
process and they will be packed together as a FIT image named linux.itb in
this process.
CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT enables the Falcon Mode boot on RISC-V.
This configuration setting tells OpenSBI that Linux kernel is its next OS
image and makes it load and start the kernel afterwards.
Note that the Falcon Mode boot bypasses a lot of initializations by U-Boot.
If the Linux kernel expects hardware initializations by U-Boot, make sure to
port the relevant code to the SPL build process.
Configuration
~~~~~~~~~~~~~
CONFIG_SPL_LOAD_FIT_ADDRESS
Specifies the address to load u-boot.itb in a normal boot. When the Falcon
Mode boot is enabled, it specifies the load address of linux.itb.
CONFIG_SYS_TEXT_BASE
Specifies the address of the text section for a u-boot proper in a normal
boot. When the Falcon Mode boot is enabled, it specifies the text section
address for the Linux kernel image.
CONFIG_SPL_PAYLOAD_ARGS_ADDR
The address in the RAM to which the FDT blob is to be moved by the SPL.
SPL places the FDT blob right after the kernel. As the kernel does not
include the BSS section in its size calculation, SPL ends up placing
the FDT blob within the BSS section of the kernel. This may cause the
FDT blob to be cleared during kernel BSS initialization. To avoid the
issue, be sure to move the FDT blob out of the kernel first.
CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT
Activates the Falcon Mode boot on RISC-V.
Example for Andes AE350 Board
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A FDT blob is required to boot the Linux kernel from the SPL. Andes AE350
platforms generally come with a builtin dtb. To load a custom DTB, follow
these steps:
1. Load the custom DTB to SDRAM::
=> fatload mmc 0:1 0x20000000 user_custom.dtb
2. Set the SPI speed::
=> sf probe 0:0 50000000 0
3. Erase sectors from the SPI Flash::
=> sf erase 0xf0000 0x10000
4. Write the FDT blob to the erased sectors of the Flash::
=> sf write 0x20000000 0xf0000 0x10000
Console Log of AE350 Falcon Mode Boot
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
U-Boot SPL 2023.01-00031-g777ecdea66 (Oct 31 2023 - 18:41:36 +0800)
Trying to boot from RAM
OpenSBI v1.2-51-g7304e42
____ _____ ____ _____
/ __ \ / ____| _ \_ _|
| | | |_ __ ___ _ __ | (___ | |_) || |
| | | | '_ \ / _ \ '_ \ \___ \| _ < | |
| |__| | |_) | __/ | | |____) | |_) || |_
\____/| .__/ \___|_| |_|_____/|____/_____|
| |
|_|
Platform Name : andestech,ax25
Platform Features : medeleg
Platform HART Count : 1
Platform IPI Device : andes_plicsw
Platform Timer Device : andes_plmt @ 60000000Hz
Platform Console Device : uart8250
Platform HSM Device : andes_smu
Platform PMU Device : andes_pmu
Platform Reboot Device : atcwdt200
Platform Shutdown Device : ---
Firmware Base : 0x0
Firmware Size : 196 KB
Runtime SBI Version : 1.0
Domain0 Name : root
Domain0 Boot HART : 0
Domain0 HARTs : 0*
Domain0 Region00 : 0x0000000000000000-0x000000000003ffff ()
Domain0 Region01 : 0x00000000e6000000-0x00000000e60fffff (I,R)
Domain0 Region02 : 0x00000000e6400000-0x00000000e67fffff (I)
Domain0 Region03 : 0x0000000000000000-0xffffffffffffffff (R,W,X)
Domain0 Next Address : 0x0000000001800000
Domain0 Next Arg1 : 0x0000000001700000
Domain0 Next Mode : S-mode
Domain0 SysReset : yes
Boot HART ID : 0
Boot HART Domain : root
Boot HART Priv Version : v1.11
Boot HART Base ISA : rv64imafdcx
Boot HART ISA Extensions : none
Boot HART PMP Count : 8
Boot HART PMP Granularity : 4
Boot HART PMP Address Bits: 31
Boot HART MHPM Count : 4
Boot HART MHPM Bits : 64
Boot HART MIDELEG : 0x0000000000000222
Boot HART MEDELEG : 0x000000000000b109
[ 0.000000] Linux version 6.1.47-09019-g0584b09ad862-dirty
[ 0.000000] OF: fdt: Ignoring memory range 0x0 - 0x1800000
[ 0.000000] Machine model: andestech,ax25
[ 0.000000] earlycon: sbi0 at I/O port 0x0 (options '')
[ 0.000000] printk: bootconsole [sbi0] enabled
[ 0.000000] Disabled 4-level and 5-level paging
[ 0.000000] efi: UEFI not found.
[ 0.000000] Zone ranges:
[ 0.000000] DMA32 [mem 0x0000000001800000-0x000000003fffffff]
[ 0.000000] Normal empty
[ 0.000000] Movable zone start for each node
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x0000000001800000-0x000000003fffffff]
[ 0.000000] Initmem setup node 0 [mem 0x0000000001800000-0x000000003fffffff]
[ 0.000000] SBI specification v1.0 detected
[ 0.000000] SBI implementation ID=0x1 Version=0x10002
[ 0.000000] SBI TIME extension detected
[ 0.000000] SBI IPI extension detected
[ 0.000000] SBI RFENCE extension detected
[ 0.000000] SBI SRST extension detected
[ 0.000000] SBI HSM extension detected
[ 0.000000] riscv: base ISA extensions acim
[ 0.000000] riscv: ELF capabilities acim
[ 0.000000] percpu: Embedded 18 pages/cpu s35000 r8192 d30536 u73728
[ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 252500

View file

@ -23,6 +23,12 @@
#define YTPHY_SYNCE_CFG_REG 0xA012
#define YT8531_PAD_DRIVE_STRENGTH_CFG_REG 0xA010
#define YT8531_RGMII_RXC_DS_MASK GENMASK(15, 13)
#define YT8531_RGMII_RXD_DS_HI_MASK BIT(12) /* Bit 2 of rxd_ds */
#define YT8531_RGMII_RXD_DS_LOW_MASK GENMASK(5, 4) /* Bit 1/0 of rxd_ds */
#define YT8531_RGMII_RX_DS_DEFAULT 0x3
#define YTPHY_DTS_OUTPUT_CLK_DIS 0
#define YTPHY_DTS_OUTPUT_CLK_25M 25000000
#define YTPHY_DTS_OUTPUT_CLK_125M 125000000
@ -114,6 +120,10 @@
#define YT8531_CCR_RXC_DLY_EN BIT(8)
#define YT8531_CCR_RXC_DLY_1_900_NS 1900
#define YT8531_CCR_CFG_LDO_MASK GENMASK(5, 4)
#define YT8531_CCR_CFG_LDO_3V3 0x0
#define YT8531_CCR_CFG_LDO_1V8 0x2
/* bits in struct ytphy_plat_priv->flag */
#define TX_CLK_ADJ_ENABLED BIT(0)
#define AUTO_SLEEP_DISABLED BIT(1)
@ -224,6 +234,17 @@ static int ytphy_modify_ext(struct phy_device *phydev, u16 regnum, u16 mask,
return phy_modify(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_DATA, mask, set);
}
static int ytphy_read_ext(struct phy_device *phydev, u16 regnum)
{
int ret;
ret = phy_write(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_SELECT, regnum);
if (ret < 0)
return ret;
return phy_read(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_DATA);
}
static int ytphy_rgmii_clk_delay_config(struct phy_device *phydev)
{
struct ytphy_plat_priv *priv = phydev->priv;
@ -425,6 +446,111 @@ static int yt8511_config(struct phy_device *phydev)
return 0;
}
/**
* struct ytphy_ldo_vol_map - map a current value to a register value
* @vol: ldo voltage
* @ds: value in the register
* @cur: value in device configuration
*/
struct ytphy_ldo_vol_map {
u32 vol;
u32 ds;
u32 cur;
};
static const struct ytphy_ldo_vol_map yt8531_ldo_vol[] = {
{.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 0, .cur = 1200},
{.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 1, .cur = 2100},
{.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 2, .cur = 2700},
{.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 3, .cur = 2910},
{.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 4, .cur = 3110},
{.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 5, .cur = 3600},
{.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 6, .cur = 3970},
{.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 7, .cur = 4350},
{.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 0, .cur = 3070},
{.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 1, .cur = 4080},
{.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 2, .cur = 4370},
{.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 3, .cur = 4680},
{.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 4, .cur = 5020},
{.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 5, .cur = 5450},
{.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 6, .cur = 5740},
{.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 7, .cur = 6140},
};
static u32 yt8531_get_ldo_vol(struct phy_device *phydev)
{
u32 val;
val = ytphy_read_ext(phydev, YT8531_CHIP_CONFIG_REG);
val = FIELD_GET(YT8531_CCR_CFG_LDO_MASK, val);
return val <= YT8531_CCR_CFG_LDO_1V8 ? val : YT8531_CCR_CFG_LDO_1V8;
}
static int yt8531_get_ds_map(struct phy_device *phydev, u32 cur)
{
u32 vol;
int i;
vol = yt8531_get_ldo_vol(phydev);
for (i = 0; i < ARRAY_SIZE(yt8531_ldo_vol); i++) {
if (yt8531_ldo_vol[i].vol == vol && yt8531_ldo_vol[i].cur == cur)
return yt8531_ldo_vol[i].ds;
}
return -EINVAL;
}
static int yt8531_set_ds(struct phy_device *phydev)
{
u32 ds_field_low, ds_field_hi, val;
int ret, ds;
/* set rgmii rx clk driver strength */
if (!ofnode_read_u32(phydev->node, "motorcomm,rx-clk-drv-microamp", &val)) {
ds = yt8531_get_ds_map(phydev, val);
if (ds < 0) {
pr_warn("No matching current value was found.");
return -EINVAL;
}
} else {
ds = YT8531_RGMII_RX_DS_DEFAULT;
}
ret = ytphy_modify_ext(phydev,
YT8531_PAD_DRIVE_STRENGTH_CFG_REG,
YT8531_RGMII_RXC_DS_MASK,
FIELD_PREP(YT8531_RGMII_RXC_DS_MASK, ds));
if (ret < 0)
return ret;
/* set rgmii rx data driver strength */
if (!ofnode_read_u32(phydev->node, "motorcomm,rx-data-drv-microamp", &val)) {
ds = yt8531_get_ds_map(phydev, val);
if (ds < 0) {
pr_warn("No matching current value was found.");
return -EINVAL;
}
} else {
ds = YT8531_RGMII_RX_DS_DEFAULT;
}
ds_field_hi = FIELD_GET(BIT(2), ds);
ds_field_hi = FIELD_PREP(YT8531_RGMII_RXD_DS_HI_MASK, ds_field_hi);
ds_field_low = FIELD_GET(GENMASK(1, 0), ds);
ds_field_low = FIELD_PREP(YT8531_RGMII_RXD_DS_LOW_MASK, ds_field_low);
ret = ytphy_modify_ext(phydev,
YT8531_PAD_DRIVE_STRENGTH_CFG_REG,
YT8531_RGMII_RXD_DS_LOW_MASK | YT8531_RGMII_RXD_DS_HI_MASK,
ds_field_low | ds_field_hi);
if (ret < 0)
return ret;
return 0;
}
static int yt8531_config(struct phy_device *phydev)
{
struct ytphy_plat_priv *priv = phydev->priv;
@ -487,6 +613,10 @@ static int yt8531_config(struct phy_device *phydev)
return ret;
}
ret = yt8531_set_ds(phydev);
if (ret < 0)
return ret;
return 0;
}

View file

@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com>
*
*/
#ifndef __CONFIG_H
#define __CONFIG_H
#define CFG_SYS_SDRAM_BASE 0x80000000
#endif /* __CONFIG_H */

View file

@ -23,6 +23,7 @@
#define BOOT_TARGET_DEVICES(func) \
func(VIRTIO, virtio, 0) \
func(VIRTIO, virtio, 1) \
func(SCSI, scsi, 0) \
func(DHCP, dhcp, na)