]> git.ipfire.org Git - thirdparty/u-boot.git/blame - board/xilinx/zynqmp/zynqmp.c
arm64: zynqmp: Add idcodes for new RFSoC silicons ZU48DR and ZU49DR
[thirdparty/u-boot.git] / board / xilinx / zynqmp / zynqmp.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
84c7204b
MS
2/*
3 * (C) Copyright 2014 - 2015 Xilinx, Inc.
4 * Michal Simek <michal.simek@xilinx.com>
84c7204b
MS
5 */
6
7#include <common.h>
9fb625ce 8#include <env.h>
679b994a 9#include <sata.h>
6fe6f135
MS
10#include <ahci.h>
11#include <scsi.h>
b72894f1 12#include <malloc.h>
4490e013 13#include <wdt.h>
0785dfd8 14#include <asm/arch/clk.h>
84c7204b
MS
15#include <asm/arch/hardware.h>
16#include <asm/arch/sys_proto.h>
2ad341ed 17#include <asm/arch/psu_init_gpl.h>
84c7204b 18#include <asm/io.h>
2882b39d 19#include <dm/device.h>
4490e013 20#include <dm/uclass.h>
16fa00a7
SDPP
21#include <usb.h>
22#include <dwc3-uboot.h>
47e60cbd 23#include <zynqmppl.h>
9feff385 24#include <g_dnl.h>
a69814c8 25#include <linux/sizes.h>
84c7204b 26
c28a9cfa
LC
27#include "pm_cfg_obj.h"
28
84c7204b
MS
29DECLARE_GLOBAL_DATA_PTR;
30
47e60cbd
MS
31#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
32 !defined(CONFIG_SPL_BUILD)
33static xilinx_desc zynqmppl = XILINX_ZYNQMP_DESC;
34
35static const struct {
8ebdf9ef 36 u32 id;
494fffe7 37 u32 ver;
47e60cbd 38 char *name;
83bf2ff0 39 bool evexists;
47e60cbd
MS
40} zynqmp_devices[] = {
41 {
42 .id = 0x10,
43 .name = "3eg",
44 },
494fffe7
MS
45 {
46 .id = 0x10,
47 .ver = 0x2c,
48 .name = "3cg",
49 },
47e60cbd
MS
50 {
51 .id = 0x11,
52 .name = "2eg",
53 },
494fffe7
MS
54 {
55 .id = 0x11,
56 .ver = 0x2c,
57 .name = "2cg",
58 },
47e60cbd
MS
59 {
60 .id = 0x20,
61 .name = "5ev",
83bf2ff0 62 .evexists = 1,
47e60cbd 63 },
494fffe7
MS
64 {
65 .id = 0x20,
66 .ver = 0x100,
67 .name = "5eg",
83bf2ff0 68 .evexists = 1,
494fffe7
MS
69 },
70 {
71 .id = 0x20,
72 .ver = 0x12c,
73 .name = "5cg",
5473f245 74 .evexists = 1,
494fffe7 75 },
47e60cbd
MS
76 {
77 .id = 0x21,
78 .name = "4ev",
83bf2ff0 79 .evexists = 1,
47e60cbd 80 },
494fffe7
MS
81 {
82 .id = 0x21,
83 .ver = 0x100,
84 .name = "4eg",
83bf2ff0 85 .evexists = 1,
494fffe7
MS
86 },
87 {
88 .id = 0x21,
89 .ver = 0x12c,
90 .name = "4cg",
5473f245 91 .evexists = 1,
494fffe7 92 },
47e60cbd
MS
93 {
94 .id = 0x30,
95 .name = "7ev",
83bf2ff0 96 .evexists = 1,
47e60cbd 97 },
494fffe7
MS
98 {
99 .id = 0x30,
100 .ver = 0x100,
101 .name = "7eg",
83bf2ff0 102 .evexists = 1,
494fffe7
MS
103 },
104 {
105 .id = 0x30,
106 .ver = 0x12c,
107 .name = "7cg",
5473f245 108 .evexists = 1,
494fffe7 109 },
47e60cbd
MS
110 {
111 .id = 0x38,
112 .name = "9eg",
113 },
494fffe7
MS
114 {
115 .id = 0x38,
116 .ver = 0x2c,
117 .name = "9cg",
118 },
47e60cbd
MS
119 {
120 .id = 0x39,
121 .name = "6eg",
122 },
494fffe7
MS
123 {
124 .id = 0x39,
125 .ver = 0x2c,
126 .name = "6cg",
127 },
47e60cbd
MS
128 {
129 .id = 0x40,
130 .name = "11eg",
131 },
494fffe7
MS
132 { /* For testing purpose only */
133 .id = 0x50,
134 .ver = 0x2c,
135 .name = "15cg",
136 },
47e60cbd
MS
137 {
138 .id = 0x50,
139 .name = "15eg",
140 },
141 {
142 .id = 0x58,
143 .name = "19eg",
144 },
145 {
146 .id = 0x59,
147 .name = "17eg",
148 },
b030fedf
MS
149 {
150 .id = 0x61,
151 .name = "21dr",
152 },
153 {
154 .id = 0x63,
155 .name = "23dr",
156 },
157 {
158 .id = 0x65,
159 .name = "25dr",
160 },
161 {
162 .id = 0x64,
163 .name = "27dr",
164 },
165 {
166 .id = 0x60,
167 .name = "28dr",
168 },
169 {
170 .id = 0x62,
171 .name = "29dr",
172 },
c7490907
SDPP
173 {
174 .id = 0x66,
175 .name = "39dr",
176 },
134b0c8d
SDPP
177 {
178 .id = 0x7b,
179 .name = "48dr",
180 },
181 {
182 .id = 0x7e,
183 .name = "49dr",
184 },
47e60cbd 185};
74ba69db 186#endif
47e60cbd 187
f52bf5a3 188int chip_id(unsigned char id)
47e60cbd
MS
189{
190 struct pt_regs regs;
db3123b4 191 int val = -EINVAL;
47e60cbd 192
74ba69db
SDPP
193 if (current_el() != 3) {
194 regs.regs[0] = ZYNQMP_SIP_SVC_CSU_DMA_CHIPID;
195 regs.regs[1] = 0;
196 regs.regs[2] = 0;
197 regs.regs[3] = 0;
198
199 smc_call(&regs);
200
201 /*
202 * SMC returns:
203 * regs[0][31:0] = status of the operation
204 * regs[0][63:32] = CSU.IDCODE register
205 * regs[1][31:0] = CSU.version register
494fffe7 206 * regs[1][63:32] = CSU.IDCODE2 register
74ba69db
SDPP
207 */
208 switch (id) {
209 case IDCODE:
210 regs.regs[0] = upper_32_bits(regs.regs[0]);
211 regs.regs[0] &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
212 ZYNQMP_CSU_IDCODE_SVD_MASK;
213 regs.regs[0] >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
214 val = regs.regs[0];
215 break;
216 case VERSION:
217 regs.regs[1] = lower_32_bits(regs.regs[1]);
218 regs.regs[1] &= ZYNQMP_CSU_SILICON_VER_MASK;
219 val = regs.regs[1];
220 break;
494fffe7
MS
221 case IDCODE2:
222 regs.regs[1] = lower_32_bits(regs.regs[1]);
223 regs.regs[1] >>= ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
224 val = regs.regs[1];
225 break;
74ba69db
SDPP
226 default:
227 printf("%s, Invalid Req:0x%x\n", __func__, id);
228 }
229 } else {
230 switch (id) {
231 case IDCODE:
232 val = readl(ZYNQMP_CSU_IDCODE_ADDR);
233 val &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
234 ZYNQMP_CSU_IDCODE_SVD_MASK;
235 val >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
236 break;
237 case VERSION:
238 val = readl(ZYNQMP_CSU_VER_ADDR);
239 val &= ZYNQMP_CSU_SILICON_VER_MASK;
240 break;
241 default:
242 printf("%s, Invalid Req:0x%x\n", __func__, id);
243 }
db3123b4 244 }
0cba6abb 245
db3123b4 246 return val;
47e60cbd
MS
247}
248
83bf2ff0
SDPP
249#define ZYNQMP_VERSION_SIZE 9
250#define ZYNQMP_PL_STATUS_BIT 9
5473f245 251#define ZYNQMP_IPDIS_VCU_BIT 8
83bf2ff0
SDPP
252#define ZYNQMP_PL_STATUS_MASK BIT(ZYNQMP_PL_STATUS_BIT)
253#define ZYNQMP_CSU_VERSION_MASK ~(ZYNQMP_PL_STATUS_MASK)
5473f245
SDPP
254#define ZYNQMP_CSU_VCUDIS_VER_MASK ZYNQMP_CSU_VERSION_MASK & \
255 ~BIT(ZYNQMP_IPDIS_VCU_BIT)
256#define MAX_VARIANTS_EV 3
83bf2ff0 257
74ba69db
SDPP
258#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
259 !defined(CONFIG_SPL_BUILD)
47e60cbd
MS
260static char *zynqmp_get_silicon_idcode_name(void)
261{
5473f245 262 u32 i, id, ver, j;
83bf2ff0
SDPP
263 char *buf;
264 static char name[ZYNQMP_VERSION_SIZE];
47e60cbd 265
db3123b4 266 id = chip_id(IDCODE);
494fffe7
MS
267 ver = chip_id(IDCODE2);
268
47e60cbd 269 for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
5473f245
SDPP
270 if (zynqmp_devices[i].id == id) {
271 if (zynqmp_devices[i].evexists &&
272 !(ver & ZYNQMP_PL_STATUS_MASK))
273 break;
274 if (zynqmp_devices[i].ver == (ver &
275 ZYNQMP_CSU_VERSION_MASK))
276 break;
83bf2ff0 277 }
47e60cbd 278 }
83bf2ff0
SDPP
279
280 if (i >= ARRAY_SIZE(zynqmp_devices))
281 return "unknown";
282
5473f245
SDPP
283 strncat(name, "zu", 2);
284 if (!zynqmp_devices[i].evexists ||
285 (ver & ZYNQMP_PL_STATUS_MASK)) {
286 strncat(name, zynqmp_devices[i].name,
287 ZYNQMP_VERSION_SIZE - 3);
83bf2ff0 288 return name;
5473f245 289 }
83bf2ff0 290
5473f245
SDPP
291 /*
292 * Here we are means, PL not powered up and ev variant
293 * exists. So, we need to ignore VCU disable bit(8) in
294 * version and findout if its CG or EG/EV variant.
295 */
296 for (j = 0; j < MAX_VARIANTS_EV; j++, i++) {
297 if ((zynqmp_devices[i].ver & ~BIT(ZYNQMP_IPDIS_VCU_BIT)) ==
298 (ver & ZYNQMP_CSU_VCUDIS_VER_MASK)) {
299 strncat(name, zynqmp_devices[i].name,
300 ZYNQMP_VERSION_SIZE - 3);
301 break;
302 }
303 }
304
305 if (j >= MAX_VARIANTS_EV)
306 return "unknown";
83bf2ff0
SDPP
307
308 if (strstr(name, "eg") || strstr(name, "ev")) {
309 buf = strstr(name, "e");
310 *buf = '\0';
311 }
312
313 return name;
47e60cbd
MS
314}
315#endif
316
fb4000e8
MS
317int board_early_init_f(void)
318{
f32e79f1 319 int ret = 0;
fb4000e8 320#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_CLK_ZYNQMP)
b94a8271
SDPP
321 u32 pm_api_version;
322
323 pm_api_version = zynqmp_pmufw_version();
324 printf("PMUFW:\tv%d.%d\n",
325 pm_api_version >> ZYNQMP_PM_VERSION_MAJOR_SHIFT,
326 pm_api_version & ZYNQMP_PM_VERSION_MINOR_MASK);
327
328 if (pm_api_version < ZYNQMP_PM_VERSION)
329 panic("PMUFW version error. Expected: v%d.%d\n",
330 ZYNQMP_PM_VERSION_MAJOR, ZYNQMP_PM_VERSION_MINOR);
fb4000e8 331#endif
55de0929 332
88f05a92 333#if defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED)
f32e79f1 334 ret = psu_init();
55de0929
MS
335#endif
336
f32e79f1 337 return ret;
fb4000e8
MS
338}
339
84c7204b
MS
340int board_init(void)
341{
c28a9cfa
LC
342#if defined(CONFIG_SPL_BUILD)
343 /* Check *at build time* if the filename is an non-empty string */
344 if (sizeof(CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE) > 1)
345 zynqmp_pmufw_load_config_object(zynqmp_pm_cfg_obj,
346 zynqmp_pm_cfg_obj_size);
347#endif
348
a0736efb
MS
349 printf("EL Level:\tEL%d\n", current_el());
350
47e60cbd
MS
351#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
352 !defined(CONFIG_SPL_BUILD) || (defined(CONFIG_SPL_FPGA_SUPPORT) && \
353 defined(CONFIG_SPL_BUILD))
354 if (current_el() != 3) {
83bf2ff0 355 zynqmppl.name = zynqmp_get_silicon_idcode_name();
47e60cbd
MS
356 printf("Chip ID:\t%s\n", zynqmppl.name);
357 fpga_init();
358 fpga_add(fpga_xilinx, &zynqmppl);
359 }
360#endif
361
84c7204b
MS
362 return 0;
363}
364
365int board_early_init_r(void)
366{
367 u32 val;
368
ec60a279
SDPP
369 if (current_el() != 3)
370 return 0;
371
90a35db4
MS
372 val = readl(&crlapb_base->timestamp_ref_ctrl);
373 val &= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT;
374
ec60a279 375 if (!val) {
0785dfd8
MS
376 val = readl(&crlapb_base->timestamp_ref_ctrl);
377 val |= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT;
378 writel(val, &crlapb_base->timestamp_ref_ctrl);
84c7204b 379
0785dfd8
MS
380 /* Program freq register in System counter */
381 writel(zynqmp_get_system_timer_freq(),
382 &iou_scntr_secure->base_frequency_id_register);
383 /* And enable system counter */
384 writel(ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_EN,
385 &iou_scntr_secure->counter_control_register);
386 }
84c7204b
MS
387 return 0;
388}
389
51916864
NJ
390unsigned long do_go_exec(ulong (*entry)(int, char * const []), int argc,
391 char * const argv[])
392{
393 int ret = 0;
394
395 if (current_el() > 1) {
396 smp_kick_all_cpus();
397 dcache_disable();
398 armv8_switch_to_el1(0x0, 0, 0, 0, (unsigned long)entry,
399 ES_TO_AARCH64);
400 } else {
401 printf("FAIL: current EL is not above EL1\n");
402 ret = EINVAL;
403 }
404 return ret;
405}
406
8d59d7f6 407#if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
76b00aca 408int dram_init_banksize(void)
361a8799 409{
0678941a
NJ
410 int ret;
411
412 ret = fdtdec_setup_memory_banksize();
413 if (ret)
414 return ret;
415
416 mem_map_fill();
417
418 return 0;
8a5db0ab 419}
8d59d7f6 420
361a8799 421int dram_init(void)
8a5db0ab 422{
12308b12 423 if (fdtdec_setup_mem_size_base() != 0)
950f86ca 424 return -EINVAL;
8a5db0ab 425
361a8799 426 return 0;
8d59d7f6
MS
427}
428#else
0678941a
NJ
429int dram_init_banksize(void)
430{
431#if defined(CONFIG_NR_DRAM_BANKS)
432 gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
433 gd->bd->bi_dram[0].size = get_effective_memsize();
434#endif
435
436 mem_map_fill();
437
438 return 0;
439}
440
84c7204b
MS
441int dram_init(void)
442{
61dc92a2
MS
443 gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
444 CONFIG_SYS_SDRAM_SIZE);
84c7204b
MS
445
446 return 0;
447}
8d59d7f6 448#endif
84c7204b 449
84c7204b
MS
450void reset_cpu(ulong addr)
451{
452}
453
0bf3f9cb 454#if defined(CONFIG_BOARD_LATE_INIT)
d348beaa
MS
455static const struct {
456 u32 bit;
457 const char *name;
458} reset_reasons[] = {
459 { RESET_REASON_DEBUG_SYS, "DEBUG" },
460 { RESET_REASON_SOFT, "SOFT" },
461 { RESET_REASON_SRST, "SRST" },
462 { RESET_REASON_PSONLY, "PS-ONLY" },
463 { RESET_REASON_PMU, "PMU" },
464 { RESET_REASON_INTERNAL, "INTERNAL" },
465 { RESET_REASON_EXTERNAL, "EXTERNAL" },
466 {}
467};
468
be52372f 469static int reset_reason(void)
d348beaa 470{
be52372f
KR
471 u32 reg;
472 int i, ret;
d348beaa
MS
473 const char *reason = NULL;
474
be52372f
KR
475 ret = zynqmp_mmio_read((ulong)&crlapb_base->reset_reason, &reg);
476 if (ret)
477 return -EINVAL;
d348beaa
MS
478
479 puts("Reset reason:\t");
480
481 for (i = 0; i < ARRAY_SIZE(reset_reasons); i++) {
be52372f 482 if (reg & reset_reasons[i].bit) {
d348beaa
MS
483 reason = reset_reasons[i].name;
484 printf("%s ", reset_reasons[i].name);
485 break;
486 }
487 }
488
489 puts("\n");
490
491 env_set("reset_reason", reason);
492
be52372f
KR
493 ret = zynqmp_mmio_write(~0, ~0, (ulong)&crlapb_base->reset_reason);
494 if (ret)
495 return -EINVAL;
d348beaa
MS
496
497 return ret;
498}
499
91d7e0c4
MS
500static int set_fdtfile(void)
501{
502 char *compatible, *fdtfile;
503 const char *suffix = ".dtb";
504 const char *vendor = "xilinx/";
505
506 if (env_get("fdtfile"))
507 return 0;
508
509 compatible = (char *)fdt_getprop(gd->fdt_blob, 0, "compatible", NULL);
510 if (compatible) {
511 debug("Compatible: %s\n", compatible);
512
513 /* Discard vendor prefix */
514 strsep(&compatible, ",");
515
516 fdtfile = calloc(1, strlen(vendor) + strlen(compatible) +
517 strlen(suffix) + 1);
518 if (!fdtfile)
519 return -ENOMEM;
520
521 sprintf(fdtfile, "%s%s%s", vendor, compatible, suffix);
522
523 env_set("fdtfile", fdtfile);
524 free(fdtfile);
525 }
526
527 return 0;
528}
529
84c7204b
MS
530int board_late_init(void)
531{
532 u32 reg = 0;
533 u8 bootmode;
2882b39d
MS
534 struct udevice *dev;
535 int bootseq = -1;
536 int bootseq_len = 0;
0478b0b9 537 int env_targets_len = 0;
b72894f1
MS
538 const char *mode;
539 char *new_targets;
01c42d3d 540 char *env_targets;
d1db89f4 541 int ret;
a69814c8 542 ulong initrd_hi;
b72894f1 543
e615f39e
MS
544#if defined(CONFIG_USB_ETHER) && !defined(CONFIG_USB_GADGET_DOWNLOAD)
545 usb_ether_init();
546#endif
547
b72894f1
MS
548 if (!(gd->flags & GD_FLG_ENV_DEFAULT)) {
549 debug("Saved variables - Skipping\n");
550 return 0;
551 }
84c7204b 552
91d7e0c4
MS
553 ret = set_fdtfile();
554 if (ret)
555 return ret;
556
d1db89f4
SDPP
557 ret = zynqmp_mmio_read((ulong)&crlapb_base->boot_mode, &reg);
558 if (ret)
559 return -EINVAL;
560
47359a03
MS
561 if (reg >> BOOT_MODE_ALT_SHIFT)
562 reg >>= BOOT_MODE_ALT_SHIFT;
563
84c7204b
MS
564 bootmode = reg & BOOT_MODES_MASK;
565
fb90917c 566 puts("Bootmode: ");
84c7204b 567 switch (bootmode) {
d58fc12e
MS
568 case USB_MODE:
569 puts("USB_MODE\n");
570 mode = "usb";
07656ba5 571 env_set("modeboot", "usb_dfu_spl");
d58fc12e 572 break;
0a5bcc8c 573 case JTAG_MODE:
fb90917c 574 puts("JTAG_MODE\n");
5d2274c0 575 mode = "jtag pxe dhcp";
07656ba5 576 env_set("modeboot", "jtagboot");
0a5bcc8c
SDPP
577 break;
578 case QSPI_MODE_24BIT:
579 case QSPI_MODE_32BIT:
b72894f1 580 mode = "qspi0";
fb90917c 581 puts("QSPI_MODE\n");
07656ba5 582 env_set("modeboot", "qspiboot");
0a5bcc8c 583 break;
39c56f55 584 case EMMC_MODE:
78678fee 585 puts("EMMC_MODE\n");
b72894f1 586 mode = "mmc0";
07656ba5 587 env_set("modeboot", "emmcboot");
78678fee
MS
588 break;
589 case SD_MODE:
fb90917c 590 puts("SD_MODE\n");
2882b39d 591 if (uclass_get_device_by_name(UCLASS_MMC,
e7c9de66
SDPP
592 "mmc@ff160000", &dev) &&
593 uclass_get_device_by_name(UCLASS_MMC,
2882b39d
MS
594 "sdhci@ff160000", &dev)) {
595 puts("Boot from SD0 but without SD0 enabled!\n");
596 return -1;
597 }
598 debug("mmc0 device found at %p, seq %d\n", dev, dev->seq);
599
600 mode = "mmc";
601 bootseq = dev->seq;
07656ba5 602 env_set("modeboot", "sdboot");
84c7204b 603 break;
e1992276
SDPP
604 case SD1_LSHFT_MODE:
605 puts("LVL_SHFT_");
606 /* fall through */
af813acd 607 case SD_MODE1:
fb90917c 608 puts("SD_MODE1\n");
2882b39d 609 if (uclass_get_device_by_name(UCLASS_MMC,
e7c9de66
SDPP
610 "mmc@ff170000", &dev) &&
611 uclass_get_device_by_name(UCLASS_MMC,
2882b39d
MS
612 "sdhci@ff170000", &dev)) {
613 puts("Boot from SD1 but without SD1 enabled!\n");
614 return -1;
615 }
616 debug("mmc1 device found at %p, seq %d\n", dev, dev->seq);
617
618 mode = "mmc";
619 bootseq = dev->seq;
07656ba5 620 env_set("modeboot", "sdboot");
af813acd
MS
621 break;
622 case NAND_MODE:
fb90917c 623 puts("NAND_MODE\n");
b72894f1 624 mode = "nand0";
07656ba5 625 env_set("modeboot", "nandboot");
af813acd 626 break;
84c7204b 627 default:
b72894f1 628 mode = "";
84c7204b
MS
629 printf("Invalid Boot Mode:0x%x\n", bootmode);
630 break;
631 }
632
2882b39d
MS
633 if (bootseq >= 0) {
634 bootseq_len = snprintf(NULL, 0, "%i", bootseq);
635 debug("Bootseq len: %x\n", bootseq_len);
636 }
637
b72894f1
MS
638 /*
639 * One terminating char + one byte for space between mode
640 * and default boot_targets
641 */
01c42d3d 642 env_targets = env_get("boot_targets");
0478b0b9
MS
643 if (env_targets)
644 env_targets_len = strlen(env_targets);
645
2882b39d
MS
646 new_targets = calloc(1, strlen(mode) + env_targets_len + 2 +
647 bootseq_len);
1e3e68f1
MS
648 if (!new_targets)
649 return -ENOMEM;
0478b0b9 650
2882b39d
MS
651 if (bootseq >= 0)
652 sprintf(new_targets, "%s%x %s", mode, bootseq,
653 env_targets ? env_targets : "");
654 else
655 sprintf(new_targets, "%s %s", mode,
656 env_targets ? env_targets : "");
b72894f1 657
382bee57 658 env_set("boot_targets", new_targets);
b72894f1 659
a69814c8
KR
660 initrd_hi = gd->start_addr_sp - CONFIG_STACK_SIZE;
661 initrd_hi = round_down(initrd_hi, SZ_16M);
662 env_set_addr("initrd_high", (void *)initrd_hi);
663
d348beaa
MS
664 reset_reason();
665
84c7204b
MS
666 return 0;
667}
0bf3f9cb 668#endif
84696ff5
SDPP
669
670int checkboard(void)
671{
5af08556 672 puts("Board: Xilinx ZynqMP\n");
84696ff5
SDPP
673 return 0;
674}