summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHal Feng <hal.feng@starfivetech.com>2023-08-09 09:06:59 +0300
committerHal Feng <hal.feng@starfivetech.com>2023-11-29 05:45:35 +0300
commit93cc1e2b6d33b9fd588a640ba161f6db377d6181 (patch)
treeaa597e38c79a9f5122f395319b6453fe82d5f6f6
parentb9ea242a49cd2e7d84ca0ea9086e8a76cd92e485 (diff)
downloadu-boot-93cc1e2b6d33b9fd588a640ba161f6db377d6181.tar.xz
board: starfive: Add StarFive VisionFive 2 board support
Add board support for StarFive VisionFive 2. The code is ported from tag JH7110_VF2_515_v3.9.3 of VF2 repo. Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-rw-r--r--board/starfive/visionfive/MAINTAINERS7
-rw-r--r--board/starfive/visionfive/spl.c85
-rwxr-xr-xboard/starfive/visionfive/starfive_visionfive.c207
-rw-r--r--board/starfive/visionfive2/Kconfig (renamed from board/starfive/visionfive/Kconfig)6
-rw-r--r--board/starfive/visionfive2/MAINTAINERS7
-rw-r--r--board/starfive/visionfive2/Makefile (renamed from board/starfive/visionfive/Makefile)4
-rw-r--r--board/starfive/visionfive2/spl.c189
-rw-r--r--board/starfive/visionfive2/starfive_visionfive2.c547
-rw-r--r--board/starfive/visionfive2/visionfive2-i2c-eeprom.c832
-rw-r--r--include/configs/starfive-visionfive.h151
-rw-r--r--include/configs/starfive-visionfive2.h374
11 files changed, 1954 insertions, 455 deletions
diff --git a/board/starfive/visionfive/MAINTAINERS b/board/starfive/visionfive/MAINTAINERS
deleted file mode 100644
index 437f6c2d24..0000000000
--- a/board/starfive/visionfive/MAINTAINERS
+++ /dev/null
@@ -1,7 +0,0 @@
-STARFIVE JH7110 VISIONFIVE BOARD
-M: startfive
-S: Maintained
-F: arch/riscv/include/asm/arch-jh7110/
-F: board/starfive/visionfive/
-F: include/configs/starfive-visionfive.h
-F: configs/starfive_visionfive_defconfig
diff --git a/board/starfive/visionfive/spl.c b/board/starfive/visionfive/spl.c
deleted file mode 100644
index 13e934de4b..0000000000
--- a/board/starfive/visionfive/spl.c
+++ /dev/null
@@ -1,85 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
- * Author: yanhong <yanhong.wang@starfivetech.com>
- *
- */
-
-#include <common.h>
-#include <init.h>
-#include <spl.h>
-#include <log.h>
-#include <linux/delay.h>
-#include <image.h>
-#include <asm/arch/spl.h>
-#include <asm/io.h>
-
-#define MODE_SELECT_REG 0x1702002c
-
-int spl_board_init_f(void)
-{
- int ret;
-
- ret = spl_soc_init();
- if (ret) {
- debug("JH7110 SPL init failed: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-u32 spl_boot_device(void)
-{
- int boot_mode = 0;
-
- boot_mode = readl((const volatile void *)MODE_SELECT_REG) & 0xF;
- switch (boot_mode) {
- case 0:
- return BOOT_DEVICE_SPI;
- case 1:
- return BOOT_DEVICE_MMC2;
- case 2:
- return BOOT_DEVICE_MMC1;
- case 4:
- return BOOT_DEVICE_UART;
- default:
- debug("Unsupported boot device 0x%x.\n",
- boot_mode);
- return BOOT_DEVICE_NONE;
- }
-}
-
-struct image_header *spl_get_load_buffer(ssize_t offset, size_t size)
-{
- return (struct image_header *)(STARFIVE_SPL_BOOT_LOAD_ADDR);
-}
-
-void board_init_f(ulong dummy)
-{
- int ret;
-
- ret = spl_early_init();
- if (ret)
- panic("spl_early_init() failed: %d\n", ret);
-
- arch_cpu_init_dm();
-
- preloader_console_init();
-
- ret = spl_board_init_f();
- if (ret) {
- debug("spl_board_init_f init failed: %d\n", ret);
- return;
- }
-}
-
-#ifdef CONFIG_SPL_LOAD_FIT
-int board_fit_config_name_match(const char *name)
-{
- /* boot using first FIT config */
- return 0;
-}
-#endif
-
-
diff --git a/board/starfive/visionfive/starfive_visionfive.c b/board/starfive/visionfive/starfive_visionfive.c
deleted file mode 100755
index 462781a526..0000000000
--- a/board/starfive/visionfive/starfive_visionfive.c
+++ /dev/null
@@ -1,207 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
- * Author: yanhong <yanhong.wang@starfivetech.com>
- *
- */
-
-#include <common.h>
-#include <asm/io.h>
-#include <asm/arch/jh7110-regs.h>
-#include <cpu_func.h>
-#include <dm/uclass.h>
-#include <dm/device.h>
-#include <env.h>
-#include <inttypes.h>
-#include <misc.h>
-#include <linux/bitops.h>
-#include <asm/arch/gpio.h>
-
-#define SYS_IOMUX_DOEN(gpio, oen) \
- clrsetbits_le32(SYS_IOMUX_BASE+GPIO_OFFSET(gpio), \
- GPIO_DOEN_MASK << GPIO_SHIFT(gpio), \
- (oen) << GPIO_SHIFT(gpio))
-
-#define SYS_IOMUX_DOUT(gpio, gpo) \
- clrsetbits_le32(SYS_IOMUX_BASE + GPIO_DOUT + GPIO_OFFSET(gpio),\
- GPIO_DOUT_MASK << GPIO_SHIFT(gpio),\
- ((gpo) & GPIO_DOUT_MASK) << GPIO_SHIFT(gpio))
-
-#define SYS_IOMUX_DIN(gpio, gpi)\
- clrsetbits_le32(SYS_IOMUX_BASE + GPIO_DIN + GPIO_OFFSET(gpi),\
- GPIO_DIN_MASK << GPIO_SHIFT(gpi),\
- ((gpio+2) & GPIO_DIN_MASK) << GPIO_SHIFT(gpi))
-
-#define SYS_IOMUX_COMPLEX(gpio, gpi, gpo, oen) do {\
- SYS_IOMUX_DOEN(gpio, oen);\
- SYS_IOMUX_DOUT(gpio, gpo);\
- SYS_IOMUX_DIN(gpio, gpi); }while(0)
-
-#define SYS_CLOCK_ENABLE(clk) \
- setbits_le32(SYS_CRG_BASE + clk, CLK_ENABLE_MASK)
-
-static void sys_reset_clear(ulong assert, ulong status, u32 rst)
-{
- volatile u32 value;
-
- clrbits_le32(SYS_CRG_BASE + assert, BIT(rst));
- do{
- value = in_le32(SYS_CRG_BASE + status);
- }while((value & BIT(rst)) != BIT(rst));
-}
-
-static void jh7110_timer_init(void)
-{
- SYS_CLOCK_ENABLE(TIMER_CLK_APB_SHIFT);
- SYS_CLOCK_ENABLE(TIMER_CLK_TIMER0_SHIFT);
- SYS_CLOCK_ENABLE(TIMER_CLK_TIMER1_SHIFT);
- SYS_CLOCK_ENABLE(TIMER_CLK_TIMER2_SHIFT);
- SYS_CLOCK_ENABLE(TIMER_CLK_TIMER3_SHIFT);
-
- sys_reset_clear(SYS_CRG_RESET_ASSERT3_SHIFT,
- SYS_CRG_RESET_STATUS3_SHIFT, TIMER_RSTN_APB_SHIFT);
- sys_reset_clear(SYS_CRG_RESET_ASSERT3_SHIFT,
- SYS_CRG_RESET_STATUS3_SHIFT, TIMER_RSTN_TIMER0_SHIFT);
- sys_reset_clear(SYS_CRG_RESET_ASSERT3_SHIFT,
- SYS_CRG_RESET_STATUS3_SHIFT, TIMER_RSTN_TIMER1_SHIFT);
- sys_reset_clear(SYS_CRG_RESET_ASSERT3_SHIFT,
- SYS_CRG_RESET_STATUS3_SHIFT, TIMER_RSTN_TIMER2_SHIFT);
- sys_reset_clear(SYS_CRG_RESET_ASSERT3_SHIFT,
- SYS_CRG_RESET_STATUS3_SHIFT, TIMER_RSTN_TIMER3_SHIFT);
-}
-
-static void jh7110_gmac_init(int id)
-{
- switch (id) {
- case 0:
- clrsetbits_le32(AON_SYSCON_BASE + AON_SYSCFG_12,
- GMAC5_0_SEL_I_MASK,
- BIT(GMAC5_0_SEL_I_SHIFT) & GMAC5_0_SEL_I_MASK);
- break;
-
- case 1:
- clrsetbits_le32(SYS_SYSCON_BASE + SYS_SYSCON_144,
- GMAC5_1_SEL_I_MASK,
- BIT(GMAC5_1_SEL_I_SHIFT) & GMAC5_1_SEL_I_MASK);
- break;
-
- default:
- break;
- }
-}
-
-static void jh7110_usb_init(void)
-{
- clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_4,
- USB_MODE_STRAP_MASK,
- (2<<USB_MODE_STRAP_SHIFT) & USB_MODE_STRAP_MASK);
- clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_4,
- USB_OTG_SUSPENDM_BYPS_MASK,
- BIT(USB_OTG_SUSPENDM_BYPS_SHIFT)
- & USB_OTG_SUSPENDM_BYPS_MASK);
-
- clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_4,
- USB_OTG_SUSPENDM_MASK,
- BIT(USB_OTG_SUSPENDM_SHIFT) & USB_OTG_SUSPENDM_MASK);
- clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_4,
- USB_PLL_EN_MASK,
- BIT(USB_PLL_EN_SHIFT) & USB_PLL_EN_MASK);
- clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_4,
- USB_REFCLK_MODE_MASK,
- BIT(USB_REFCLK_MODE_SHIFT) & USB_REFCLK_MODE_MASK);
-
- clrsetbits_le32(SYS_SYSCON_BASE + SYS_SYSCON_24,
- PDRSTN_SPLIT_MASK,
- BIT(PDRSTN_SPLIT_SHIFT) & PDRSTN_SPLIT_MASK);
- clrsetbits_le32(SYS_IOMUX_BASE + SYS_IOMUX_32,
- IOMUX_USB_MASK,
- BIT(IOMUX_USB_SHIFT) & IOMUX_USB_MASK);
-}
-
-static void jh7110_mmc_init(int id)
-{
- if (id == 0) {
- SYS_IOMUX_DOEN(62, LOW);
- SYS_IOMUX_DOUT(62, 19);
- } else {
- SYS_IOMUX_DOEN(10, LOW);
- SYS_IOMUX_DOUT(10, 55);
- SYS_IOMUX_COMPLEX(9, 44, 57, 19);
- SYS_IOMUX_COMPLEX(11, 45, 58, 20);
- SYS_IOMUX_COMPLEX(12, 46, 59, 21);
- SYS_IOMUX_COMPLEX(7, 47, 60, 22);
- SYS_IOMUX_COMPLEX(8, 48, 61, 23);
- }
-}
-
-/*enable U74-mc hart1~hart4 prefetcher*/
-static void enable_prefetcher(void)
-{
- u32 hart;
- u32 *reg;
-#define L2_PREFETCHER_BASE_ADDR 0x2030000
-#define L2_PREFETCHER_OFFSET 0x2000
-
- /*hart1~hart4*/
- for (hart = 1; hart < 5; hart++) {
- reg = (u32 *)((u64)(L2_PREFETCHER_BASE_ADDR
- + hart*L2_PREFETCHER_OFFSET));
-
- mb(); /* memory barrier */
- setbits_le32(reg, 0x1);
- mb(); /* memory barrier */
- }
-}
-
-int board_init(void)
-{
- enable_caches();
-
- /*enable hart1-hart4 prefetcher*/
-// enable_prefetcher();
-
- jh7110_gmac_init(0);
- jh7110_gmac_init(1);
- jh7110_timer_init();
-
- jh7110_usb_init();
-
- jh7110_mmc_init(0);
- jh7110_mmc_init(1);
-
- return 0;
-}
-
-#ifdef CONFIG_MISC_INIT_R
-
-int misc_init_r(void)
-{
- char mac[6] = {0x66, 0x34, 0xb0, 0x6c, 0xde, 0xad };
-
-#if CONFIG_IS_ENABLED(STARFIVE_OTP)
- struct udevice *dev;
- char buf[8];
- int ret;
-#define MACADDR_OFFSET 0x8
-
- ret = uclass_get_device_by_driver(UCLASS_MISC,
- DM_DRIVER_GET(starfive_otp), &dev);
- if (ret) {
- debug("%s: could not find otp device\n", __func__);
- goto err;
- }
-
- ret = misc_read(dev, MACADDR_OFFSET, buf, sizeof(buf));
- if (ret != sizeof(buf))
- printf("%s: error reading mac from OTP\n", __func__);
- else
- if (buf[0] != 0xff)
- memcpy(mac, buf, 6);
-err:
-#endif
- eth_env_set_enetaddr("ethaddr", mac);
-
- return 0;
-}
-#endif
-
diff --git a/board/starfive/visionfive/Kconfig b/board/starfive/visionfive2/Kconfig
index d0ed065307..28bde2a09b 100644
--- a/board/starfive/visionfive/Kconfig
+++ b/board/starfive/visionfive2/Kconfig
@@ -1,16 +1,16 @@
-if TARGET_STARFIVE_VISIONFIVE
+if TARGET_STARFIVE_VISIONFIVE2
config SYS_CPU
default "jh7110"
config SYS_BOARD
- default "visionfive"
+ default "visionfive2"
config SYS_VENDOR
default "starfive"
config SYS_CONFIG_NAME
- default "starfive-visionfive"
+ default "starfive-visionfive2"
config ENV_SIZE
default 0x2000 if ENV_IS_IN_SPI_FLASH
diff --git a/board/starfive/visionfive2/MAINTAINERS b/board/starfive/visionfive2/MAINTAINERS
new file mode 100644
index 0000000000..600ff9575b
--- /dev/null
+++ b/board/starfive/visionfive2/MAINTAINERS
@@ -0,0 +1,7 @@
+STARFIVE JH7110 VISIONFIVE2 BOARD
+M: Yanhong Wang <yanhong.wang@starfivetech.com>
+S: Maintained
+F: arch/riscv/include/asm/arch-jh7110/
+F: board/starfive/visionfive2/
+F: include/configs/starfive-visionfive2.h
+F: configs/starfive_visionfive2_defconfig
diff --git a/board/starfive/visionfive/Makefile b/board/starfive/visionfive2/Makefile
index 841d5d9b2d..080eed87b2 100644
--- a/board/starfive/visionfive/Makefile
+++ b/board/starfive/visionfive2/Makefile
@@ -3,7 +3,7 @@
# Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
#
-obj-y := starfive_visionfive.o
+obj-y := starfive_visionfive2.o
obj-$(CONFIG_SPL_BUILD) += spl.o
-
+obj-$(CONFIG_ID_EEPROM) += visionfive2-i2c-eeprom.o
diff --git a/board/starfive/visionfive2/spl.c b/board/starfive/visionfive2/spl.c
new file mode 100644
index 0000000000..2149fc519f
--- /dev/null
+++ b/board/starfive/visionfive2/spl.c
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2022 Starfive, Inc.
+ * Author: yanhong <yanhong.wang@starfivetech.com>
+ *
+ */
+
+#include <common.h>
+#include <init.h>
+#include <asm/arch/spl.h>
+#include <asm/io.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/jh7110-regs.h>
+#include <asm/arch/clk.h>
+#include <image.h>
+#include <log.h>
+#include <spl.h>
+
+#define MODE_SELECT_REG 0x1702002c
+
+int spl_board_init_f(void)
+{
+ int ret;
+
+ ret = spl_soc_init();
+ if (ret) {
+ debug("JH7110 SPL init failed: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+u32 spl_boot_device(void)
+{
+ int boot_mode = 0;
+
+ boot_mode = readl((const volatile void *)MODE_SELECT_REG) & 0x3;
+ switch (boot_mode) {
+ case 0:
+ return BOOT_DEVICE_SPI;
+ case 1:
+ return BOOT_DEVICE_MMC2;
+ case 2:
+ return BOOT_DEVICE_MMC1;
+ case 3:
+ return BOOT_DEVICE_UART;
+ default:
+ debug("Unsupported boot device 0x%x.\n",
+ boot_mode);
+ return BOOT_DEVICE_NONE;
+ }
+}
+
+struct image_header *spl_get_load_buffer(ssize_t offset, size_t size)
+{
+ return (struct image_header *)(STARFIVE_SPL_BOOT_LOAD_ADDR);
+}
+
+void board_init_f(ulong dummy)
+{
+ int ret;
+
+ /* Set pll0 cpufreq to 1000M */
+ starfive_jh7110_pll_set_rate(PLL0, 1000000000);
+
+ /*change pll2 to 1188MHz*/
+ starfive_jh7110_pll_set_rate(PLL2, 1188000000);
+
+ /*DDR control depend clk init*/
+ clrsetbits_le32(SYS_CRG_BASE, CLK_CPU_ROOT_SW_MASK,
+ BIT(CLK_CPU_ROOT_SW_SHIFT) & CLK_CPU_ROOT_SW_MASK);
+
+ clrsetbits_le32(SYS_CRG_BASE + CLK_BUS_ROOT_OFFSET,
+ CLK_BUS_ROOT_SW_MASK,
+ BIT(CLK_BUS_ROOT_SW_SHIFT) & CLK_BUS_ROOT_SW_MASK);
+
+ /*Set clk_perh_root clk default mux sel to pll2*/
+ clrsetbits_le32(SYS_CRG_BASE + CLK_PERH_ROOT_OFFSET,
+ CLK_PERH_ROOT_MASK,
+ BIT(CLK_PERH_ROOT_SHIFT) & CLK_PERH_ROOT_MASK);
+
+ clrsetbits_le32(SYS_CRG_BASE + CLK_NOC_BUS_STG_AXI_OFFSET,
+ CLK_NOC_BUS_STG_AXI_EN_MASK,
+ BIT(CLK_NOC_BUS_STG_AXI_EN_SHIFT)
+ & CLK_NOC_BUS_STG_AXI_EN_MASK);
+
+ clrsetbits_le32(AON_CRG_BASE + CLK_AON_APB_FUNC_OFFSET,
+ CLK_AON_APB_FUNC_SW_MASK,
+ BIT(CLK_AON_APB_FUNC_SW_SHIFT) & CLK_AON_APB_FUNC_SW_MASK);
+
+ clrsetbits_le32(SYS_CRG_BASE + CLK_QSPI_REF_OFFSET,
+ CLK_QSPI_REF_SW_MASK,
+ (1 << CLK_QSPI_REF_SW_SHIFT) & CLK_QSPI_REF_SW_MASK);
+
+ /* Improved GMAC0 TX I/O PAD capability */
+ clrsetbits_le32(AON_IOMUX_BASE + 0x78, 0x3, BIT(0) & 0x3);
+ clrsetbits_le32(AON_IOMUX_BASE + 0x7c, 0x3, BIT(0) & 0x3);
+ clrsetbits_le32(AON_IOMUX_BASE + 0x80, 0x3, BIT(0) & 0x3);
+ clrsetbits_le32(AON_IOMUX_BASE + 0x84, 0x3, BIT(0) & 0x3);
+ clrsetbits_le32(AON_IOMUX_BASE + 0x88, 0x3, BIT(0) & 0x3);
+
+ /* Improved GMAC1 TX I/O PAD capability */
+ clrsetbits_le32(SYS_IOMUX_BASE + 0x26c, 0x3, BIT(0) & 0x3);
+ clrsetbits_le32(SYS_IOMUX_BASE + 0x270, 0x3, BIT(0) & 0x3);
+ clrsetbits_le32(SYS_IOMUX_BASE + 0x274, 0x3, BIT(0) & 0x3);
+ clrsetbits_le32(SYS_IOMUX_BASE + 0x278, 0x3, BIT(0) & 0x3);
+ clrsetbits_le32(SYS_IOMUX_BASE + 0x27c, 0x3, BIT(0) & 0x3);
+
+ /*set GPIO to 3.3v*/
+ setbits_le32(SYS_SYSCON_BASE + 0xC, 0x0);
+
+ /*uart0 tx*/
+ SYS_IOMUX_DOEN(5, LOW);
+ SYS_IOMUX_DOUT(5, 20);
+ /*uart0 rx*/
+ SYS_IOMUX_DOEN(6, HIGH);
+ SYS_IOMUX_DIN(6, 14);
+
+ /*jtag*/
+ SYS_IOMUX_DOEN(36, HIGH);
+ SYS_IOMUX_DIN(36, 4);
+ SYS_IOMUX_DOEN(61, HIGH);
+ SYS_IOMUX_DIN(61, 19);
+ SYS_IOMUX_DOEN(63, HIGH);
+ SYS_IOMUX_DIN(63, 20);
+ SYS_IOMUX_DOEN(60, HIGH);
+ SYS_IOMUX_DIN(60, 29);
+ SYS_IOMUX_DOEN(44, 8);
+ SYS_IOMUX_DOUT(44, 22);
+
+ /* reset emmc */
+ SYS_IOMUX_DOEN(62, LOW);
+ SYS_IOMUX_DOUT(62, 19);
+ SYS_IOMUX_SET_DS(64, 2);
+ SYS_IOMUX_SET_SLEW(64, 1);
+ SYS_IOMUX_SET_DS(65, 1);
+ SYS_IOMUX_SET_DS(66, 1);
+ SYS_IOMUX_SET_DS(67, 1);
+ SYS_IOMUX_SET_DS(68, 1);
+ SYS_IOMUX_SET_DS(69, 1);
+ SYS_IOMUX_SET_DS(70, 1);
+ SYS_IOMUX_SET_DS(71, 1);
+ SYS_IOMUX_SET_DS(72, 1);
+ SYS_IOMUX_SET_DS(73, 1);
+ /* reset sdio */
+ SYS_IOMUX_DOEN(10, LOW);
+ SYS_IOMUX_DOUT(10, 55);
+ SYS_IOMUX_SET_DS(10, 2);
+ SYS_IOMUX_SET_SLEW(10, 1);
+ SYS_IOMUX_COMPLEX(9, 44, 57, 19);
+ SYS_IOMUX_SET_DS(9, 1);
+ SYS_IOMUX_COMPLEX(11, 45, 58, 20);
+ SYS_IOMUX_SET_DS(11, 1);
+ SYS_IOMUX_COMPLEX(12, 46, 59, 21);
+ SYS_IOMUX_SET_DS(12, 1);
+ SYS_IOMUX_COMPLEX(7, 47, 60, 22);
+ SYS_IOMUX_SET_DS(7, 1);
+ SYS_IOMUX_COMPLEX(8, 48, 61, 23);
+ SYS_IOMUX_SET_DS(8, 1);
+
+ /*i2c5*/
+ SYS_IOMUX_COMPLEX(19, 79, 0, 42);//scl
+ SYS_IOMUX_COMPLEX(20, 80, 0, 43);//sda
+
+ ret = spl_early_init();
+ if (ret)
+ panic("spl_early_init() failed: %d\n", ret);
+
+ arch_cpu_init_dm();
+
+ preloader_console_init();
+
+ ret = spl_board_init_f();
+ if (ret) {
+ debug("spl_board_init_f init failed: %d\n", ret);
+ return;
+ }
+}
+
+#ifdef CONFIG_SPL_LOAD_FIT
+int board_fit_config_name_match(const char *name)
+{
+ /* boot using first FIT config */
+ return 0;
+}
+#endif
+
+
diff --git a/board/starfive/visionfive2/starfive_visionfive2.c b/board/starfive/visionfive2/starfive_visionfive2.c
new file mode 100644
index 0000000000..1d14c618dc
--- /dev/null
+++ b/board/starfive/visionfive2/starfive_visionfive2.c
@@ -0,0 +1,547 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2022 Starfive, Inc.
+ * Author: yanhong <yanhong.wang@starfivetech.com>
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/eeprom.h>
+#include <asm/arch/jh7110-regs.h>
+#include <cpu_func.h>
+#include <dm/uclass.h>
+#include <dm/device.h>
+#include <env.h>
+#include <inttypes.h>
+#include <misc.h>
+#include <linux/bitops.h>
+#include <asm/arch/gpio.h>
+#include <bmp_logo.h>
+#include <video.h>
+#include <splash.h>
+
+#define SYS_CLOCK_ENABLE(clk) \
+ setbits_le32(SYS_CRG_BASE + clk, CLK_ENABLE_MASK)
+
+#define PCB_REVISION_MASK 0xF0
+#define PCB_REVISION_SHIFT 4
+#define PCB_REVISION_A 0x0A
+#define PCB_REVISION_B 0x0B
+#define CHIP_REVISION_SHIFT 80
+
+#define CPU_VOL_BINNING_OFFSET 0x7fc
+
+enum {
+ BOOT_FLASH = 0,
+ BOOT_SD,
+ BOOT_EMMC,
+ BOOT_UART,
+};
+
+enum chip_type_t {
+ CHIP_A = 0,
+ CHIP_B,
+ CHIP_MAX,
+};
+
+enum board_type_t {
+ BOARD_1000M_1000M = 0,
+ BOARD_1000M_100M,
+ BOARD_TYPE_MAX,
+};
+
+
+enum cpu_voltage_type_t {
+ CPU_VOL_1020 = 0xef0,
+ CPU_VOL_1040 = 0xfff,
+ CPU_VOL_1060 = 0xff0,
+ CPU_VOL_1000 = 0x8f0,
+};
+#define CPU_VOL_MASK 0xfff
+
+static void sys_reset_clear(ulong assert, ulong status, u32 rst)
+{
+ u32 value;
+
+ clrbits_le32(SYS_CRG_BASE + assert, BIT(rst));
+ do {
+ value = in_le32(SYS_CRG_BASE + status);
+ } while ((value & BIT(rst)) != BIT(rst));
+}
+
+static void jh7110_timer_init(void)
+{
+ SYS_CLOCK_ENABLE(TIMER_CLK_APB_SHIFT);
+ SYS_CLOCK_ENABLE(TIMER_CLK_TIMER0_SHIFT);
+ SYS_CLOCK_ENABLE(TIMER_CLK_TIMER1_SHIFT);
+ SYS_CLOCK_ENABLE(TIMER_CLK_TIMER2_SHIFT);
+ SYS_CLOCK_ENABLE(TIMER_CLK_TIMER3_SHIFT);
+
+ sys_reset_clear(SYS_CRG_RESET_ASSERT3_SHIFT,
+ SYS_CRG_RESET_STATUS3_SHIFT, TIMER_RSTN_APB_SHIFT);
+ sys_reset_clear(SYS_CRG_RESET_ASSERT3_SHIFT,
+ SYS_CRG_RESET_STATUS3_SHIFT, TIMER_RSTN_TIMER0_SHIFT);
+ sys_reset_clear(SYS_CRG_RESET_ASSERT3_SHIFT,
+ SYS_CRG_RESET_STATUS3_SHIFT, TIMER_RSTN_TIMER1_SHIFT);
+ sys_reset_clear(SYS_CRG_RESET_ASSERT3_SHIFT,
+ SYS_CRG_RESET_STATUS3_SHIFT, TIMER_RSTN_TIMER2_SHIFT);
+ sys_reset_clear(SYS_CRG_RESET_ASSERT3_SHIFT,
+ SYS_CRG_RESET_STATUS3_SHIFT, TIMER_RSTN_TIMER3_SHIFT);
+}
+
+static void jh7110_gmac_init_1000M(int id)
+{
+ switch (id) {
+ case 0:
+ clrsetbits_le32(AON_SYSCON_BASE + AON_SYSCFG_12,
+ GMAC5_0_SEL_I_MASK,
+ BIT(GMAC5_0_SEL_I_SHIFT) & GMAC5_0_SEL_I_MASK);
+ break;
+
+ case 1:
+ clrsetbits_le32(SYS_SYSCON_BASE + SYS_SYSCON_144,
+ GMAC5_1_SEL_I_MASK,
+ BIT(GMAC5_1_SEL_I_SHIFT) & GMAC5_1_SEL_I_MASK);
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void jh7110_gmac_init_100M(int id)
+{
+ switch (id) {
+ case 0:
+ clrsetbits_le32(AON_SYSCON_BASE + AON_SYSCFG_12,
+ GMAC5_0_SEL_I_MASK,
+ (4 << GMAC5_0_SEL_I_SHIFT) & GMAC5_0_SEL_I_MASK);
+ setbits_le32(AON_CRG_BASE + GMAC5_0_CLK_TX_SHIFT, 0x1000000);
+ setbits_le32(AON_CRG_BASE + GMAC5_0_CLK_RX_SHIFT, 0x1000000);
+ break;
+
+ case 1:
+ clrsetbits_le32(SYS_SYSCON_BASE + SYS_SYSCON_144,
+ GMAC5_1_SEL_I_MASK,
+ (4 << GMAC5_1_SEL_I_SHIFT) & GMAC5_1_SEL_I_MASK);
+ setbits_le32(SYS_CRG_BASE + GMAC5_1_CLK_TX_SHIFT, 0x1000000);
+ setbits_le32(SYS_CRG_BASE + GMAC5_1_CLK_RX_SHIFT, 0x1000000);
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void jh7110_gmac_sel_tx_to_rgmii(int id)
+{
+ switch (id) {
+ case 0:
+ clrsetbits_le32(AON_CRG_BASE + GMAC5_0_CLK_TX_SHIFT,
+ GMAC5_0_CLK_TX_MASK,
+ BIT(GMAC5_0_CLK_TX_BIT) & GMAC5_0_CLK_TX_MASK);
+ break;
+
+ case 1:
+ clrsetbits_le32(SYS_CRG_BASE + GMAC5_1_CLK_TX_SHIFT,
+ GMAC5_1_CLK_TX_MASK,
+ BIT(GMAC5_1_CLK_TX_BIT) & GMAC5_1_CLK_TX_MASK);
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void set_uboot_fdt_addr_env(void)
+{
+ char str[17];
+ ulong fdt_addr = (ulong)gd->fdt_blob;
+
+ sprintf(str, "0x%lx", fdt_addr);
+ env_set("uboot_fdt_addr", str);
+}
+
+static int get_chip_type(void)
+{
+ int type;
+ int len = -1;
+ u8 data;
+
+ len = get_data_from_eeprom(CHIP_REVISION_SHIFT, 1, &data);
+ if (len <= 0) {
+ env_set("chip_vision", "UNKOWN");
+ return -EINVAL;
+ }
+
+ switch (data) {
+ case 'a':
+ case 'A':
+ type = CHIP_A;
+ env_set("chip_vision", "A");
+ break;
+ case 'b':
+ case 'B':
+ type = CHIP_B;
+ env_set("chip_vision", "B");
+ break;
+ default:
+ type = CHIP_MAX;
+ env_set("chip_vision", "UNKOWN");
+ break;
+ }
+ return type;
+}
+static int get_board_type(void)
+{
+ u8 pv;
+ int type;
+
+ pv = get_pcb_revision_from_eeprom();
+ pv = (pv & PCB_REVISION_MASK) >> PCB_REVISION_SHIFT;
+
+ if (pv == PCB_REVISION_A) {
+ type = BOARD_1000M_100M;
+ } else if (pv == PCB_REVISION_B) {
+ type = BOARD_1000M_1000M;
+ } else {
+ type = BOARD_TYPE_MAX;
+ }
+
+ return type;
+}
+
+static void jh7110_gmac_init(int chip_type, int pcb_type)
+{
+ switch (chip_type) {
+ case CHIP_A:
+ break;
+ case CHIP_B:
+ default:
+ jh7110_gmac_sel_tx_to_rgmii(0);
+ jh7110_gmac_sel_tx_to_rgmii(1);
+ break;
+ }
+
+ switch (pcb_type) {
+ case BOARD_1000M_100M:
+ jh7110_gmac_init_1000M(0);
+ jh7110_gmac_init_100M(1);
+ break;
+
+ case BOARD_1000M_1000M:
+ default:
+ jh7110_gmac_init_1000M(0);
+ jh7110_gmac_init_1000M(1);
+ break;
+ }
+}
+
+static void jh7110_usb_init(bool usb2_enable)
+{
+ if (usb2_enable) {
+ /*usb 2.0 utmi phy init*/
+ clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_4,
+ USB_MODE_STRAP_MASK,
+ (2<<USB_MODE_STRAP_SHIFT) &
+ USB_MODE_STRAP_MASK);/*2:host mode, 4:device mode*/
+ clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_4,
+ USB_OTG_SUSPENDM_BYPS_MASK,
+ BIT(USB_OTG_SUSPENDM_BYPS_SHIFT)
+ & USB_OTG_SUSPENDM_BYPS_MASK);
+ clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_4,
+ USB_OTG_SUSPENDM_MASK,
+ BIT(USB_OTG_SUSPENDM_SHIFT) &
+ USB_OTG_SUSPENDM_MASK);/*HOST = 1. DEVICE = 0;*/
+ clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_4,
+ USB_PLL_EN_MASK,
+ BIT(USB_PLL_EN_SHIFT) & USB_PLL_EN_MASK);
+ clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_4,
+ USB_REFCLK_MODE_MASK,
+ BIT(USB_REFCLK_MODE_SHIFT) & USB_REFCLK_MODE_MASK);
+ /* usb 2.0 phy mode,REPLACE USB3.0 PHY module = 1;else = 0*/
+ clrsetbits_le32(SYS_SYSCON_BASE + SYS_SYSCON_24,
+ PDRSTN_SPLIT_MASK,
+ BIT(PDRSTN_SPLIT_SHIFT) &
+ PDRSTN_SPLIT_MASK);
+ } else {
+ /*usb 3.0 pipe phy config*/
+ clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_196,
+ PCIE_CKREF_SRC_MASK,
+ (0<<PCIE_CKREF_SRC_SHIFT) & PCIE_CKREF_SRC_MASK);
+ clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_196,
+ PCIE_CLK_SEL_MASK,
+ (0<<PCIE_CLK_SEL_SHIFT) & PCIE_CLK_SEL_MASK);
+ clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_328,
+ PCIE_PHY_MODE_MASK,
+ BIT(PCIE_PHY_MODE_SHIFT) & PCIE_PHY_MODE_MASK);
+ clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_500,
+ PCIE_USB3_BUS_WIDTH_MASK,
+ (0 << PCIE_USB3_BUS_WIDTH_SHIFT) &
+ PCIE_USB3_BUS_WIDTH_MASK);
+ clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_500,
+ PCIE_USB3_RATE_MASK,
+ (0 << PCIE_USB3_RATE_SHIFT) & PCIE_USB3_RATE_MASK);
+ clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_500,
+ PCIE_USB3_RX_STANDBY_MASK,
+ (0 << PCIE_USB3_RX_STANDBY_SHIFT)
+ & PCIE_USB3_RX_STANDBY_MASK);
+ clrsetbits_le32(STG_SYSCON_BASE + STG_SYSCON_500,
+ PCIE_USB3_PHY_ENABLE_MASK,
+ BIT(PCIE_USB3_PHY_ENABLE_SHIFT)
+ & PCIE_USB3_PHY_ENABLE_MASK);
+
+ /* usb 3.0 phy mode,REPLACE USB3.0 PHY module = 1;else = 0*/
+ clrsetbits_le32(SYS_SYSCON_BASE + SYS_SYSCON_24,
+ PDRSTN_SPLIT_MASK,
+ (0 << PDRSTN_SPLIT_SHIFT) & PDRSTN_SPLIT_MASK);
+ }
+ SYS_IOMUX_DOEN(25, LOW);
+ SYS_IOMUX_DOUT(25, 7);
+}
+
+#if CONFIG_IS_ENABLED(STARFIVE_OTP)
+static void get_cpu_voltage_type(struct udevice *dev)
+{
+ int ret;
+ u32 buf = CPU_VOL_1040;
+
+ ret = misc_read(dev, CPU_VOL_BINNING_OFFSET, &buf, sizeof(buf));
+ if (ret != sizeof(buf))
+ printf("%s: error reading CPU vol from OTP\n", __func__);
+ else {
+ switch ((buf & CPU_VOL_MASK)) {
+ case CPU_VOL_1000:
+ env_set("cpu_max_vol", "1000000");
+ break;
+ case CPU_VOL_1060:
+ env_set("cpu_max_vol", "1060000");
+ break;
+ case CPU_VOL_1020:
+ env_set("cpu_max_vol", "1020000");
+ break;
+ default:
+ env_set("cpu_max_vol", "1040000");
+ break;
+ }
+ }
+}
+#endif
+
+static void jh7110_jtag_init(void)
+{
+ /*jtag*/
+ SYS_IOMUX_DOEN(36, HIGH);
+ SYS_IOMUX_DIN(36, 4);
+ SYS_IOMUX_DOEN(61, HIGH);
+ SYS_IOMUX_DIN(61, 19);
+ SYS_IOMUX_DOEN(63, HIGH);
+ SYS_IOMUX_DIN(63, 20);
+ SYS_IOMUX_DOEN(60, HIGH);
+ SYS_IOMUX_DIN(60, 29);
+ SYS_IOMUX_DOEN(44, 8);
+ SYS_IOMUX_DOUT(44, 22);
+}
+
+static void jh7110_i2c_init(int id)
+{
+ switch (id) {
+ case 5:
+ //scl
+ SYS_IOMUX_COMPLEX(19, 79, 0, 42);
+ //sda
+ SYS_IOMUX_COMPLEX(20, 80, 0, 43);
+
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void get_boot_mode(void)
+{
+ u32 value;
+
+ value = in_le32(AON_IOMUX_BASE + AON_GPIO_DIN_REG);
+ switch (value & 0x03) {
+ case BOOT_FLASH:
+ env_set("bootmode", "flash");
+ env_set("devnum", "1");
+ break;
+
+ case BOOT_SD:
+ env_set("bootmode", "sd");
+ env_set("devnum", "1");
+ break;
+
+ case BOOT_EMMC:
+ env_set("bootmode", "emmc");
+ env_set("devnum", "0");
+ break;
+
+ default:
+ env_set("bootmode", "uart");
+ env_set("devnum", "1");
+ break;
+ }
+}
+
+static void jh7110_gpio_init(void)
+{
+ /* This is for fixing don't detect wm8960 occasionally.
+ * Set scl/sda gpio output enable
+ * Set drive strength to 12mA
+ * Set gpio pull up
+ */
+ SYS_IOMUX_COMPLEX(57, 9, 0, 1);
+ SYS_IOMUX_SET_DS(57, 3);
+ SYS_IOMUX_SET_PULL(57, GPIO_PULL_UP);
+
+ SYS_IOMUX_COMPLEX(58, 10, 0, 1);
+ SYS_IOMUX_SET_DS(58, 3);
+ SYS_IOMUX_SET_PULL(58, GPIO_PULL_UP);
+}
+
+int board_init(void)
+{
+ enable_caches();
+
+ jh7110_jtag_init();
+ jh7110_timer_init();
+
+ jh7110_usb_init(true);
+
+ jh7110_i2c_init(5);
+ jh7110_gpio_init();
+
+ return 0;
+}
+
+#ifdef CONFIG_BOARD_LATE_INIT
+int board_late_init(void)
+{
+ struct udevice *dev;
+ int ret;
+
+ get_boot_mode();
+
+ jh7110_gmac_init(get_chip_type(), get_board_type());
+ /*
+ * save the memory info by environment variable in u-boot,
+ * It will used to update the memory configuration in dts,
+ * which passed to kernel lately.
+ */
+ env_set_hex("memory_addr", gd->ram_base);
+ env_set_hex("memory_size", gd->ram_size);
+
+ ret = uclass_get_device(UCLASS_VIDEO, 0, &dev);
+ if (ret)
+ return ret;
+
+ ret = video_bmp_display(dev, (ulong)&bmp_logo_bitmap[0], BMP_ALIGN_CENTER, BMP_ALIGN_CENTER, true);
+ if (ret)
+ goto err;
+
+err:
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_MISC_INIT_R
+
+int misc_init_r(void)
+{
+ char mac0[6] = {0x6c, 0xcf, 0x39, 0x6c, 0xde, 0xad};
+ char mac1[6] = {0x6c, 0xcf, 0x39, 0x7c, 0xae, 0x5d};
+
+#if CONFIG_IS_ENABLED(STARFIVE_OTP)
+ struct udevice *dev;
+ char buf[16];
+ int ret;
+#define MACADDR_OFFSET 0x8
+
+ ret = uclass_get_device_by_driver(UCLASS_MISC,
+ DM_DRIVER_GET(starfive_otp), &dev);
+ if (ret) {
+ debug("%s: could not find otp device\n", __func__);
+ goto err;
+ }
+
+ ret = misc_read(dev, MACADDR_OFFSET, buf, sizeof(buf));
+ if (ret != sizeof(buf))
+ printf("%s: error reading mac from OTP\n", __func__);
+ else
+ if (buf[0] != 0xff) {
+ memcpy(mac0, buf, 6);
+ memcpy(mac1, &buf[8], 6);
+ }
+err:
+#endif
+ eth_env_set_enetaddr("eth0addr", mac0);
+ eth_env_set_enetaddr("eth1addr", mac1);
+
+ get_chip_type();
+ set_uboot_fdt_addr_env();
+#if CONFIG_IS_ENABLED(STARFIVE_OTP)
+ get_cpu_voltage_type(dev);
+#endif
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_ID_EEPROM
+
+#include <asm/arch/eeprom.h>
+#define STARFIVE_JH7110_EEPROM_DDRINFO_OFFSET 91
+
+static bool check_eeprom_dram_info(ulong size)
+{
+ switch (size) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ case 16:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static int resize_ddr_from_eeprom(void)
+{
+ struct udevice *dev;
+ ulong size;
+ u32 len = 1;
+ u8 data = 0;
+ int ret;
+
+ /* I2C init */
+ ret = uclass_get_device(UCLASS_I2C, 0, &dev);
+ if (ret) {
+ debug("I2C init failed: %d\n", ret);
+ return 0;
+ }
+
+ /* read memory size info */
+ ret = get_data_from_eeprom(STARFIVE_JH7110_EEPROM_DDRINFO_OFFSET, len, &data);
+ if (ret == len) {
+ size = hextoul(&data, NULL);
+ if (check_eeprom_dram_info(size))
+ return size;
+ }
+ return 0;
+}
+#else
+static int resize_ddr_from_eeprom(void)
+{
+ return 0;
+}
+#endif /* CONFIG_ID_EEPROM */
+
+int board_ddr_size(void)
+{
+ return resize_ddr_from_eeprom();
+}
diff --git a/board/starfive/visionfive2/visionfive2-i2c-eeprom.c b/board/starfive/visionfive2/visionfive2-i2c-eeprom.c
new file mode 100644
index 0000000000..5f2e698ad9
--- /dev/null
+++ b/board/starfive/visionfive2/visionfive2-i2c-eeprom.c
@@ -0,0 +1,832 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
+ * Written by Wei Fu (wefu@redhat.com)
+ */
+
+
+#include <common.h>
+#include <command.h>
+#include <env.h>
+#include <i2c.h>
+#include <init.h>
+#include <linux/ctype.h>
+#include <linux/delay.h>
+
+#define CONFIG_SYS_EEPROM_BUS_NUM 0
+
+#define FORMAT_VERSION 0x2
+#define PCB_VERSION 0xB1
+#define BOM_VERSION 'A'
+/*
+ * BYTES_PER_EEPROM_PAGE: the 24FC04H datasheet says that data can
+ * only be written in page mode, which means 16 bytes at a time:
+ * 16-Byte Page Write Buffer
+ */
+#define BYTES_PER_EEPROM_PAGE 16
+
+/*
+ * EEPROM_WRITE_DELAY_MS: the 24FC04H datasheet says it takes up to
+ * 5ms to complete a given write:
+ * Write Cycle Time (byte or page) ro Page Write Time 5 ms, Maximum
+ */
+#define EEPROM_WRITE_DELAY_MS 5000
+/*
+ * StarFive OUI. Registration Date is 20xx-xx-xx
+ */
+#define STARFIVE_OUI_PREFIX "6C:CF:39:"
+#define STARFIVE_DEFAULT_MAC0 {0x6c, 0xcf, 0x39, 0x6c, 0xde, 0xad}
+#define STARFIVE_DEFAULT_MAC1 {0x6c, 0xcf, 0x39, 0x7c, 0xae, 0x5d}
+
+/* Magic number at the first four bytes of EEPROM HATs */
+#define STARFIVE_EEPROM_HATS_SIG "SFVF" /* StarFive VisionFive */
+
+#define STARFIVE_EEPROM_HATS_SIZE_MAX 256 /* Header + Atom1&4(v1) */
+#define STARFIVE_EEPROM_WP_OFFSET 0 /* Read only field */
+#define STARFIVE_EEPROM_ATOM1_PSTR "VF7110A1-2228-D008E000-00000001\0"
+#define STARFIVE_EEPROM_ATOM1_PSTR_SIZE 32
+#define STARFIVE_EEPROM_ATOM1_SN_OFFSET 23
+#define STARFIVE_EEPROM_ATOM1_VSTR "StarFive Technology Co., Ltd.\0\0\0"
+#define STARFIVE_EEPROM_ATOM1_VSTR_SIZE 32
+
+/*
+ * MAGIC_NUMBER_BYTES: number of bytes used by the magic number
+ */
+#define MAGIC_NUMBER_BYTES 4
+
+/*
+ * MAC_ADDR_BYTES: number of bytes used by the Ethernet MAC address
+ */
+#define MAC_ADDR_BYTES 6
+
+/*
+ * MAC_ADDR_STRLEN: length of mac address string
+ */
+#define MAC_ADDR_STRLEN 17
+
+/*
+ * Atom Types
+ * 0x0000 = invalid
+ * 0x0001 = vendor info
+ * 0x0002 = GPIO map
+ * 0x0003 = Linux device tree blob
+ * 0x0004 = manufacturer custom data
+ * 0x0005-0xfffe = reserved for future use
+ * 0xffff = invalid
+ */
+
+#define HATS_ATOM_INVALID 0x0000
+#define HATS_ATOM_VENDOR 0x0001
+#define HATS_ATOM_GPIO 0x0002
+#define HATS_ATOM_DTB 0x0003
+#define HATS_ATOM_CUSTOM 0x0004
+#define HATS_ATOM_INVALID_END 0xffff
+
+struct eeprom_hats_header {
+ char signature[MAGIC_NUMBER_BYTES]; /* ASCII table signature */
+ u8 version; /* EEPROM data format version */
+ /* (0x00 reserved, 0x01 = first version) */
+ u8 reversed; /* 0x00, Reserved field */
+ u16 numatoms; /* total atoms in EEPROM */
+ u32 eeplen; /* total length in bytes of all eeprom data */
+ /* (including this header) */
+};
+
+struct eeprom_hats_atom_header {
+ u16 type;
+ u16 count;
+ u32 dlen;
+};
+
+/**
+ * static eeprom: EEPROM layout for the StarFive platform I2C format
+ */
+struct starfive_eeprom_atom1_data {
+ u8 uuid[16];
+ u16 pid;
+ u16 pver;
+ u8 vslen;
+ u8 pslen;
+ uchar vstr[STARFIVE_EEPROM_ATOM1_VSTR_SIZE];
+ uchar pstr[STARFIVE_EEPROM_ATOM1_PSTR_SIZE]; /* product SN */
+};
+
+struct starfive_eeprom_atom1 {
+ struct eeprom_hats_atom_header header;
+ struct starfive_eeprom_atom1_data data;
+ u16 crc16;
+};
+
+struct starfive_eeprom_atom4_v1_data {
+ u16 version;
+ u8 pcb_revision; /* PCB version */
+ u8 bom_revision; /* BOM version */
+ u8 mac0_addr[MAC_ADDR_BYTES]; /* Ethernet0 MAC */
+ u8 mac1_addr[MAC_ADDR_BYTES]; /* Ethernet1 MAC */
+ u8 reserved[2];
+};
+
+struct starfive_eeprom_atom4_v1 {
+ struct eeprom_hats_atom_header header;
+ struct starfive_eeprom_atom4_v1_data data;
+ u16 crc16;
+};
+
+/* Set to 1 if we've read EEPROM into memory
+ * Set to -1 if EEPROM data is wrong
+ */
+static int has_been_read;
+
+/**
+ * helper struct for getting info from the local EEPROM copy.
+ * most of the items are pointers to the eeprom_wp_buff.
+ * ONLY serialnum is the u32 from the last 8 Bytes of product string
+ */
+struct starfive_eeprom_info {
+ char *vstr; /* Vendor string in ATOM1 */
+ char *pstr; /* product string in ATOM1 */
+ u32 serialnum; /* serial number from in product string*/
+ u16 *version; /* custom data version in ATOM4 */
+ u8 *pcb_revision; /* PCB version in ATOM4 */
+ u8 *bom_revision; /* BOM version in ATOM4 */
+ u8 *mac0_addr; /* Ethernet0 MAC in ATOM4 */
+ u8 *mac1_addr; /* Ethernet1 MAC in ATOM4 */
+};
+static struct starfive_eeprom_info einfo;
+
+
+static uchar eeprom_wp_buff[STARFIVE_EEPROM_HATS_SIZE_MAX];
+static struct eeprom_hats_header starfive_eeprom_hats_header_default = {
+ .signature = STARFIVE_EEPROM_HATS_SIG,
+ .version = FORMAT_VERSION,
+ .numatoms = 2,
+ .eeplen = sizeof(struct eeprom_hats_header) +
+ sizeof(struct starfive_eeprom_atom1) +
+ sizeof(struct starfive_eeprom_atom4_v1)
+};
+static struct starfive_eeprom_atom1 starfive_eeprom_atom1_default = {
+ .header = {
+ .type = HATS_ATOM_VENDOR,
+ .count = 1,
+ .dlen = sizeof(struct starfive_eeprom_atom1_data) + sizeof(u16)
+ },
+ .data = {
+ .uuid = {0},
+ .pid = 0,
+ .pver = 0,
+ .vslen = STARFIVE_EEPROM_ATOM1_VSTR_SIZE,
+ .pslen = STARFIVE_EEPROM_ATOM1_PSTR_SIZE,
+ .vstr = STARFIVE_EEPROM_ATOM1_VSTR,
+ .pstr = STARFIVE_EEPROM_ATOM1_PSTR
+ }
+};
+static struct starfive_eeprom_atom4_v1 starfive_eeprom_atom4_v1_default = {
+ .header = {
+ .type = HATS_ATOM_CUSTOM,
+ .count = 2,
+ .dlen = sizeof(struct starfive_eeprom_atom4_v1_data) + sizeof(u16)
+ },
+ .data = {
+ .version = FORMAT_VERSION,
+ .pcb_revision = PCB_VERSION,
+ .bom_revision = BOM_VERSION,
+ .mac0_addr = STARFIVE_DEFAULT_MAC0,
+ .mac1_addr = STARFIVE_DEFAULT_MAC1,
+ .reserved = {0}
+ }
+};
+
+//static u8 starfive_default_mac[MAC_ADDR_BYTES] = STARFIVE_DEFAULT_MAC;
+
+/**
+ * is_match_magic() - Does the magic number match that of a StarFive EEPROM?
+ *
+ * @hats: the pointer of eeprom_hats_header
+ * Return: status code, 0: Yes, non-0: NO
+ */
+static inline int is_match_magic(char *hats)
+{
+ return strncmp(hats, STARFIVE_EEPROM_HATS_SIG, MAGIC_NUMBER_BYTES);
+}
+
+/**
+ * calculate_crc16() - Calculate the current CRC for atom
+ * Porting from https://github.com/raspberrypi/hats, getcrc
+ * @data: the pointer of eeprom_hats_atom_header
+ * @size: total length in bytes of the entire atom
+ * (type, count, dlen, data)
+ * Return: result: crc16 code
+ */
+#define CRC16 0x8005
+static u16 calculate_crc16(uchar* data, unsigned int size)
+{
+ int i, j = 0x0001;
+ u16 out = 0, crc = 0;
+ int bits_read = 0, bit_flag;
+
+ /* Sanity check: */
+ if((data == NULL) || size == 0)
+ return 0;
+
+ while(size > 0) {
+ bit_flag = out >> 15;
+
+ /* Get next bit: */
+ out <<= 1;
+ // item a) work from the least significant bits
+ out |= (*data >> bits_read) & 1;
+
+ /* Increment bit counter: */
+ bits_read++;
+ if(bits_read > 7) {
+ bits_read = 0;
+ data++;
+ size--;
+ }
+
+ /* Cycle check: */
+ if(bit_flag)
+ out ^= CRC16;
+ }
+
+ // item b) "push out" the last 16 bits
+ for (i = 0; i < 16; ++i) {
+ bit_flag = out >> 15;
+ out <<= 1;
+ if(bit_flag)
+ out ^= CRC16;
+ }
+
+ // item c) reverse the bits
+ for (i = 0x8000; i != 0; i >>=1, j <<= 1) {
+ if (i & out)
+ crc |= j;
+ }
+
+ return crc;
+}
+
+/* This function should be called after each update to any EEPROM ATOM */
+static inline void update_crc(struct eeprom_hats_atom_header *atom)
+{
+ uint atom_crc_offset = sizeof(struct eeprom_hats_atom_header) +
+ atom->dlen - sizeof(u16);
+ u16 *atom_crc_p = (void *) atom + atom_crc_offset;
+ *atom_crc_p = calculate_crc16((uchar*) atom, atom_crc_offset);
+}
+
+/**
+ * dump_raw_eeprom - display the raw contents of the EEPROM
+ */
+static void dump_raw_eeprom(u8 *e, unsigned int size)
+{
+ unsigned int i;
+
+ printf("EEPROM dump: (0x%x bytes)\n", size);
+
+ for (i = 0; i < size; i++) {
+ if (!(i % 0x10))
+ printf("%02X: ", i);
+
+ printf("%02X ", e[i]);
+
+ if (((i % 16) == 15) || (i == size - 1))
+ printf("\n");
+ }
+
+ return;
+}
+
+static int hats_atom_crc_check(struct eeprom_hats_atom_header *atom)
+{
+ u16 atom_crc, data_crc;
+ uint atom_crc_offset = sizeof(struct eeprom_hats_atom_header) +
+ atom->dlen - sizeof(atom_crc);
+ u16 *atom_crc_p = (void *) atom + atom_crc_offset;
+
+ atom_crc = *atom_crc_p;
+ data_crc = calculate_crc16((uchar *) atom, atom_crc_offset);
+ if (atom_crc == data_crc)
+ return 0;
+
+ printf("EEPROM HATs: CRC ERROR in atom %x type %x, (%x!=%x)\n",
+ atom->count, atom->type, atom_crc, data_crc);
+ return -1;
+}
+
+static void *hats_get_atom(struct eeprom_hats_header *header, u16 type)
+ {
+ struct eeprom_hats_atom_header *atom;
+ void *hats_eeprom_max = (void *)header + header->eeplen;
+ void *temp = (void *)header + sizeof(struct eeprom_hats_header);
+
+ for (int numatoms = (int)header->numatoms; numatoms > 0; numatoms--) {
+ atom = (struct eeprom_hats_atom_header *)temp;
+ if (hats_atom_crc_check(atom))
+ return NULL;
+ if (atom->type == type)
+ return (void *)atom;
+ /* go to next atom */
+ temp = (void *)atom + sizeof(struct eeprom_hats_atom_header) +
+ atom->dlen;
+ if (temp > hats_eeprom_max) {
+ printf("EEPROM HATs: table overflow next@%p, max@%p\n",
+ temp, hats_eeprom_max);
+ break;
+ }
+ }
+
+ /* fail to get atom */
+ return NULL;
+}
+
+/**
+ * show_eeprom - display the contents of the EEPROM
+ */
+static void show_eeprom(struct starfive_eeprom_info *einfo)
+{
+ if (has_been_read != 1)
+ return;
+
+ printf("\n--------EEPROM INFO--------\n");
+ printf("Vendor : %s\n", einfo->vstr);
+ printf("Product full SN: %s\n", einfo->pstr);
+ printf("data version: 0x%x\n", *einfo->version);
+ if (2 == *einfo->version) {
+ printf("PCB revision: 0x%x\n", *einfo->pcb_revision);
+ printf("BOM revision: %c\n", *einfo->bom_revision);
+ printf("Ethernet MAC0 address: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ einfo->mac0_addr[0], einfo->mac0_addr[1],
+ einfo->mac0_addr[2], einfo->mac0_addr[3],
+ einfo->mac0_addr[4], einfo->mac0_addr[5]);
+ printf("Ethernet MAC1 address: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ einfo->mac1_addr[0], einfo->mac1_addr[1],
+ einfo->mac1_addr[2], einfo->mac1_addr[3],
+ einfo->mac1_addr[4], einfo->mac1_addr[5]);
+ } else {
+ printf("Custom data v%d is not Supported\n", *einfo->version);
+ }
+ printf("--------EEPROM INFO--------\n\n");
+}
+
+/**
+ * parse_eeprom_info - parse the contents of the EEPROM
+ * If everthing gose right,
+ * 1, set has_been_read to 1
+ * 2, display info
+ *
+ * If anything goes wrong,
+ * 1, set has_been_read to -1
+ * 2, dump data by hex for debug
+ *
+ * @buf: the pointer of eeprom_hats_header in memory
+ * Return: status code, 0: Success, non-0: Fail
+ *
+ */
+static int parse_eeprom_info(struct eeprom_hats_header *buf)
+{
+ struct eeprom_hats_atom_header *atom;
+ void *atom_data;
+ struct starfive_eeprom_atom1_data *atom1 = NULL;
+ struct starfive_eeprom_atom4_v1_data *atom4_v1 = NULL;
+
+ if (is_match_magic((char *)buf)) {
+ printf("Not a StarFive EEPROM data format - magic error\n");
+ goto error;
+ };
+
+ // parse atom1(verdor)
+ atom = (struct eeprom_hats_atom_header *)
+ hats_get_atom(buf, HATS_ATOM_VENDOR);
+ if (atom) {
+ atom_data = (void *)atom +
+ sizeof(struct eeprom_hats_atom_header);
+ atom1 = (struct starfive_eeprom_atom1_data *)atom_data;
+ einfo.vstr = atom1->vstr;
+ einfo.pstr = atom1->pstr;
+ einfo.serialnum = (u32)hextoul((void *)atom1->pstr +
+ STARFIVE_EEPROM_ATOM1_SN_OFFSET,
+ NULL);
+ } else {
+ printf("fail to get vendor atom\n");
+ goto error;
+ };
+
+ // parse atom4(custom)
+ atom = (struct eeprom_hats_atom_header *)
+ hats_get_atom(buf, HATS_ATOM_CUSTOM);
+ if (atom) {
+ atom_data = (void *)atom +
+ sizeof(struct eeprom_hats_atom_header);
+ atom4_v1 = (struct starfive_eeprom_atom4_v1_data *)atom_data;
+ einfo.version = &atom4_v1->version;
+ if (*einfo.version == 2) {
+ einfo.pcb_revision = &atom4_v1->pcb_revision;
+ einfo.bom_revision = &atom4_v1->bom_revision;
+ einfo.mac0_addr = atom4_v1->mac0_addr;
+ einfo.mac1_addr = atom4_v1->mac1_addr;
+ }
+ } else {
+ printf("fail to get custom data atom\n");
+ goto error;
+ };
+
+ // everthing gose right
+ has_been_read = 1;
+
+ return 0;
+
+error:
+ has_been_read = -1;
+ return -1;
+}
+
+/**
+ * read_eeprom() - read the EEPROM into memory, if it hasn't been read yet
+ * @buf: the pointer of eeprom data buff
+ * Return: status code, 0: Success, non-0: Fail
+ * Note: depend on CONFIG_SYS_EEPROM_BUS_NUM
+ * CONFIG_SYS_I2C_EEPROM_ADDR
+ * STARFIVE_EEPROM_WP_OFFSET
+ * STARFIVE_EEPROM_HATS_SIZE_MAX
+ */
+static int read_eeprom(uint8_t *buf)
+{
+ int ret;
+ struct udevice *dev;
+
+ if (has_been_read == 1)
+ return 0;
+
+ ret = i2c_get_chip_for_busnum(CONFIG_SYS_EEPROM_BUS_NUM,
+ CONFIG_SYS_I2C_EEPROM_ADDR,
+ CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
+ &dev);
+ if (!ret) {
+ ret = dm_i2c_read(dev, STARFIVE_EEPROM_WP_OFFSET,
+ buf, STARFIVE_EEPROM_HATS_SIZE_MAX);
+ }
+
+ if (ret) {
+ printf("fail to read EEPROM.\n");
+ return ret;
+ }
+
+ return parse_eeprom_info((struct eeprom_hats_header *)buf);
+}
+
+/**
+ * prog_eeprom() - write the EEPROM from memory
+ */
+static int prog_eeprom(uint8_t *buf, unsigned int size)
+{
+ unsigned int i;
+ void *p;
+ uchar tmp_buff[STARFIVE_EEPROM_HATS_SIZE_MAX];
+ struct udevice *dev;
+ int ret = i2c_get_chip_for_busnum(CONFIG_SYS_EEPROM_BUS_NUM,
+ CONFIG_SYS_I2C_EEPROM_ADDR,
+ CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
+ &dev);
+
+ if (is_match_magic(buf)) {
+ printf("MAGIC ERROR, Please check the data@%p.\n", buf);
+ return -1;
+ }
+
+ for (i = 0, p = buf; i < size;
+ i += BYTES_PER_EEPROM_PAGE, p += BYTES_PER_EEPROM_PAGE) {
+ if (!ret)
+ ret = dm_i2c_write(dev,
+ i + STARFIVE_EEPROM_WP_OFFSET,
+ p, min((int)(size - i),
+ BYTES_PER_EEPROM_PAGE));
+ if (ret)
+ break;
+ udelay(EEPROM_WRITE_DELAY_MS);
+ }
+
+ if (!ret) {
+ /* Verify the write by reading back the EEPROM and comparing */
+ ret = dm_i2c_read(dev,
+ STARFIVE_EEPROM_WP_OFFSET,
+ tmp_buff,
+ STARFIVE_EEPROM_HATS_SIZE_MAX);
+ if (!ret && memcmp((void *)buf, (void *)tmp_buff,
+ STARFIVE_EEPROM_HATS_SIZE_MAX))
+ ret = -1;
+ }
+
+ if (ret) {
+ has_been_read = -1;
+ printf("Programming failed.Temp buff:\n");
+ dump_raw_eeprom(tmp_buff,
+ STARFIVE_EEPROM_HATS_SIZE_MAX);
+ return -1;
+ }
+
+ printf("Programming passed.\n");
+ return 0;
+}
+
+/**
+ * set_mac_address() - stores a MAC address into the local EEPROM copy
+ *
+ * This function takes a pointer to MAC address string
+ * (i.e."XX:XX:XX:XX:XX:XX", where "XX" is a two-digit hex number),
+ * stores it in the MAC address field of the EEPROM local copy, and
+ * updates the local copy of the CRC.
+ */
+static void set_mac_address(char *string, int index)
+{
+ unsigned int i;
+ struct eeprom_hats_atom_header *atom4;
+ atom4 = (struct eeprom_hats_atom_header *)
+ hats_get_atom((struct eeprom_hats_header *)eeprom_wp_buff,
+ HATS_ATOM_CUSTOM);
+
+ if (strncasecmp(STARFIVE_OUI_PREFIX, string,
+ strlen(STARFIVE_OUI_PREFIX))) {
+ printf("The MAC address doesn't match StarFive OUI %s\n",
+ STARFIVE_OUI_PREFIX);
+ return;
+ }
+
+ for (i = 0; *string && (i < MAC_ADDR_BYTES); i++) {
+ if (index == 0) {
+ einfo.mac0_addr[i] = hextoul(string, &string);
+ } else {
+ einfo.mac1_addr[i] = hextoul(string, &string);
+ }
+ if (*string == ':')
+ string++;
+ }
+
+ update_crc(atom4);
+}
+
+/**
+ * set_pcb_revision() - stores a StarFive PCB revision into the local EEPROM copy
+ *
+ * Takes a pointer to a string representing the numeric PCB revision in
+ * decimal ("0" - "255"), stores it in the pcb_revision field of the
+ * EEPROM local copy, and updates the CRC of the local copy.
+ */
+static void set_pcb_revision(char *string)
+{
+ u8 p;
+ uint base = 16;
+ struct eeprom_hats_atom_header *atom4;
+ atom4 = (struct eeprom_hats_atom_header *)
+ hats_get_atom((struct eeprom_hats_header *)eeprom_wp_buff,
+ HATS_ATOM_CUSTOM);
+
+ p = (u8)simple_strtoul(string, NULL, base);
+ if (p > U8_MAX) {
+ printf("%s must not be greater than %d\n", "PCB revision",
+ U8_MAX);
+ return;
+ }
+
+ *einfo.pcb_revision = p;
+
+ update_crc(atom4);
+}
+
+/**
+ * set_bom_revision() - stores a StarFive BOM revision into the local EEPROM copy
+ *
+ * Takes a pointer to a uppercase ASCII character representing the BOM
+ * revision ("A" - "Z"), stores it in the bom_revision field of the
+ * EEPROM local copy, and updates the CRC of the local copy.
+ */
+static void set_bom_revision(char *string)
+{
+ struct eeprom_hats_atom_header *atom4;
+ atom4 = (struct eeprom_hats_atom_header *)
+ hats_get_atom((struct eeprom_hats_header *)eeprom_wp_buff,
+ HATS_ATOM_CUSTOM);
+
+ if (string[0] < 'A' || string[0] > 'Z') {
+ printf("BOM revision must be an uppercase letter between A and Z\n");
+ return;
+ }
+
+ *einfo.bom_revision = string[0];
+
+ update_crc(atom4);
+}
+
+/**
+ * set_product_id() - stores a StarFive product ID into the local EEPROM copy
+ *
+ * Takes a pointer to a string representing the numeric product ID in
+ * string ("VF7100A1-2150-D008E000-00000001\0"), stores it in the product string
+ * field of the EEPROM local copy, and updates the CRC of the local copy.
+ */
+static void set_product_id(char *string)
+{
+ struct eeprom_hats_atom_header *atom1;
+ atom1 = (struct eeprom_hats_atom_header *)
+ hats_get_atom((struct eeprom_hats_header *)eeprom_wp_buff,
+ HATS_ATOM_VENDOR);
+
+ memcpy((void *)einfo.pstr, (void *)string,
+ STARFIVE_EEPROM_ATOM1_PSTR_SIZE);
+
+ update_crc(atom1);
+}
+
+/**
+ * init_local_copy() - initialize the in-memory EEPROM copy
+ *
+ * Initialize the in-memory EEPROM copy with the magic number. Must
+ * be done when preparing to initialize a blank EEPROM, or overwrite
+ * one with a corrupted magic number.
+ */
+static void init_local_copy(uchar *buff)
+{
+ struct eeprom_hats_header *hats = (struct eeprom_hats_header *)buff;
+ struct eeprom_hats_atom_header *atom1 = (void *)hats +
+ sizeof(struct eeprom_hats_header);
+ struct eeprom_hats_atom_header *atom4_v1 = (void *)atom1 +
+ sizeof(struct starfive_eeprom_atom1);
+
+ memcpy((void *)hats, (void *)&starfive_eeprom_hats_header_default,
+ sizeof(struct eeprom_hats_header));
+ memcpy((void *)atom1, (void *)&starfive_eeprom_atom1_default,
+ sizeof(struct starfive_eeprom_atom1));
+ memcpy((void *)atom4_v1, (void *)&starfive_eeprom_atom4_v1_default,
+ sizeof(struct starfive_eeprom_atom4_v1));
+
+ update_crc(atom1);
+ update_crc(atom4_v1);
+}
+
+static int print_usage(void)
+{
+ printf("display and program the system ID and MAC addresses in EEPROM\n"
+ "[read_eeprom|initialize|write_eeprom|mac_address|pcb_revision|bom_revision|product_id]\n"
+ "mac read_eeprom\n"
+ " - read EEPROM content into memory data structure\n"
+ "mac write_eeprom\n"
+ " - save memory data structure to the EEPROM\n"
+ "mac initialize\n"
+ " - initialize the in-memory EEPROM copy with default data\n"
+ "mac mac0_address <xx:xx:xx:xx:xx:xx>\n"
+ " - stores a MAC0 address into the local EEPROM copy\n"
+ "mac mac1_address <xx:xx:xx:xx:xx:xx>\n"
+ " - stores a MAC1 address into the local EEPROM copy\n"
+ "mac pcb_revision <?>\n"
+ " - stores a StarFive PCB revision into the local EEPROM copy\n"
+ "mac bom_revision <A>\n"
+ " - stores a StarFive BOM revision into the local EEPROM copy\n"
+ "mac product_id <VF7110A1-2228-D008E000-xxxxxxxx>\n"
+ " - stores a StarFive product ID into the local EEPROM copy\n");
+ return 0;
+}
+
+int do_mac(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+ char *cmd;
+
+ if (argc == 1) {
+ show_eeprom(&einfo);
+ return 0;
+ }
+
+ if (argc > 3)
+ return print_usage();
+
+ cmd = argv[1];
+
+ /* Commands with no argument */
+ if (!strcmp(cmd, "read_eeprom")) {
+ has_been_read = 0;
+ return read_eeprom(eeprom_wp_buff);
+ } else if (!strcmp(cmd, "initialize")) {
+ init_local_copy(eeprom_wp_buff);
+ return 0;
+ } else if (!strcmp(cmd, "write_eeprom")) {
+ return prog_eeprom(eeprom_wp_buff,
+ STARFIVE_EEPROM_HATS_SIZE_MAX);
+ }
+
+ if (argc != 3)
+ return print_usage();
+
+ if (is_match_magic(eeprom_wp_buff)) {
+ printf("Please read the EEPROM ('read_eeprom') and/or initialize the EEPROM ('initialize') first.\n");
+ return 0;
+ }
+
+ if (!strcmp(cmd, "mac0_address")) {
+ set_mac_address(argv[2], 0);
+ return 0;
+ } else if (!strcmp(cmd, "mac1_address")) {
+ set_mac_address(argv[2], 1);
+ return 0;
+ } else if (!strcmp(cmd, "pcb_revision")) {
+ set_pcb_revision(argv[2]);
+ return 0;
+ } else if (!strcmp(cmd, "bom_revision")) {
+ set_bom_revision(argv[2]);
+ return 0;
+ } else if (!strcmp(cmd, "product_id")) {
+ set_product_id(argv[2]);
+ return 0;
+ }
+
+ return print_usage();
+}
+
+/**
+ * mac_read_from_eeprom() - read the MAC address & the serial number in EEPROM
+ *
+ * This function reads the MAC address and the serial number from EEPROM and
+ * sets the appropriate environment variables for each one read.
+ *
+ * The environment variables are only set if they haven't been set already.
+ * This ensures that any user-saved variables are never overwritten.
+ *
+ * If CONFIG_ID_EEPROM is enabled, this function will be called in
+ * "static init_fnc_t init_sequence_r[]" of u-boot/common/board_r.c.
+ */
+int mac_read_from_eeprom(void)
+{
+ /**
+ * try to fill the buff from EEPROM,
+ * always return SUCCESS, even some error happens.
+ */
+ if (read_eeprom(eeprom_wp_buff)) {
+ dump_raw_eeprom(eeprom_wp_buff, STARFIVE_EEPROM_HATS_SIZE_MAX);
+ return 0;
+ }
+
+ // 1, setup ethaddr env
+ eth_env_set_enetaddr("eth0addr", einfo.mac0_addr);
+ eth_env_set_enetaddr("eth1addr", einfo.mac1_addr);
+
+ /**
+ * 2, setup serial# env, reference to hifive-platform-i2c-eeprom.c,
+ * serial# can be a ASCII string, but not just a hex number, so we
+ * setup serial# in the 32Byte format:
+ * "VF7100A1-2201-D008E000-00000001;"
+ * "<product>-<date>-<DDR&eMMC>-<serial_number>"
+ * <date>: 4Byte, should be the output of `date +%y%W`
+ * <DDR&eMMC>: 8Byte, "D008" means 8GB, "D01T" means 1TB;
+ * "E000" means no eMMC,"E032" means 32GB, "E01T" means 1TB.
+ * <serial_number>: 8Byte, the Unique Identifier of board in hex.
+ */
+ if (!env_get("serial#"))
+ env_set("serial#", einfo.pstr);
+
+ printf("StarFive EEPROM format v%u\n", *einfo.version);
+ show_eeprom(&einfo);
+ return 0;
+}
+
+/**
+ * get_pcb_revision_from_eeprom - get the PCB revision
+ *
+ * Read the EEPROM to determine the board revision.
+ */
+u8 get_pcb_revision_from_eeprom(void)
+{
+ u8 pv = 0xFF;
+
+ if (read_eeprom(eeprom_wp_buff))
+ return pv;
+
+ if (einfo.pcb_revision) {
+ pv = *einfo.pcb_revision;
+ }
+ return pv;
+}
+
+/**
+ * get_data_from_eeprom
+ *
+ * Read data from eeprom, must use int mac_read_from_eeprom(void) first
+ *
+ * offset: offset of eeprom
+ * len: count of data
+ * data: return data
+ *
+ * return the len of valid data
+ */
+int get_data_from_eeprom(int offset, int len, unsigned char *data)
+{
+ int cp_len = -1;
+
+ if (read_eeprom(eeprom_wp_buff))
+ return cp_len;
+
+ if (offset < STARFIVE_EEPROM_HATS_SIZE_MAX) {
+ cp_len = (offset + len > STARFIVE_EEPROM_HATS_SIZE_MAX) ?
+ (offset + len - STARFIVE_EEPROM_HATS_SIZE_MAX) : len;
+ memcpy(data, &eeprom_wp_buff[offset], cp_len);
+ }
+
+ return cp_len;
+}
diff --git a/include/configs/starfive-visionfive.h b/include/configs/starfive-visionfive.h
deleted file mode 100644
index 956c6a7d12..0000000000
--- a/include/configs/starfive-visionfive.h
+++ /dev/null
@@ -1,151 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
- * YanHong Wang <yanhong.wang@starfivetech.com>
- */
-
-
-#ifndef _STARFIVE_VISIONFIVE_H
-#define _STARFIVE_VISIONFIVE_H
-
-#include <version.h>
-#include <linux/sizes.h>
-
-#ifdef CONFIG_SPL
-
-#define CONFIG_SPL_MAX_SIZE 0x00040000
-#define CONFIG_SPL_BSS_START_ADDR 0x08040000
-#define CONFIG_SPL_BSS_MAX_SIZE 0x00010000
-#define CONFIG_SYS_SPL_MALLOC_START (CONFIG_SPL_BSS_START_ADDR + \
- CONFIG_SPL_BSS_MAX_SIZE)
-#define CONFIG_SYS_SPL_MALLOC_SIZE 0x00100000
-
-#define CONFIG_SPL_STACK (0x08000000 + 0x00180000 - \
- GENERATED_GBL_DATA_SIZE)
-
-#define STARFIVE_SPL_BOOT_LOAD_ADDR 0xa0000000
-#endif
-
-
-#define CONFIG_SYS_CACHELINE_SIZE 64
-
-/*
- * Miscellaneous configurable options
- */
-#define CONFIG_SYS_CBSIZE 1024 /* Console I/O Buffer Size */
-#define CONFIG_SYS_BOOTM_LEN (32 << 20) /* 32MB */
-
-/*
- * Print Buffer Size
- */
-#define CONFIG_SYS_PBSIZE \
- (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
-
-/*
- * max number of command args
- */
-#define CONFIG_SYS_MAXARGS 16
-
-/*
- * Boot Argument Buffer Size
- */
-#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
-
-/*
- * Size of malloc() pool
- * 512kB is suggested, (CONFIG_ENV_SIZE + 128 * 1024) was not enough
- */
-#define CONFIG_SYS_MALLOC_LEN SZ_8M
-
-#define CONFIG_NR_DRAM_BANKS 1
-
-#define PHYS_SDRAM_0 0x40000000 /* SDRAM Bank #1 */
-#define PHYS_SDRAM_0_SIZE 0x100000000 /* 8 GB */
-
-#define CONFIG_SYS_SDRAM_BASE (PHYS_SDRAM_0)
-
-
-/* Init Stack Pointer */
-#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_2M)
-
-#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_16M)
-#define CONFIG_STANDALONE_LOAD_ADDR 0x41000000
-
-/*
- * Ethernet
- */
-#ifdef CONFIG_CMD_NET
-#define CONFIG_DW_ALTDESCRIPTOR
-#define DWC_NET_PHYADDR 0
-#define CONFIG_ARP_TIMEOUT 500
-#define CONFIG_NETMASK 255.255.255.0
-#define CONFIG_IPADDR 192.168.120.230
-#define CONFIG_IP_DEFRAG
-#ifndef CONFIG_NET_MAXDEFRAG
-#define CONFIG_NET_MAXDEFRAG 16384
-#endif
-#endif
-
-/* allow to overwrite serial and ethaddr */
-#define CONFIG_ENV_OVERWRITE
-
-/* HACK these should have '#if defined (stuff) around them like zynqp*/
-#define BOOT_TARGET_DEVICES(func) func(DHCP, dhcp, na) func(MMC, mmc, 0)
-
-#include <config_distro_bootcmd.h>
-
-
-#include <environment/distro/sf.h>
-
-#define TYPE_GUID_LOADER1 "5B193300-FC78-40CD-8002-E86C45580B47"
-#define TYPE_GUID_LOADER2 "2E54B353-1271-4842-806F-E436D6AF6985"
-#define TYPE_GUID_SYSTEM "0FC63DAF-8483-4772-8E79-3D69D8477DE4"
-
-#define PARTS_DEFAULT \
- "name=loader1,start=17K,size=1M,type=${type_guid_gpt_loader1};" \
- "name=loader2,size=4MB,type=${type_guid_gpt_loader2};" \
- "name=system,size=-,bootable,type=${type_guid_gpt_system};"
-
-#define CONFIG_EXTRA_ENV_SETTINGS \
- "fdt_high=0xffffffffffffffff\0" \
- "initrd_high=0xffffffffffffffff\0" \
- "kernel_addr_r=0x44000000\0" \
- "fdt_addr_r=0x46000000\0" \
- "scriptaddr=0x88100000\0" \
- "script_offset_f=0x1fff000\0" \
- "script_size_f=0x1000\0" \
- "pxefile_addr_r=0x88200000\0" \
- "ramdisk_addr_r=0x88300000\0" \
- "type_guid_gpt_loader1=" TYPE_GUID_LOADER1 "\0" \
- "type_guid_gpt_loader2=" TYPE_GUID_LOADER2 "\0" \
- "type_guid_gpt_system=" TYPE_GUID_SYSTEM "\0" \
- "partitions=" PARTS_DEFAULT "\0" \
- BOOTENV \
- BOOTENV_SF
-
-/*
- * memtest works on 1.9 MB in DRAM
- */
-#define CONFIG_SYS_MEMTEST_START PHYS_SDRAM_0
-#define CONFIG_SYS_MEMTEST_END (PHYS_SDRAM_0 + PHYS_SDRAM_0_SIZE)
-
-#define CONFIG_SYS_BAUDRATE_TABLE {9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600}
-#define CONFIG_SYS_LOADS_BAUD_CHANGE 1 /* allow baudrate change */
-
-/* 6.25MHz RTC clock, StarFive JH7110*/
-#define CONFIG_SYS_HZ_CLOCK 4000000
-
-#define __io
-
-#define memset_io(c, v, l) memset((c), (v), (l))
-#define memcpy_fromio(a, c, l) memcpy((a), (c), (l))
-#define memcpy_toio(c, a, l) memcpy((c), (a), (l))
-
-#define CONFIG_VIDEO_BMP_LOGO
-#define CONFIG_VIDEO_LOGO
-#define CONFIG_BMP_16BPP
-#define CONFIG_BMP_24BPP
-#define CONFIG_BMP_32BPP
-
-#endif /* _STARFIVE_EVB_H */
-
diff --git a/include/configs/starfive-visionfive2.h b/include/configs/starfive-visionfive2.h
new file mode 100644
index 0000000000..37a51004ca
--- /dev/null
+++ b/include/configs/starfive-visionfive2.h
@@ -0,0 +1,374 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 Shanghai StarFive Technology Co., Ltd.
+ * YanHong Wang <yanhong.wang@starfivetech.com>
+ */
+
+
+#ifndef _STARFIVE_VISIONFIVE2_H
+#define _STARFIVE_VISIONFIVE2_H
+
+#include <version.h>
+#include <linux/sizes.h>
+
+#ifdef CONFIG_SPL
+
+#define CONFIG_SPL_MAX_SIZE 0x00040000
+#define CONFIG_SPL_BSS_START_ADDR 0x08040000
+#define CONFIG_SPL_BSS_MAX_SIZE 0x00010000
+#define CONFIG_SYS_SPL_MALLOC_START 0x42000000
+
+#define CONFIG_SYS_SPL_MALLOC_SIZE 0x00800000
+
+#define CONFIG_SPL_STACK (0x08000000 + 0x00180000 - \
+ GENERATED_GBL_DATA_SIZE)
+#define STARFIVE_SPL_BOOT_LOAD_ADDR 0x60000000
+#endif
+
+#define CONFIG_SYS_BOOTM_LEN SZ_64M
+
+
+#define CONFIG_SYS_CACHELINE_SIZE 64
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_SYS_CBSIZE 1024 /* Console I/O Buffer Size */
+
+/*
+ * Print Buffer Size
+ */
+#define CONFIG_SYS_PBSIZE \
+ (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+
+/*
+ * max number of command args
+ */
+#define CONFIG_SYS_MAXARGS 16
+
+/*
+ * Boot Argument Buffer Size
+ */
+#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
+
+/*
+ * Size of malloc() pool
+ * 512kB is suggested, (CONFIG_ENV_SIZE + 128 * 1024) was not enough
+ */
+#define CONFIG_SYS_MALLOC_LEN SZ_8M
+
+#define CONFIG_SYS_SDRAM_BASE 0x40000000
+
+/* Init Stack Pointer */
+#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_8M)
+
+#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_16M)
+#define CONFIG_STANDALONE_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_16M)
+
+#define CONFIG_SYS_PCI_64BIT /* enable 64-bit PCI resources */
+
+/*
+ * Ethernet
+ */
+#ifdef CONFIG_CMD_NET
+#define CONFIG_DW_ALTDESCRIPTOR
+#define CONFIG_ARP_TIMEOUT 500
+#define CONFIG_NETMASK 255.255.255.0
+#define CONFIG_IPADDR 192.168.120.230
+#define CONFIG_IP_DEFRAG
+#ifndef CONFIG_NET_MAXDEFRAG
+#define CONFIG_NET_MAXDEFRAG 16384
+#endif
+#endif
+
+/* HACK these should have '#if defined (stuff) around them like zynqp*/
+#define BOOT_TARGET_DEVICES(func) func(MMC, mmc, 0) func(DHCP, dhcp, na)
+
+#include <config_distro_bootcmd.h>
+
+
+#include <environment/distro/sf.h>
+
+#define TYPE_GUID_LOADER1 "5B193300-FC78-40CD-8002-E86C45580B47"
+#define TYPE_GUID_LOADER2 "2E54B353-1271-4842-806F-E436D6AF6985"
+#define TYPE_GUID_SYSTEM "0FC63DAF-8483-4772-8E79-3D69D8477DE4"
+
+#define CPU_VOL_1020_SET \
+ "cpu_vol_1020_set=" \
+ "fdt set /opp-table-0/opp-1500000000 opp-microvolt <1020000>;\0"
+
+#define CPU_VOL_1040_SET \
+ "cpu_vol_1040_set=" \
+ "fdt set /opp-table-0/opp-1500000000 opp-microvolt <1040000>;\0"
+
+#define CPU_VOL_1060_SET \
+ "cpu_vol_1060_set=" \
+ "fdt set /opp-table-0/opp-1500000000 opp-microvolt <1060000>;\0"
+
+#define CPU_SPEED_1250_SET \
+ "cpu_speed_1250_set=" \
+ "fdt rm /opp-table-0/opp-375000000;" \
+ "fdt rm /opp-table-0/opp-500000000;" \
+ "fdt rm /opp-table-0/opp-750000000;" \
+ "fdt rm /opp-table-0/opp-1500000000;\0"
+
+#define CPU_SPEED_1500_SET \
+ "cpu_speed_1500_set=" \
+ "fdt rm /opp-table-0/opp-312500000;" \
+ "fdt rm /opp-table-0/opp-417000000;" \
+ "fdt rm /opp-table-0/opp-625000000;" \
+ "fdt rm /opp-table-0/opp-1250000000;\0"
+
+#define CPU_FREQ_VOL_SET \
+ "cpu_vol_set=" \
+ "if test ${cpu_max_vol} = 1000000; then " \
+ "run cpu_speed_1250_set; " \
+ "else " \
+ "run cpu_speed_1500_set; " \
+ "if test ${cpu_max_vol} = 1060000; then " \
+ "run cpu_vol_1060_set; " \
+ "elif test ${cpu_max_vol} = 1020000; then " \
+ "run cpu_vol_1020_set; " \
+ "else " \
+ "run cpu_vol_1040_set; " \
+ "fi; " \
+ "fi; \0"
+
+#define CMA_SIZE_SET \
+ "cma_start=70000000\0" \
+ "cma_1g=b000000\0" \
+ "cma_2g=20000000\0" \
+ "cma_4g=40000000\0" \
+ "cma_8g=60000000\0" \
+ "cma_node=/reserved-memory/linux,cma\0" \
+ "cma_ddr1g_set=" \
+ "fdt set ${cma_node} size <0x0 0x${cma_1g}>;" \
+ "fdt set ${cma_node} alloc-ranges <0x0 0x${cma_start} 0x0 0x${cma_1g}>;\0" \
+ "cma_ddr2g_set=" \
+ "fdt set ${cma_node} size <0x0 0x${cma_2g}>;" \
+ "fdt set ${cma_node} alloc-ranges <0x0 0x${cma_start} 0x0 0x${cma_2g}>;\0" \
+ "cma_ddr4g_set=" \
+ "fdt set ${cma_node} size <0x0 0x${cma_4g}>;" \
+ "fdt set ${cma_node} alloc-ranges <0x0 0x${cma_start} 0x0 0x${cma_4g}>;\0" \
+ "cma_ddr8g_set=" \
+ "fdt set ${cma_node} size <0x0 0x${cma_8g}>;" \
+ "fdt set ${cma_node} alloc-ranges <0x0 0x${cma_start} 0x0 0x${cma_8g}>;\0" \
+ "cma_resize=" \
+ "if test ${memory_size} -eq 40000000; then " \
+ "run cma_ddr1g_set;" \
+ "elif test ${memory_size} -eq 80000000; then " \
+ "run cma_ddr2g_set;" \
+ "elif test ${memory_size} -eq 100000000; then " \
+ "run cma_ddr4g_set;" \
+ "elif test ${memory_size} -ge 200000000; then " \
+ "run cma_ddr8g_set;" \
+ "fi; \0 "
+
+#define PARTS_DEFAULT \
+ "name=loader1,start=17K,size=1M,type=${type_guid_gpt_loader1};" \
+ "name=loader2,size=4MB,type=${type_guid_gpt_loader2};" \
+ "name=system,size=-,bootable,type=${type_guid_gpt_system};"
+
+#define CHIPA_GMAC_SET \
+ "chipa_gmac_set=" \
+ "fdt set /soc/ethernet@16030000/ethernet-phy@0 tx_inverted_10 <0x0>;" \
+ "fdt set /soc/ethernet@16030000/ethernet-phy@0 tx_inverted_100 <0x0>;" \
+ "fdt set /soc/ethernet@16030000/ethernet-phy@0 tx_inverted_1000 <0x0>;" \
+ "fdt set /soc/ethernet@16030000/ethernet-phy@0 tx_delay_sel <0x9>;" \
+ "fdt set /soc/ethernet@16040000/ethernet-phy@1 tx_inverted_10 <0x0>;" \
+ "fdt set /soc/ethernet@16040000/ethernet-phy@1 tx_inverted_100 <0x0>;" \
+ "fdt set /soc/ethernet@16040000/ethernet-phy@1 tx_inverted_1000 <0x0>;" \
+ "fdt set /soc/ethernet@16040000/ethernet-phy@1 tx_delay_sel <0x9> \0"
+
+#define VISIONFIVE2_MEM_SET \
+ "visionfive2_mem_set=" \
+ "fdt memory ${memory_addr} ${memory_size};" \
+ "run cma_resize; \0"
+
+#define CHIPA_SET \
+ "chipa_set=" \
+ "if test ${chip_vision} = A; then " \
+ "run chipa_gmac_set;" \
+ "fi; \0" \
+ "chipa_set_uboot=" \
+ "fdt addr ${uboot_fdt_addr};" \
+ "run chipa_set;\0" \
+ "chipa_set_linux=" \
+ "fdt addr ${fdt_addr_r};" \
+ "run visionfive2_mem_set;" \
+ "run chipa_set;\0"
+
+#define VF2_SDK_BOOTENV \
+ "bootenv=uEnv.txt\0" \
+ "bootenv_sdk=vf2_uEnv.txt\0" \
+ "boot_devs=mmc nvme\0" \
+ "emmc_devnum=0\0" \
+ "sd_devnum=1\0" \
+ "mmc_devnum_l=1 0\0" \
+ "nvme_devnum_l=0 0\0"
+
+#define JH7110_SDK_BOOTENV \
+ "bootdir=/boot\0" \
+ "bootpart=3\0" \
+ "rootpart=4\0" \
+ "load_sdk_uenv=" \
+ "fatload ${bootdev} ${devnum}:${bootpart} ${loadaddr} ${bootenv_sdk};" \
+ "env import -t ${loadaddr} ${filesize}; \0" \
+ "mmc_test_and_boot=" \
+ "if mmc dev ${devnum}; then " \
+ "echo Try booting from MMC${devnum} ...; " \
+ "setenv sdev_blk mmcblk${devnum}p${rootpart};" \
+ "run load_sdk_uenv; run boot2;" \
+ "fi;\0" \
+ "bootenv_mmc=" \
+ "setenv bootdev mmc;" \
+ "if test ${bootmode} = flash; then " \
+ "for mmc_devnum in ${mmc_devnum_l}; do " \
+ "setenv devnum ${mmc_devnum}; " \
+ "run mmc_test_and_boot;" \
+ "done;" \
+ "fi; " \
+ "if test ${bootmode} = sd; then " \
+ "setenv devnum ${sd_devnum};" \
+ "run mmc_test_and_boot;" \
+ "fi; " \
+ "if test ${bootmode} = emmc; then " \
+ "setenv devnum ${emmc_devnum};"\
+ "run mmc_test_and_boot;" \
+ "fi; \0" \
+ "bootenv_nvme=" \
+ "if test ${bootmode} = flash; then " \
+ "for nvme_devnum in ${nvme_devnum_l}; do " \
+ "setenv devnum ${nvme_devnum};" \
+ "if pci enum; then " \
+ "nvme scan; " \
+ "fi; " \
+ "if nvme dev ${devnum}; then " \
+ "echo Try booting from NVME${devnum} ...; " \
+ "setenv bootdev nvme;" \
+ "setenv sdev_blk nvme${devnum}n1p${rootpart};" \
+ "run load_sdk_uenv; run boot2;" \
+ "fi; " \
+ "done; " \
+ "fi; \0" \
+ "sdk_boot_env=" \
+ "for bootdev_s in ${boot_devs}; do " \
+ "run bootenv_${bootdev_s}; " \
+ "done;\0" \
+ "fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0"
+
+#define JH7110_DISTRO_BOOTENV \
+ "bootdir=/boot\0" \
+ "bootpart=3\0" \
+ "rootpart=4\0" \
+ "load_distro_uenv=" \
+ "fatload ${bootdev} ${devnum}:${bootpart} ${loadaddr} /${bootenv}; " \
+ "env import ${loadaddr} ${filesize}; \0" \
+ "fdt_loaddtb=" \
+ "fatload ${bootdev} ${devnum}:${bootpart} ${fdt_addr_r} /dtbs/${fdtfile}; fdt addr ${fdt_addr_r}; \0" \
+ "fdt_sizecheck=" \
+ "fatsize ${bootdev} ${devnum}:${bootpart} /dtbs/${fdtfile}; \0" \
+ "set_fdt_distro=" \
+ "run chipa_set_linux; run cpu_vol_set;" \
+ "fatwrite ${bootdev} ${devnum}:${bootpart} ${fdt_addr_r} /dtbs/${fdtfile} ${filesize}; \0" \
+ "bootcmd_distro=" \
+ "run load_distro_uenv; " \
+ "run fdt_loaddtb; run fdt_sizecheck; run set_fdt_distro; " \
+ "sysboot ${bootdev} ${devnum}:${bootpart} fat ${scriptaddr} /${boot_syslinux_conf}; \0" \
+ "distro_mmc_test_and_boot=" \
+ "if mmc dev ${devnum}; then " \
+ "echo Try booting from MMC${devnum} ...; " \
+ "run bootcmd_distro;" \
+ "fi;\0" \
+ "distro_bootenv_mmc=" \
+ "setenv bootdev mmc;" \
+ "if test ${bootmode} = flash; then " \
+ "for mmc_devnum in ${mmc_devnum_l}; do "\
+ "setenv devnum ${mmc_devnum}; " \
+ "run distro_mmc_test_and_boot;" \
+ "done;" \
+ "fi; " \
+ "if test ${bootmode} = sd; then " \
+ "setenv devnum ${sd_devnum};" \
+ "run distro_mmc_test_and_boot;" \
+ "fi; " \
+ "if test ${bootmode} = emmc; then " \
+ "setenv devnum ${emmc_devnum};"\
+ "run distro_mmc_test_and_boot;" \
+ "fi; \0" \
+ "distro_bootenv_nvme=" \
+ "if test ${bootmode} = flash; then " \
+ "for nvme_devnum in ${nvme_devnum_l}; do " \
+ "setenv devnum ${nvme_devnum};" \
+ "if pci enum; then " \
+ "nvme scan; " \
+ "fi; " \
+ "if nvme dev ${devnum}; then " \
+ "echo Try booting from NVME${devnum} ...; " \
+ "setenv bootdev nvme;" \
+ "run bootcmd_distro; " \
+ "fi; " \
+ "done; " \
+ "fi; \0" \
+ "distro_boot_env=" \
+ "echo Tring booting distro ...;" \
+ "for bootdev_s in ${boot_devs}; do " \
+ "run distro_bootenv_${bootdev_s}; " \
+ "done; \0"
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "fdt_high=0xffffffffffffffff\0" \
+ "initrd_high=0xffffffffffffffff\0" \
+ "kernel_addr_r=0x40200000\0" \
+ "kernel_comp_addr_r=0x5a000000\0" \
+ "kernel_comp_size=0x4000000\0" \
+ "fdt_addr_r=0x46000000\0" \
+ "scriptaddr=0x43900000\0" \
+ "script_offset_f=0x1fff000\0" \
+ "script_size_f=0x1000\0" \
+ "pxefile_addr_r=0x45900000\0" \
+ "ramdisk_addr_r=0x46100000\0" \
+ "fdtoverlay_addr_r=0x4f000000\0" \
+ "loadaddr=0x60000000\0" \
+ VF2_SDK_BOOTENV \
+ JH7110_SDK_BOOTENV \
+ JH7110_DISTRO_BOOTENV \
+ CHIPA_GMAC_SET \
+ CHIPA_SET \
+ CPU_VOL_1020_SET \
+ CPU_VOL_1040_SET \
+ CPU_VOL_1060_SET \
+ CPU_SPEED_1250_SET \
+ CPU_SPEED_1500_SET \
+ CPU_FREQ_VOL_SET \
+ CMA_SIZE_SET \
+ VISIONFIVE2_MEM_SET \
+ "type_guid_gpt_loader1=" TYPE_GUID_LOADER1 "\0" \
+ "type_guid_gpt_loader2=" TYPE_GUID_LOADER2 "\0" \
+ "type_guid_gpt_system=" TYPE_GUID_SYSTEM "\0" \
+ "partitions=" PARTS_DEFAULT "\0" \
+ BOOTENV \
+ BOOTENV_SF
+
+#define CONFIG_SYS_BAUDRATE_TABLE {9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600}
+#define CONFIG_SYS_LOADS_BAUD_CHANGE 1 /* allow baudrate change */
+
+/* 6.25MHz RTC clock, StarFive JH7110*/
+#define CONFIG_SYS_HZ_CLOCK 4000000
+
+#define __io
+
+#define memset_io(c, v, l) memset((c), (v), (l))
+#define memcpy_fromio(a, c, l) memcpy((a), (c), (l))
+#define memcpy_toio(c, a, l) memcpy((c), (a), (l))
+
+#define CONFIG_VIDEO_BMP_LOGO
+#define CONFIG_VIDEO_LOGO
+#define CONFIG_BMP_16BPP
+#define CONFIG_BMP_24BPP
+#define CONFIG_BMP_32BPP
+
+#define CONFIG_ID_EEPROM
+
+#endif /* _STARFIVE_VISIONFIVE2_H */
+