1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2022 StarFive Technology Co., Ltd.
4 * Author: Yanhong Wang<yanhong.wang@starfivetech.com>
8 #include <asm/arch/eeprom.h>
9 #include <asm/arch/regs.h>
10 #include <asm/arch/spl.h>
12 #include <dt-bindings/clock/starfive,jh7110-crg.h>
13 #include <fdt_support.h>
14 #include <linux/libfdt.h>
18 DECLARE_GLOBAL_DATA_PTR;
19 #define JH7110_CLK_CPU_ROOT_OFFSET 0x0U
20 #define JH7110_CLK_CPU_ROOT_SHIFT 24
21 #define JH7110_CLK_CPU_ROOT_MASK GENMASK(29, 24)
23 struct starfive_vf2_pro {
29 static const struct starfive_vf2_pro starfive_vera[] = {
30 {"/soc/ethernet@16030000/mdio/ethernet-phy@0", "rx-internal-delay-ps",
32 {"/soc/ethernet@16030000/mdio/ethernet-phy@0", "tx-internal-delay-ps",
36 static const struct starfive_vf2_pro starfive_verb[] = {
37 {"/soc/ethernet@16030000", "starfive,tx-use-rgmii-clk", NULL},
38 {"/soc/ethernet@16040000", "starfive,tx-use-rgmii-clk", NULL},
40 {"/soc/ethernet@16030000/mdio/ethernet-phy@0",
41 "motorcomm,tx-clk-adj-enabled", NULL},
42 {"/soc/ethernet@16030000/mdio/ethernet-phy@0",
43 "motorcomm,tx-clk-100-inverted", NULL},
44 {"/soc/ethernet@16030000/mdio/ethernet-phy@0",
45 "motorcomm,tx-clk-1000-inverted", NULL},
46 {"/soc/ethernet@16030000/mdio/ethernet-phy@0",
47 "rx-internal-delay-ps", "1900"},
48 {"/soc/ethernet@16030000/mdio/ethernet-phy@0",
49 "tx-internal-delay-ps", "1500"},
51 {"/soc/ethernet@16040000/mdio/ethernet-phy@1",
52 "motorcomm,tx-clk-adj-enabled", NULL},
53 { "/soc/ethernet@16040000/mdio/ethernet-phy@1",
54 "motorcomm,tx-clk-100-inverted", NULL},
55 {"/soc/ethernet@16040000/mdio/ethernet-phy@1",
56 "rx-internal-delay-ps", "0"},
57 {"/soc/ethernet@16040000/mdio/ethernet-phy@1",
58 "tx-internal-delay-ps", "0"},
61 void spl_fdt_fixup_version_a(void *fdt)
68 fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "model",
69 "StarFive VisionFive 2 v1.2A");
71 offset = fdt_path_offset(fdt, "/soc/clock-controller@13020000");
72 phandle = fdt_get_phandle(fdt, offset);
73 offset = fdt_path_offset(fdt, "/soc/ethernet@16040000");
75 fdt_setprop_u32(fdt, offset, "assigned-clocks", phandle);
76 fdt_appendprop_u32(fdt, offset, "assigned-clocks", JH7110_SYSCLK_GMAC1_TX);
77 fdt_appendprop_u32(fdt, offset, "assigned-clocks", phandle);
78 fdt_appendprop_u32(fdt, offset, "assigned-clocks", JH7110_SYSCLK_GMAC1_RX);
80 fdt_setprop_u32(fdt, offset, "assigned-clock-parents", phandle);
81 fdt_appendprop_u32(fdt, offset, "assigned-clock-parents",
82 JH7110_SYSCLK_GMAC1_RMII_RTX);
83 fdt_appendprop_u32(fdt, offset, "assigned-clock-parents", phandle);
84 fdt_appendprop_u32(fdt, offset, "assigned-clock-parents",
85 JH7110_SYSCLK_GMAC1_RMII_RTX);
87 fdt_setprop_string(fdt, fdt_path_offset(fdt, "/soc/ethernet@16040000"),
90 for (i = 0; i < ARRAY_SIZE(starfive_vera); i++) {
91 offset = fdt_path_offset(fdt, starfive_vera[i].path);
93 if (starfive_vera[i].value)
94 ret = fdt_setprop_u32(fdt, offset, starfive_vera[i].name,
95 dectoul(starfive_vera[i].value, NULL));
97 ret = fdt_setprop_empty(fdt, offset, starfive_vera[i].name);
100 pr_err("%s set prop %s fail.\n", __func__, starfive_vera[i].name);
106 void spl_fdt_fixup_version_b(void *fdt)
113 fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "model",
114 "StarFive VisionFive 2 v1.3B");
117 offset = fdt_path_offset(fdt, "/soc/clock-controller@17000000");
118 phandle = fdt_get_phandle(fdt, offset);
119 offset = fdt_path_offset(fdt, "/soc/ethernet@16030000");
121 fdt_setprop_u32(fdt, offset, "assigned-clocks", phandle);
122 fdt_appendprop_u32(fdt, offset, "assigned-clocks", JH7110_AONCLK_GMAC0_TX);
123 fdt_setprop_u32(fdt, offset, "assigned-clock-parents", phandle);
124 fdt_appendprop_u32(fdt, offset, "assigned-clock-parents",
125 JH7110_AONCLK_GMAC0_RMII_RTX);
128 offset = fdt_path_offset(fdt, "/soc/clock-controller@13020000");
129 phandle = fdt_get_phandle(fdt, offset);
130 offset = fdt_path_offset(fdt, "/soc/ethernet@16040000");
132 fdt_setprop_u32(fdt, offset, "assigned-clocks", phandle);
133 fdt_appendprop_u32(fdt, offset, "assigned-clocks", JH7110_SYSCLK_GMAC1_TX);
134 fdt_setprop_u32(fdt, offset, "assigned-clock-parents", phandle);
135 fdt_appendprop_u32(fdt, offset, "assigned-clock-parents",
136 JH7110_SYSCLK_GMAC1_RMII_RTX);
138 for (i = 0; i < ARRAY_SIZE(starfive_verb); i++) {
139 offset = fdt_path_offset(fdt, starfive_verb[i].path);
141 if (starfive_verb[i].value)
142 ret = fdt_setprop_u32(fdt, offset, starfive_verb[i].name,
143 dectoul(starfive_verb[i].value, NULL));
145 ret = fdt_setprop_empty(fdt, offset, starfive_verb[i].name);
148 pr_err("%s set prop %s fail.\n", __func__, starfive_verb[i].name);
154 void spl_perform_fixups(struct spl_image_info *spl_image)
158 version = get_pcb_revision_from_eeprom();
162 spl_fdt_fixup_version_a(spl_image->fdt_addr);
168 spl_fdt_fixup_version_b(spl_image->fdt_addr);
172 /* Update the memory size which read form eeprom or DT */
173 fdt_fixup_memory(spl_image->fdt_addr, 0x40000000, gd->ram_size);
175 int spl_board_init_f(void)
179 ret = spl_soc_init();
181 debug("JH7110 SPL init failed: %d\n", ret);
188 u32 spl_boot_device(void)
192 mode = in_le32(JH7110_BOOT_MODE_SELECT_REG)
193 & JH7110_BOOT_MODE_SELECT_MASK;
196 return BOOT_DEVICE_SPI;
199 return BOOT_DEVICE_MMC2;
202 return BOOT_DEVICE_MMC1;
205 return BOOT_DEVICE_UART;
208 debug("Unsupported boot device 0x%x.\n", mode);
209 return BOOT_DEVICE_NONE;
213 void board_init_f(ulong dummy)
217 ret = spl_early_init();
219 panic("spl_early_init() failed: %d\n", ret);
221 riscv_cpu_setup(NULL, NULL);
222 preloader_console_init();
224 /* Set the parent clock of cpu_root clock to pll0,
225 * it must be initialized here
227 clrsetbits_le32(JH7110_SYS_CRG + JH7110_CLK_CPU_ROOT_OFFSET,
228 JH7110_CLK_CPU_ROOT_MASK,
229 BIT(JH7110_CLK_CPU_ROOT_SHIFT));
231 ret = spl_board_init_f();
233 debug("spl_board_init_f init failed: %d\n", ret);
238 #if CONFIG_IS_ENABLED(SPL_LOAD_FIT)
239 int board_fit_config_name_match(const char *name)
241 /* boot using first FIT config */