blob: ad5f71a201803906dc29b39fcc1d9f1ca36adad8 [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>
Yanhong Wang6a5a45d2023-03-29 11:42:17 +08009#include <asm/arch/regs.h>
10#include <asm/arch/spl.h>
11#include <asm/io.h>
Yanhong Wang4e321fa2023-06-15 17:36:52 +080012#include <dt-bindings/clock/starfive,jh7110-crg.h>
13#include <fdt_support.h>
14#include <linux/libfdt.h>
Yanhong Wang6a5a45d2023-03-29 11:42:17 +080015#include <log.h>
16#include <spl.h>
17
Yanhong Wang4e321fa2023-06-15 17:36:52 +080018DECLARE_GLOBAL_DATA_PTR;
Yanhong Wang6a5a45d2023-03-29 11:42:17 +080019#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
Yanhong Wang4e321fa2023-06-15 17:36:52 +080023struct starfive_vf2_pro {
24 const char *path;
25 const char *name;
26 const char *value;
27};
28
29static 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
36static 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
61void 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
106void 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
154void 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}
Yanhong Wang6a5a45d2023-03-29 11:42:17 +0800175int 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
188u32 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
213void 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
Simon Glassb8357c12023-08-21 21:16:56 -0600221 riscv_cpu_setup();
Yanhong Wang6a5a45d2023-03-29 11:42:17 +0800222 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)
239int board_fit_config_name_match(const char *name)
240{
241 /* boot using first FIT config */
242 return 0;
243}
244#endif