blob: 72967e69a84f778626e6f5e16d4304ae2db2daf5 [file] [log] [blame]
Michal Simekd903ce42024-05-29 16:47:58 +02001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2021 - 2022, Xilinx, Inc.
Michal Simek651d0f52025-04-10 09:38:51 +02004 * Copyright (C) 2022 - 2025, Advanced Micro Devices, Inc.
Michal Simekd903ce42024-05-29 16:47:58 +02005 *
6 * Michal Simek <michal.simek@amd.com>
7 */
8
9#include <cpu_func.h>
10#include <fdtdec.h>
11#include <init.h>
12#include <env_internal.h>
13#include <log.h>
14#include <malloc.h>
15#include <time.h>
16#include <asm/cache.h>
17#include <asm/global_data.h>
18#include <asm/io.h>
19#include <asm/arch/hardware.h>
20#include <asm/arch/sys_proto.h>
21#include <dm/device.h>
22#include <dm/uclass.h>
Prasad Kummari48630ae2025-03-27 16:21:59 +053023#include <versalpl.h>
Michal Simekd903ce42024-05-29 16:47:58 +020024#include "../../xilinx/common/board.h"
25
26#include <linux/bitfield.h>
27#include <debug_uart.h>
28#include <generated/dt.h>
29
30DECLARE_GLOBAL_DATA_PTR;
31
Prasad Kummari48630ae2025-03-27 16:21:59 +053032#if defined(CONFIG_FPGA_VERSALPL)
33static xilinx_desc versalpl = {
34 xilinx_versal2, csu_dma, 1, &versal_op, 0, &versal_op, NULL,
35 FPGA_LEGACY
36};
37#endif
38
Michal Simekd903ce42024-05-29 16:47:58 +020039int board_init(void)
40{
41 printf("EL Level:\tEL%d\n", current_el());
42
Prasad Kummari48630ae2025-03-27 16:21:59 +053043#if defined(CONFIG_FPGA_VERSALPL)
44 fpga_init();
45 fpga_add(fpga_xilinx, &versalpl);
46#endif
47
Padmarao Begariebdfd192025-04-09 21:56:39 +053048 if (CONFIG_IS_ENABLED(DM_I2C) && CONFIG_IS_ENABLED(I2C_EEPROM))
49 xilinx_read_eeprom();
50
Michal Simekd903ce42024-05-29 16:47:58 +020051 return 0;
52}
53
54static u32 platform_id, platform_version;
55
56char *soc_name_decode(void)
57{
58 char *name, *platform_name;
59
60 switch (platform_id) {
61 case VERSAL2_SPP:
62 platform_name = "spp";
63 break;
64 case VERSAL2_EMU:
65 platform_name = "emu";
66 break;
67 case VERSAL2_SPP_MMD:
68 platform_name = "spp-mmd";
69 break;
70 case VERSAL2_EMU_MMD:
71 platform_name = "emu-mmd";
72 break;
73 case VERSAL2_QEMU:
74 platform_name = "qemu";
75 break;
76 default:
77 return NULL;
78 }
79
80 /*
81 * --rev. are 6 chars
82 * max platform name is qemu which is 4 chars
83 * platform version number are 1+1
84 * Plus 1 char for \n
85 */
86 name = calloc(1, strlen(CONFIG_SYS_BOARD) + 13);
87 if (!name)
88 return NULL;
89
90 sprintf(name, "%s-%s-rev%d.%d-el%d", CONFIG_SYS_BOARD,
91 platform_name, platform_version / 10,
92 platform_version % 10, current_el());
93
94 return name;
95}
96
97bool soc_detection(void)
98{
99 u32 version, ps_version;
100
101 version = readl(PMC_TAP_VERSION);
102 platform_id = FIELD_GET(PLATFORM_MASK, version);
103 ps_version = FIELD_GET(PS_VERSION_MASK, version);
104
105 debug("idcode %x, version %x, usercode %x\n",
106 readl(PMC_TAP_IDCODE), version,
107 readl(PMC_TAP_USERCODE));
108
109 debug("pmc_ver %lx, ps version %x, rtl version %lx\n",
110 FIELD_GET(PMC_VERSION_MASK, version),
111 ps_version,
112 FIELD_GET(RTL_VERSION_MASK, version));
113
114 platform_version = FIELD_GET(PLATFORM_VERSION_MASK, version);
115
116 debug("Platform id: %d version: %d.%d\n", platform_id,
117 platform_version / 10, platform_version % 10);
118
119 return true;
120}
121
122int board_early_init_r(void)
123{
124 u32 val;
125
126 if (current_el() != 3)
127 return 0;
128
129 debug("iou_switch ctrl div0 %x\n",
130 readl(&crlapb_base->iou_switch_ctrl));
131
132 writel(IOU_SWITCH_CTRL_CLKACT_BIT |
133 (CONFIG_IOU_SWITCH_DIVISOR0 << IOU_SWITCH_CTRL_DIVISOR0_SHIFT),
134 &crlapb_base->iou_switch_ctrl);
135
136 /* Global timer init - Program time stamp reference clk */
137 val = readl(&crlapb_base->timestamp_ref_ctrl);
138 val |= CRL_APB_TIMESTAMP_REF_CTRL_CLKACT_BIT;
139 writel(val, &crlapb_base->timestamp_ref_ctrl);
140
141 debug("ref ctrl 0x%x\n",
142 readl(&crlapb_base->timestamp_ref_ctrl));
143
144 /* Clear reset of timestamp reg */
145 writel(0, &crlapb_base->rst_timestamp);
146
147 /*
148 * Program freq register in System counter and
149 * enable system counter.
150 */
151 writel(CONFIG_COUNTER_FREQUENCY,
152 &iou_scntr_secure->base_frequency_id_register);
153
154 debug("counter val 0x%x\n",
155 readl(&iou_scntr_secure->base_frequency_id_register));
156
157 writel(IOU_SCNTRS_CONTROL_EN,
158 &iou_scntr_secure->counter_control_register);
159
160 debug("scntrs control 0x%x\n",
161 readl(&iou_scntr_secure->counter_control_register));
162 debug("timer 0x%llx\n", get_ticks());
163 debug("timer 0x%llx\n", get_ticks());
164
165 return 0;
166}
167
Michal Simek8bb91ee2025-02-18 13:40:48 +0100168static u8 versal2_get_bootmode(void)
Michal Simekd903ce42024-05-29 16:47:58 +0200169{
170 u8 bootmode;
171 u32 reg = 0;
172
173 reg = readl(&crp_base->boot_mode_usr);
174
175 if (reg >> BOOT_MODE_ALT_SHIFT)
176 reg >>= BOOT_MODE_ALT_SHIFT;
177
178 bootmode = reg & BOOT_MODES_MASK;
179
180 return bootmode;
181}
182
183static int boot_targets_setup(void)
184{
185 u8 bootmode;
186 struct udevice *dev;
187 int bootseq = -1;
188 int bootseq_len = 0;
189 int env_targets_len = 0;
190 const char *mode = NULL;
191 char *new_targets;
192 char *env_targets;
193
Michal Simek8bb91ee2025-02-18 13:40:48 +0100194 bootmode = versal2_get_bootmode();
Michal Simekd903ce42024-05-29 16:47:58 +0200195
196 puts("Bootmode: ");
197 switch (bootmode) {
198 case USB_MODE:
199 puts("USB_MODE\n");
200 mode = "usb_dfu0 usb_dfu1";
201 break;
202 case JTAG_MODE:
203 puts("JTAG_MODE\n");
204 mode = "jtag pxe dhcp";
205 break;
206 case QSPI_MODE_24BIT:
207 puts("QSPI_MODE_24\n");
208 if (uclass_get_device_by_name(UCLASS_SPI,
209 "spi@f1030000", &dev)) {
210 debug("QSPI driver for QSPI device is not present\n");
211 break;
212 }
213 mode = "xspi";
214 bootseq = dev_seq(dev);
215 break;
216 case QSPI_MODE_32BIT:
217 puts("QSPI_MODE_32\n");
218 if (uclass_get_device_by_name(UCLASS_SPI,
219 "spi@f1030000", &dev)) {
220 debug("QSPI driver for QSPI device is not present\n");
221 break;
222 }
223 mode = "xspi";
224 bootseq = dev_seq(dev);
225 break;
226 case OSPI_MODE:
227 puts("OSPI_MODE\n");
228 if (uclass_get_device_by_name(UCLASS_SPI,
229 "spi@f1010000", &dev)) {
230 debug("OSPI driver for OSPI device is not present\n");
231 break;
232 }
233 mode = "xspi";
234 bootseq = dev_seq(dev);
235 break;
236 case EMMC_MODE:
237 puts("EMMC_MODE\n");
238 mode = "mmc";
239 bootseq = dev_seq(dev);
240 break;
241 case SELECTMAP_MODE:
242 puts("SELECTMAP_MODE\n");
243 break;
244 case SD_MODE:
245 puts("SD_MODE\n");
246 if (uclass_get_device_by_name(UCLASS_MMC,
247 "mmc@f1040000", &dev)) {
248 debug("SD0 driver for SD0 device is not present\n");
249 break;
250 }
251 debug("mmc0 device found at %p, seq %d\n", dev, dev_seq(dev));
252
253 mode = "mmc";
254 bootseq = dev_seq(dev);
255 break;
256 case SD1_LSHFT_MODE:
257 puts("LVL_SHFT_");
258 fallthrough;
259 case SD_MODE1:
260 puts("SD_MODE1\n");
261 if (uclass_get_device_by_name(UCLASS_MMC,
262 "mmc@f1050000", &dev)) {
263 debug("SD1 driver for SD1 device is not present\n");
264 break;
265 }
266 debug("mmc1 device found at %p, seq %d\n", dev, dev_seq(dev));
267
268 mode = "mmc";
269 bootseq = dev_seq(dev);
270 break;
Venkatesh Yadav Abbarapu94fb42f2025-02-24 15:28:06 -1200271 case UFS_MODE:
272 puts("UFS_MODE\n");
273 if (uclass_get_device(UCLASS_UFS, 0, &dev)) {
274 debug("UFS driver for UFS device is not present\n");
275 break;
276 }
277 debug("ufs device found at %p\n", dev);
278
279 mode = "ufs";
280 break;
Michal Simekd903ce42024-05-29 16:47:58 +0200281 default:
282 printf("Invalid Boot Mode:0x%x\n", bootmode);
283 break;
284 }
285
286 if (mode) {
287 if (bootseq >= 0) {
288 bootseq_len = snprintf(NULL, 0, "%i", bootseq);
289 debug("Bootseq len: %x\n", bootseq_len);
290 }
291
292 /*
293 * One terminating char + one byte for space between mode
294 * and default boot_targets
295 */
296 env_targets = env_get("boot_targets");
297 if (env_targets)
298 env_targets_len = strlen(env_targets);
299
300 new_targets = calloc(1, strlen(mode) + env_targets_len + 2 +
301 bootseq_len);
302 if (!new_targets)
303 return -ENOMEM;
304
305 if (bootseq >= 0)
306 sprintf(new_targets, "%s%x %s", mode, bootseq,
307 env_targets ? env_targets : "");
308 else
309 sprintf(new_targets, "%s %s", mode,
310 env_targets ? env_targets : "");
311
312 env_set("boot_targets", new_targets);
Michal Simek651d0f52025-04-10 09:38:51 +0200313 free(new_targets);
Michal Simekd903ce42024-05-29 16:47:58 +0200314 }
315
316 return 0;
317}
318
319int board_late_init(void)
320{
321 int ret;
322
323 if (!(gd->flags & GD_FLG_ENV_DEFAULT)) {
324 debug("Saved variables - Skipping\n");
325 return 0;
326 }
327
328 if (!IS_ENABLED(CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG))
329 return 0;
330
331 if (IS_ENABLED(CONFIG_DISTRO_DEFAULTS)) {
332 ret = boot_targets_setup();
333 if (ret)
334 return ret;
335 }
336
337 return board_late_init_xilinx();
338}
339
340int dram_init_banksize(void)
341{
342 int ret;
343
344 ret = fdtdec_setup_memory_banksize();
345 if (ret)
346 return ret;
347
348 mem_map_fill();
349
350 return 0;
351}
352
353int dram_init(void)
354{
355 int ret;
356
357 if (IS_ENABLED(CONFIG_SYS_MEM_RSVD_FOR_MMU))
358 ret = fdtdec_setup_mem_size_base();
359 else
360 ret = fdtdec_setup_mem_size_base_lowest();
361
362 if (ret)
363 return -EINVAL;
364
365 return 0;
366}
367
368void reset_cpu(void)
369{
370}
Venkatesh Yadav Abbarapuf0a503d2025-04-11 21:16:12 +0530371
372#if defined(CONFIG_ENV_IS_NOWHERE)
373enum env_location env_get_location(enum env_operation op, int prio)
374{
375 u32 bootmode = versal2_get_bootmode();
376
377 if (prio)
378 return ENVL_UNKNOWN;
379
380 switch (bootmode) {
381 case EMMC_MODE:
382 case SD_MODE:
383 case SD1_LSHFT_MODE:
384 case SD_MODE1:
385 if (IS_ENABLED(CONFIG_ENV_IS_IN_FAT))
386 return ENVL_FAT;
387 if (IS_ENABLED(CONFIG_ENV_IS_IN_EXT4))
388 return ENVL_EXT4;
389 return ENVL_NOWHERE;
390 case OSPI_MODE:
391 case QSPI_MODE_24BIT:
392 case QSPI_MODE_32BIT:
393 if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH))
394 return ENVL_SPI_FLASH;
395 return ENVL_NOWHERE;
396 case JTAG_MODE:
397 case SELECTMAP_MODE:
398 default:
399 return ENVL_NOWHERE;
400 }
401}
402#endif