board: starfive: Dynamic configuration of DT for 1.2A and 1.3B
[platform/kernel/u-boot.git] / board / starfive / visionfive2 / spl.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2022 StarFive Technology Co., Ltd.
4  * Author: Yanhong Wang<yanhong.wang@starfivetech.com>
5  */
6
7 #include <common.h>
8 #include <asm/arch/eeprom.h>
9 #include <asm/arch/regs.h>
10 #include <asm/arch/spl.h>
11 #include <asm/io.h>
12 #include <dt-bindings/clock/starfive,jh7110-crg.h>
13 #include <fdt_support.h>
14 #include <linux/libfdt.h>
15 #include <log.h>
16 #include <spl.h>
17
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)
22
23 struct starfive_vf2_pro {
24         const char *path;
25         const char *name;
26         const char *value;
27 };
28
29 static const struct starfive_vf2_pro starfive_vera[] = {
30         {"/soc/ethernet@16030000/mdio/ethernet-phy@0", "rx-internal-delay-ps",
31                 "1900"},
32         {"/soc/ethernet@16030000/mdio/ethernet-phy@0", "tx-internal-delay-ps",
33                 "1350"}
34 };
35
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},
39
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"},
50
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"},
59 };
60
61 void spl_fdt_fixup_version_a(void *fdt)
62 {
63         u32 phandle;
64         u8 i;
65         int offset;
66         int ret;
67
68         fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "model",
69                            "StarFive VisionFive 2 v1.2A");
70
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");
74
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);
79
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);
86
87         fdt_setprop_string(fdt, fdt_path_offset(fdt, "/soc/ethernet@16040000"),
88                            "phy-mode", "rmii");
89
90         for (i = 0; i < ARRAY_SIZE(starfive_vera); i++) {
91                 offset = fdt_path_offset(fdt, starfive_vera[i].path);
92
93                 if (starfive_vera[i].value)
94                         ret = fdt_setprop_u32(fdt, offset,  starfive_vera[i].name,
95                                               dectoul(starfive_vera[i].value, NULL));
96                 else
97                         ret = fdt_setprop_empty(fdt, offset, starfive_vera[i].name);
98
99                 if (ret) {
100                         pr_err("%s set prop %s fail.\n", __func__, starfive_vera[i].name);
101                                 break;
102                 }
103         }
104 }
105
106 void spl_fdt_fixup_version_b(void *fdt)
107 {
108         u32 phandle;
109         u8 i;
110         int offset;
111         int ret;
112
113         fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "model",
114                            "StarFive VisionFive 2 v1.3B");
115
116         /* gmac0 */
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");
120
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);
126
127         /* gmac1 */
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");
131
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);
137
138         for (i = 0; i < ARRAY_SIZE(starfive_verb); i++) {
139                 offset = fdt_path_offset(fdt, starfive_verb[i].path);
140
141                 if (starfive_verb[i].value)
142                         ret = fdt_setprop_u32(fdt, offset,  starfive_verb[i].name,
143                                               dectoul(starfive_verb[i].value, NULL));
144                 else
145                         ret = fdt_setprop_empty(fdt, offset, starfive_verb[i].name);
146
147                 if (ret) {
148                         pr_err("%s set prop %s fail.\n", __func__, starfive_verb[i].name);
149                                 break;
150                 }
151         }
152 }
153
154 void spl_perform_fixups(struct spl_image_info *spl_image)
155 {
156         u8 version;
157
158         version = get_pcb_revision_from_eeprom();
159         switch (version) {
160         case 'a':
161         case 'A':
162                 spl_fdt_fixup_version_a(spl_image->fdt_addr);
163                 break;
164
165         case 'b':
166         case 'B':
167         default:
168                 spl_fdt_fixup_version_b(spl_image->fdt_addr);
169                 break;
170         };
171
172         /* Update the memory size which read form eeprom or DT */
173         fdt_fixup_memory(spl_image->fdt_addr, 0x40000000, gd->ram_size);
174 }
175 int spl_board_init_f(void)
176 {
177         int ret;
178
179         ret = spl_soc_init();
180         if (ret) {
181                 debug("JH7110 SPL init failed: %d\n", ret);
182                 return ret;
183         }
184
185         return 0;
186 }
187
188 u32 spl_boot_device(void)
189 {
190         u32 mode;
191
192         mode = in_le32(JH7110_BOOT_MODE_SELECT_REG)
193                                 & JH7110_BOOT_MODE_SELECT_MASK;
194         switch (mode) {
195         case 0:
196                 return BOOT_DEVICE_SPI;
197
198         case 1:
199                 return BOOT_DEVICE_MMC2;
200
201         case 2:
202                 return BOOT_DEVICE_MMC1;
203
204         case 3:
205                 return BOOT_DEVICE_UART;
206
207         default:
208                 debug("Unsupported boot device 0x%x.\n", mode);
209                 return BOOT_DEVICE_NONE;
210         }
211 }
212
213 void board_init_f(ulong dummy)
214 {
215         int ret;
216
217         ret = spl_early_init();
218         if (ret)
219                 panic("spl_early_init() failed: %d\n", ret);
220
221         riscv_cpu_setup(NULL, NULL);
222         preloader_console_init();
223
224         /* Set the parent clock of cpu_root clock to pll0,
225          * it must be initialized here
226          */
227         clrsetbits_le32(JH7110_SYS_CRG + JH7110_CLK_CPU_ROOT_OFFSET,
228                         JH7110_CLK_CPU_ROOT_MASK,
229                         BIT(JH7110_CLK_CPU_ROOT_SHIFT));
230
231         ret = spl_board_init_f();
232         if (ret) {
233                 debug("spl_board_init_f init failed: %d\n", ret);
234                 return;
235         }
236 }
237
238 #if CONFIG_IS_ENABLED(SPL_LOAD_FIT)
239 int board_fit_config_name_match(const char *name)
240 {
241         /* boot using first FIT config */
242         return 0;
243 }
244 #endif