blob: 911add429df19cfdd2d418bd976c091166c7e135 [file] [log] [blame]
Yanhong Wang6a5a45d2023-03-29 11:42:17 +08001// 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>
Yanhong Wang4e321fa2023-06-15 17:36:52 +08008#include <asm/arch/eeprom.h>
Chanho Park9ca68c92023-10-31 17:56:00 +09009#include <asm/arch/gpio.h>
Yanhong Wang6a5a45d2023-03-29 11:42:17 +080010#include <asm/arch/regs.h>
11#include <asm/arch/spl.h>
12#include <asm/io.h>
Yanhong Wang4e321fa2023-06-15 17:36:52 +080013#include <dt-bindings/clock/starfive,jh7110-crg.h>
14#include <fdt_support.h>
15#include <linux/libfdt.h>
Yanhong Wang6a5a45d2023-03-29 11:42:17 +080016#include <log.h>
17#include <spl.h>
18
Yanhong Wang4e321fa2023-06-15 17:36:52 +080019DECLARE_GLOBAL_DATA_PTR;
Yanhong Wang6a5a45d2023-03-29 11:42:17 +080020#define JH7110_CLK_CPU_ROOT_OFFSET 0x0U
21#define JH7110_CLK_CPU_ROOT_SHIFT 24
22#define JH7110_CLK_CPU_ROOT_MASK GENMASK(29, 24)
23
Yanhong Wang4e321fa2023-06-15 17:36:52 +080024struct starfive_vf2_pro {
25 const char *path;
26 const char *name;
27 const char *value;
28};
29
30static const struct starfive_vf2_pro starfive_vera[] = {
31 {"/soc/ethernet@16030000/mdio/ethernet-phy@0", "rx-internal-delay-ps",
32 "1900"},
33 {"/soc/ethernet@16030000/mdio/ethernet-phy@0", "tx-internal-delay-ps",
34 "1350"}
35};
36
37static const struct starfive_vf2_pro starfive_verb[] = {
38 {"/soc/ethernet@16030000", "starfive,tx-use-rgmii-clk", NULL},
39 {"/soc/ethernet@16040000", "starfive,tx-use-rgmii-clk", NULL},
40
41 {"/soc/ethernet@16030000/mdio/ethernet-phy@0",
42 "motorcomm,tx-clk-adj-enabled", NULL},
43 {"/soc/ethernet@16030000/mdio/ethernet-phy@0",
44 "motorcomm,tx-clk-100-inverted", NULL},
45 {"/soc/ethernet@16030000/mdio/ethernet-phy@0",
46 "motorcomm,tx-clk-1000-inverted", NULL},
47 {"/soc/ethernet@16030000/mdio/ethernet-phy@0",
48 "rx-internal-delay-ps", "1900"},
49 {"/soc/ethernet@16030000/mdio/ethernet-phy@0",
50 "tx-internal-delay-ps", "1500"},
51
52 {"/soc/ethernet@16040000/mdio/ethernet-phy@1",
53 "motorcomm,tx-clk-adj-enabled", NULL},
54 { "/soc/ethernet@16040000/mdio/ethernet-phy@1",
55 "motorcomm,tx-clk-100-inverted", NULL},
56 {"/soc/ethernet@16040000/mdio/ethernet-phy@1",
57 "rx-internal-delay-ps", "0"},
58 {"/soc/ethernet@16040000/mdio/ethernet-phy@1",
59 "tx-internal-delay-ps", "0"},
60};
61
62void spl_fdt_fixup_version_a(void *fdt)
63{
Aurelien Jarno5acb7c12024-01-10 21:17:44 +010064 static const char compat[] = "starfive,visionfive-2-v1.2a\0starfive,jh7110";
Yanhong Wang4e321fa2023-06-15 17:36:52 +080065 u32 phandle;
66 u8 i;
67 int offset;
68 int ret;
69
Aurelien Jarno5acb7c12024-01-10 21:17:44 +010070 fdt_setprop(fdt, fdt_path_offset(fdt, "/"), "compatible", compat, sizeof(compat));
Yanhong Wang4e321fa2023-06-15 17:36:52 +080071 fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "model",
72 "StarFive VisionFive 2 v1.2A");
73
74 offset = fdt_path_offset(fdt, "/soc/clock-controller@13020000");
75 phandle = fdt_get_phandle(fdt, offset);
76 offset = fdt_path_offset(fdt, "/soc/ethernet@16040000");
77
78 fdt_setprop_u32(fdt, offset, "assigned-clocks", phandle);
79 fdt_appendprop_u32(fdt, offset, "assigned-clocks", JH7110_SYSCLK_GMAC1_TX);
80 fdt_appendprop_u32(fdt, offset, "assigned-clocks", phandle);
81 fdt_appendprop_u32(fdt, offset, "assigned-clocks", JH7110_SYSCLK_GMAC1_RX);
82
83 fdt_setprop_u32(fdt, offset, "assigned-clock-parents", phandle);
84 fdt_appendprop_u32(fdt, offset, "assigned-clock-parents",
85 JH7110_SYSCLK_GMAC1_RMII_RTX);
86 fdt_appendprop_u32(fdt, offset, "assigned-clock-parents", phandle);
87 fdt_appendprop_u32(fdt, offset, "assigned-clock-parents",
88 JH7110_SYSCLK_GMAC1_RMII_RTX);
89
90 fdt_setprop_string(fdt, fdt_path_offset(fdt, "/soc/ethernet@16040000"),
91 "phy-mode", "rmii");
92
93 for (i = 0; i < ARRAY_SIZE(starfive_vera); i++) {
94 offset = fdt_path_offset(fdt, starfive_vera[i].path);
95
96 if (starfive_vera[i].value)
97 ret = fdt_setprop_u32(fdt, offset, starfive_vera[i].name,
98 dectoul(starfive_vera[i].value, NULL));
99 else
100 ret = fdt_setprop_empty(fdt, offset, starfive_vera[i].name);
101
102 if (ret) {
103 pr_err("%s set prop %s fail.\n", __func__, starfive_vera[i].name);
104 break;
105 }
106 }
107}
108
109void spl_fdt_fixup_version_b(void *fdt)
110{
Aurelien Jarno5acb7c12024-01-10 21:17:44 +0100111 static const char compat[] = "starfive,visionfive-2-v1.3b\0starfive,jh7110";
Yanhong Wang4e321fa2023-06-15 17:36:52 +0800112 u32 phandle;
113 u8 i;
114 int offset;
115 int ret;
116
Aurelien Jarno5acb7c12024-01-10 21:17:44 +0100117 fdt_setprop(fdt, fdt_path_offset(fdt, "/"), "compatible", compat, sizeof(compat));
Yanhong Wang4e321fa2023-06-15 17:36:52 +0800118 fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "model",
119 "StarFive VisionFive 2 v1.3B");
120
121 /* gmac0 */
122 offset = fdt_path_offset(fdt, "/soc/clock-controller@17000000");
123 phandle = fdt_get_phandle(fdt, offset);
124 offset = fdt_path_offset(fdt, "/soc/ethernet@16030000");
125
126 fdt_setprop_u32(fdt, offset, "assigned-clocks", phandle);
127 fdt_appendprop_u32(fdt, offset, "assigned-clocks", JH7110_AONCLK_GMAC0_TX);
128 fdt_setprop_u32(fdt, offset, "assigned-clock-parents", phandle);
129 fdt_appendprop_u32(fdt, offset, "assigned-clock-parents",
130 JH7110_AONCLK_GMAC0_RMII_RTX);
131
132 /* gmac1 */
133 offset = fdt_path_offset(fdt, "/soc/clock-controller@13020000");
134 phandle = fdt_get_phandle(fdt, offset);
135 offset = fdt_path_offset(fdt, "/soc/ethernet@16040000");
136
137 fdt_setprop_u32(fdt, offset, "assigned-clocks", phandle);
138 fdt_appendprop_u32(fdt, offset, "assigned-clocks", JH7110_SYSCLK_GMAC1_TX);
139 fdt_setprop_u32(fdt, offset, "assigned-clock-parents", phandle);
140 fdt_appendprop_u32(fdt, offset, "assigned-clock-parents",
141 JH7110_SYSCLK_GMAC1_RMII_RTX);
142
143 for (i = 0; i < ARRAY_SIZE(starfive_verb); i++) {
144 offset = fdt_path_offset(fdt, starfive_verb[i].path);
145
146 if (starfive_verb[i].value)
147 ret = fdt_setprop_u32(fdt, offset, starfive_verb[i].name,
148 dectoul(starfive_verb[i].value, NULL));
149 else
150 ret = fdt_setprop_empty(fdt, offset, starfive_verb[i].name);
151
152 if (ret) {
153 pr_err("%s set prop %s fail.\n", __func__, starfive_verb[i].name);
154 break;
155 }
156 }
157}
158
159void spl_perform_fixups(struct spl_image_info *spl_image)
160{
161 u8 version;
162
163 version = get_pcb_revision_from_eeprom();
164 switch (version) {
165 case 'a':
166 case 'A':
167 spl_fdt_fixup_version_a(spl_image->fdt_addr);
168 break;
169
170 case 'b':
171 case 'B':
172 default:
173 spl_fdt_fixup_version_b(spl_image->fdt_addr);
174 break;
175 };
176
177 /* Update the memory size which read form eeprom or DT */
178 fdt_fixup_memory(spl_image->fdt_addr, 0x40000000, gd->ram_size);
179}
Chanho Park9ca68c92023-10-31 17:56:00 +0900180
181static void jh7110_jtag_init(void)
182{
183 /* nTRST: GPIO36 */
184 SYS_IOMUX_DOEN(36, HIGH);
185 SYS_IOMUX_DIN(36, 4);
186 /* TDI: GPIO61 */
187 SYS_IOMUX_DOEN(61, HIGH);
188 SYS_IOMUX_DIN(61, 19);
189 /* TMS: GPIO63 */
190 SYS_IOMUX_DOEN(63, HIGH);
191 SYS_IOMUX_DIN(63, 20);
192 /* TCK: GPIO60 */
193 SYS_IOMUX_DOEN(60, HIGH);
194 SYS_IOMUX_DIN(60, 29);
195 /* TDO: GPIO44 */
196 SYS_IOMUX_DOEN(44, 8);
197 SYS_IOMUX_DOUT(44, 22);
198}
199
Yanhong Wang6a5a45d2023-03-29 11:42:17 +0800200int spl_board_init_f(void)
201{
202 int ret;
203
Chanho Park9ca68c92023-10-31 17:56:00 +0900204 jh7110_jtag_init();
205
Yanhong Wang6a5a45d2023-03-29 11:42:17 +0800206 ret = spl_soc_init();
207 if (ret) {
208 debug("JH7110 SPL init failed: %d\n", ret);
209 return ret;
210 }
211
212 return 0;
213}
214
215u32 spl_boot_device(void)
216{
217 u32 mode;
218
219 mode = in_le32(JH7110_BOOT_MODE_SELECT_REG)
220 & JH7110_BOOT_MODE_SELECT_MASK;
221 switch (mode) {
222 case 0:
223 return BOOT_DEVICE_SPI;
224
225 case 1:
226 return BOOT_DEVICE_MMC2;
227
228 case 2:
229 return BOOT_DEVICE_MMC1;
230
231 case 3:
232 return BOOT_DEVICE_UART;
233
234 default:
235 debug("Unsupported boot device 0x%x.\n", mode);
236 return BOOT_DEVICE_NONE;
237 }
238}
239
240void board_init_f(ulong dummy)
241{
242 int ret;
243
244 ret = spl_early_init();
245 if (ret)
246 panic("spl_early_init() failed: %d\n", ret);
247
Simon Glassb8357c12023-08-21 21:16:56 -0600248 riscv_cpu_setup();
Yanhong Wang6a5a45d2023-03-29 11:42:17 +0800249 preloader_console_init();
250
251 /* Set the parent clock of cpu_root clock to pll0,
252 * it must be initialized here
253 */
254 clrsetbits_le32(JH7110_SYS_CRG + JH7110_CLK_CPU_ROOT_OFFSET,
255 JH7110_CLK_CPU_ROOT_MASK,
256 BIT(JH7110_CLK_CPU_ROOT_SHIFT));
257
258 ret = spl_board_init_f();
259 if (ret) {
260 debug("spl_board_init_f init failed: %d\n", ret);
261 return;
262 }
263}
264
265#if CONFIG_IS_ENABLED(SPL_LOAD_FIT)
266int board_fit_config_name_match(const char *name)
267{
268 /* boot using first FIT config */
269 return 0;
270}
271#endif