blob: 336f0cdfc90fc5b1ee558fb3403cd326fd0b3752 [file] [log] [blame]
Yanhong Wang5ecf9b02023-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 Wangc9745362023-06-15 17:36:52 +08008#include <asm/arch/eeprom.h>
Chanho Parkb8a902b2023-10-31 17:56:00 +09009#include <asm/arch/gpio.h>
Yanhong Wang5ecf9b02023-03-29 11:42:17 +080010#include <asm/arch/regs.h>
11#include <asm/arch/spl.h>
12#include <asm/io.h>
Yanhong Wangc9745362023-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 Wang5ecf9b02023-03-29 11:42:17 +080016#include <log.h>
17#include <spl.h>
18
Yanhong Wangc9745362023-06-15 17:36:52 +080019DECLARE_GLOBAL_DATA_PTR;
Yanhong Wang5ecf9b02023-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 Wangc9745362023-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{
64 u32 phandle;
65 u8 i;
66 int offset;
67 int ret;
68
69 fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "model",
70 "StarFive VisionFive 2 v1.2A");
71
72 offset = fdt_path_offset(fdt, "/soc/clock-controller@13020000");
73 phandle = fdt_get_phandle(fdt, offset);
74 offset = fdt_path_offset(fdt, "/soc/ethernet@16040000");
75
76 fdt_setprop_u32(fdt, offset, "assigned-clocks", phandle);
77 fdt_appendprop_u32(fdt, offset, "assigned-clocks", JH7110_SYSCLK_GMAC1_TX);
78 fdt_appendprop_u32(fdt, offset, "assigned-clocks", phandle);
79 fdt_appendprop_u32(fdt, offset, "assigned-clocks", JH7110_SYSCLK_GMAC1_RX);
80
81 fdt_setprop_u32(fdt, offset, "assigned-clock-parents", phandle);
82 fdt_appendprop_u32(fdt, offset, "assigned-clock-parents",
83 JH7110_SYSCLK_GMAC1_RMII_RTX);
84 fdt_appendprop_u32(fdt, offset, "assigned-clock-parents", phandle);
85 fdt_appendprop_u32(fdt, offset, "assigned-clock-parents",
86 JH7110_SYSCLK_GMAC1_RMII_RTX);
87
88 fdt_setprop_string(fdt, fdt_path_offset(fdt, "/soc/ethernet@16040000"),
89 "phy-mode", "rmii");
90
91 for (i = 0; i < ARRAY_SIZE(starfive_vera); i++) {
92 offset = fdt_path_offset(fdt, starfive_vera[i].path);
93
94 if (starfive_vera[i].value)
95 ret = fdt_setprop_u32(fdt, offset, starfive_vera[i].name,
96 dectoul(starfive_vera[i].value, NULL));
97 else
98 ret = fdt_setprop_empty(fdt, offset, starfive_vera[i].name);
99
100 if (ret) {
101 pr_err("%s set prop %s fail.\n", __func__, starfive_vera[i].name);
102 break;
103 }
104 }
105}
106
107void spl_fdt_fixup_version_b(void *fdt)
108{
109 u32 phandle;
110 u8 i;
111 int offset;
112 int ret;
113
114 fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "model",
115 "StarFive VisionFive 2 v1.3B");
116
117 /* gmac0 */
118 offset = fdt_path_offset(fdt, "/soc/clock-controller@17000000");
119 phandle = fdt_get_phandle(fdt, offset);
120 offset = fdt_path_offset(fdt, "/soc/ethernet@16030000");
121
122 fdt_setprop_u32(fdt, offset, "assigned-clocks", phandle);
123 fdt_appendprop_u32(fdt, offset, "assigned-clocks", JH7110_AONCLK_GMAC0_TX);
124 fdt_setprop_u32(fdt, offset, "assigned-clock-parents", phandle);
125 fdt_appendprop_u32(fdt, offset, "assigned-clock-parents",
126 JH7110_AONCLK_GMAC0_RMII_RTX);
127
128 /* gmac1 */
129 offset = fdt_path_offset(fdt, "/soc/clock-controller@13020000");
130 phandle = fdt_get_phandle(fdt, offset);
131 offset = fdt_path_offset(fdt, "/soc/ethernet@16040000");
132
133 fdt_setprop_u32(fdt, offset, "assigned-clocks", phandle);
134 fdt_appendprop_u32(fdt, offset, "assigned-clocks", JH7110_SYSCLK_GMAC1_TX);
135 fdt_setprop_u32(fdt, offset, "assigned-clock-parents", phandle);
136 fdt_appendprop_u32(fdt, offset, "assigned-clock-parents",
137 JH7110_SYSCLK_GMAC1_RMII_RTX);
138
139 for (i = 0; i < ARRAY_SIZE(starfive_verb); i++) {
140 offset = fdt_path_offset(fdt, starfive_verb[i].path);
141
142 if (starfive_verb[i].value)
143 ret = fdt_setprop_u32(fdt, offset, starfive_verb[i].name,
144 dectoul(starfive_verb[i].value, NULL));
145 else
146 ret = fdt_setprop_empty(fdt, offset, starfive_verb[i].name);
147
148 if (ret) {
149 pr_err("%s set prop %s fail.\n", __func__, starfive_verb[i].name);
150 break;
151 }
152 }
153}
154
155void spl_perform_fixups(struct spl_image_info *spl_image)
156{
157 u8 version;
158
159 version = get_pcb_revision_from_eeprom();
160 switch (version) {
161 case 'a':
162 case 'A':
163 spl_fdt_fixup_version_a(spl_image->fdt_addr);
164 break;
165
166 case 'b':
167 case 'B':
168 default:
169 spl_fdt_fixup_version_b(spl_image->fdt_addr);
170 break;
171 };
172
173 /* Update the memory size which read form eeprom or DT */
174 fdt_fixup_memory(spl_image->fdt_addr, 0x40000000, gd->ram_size);
175}
Chanho Parkb8a902b2023-10-31 17:56:00 +0900176
177static void jh7110_jtag_init(void)
178{
179 /* nTRST: GPIO36 */
180 SYS_IOMUX_DOEN(36, HIGH);
181 SYS_IOMUX_DIN(36, 4);
182 /* TDI: GPIO61 */
183 SYS_IOMUX_DOEN(61, HIGH);
184 SYS_IOMUX_DIN(61, 19);
185 /* TMS: GPIO63 */
186 SYS_IOMUX_DOEN(63, HIGH);
187 SYS_IOMUX_DIN(63, 20);
188 /* TCK: GPIO60 */
189 SYS_IOMUX_DOEN(60, HIGH);
190 SYS_IOMUX_DIN(60, 29);
191 /* TDO: GPIO44 */
192 SYS_IOMUX_DOEN(44, 8);
193 SYS_IOMUX_DOUT(44, 22);
194}
195
Yanhong Wang5ecf9b02023-03-29 11:42:17 +0800196int spl_board_init_f(void)
197{
198 int ret;
199
Chanho Parkb8a902b2023-10-31 17:56:00 +0900200 jh7110_jtag_init();
201
Yanhong Wang5ecf9b02023-03-29 11:42:17 +0800202 ret = spl_soc_init();
203 if (ret) {
204 debug("JH7110 SPL init failed: %d\n", ret);
205 return ret;
206 }
207
208 return 0;
209}
210
211u32 spl_boot_device(void)
212{
213 u32 mode;
214
215 mode = in_le32(JH7110_BOOT_MODE_SELECT_REG)
216 & JH7110_BOOT_MODE_SELECT_MASK;
217 switch (mode) {
218 case 0:
219 return BOOT_DEVICE_SPI;
220
221 case 1:
222 return BOOT_DEVICE_MMC2;
223
224 case 2:
225 return BOOT_DEVICE_MMC1;
226
227 case 3:
228 return BOOT_DEVICE_UART;
229
230 default:
231 debug("Unsupported boot device 0x%x.\n", mode);
232 return BOOT_DEVICE_NONE;
233 }
234}
235
236void board_init_f(ulong dummy)
237{
238 int ret;
239
240 ret = spl_early_init();
241 if (ret)
242 panic("spl_early_init() failed: %d\n", ret);
243
Simon Glassf72d0d42023-08-21 21:16:56 -0600244 riscv_cpu_setup();
Yanhong Wang5ecf9b02023-03-29 11:42:17 +0800245 preloader_console_init();
246
247 /* Set the parent clock of cpu_root clock to pll0,
248 * it must be initialized here
249 */
250 clrsetbits_le32(JH7110_SYS_CRG + JH7110_CLK_CPU_ROOT_OFFSET,
251 JH7110_CLK_CPU_ROOT_MASK,
252 BIT(JH7110_CLK_CPU_ROOT_SHIFT));
253
254 ret = spl_board_init_f();
255 if (ret) {
256 debug("spl_board_init_f init failed: %d\n", ret);
257 return;
258 }
259}
260
261#if CONFIG_IS_ENABLED(SPL_LOAD_FIT)
262int board_fit_config_name_match(const char *name)
263{
264 /* boot using first FIT config */
265 return 0;
266}
267#endif