diff options
author | Yanhong Wang <yanhong.wang@starfivetech.com> | 2023-06-15 12:36:52 +0300 |
---|---|---|
committer | Leo Yu-Chi Liang <ycliang@andestech.com> | 2023-07-12 08:21:40 +0300 |
commit | c9745365f516a361be9cbe3568d2b8608084bbbf (patch) | |
tree | 20aaefd1cb8ba34f4841fb63a685957011c228d1 /board/starfive | |
parent | 38d900b409199df02a1a26dfcb464d4d2b6e27d2 (diff) | |
download | u-boot-c9745365f516a361be9cbe3568d2b8608084bbbf.tar.xz |
board: starfive: Dynamic configuration of DT for 1.2A and 1.3B
The main difference between StarFive VisionFive 2 1.2A and 1.3B is gmac.
You can read the PCB version of the current board by
get_pcb_revision_from_eeprom(), and then dynamically configure the
difference of gmac in spl_perform_fixups() according to different PCB
versions, so that one DT and one defconfig can support both 1.2A and
1.3B versions, which is more user-friendly.
Signed-off-by: Yanhong Wang <yanhong.wang@starfivetech.com>
Reviewed-by: Rick Chen <rick@andestech.com>
Diffstat (limited to 'board/starfive')
-rw-r--r-- | board/starfive/visionfive2/spl.c | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/board/starfive/visionfive2/spl.c b/board/starfive/visionfive2/spl.c index db0b4cb433..7acd3995aa 100644 --- a/board/starfive/visionfive2/spl.c +++ b/board/starfive/visionfive2/spl.c @@ -5,16 +5,173 @@ */ #include <common.h> +#include <asm/arch/eeprom.h> #include <asm/arch/regs.h> #include <asm/arch/spl.h> #include <asm/io.h> +#include <dt-bindings/clock/starfive,jh7110-crg.h> +#include <fdt_support.h> +#include <linux/libfdt.h> #include <log.h> #include <spl.h> +DECLARE_GLOBAL_DATA_PTR; #define JH7110_CLK_CPU_ROOT_OFFSET 0x0U #define JH7110_CLK_CPU_ROOT_SHIFT 24 #define JH7110_CLK_CPU_ROOT_MASK GENMASK(29, 24) +struct starfive_vf2_pro { + const char *path; + const char *name; + const char *value; +}; + +static const struct starfive_vf2_pro starfive_vera[] = { + {"/soc/ethernet@16030000/mdio/ethernet-phy@0", "rx-internal-delay-ps", + "1900"}, + {"/soc/ethernet@16030000/mdio/ethernet-phy@0", "tx-internal-delay-ps", + "1350"} +}; + +static const struct starfive_vf2_pro starfive_verb[] = { + {"/soc/ethernet@16030000", "starfive,tx-use-rgmii-clk", NULL}, + {"/soc/ethernet@16040000", "starfive,tx-use-rgmii-clk", NULL}, + + {"/soc/ethernet@16030000/mdio/ethernet-phy@0", + "motorcomm,tx-clk-adj-enabled", NULL}, + {"/soc/ethernet@16030000/mdio/ethernet-phy@0", + "motorcomm,tx-clk-100-inverted", NULL}, + {"/soc/ethernet@16030000/mdio/ethernet-phy@0", + "motorcomm,tx-clk-1000-inverted", NULL}, + {"/soc/ethernet@16030000/mdio/ethernet-phy@0", + "rx-internal-delay-ps", "1900"}, + {"/soc/ethernet@16030000/mdio/ethernet-phy@0", + "tx-internal-delay-ps", "1500"}, + + {"/soc/ethernet@16040000/mdio/ethernet-phy@1", + "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", + "rx-internal-delay-ps", "0"}, + {"/soc/ethernet@16040000/mdio/ethernet-phy@1", + "tx-internal-delay-ps", "0"}, +}; + +void spl_fdt_fixup_version_a(void *fdt) +{ + u32 phandle; + u8 i; + int offset; + int ret; + + fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "model", + "StarFive VisionFive 2 v1.2A"); + + offset = fdt_path_offset(fdt, "/soc/clock-controller@13020000"); + phandle = fdt_get_phandle(fdt, offset); + offset = fdt_path_offset(fdt, "/soc/ethernet@16040000"); + + fdt_setprop_u32(fdt, offset, "assigned-clocks", phandle); + fdt_appendprop_u32(fdt, offset, "assigned-clocks", JH7110_SYSCLK_GMAC1_TX); + fdt_appendprop_u32(fdt, offset, "assigned-clocks", phandle); + fdt_appendprop_u32(fdt, offset, "assigned-clocks", JH7110_SYSCLK_GMAC1_RX); + + fdt_setprop_u32(fdt, offset, "assigned-clock-parents", phandle); + fdt_appendprop_u32(fdt, offset, "assigned-clock-parents", + JH7110_SYSCLK_GMAC1_RMII_RTX); + fdt_appendprop_u32(fdt, offset, "assigned-clock-parents", phandle); + fdt_appendprop_u32(fdt, offset, "assigned-clock-parents", + JH7110_SYSCLK_GMAC1_RMII_RTX); + + fdt_setprop_string(fdt, fdt_path_offset(fdt, "/soc/ethernet@16040000"), + "phy-mode", "rmii"); + + for (i = 0; i < ARRAY_SIZE(starfive_vera); i++) { + offset = fdt_path_offset(fdt, starfive_vera[i].path); + + if (starfive_vera[i].value) + ret = fdt_setprop_u32(fdt, offset, starfive_vera[i].name, + dectoul(starfive_vera[i].value, NULL)); + else + ret = fdt_setprop_empty(fdt, offset, starfive_vera[i].name); + + if (ret) { + pr_err("%s set prop %s fail.\n", __func__, starfive_vera[i].name); + break; + } + } +} + +void spl_fdt_fixup_version_b(void *fdt) +{ + u32 phandle; + u8 i; + int offset; + int ret; + + fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "model", + "StarFive VisionFive 2 v1.3B"); + + /* gmac0 */ + offset = fdt_path_offset(fdt, "/soc/clock-controller@17000000"); + phandle = fdt_get_phandle(fdt, offset); + offset = fdt_path_offset(fdt, "/soc/ethernet@16030000"); + + fdt_setprop_u32(fdt, offset, "assigned-clocks", phandle); + fdt_appendprop_u32(fdt, offset, "assigned-clocks", JH7110_AONCLK_GMAC0_TX); + fdt_setprop_u32(fdt, offset, "assigned-clock-parents", phandle); + fdt_appendprop_u32(fdt, offset, "assigned-clock-parents", + JH7110_AONCLK_GMAC0_RMII_RTX); + + /* gmac1 */ + offset = fdt_path_offset(fdt, "/soc/clock-controller@13020000"); + phandle = fdt_get_phandle(fdt, offset); + offset = fdt_path_offset(fdt, "/soc/ethernet@16040000"); + + fdt_setprop_u32(fdt, offset, "assigned-clocks", phandle); + fdt_appendprop_u32(fdt, offset, "assigned-clocks", JH7110_SYSCLK_GMAC1_TX); + fdt_setprop_u32(fdt, offset, "assigned-clock-parents", phandle); + fdt_appendprop_u32(fdt, offset, "assigned-clock-parents", + JH7110_SYSCLK_GMAC1_RMII_RTX); + + for (i = 0; i < ARRAY_SIZE(starfive_verb); i++) { + offset = fdt_path_offset(fdt, starfive_verb[i].path); + + if (starfive_verb[i].value) + ret = fdt_setprop_u32(fdt, offset, starfive_verb[i].name, + dectoul(starfive_verb[i].value, NULL)); + else + ret = fdt_setprop_empty(fdt, offset, starfive_verb[i].name); + + if (ret) { + pr_err("%s set prop %s fail.\n", __func__, starfive_verb[i].name); + break; + } + } +} + +void spl_perform_fixups(struct spl_image_info *spl_image) +{ + u8 version; + + version = get_pcb_revision_from_eeprom(); + switch (version) { + case 'a': + case 'A': + spl_fdt_fixup_version_a(spl_image->fdt_addr); + break; + + case 'b': + case 'B': + default: + spl_fdt_fixup_version_b(spl_image->fdt_addr); + break; + }; + + /* Update the memory size which read form eeprom or DT */ + fdt_fixup_memory(spl_image->fdt_addr, 0x40000000, gd->ram_size); +} int spl_board_init_f(void) { int ret; |