1 // SPDX-License-Identifier: GPL-2.0+
3 * (C) Copyright 2014 - 2015 Xilinx, Inc.
4 * Michal Simek <michal.simek@amd.com>
10 #include <debug_uart.h>
13 #include <env_internal.h>
25 #include <asm/arch/clk.h>
26 #include <asm/arch/hardware.h>
27 #include <asm/arch/sys_proto.h>
28 #include <asm/arch/psu_init_gpl.h>
29 #include <asm/cache.h>
30 #include <asm/global_data.h>
32 #include <asm/ptrace.h>
33 #include <dm/device.h>
34 #include <dm/uclass.h>
36 #include <dwc3-uboot.h>
38 #include <zynqmp_firmware.h>
40 #include <linux/bitops.h>
41 #include <linux/delay.h>
42 #include <linux/sizes.h>
43 #include "../common/board.h"
45 #include "pm_cfg_obj.h"
47 DECLARE_GLOBAL_DATA_PTR
;
49 #if CONFIG_IS_ENABLED(FPGA) && defined(CONFIG_FPGA_ZYNQMPPL)
50 static xilinx_desc zynqmppl
= {
51 xilinx_zynqmp
, csu_dma
, 1, &zynqmp_op
, 0, &zynqmp_op
, NULL
,
56 int __maybe_unused
psu_uboot_init(void)
65 * PS_SYSMON_ANALOG_BUS register determines mapping between SysMon
66 * supply sense channel to SysMon supply registers inside the IP.
67 * This register must be programmed to complete SysMon IP
68 * configuration. The default register configuration after
69 * power-up is incorrect. Hence, fix this by writing the
70 * correct value - 0x3210.
72 writel(ZYNQMP_PS_SYSMON_ANALOG_BUS_VAL
,
73 ZYNQMP_AMS_PS_SYSMON_ANALOG_BUS
);
75 /* Delay is required for clocks to be propagated */
81 #if !defined(CONFIG_SPL_BUILD)
82 # if defined(CONFIG_DEBUG_UART_BOARD_INIT)
83 void board_debug_uart_init(void)
85 # if defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED)
91 # if defined(CONFIG_BOARD_EARLY_INIT_F)
92 int board_early_init_f(void)
95 # if defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED) && !defined(CONFIG_DEBUG_UART_BOARD_INIT)
96 ret
= psu_uboot_init();
103 static int multi_boot(void)
108 ret
= zynqmp_mmio_read((ulong
)&csu_base
->multi_boot
, &multiboot
);
115 #if defined(CONFIG_SPL_BUILD)
116 static void restore_jtag(void)
118 if (current_el() != 3)
121 writel(CSU_JTAG_SEC_GATE_DISABLE
, &csu_base
->jtag_sec
);
122 writel(CSU_JTAG_DAP_ENABLE_DEBUG
, &csu_base
->jtag_dap_cfg
);
123 writel(CSU_JTAG_CHAIN_WR_SETUP
, &csu_base
->jtag_chain_status_wr
);
124 writel(CRLAPB_DBG_LPD_CTRL_SETUP_CLK
, &crlapb_base
->dbg_lpd_ctrl
);
125 writel(CRLAPB_RST_LPD_DBG_RESET
, &crlapb_base
->rst_lpd_dbg
);
126 writel(CSU_PCAP_PROG_RELEASE_PL
, &csu_base
->pcap_prog
);
130 static void print_secure_boot(void)
134 if (zynqmp_mmio_read((ulong
)&csu_base
->status
, &status
))
137 printf("Secure Boot:\t%sauthenticated, %sencrypted\n",
138 status
& ZYNQMP_CSU_STATUS_AUTHENTICATED
? "" : "not ",
139 status
& ZYNQMP_CSU_STATUS_ENCRYPTED
? "" : "not ");
144 #if CONFIG_IS_ENABLED(FPGA) && defined(CONFIG_FPGA_ZYNQMPPL)
146 char name
[SOC_MAX_STR_SIZE
];
150 #if defined(CONFIG_SPL_BUILD)
151 /* Check *at build time* if the filename is an non-empty string */
152 if (sizeof(CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE
) > 1)
153 zynqmp_pmufw_load_config_object(zynqmp_pm_cfg_obj
,
154 zynqmp_pm_cfg_obj_size
);
157 #if defined(CONFIG_ZYNQMP_FIRMWARE)
160 uclass_get_device_by_name(UCLASS_FIRMWARE
, "power-management", &dev
);
162 uclass_get_device_by_name(UCLASS_FIRMWARE
, "zynqmp-power", &dev
);
164 panic("PMU Firmware device not found - Enable it");
168 #if defined(CONFIG_SPL_BUILD)
169 printf("Silicon version:\t%d\n", zynqmp_get_silicon_version());
171 /* the CSU disables the JTAG interface when secure boot is enabled */
172 if (CONFIG_IS_ENABLED(ZYNQMP_RESTORE_JTAG
))
175 if (CONFIG_IS_ENABLED(DM_I2C
) && CONFIG_IS_ENABLED(I2C_EEPROM
))
176 xilinx_read_eeprom();
179 printf("EL Level:\tEL%d\n", current_el());
181 #if CONFIG_IS_ENABLED(FPGA) && defined(CONFIG_FPGA_ZYNQMPPL)
184 ret
= soc_get_machine(soc
, name
, sizeof(name
));
186 zynqmppl
.name
= strdup(name
);
188 fpga_add(fpga_xilinx
, &zynqmppl
);
193 /* display secure boot information */
195 if (current_el() == 3)
196 printf("Multiboot:\t%d\n", multi_boot());
201 int board_early_init_r(void)
205 if (current_el() != 3)
208 val
= readl(&crlapb_base
->timestamp_ref_ctrl
);
209 val
&= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT
;
212 val
= readl(&crlapb_base
->timestamp_ref_ctrl
);
213 val
|= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT
;
214 writel(val
, &crlapb_base
->timestamp_ref_ctrl
);
216 /* Program freq register in System counter */
217 writel(zynqmp_get_system_timer_freq(),
218 &iou_scntr_secure
->base_frequency_id_register
);
219 /* And enable system counter */
220 writel(ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_EN
,
221 &iou_scntr_secure
->counter_control_register
);
226 unsigned long do_go_exec(ulong (*entry
)(int, char * const []), int argc
,
231 if (current_el() > 1) {
234 armv8_switch_to_el1(0x0, 0, 0, 0, (unsigned long)entry
,
237 printf("FAIL: current EL is not above EL1\n");
243 #if !defined(CFG_SYS_SDRAM_BASE) && !defined(CFG_SYS_SDRAM_SIZE)
244 int dram_init_banksize(void)
248 ret
= fdtdec_setup_memory_banksize();
259 if (fdtdec_setup_mem_size_base() != 0)
266 int dram_init_banksize(void)
268 gd
->bd
->bi_dram
[0].start
= CFG_SYS_SDRAM_BASE
;
269 gd
->bd
->bi_dram
[0].size
= get_effective_memsize();
278 gd
->ram_size
= get_ram_size((void *)CFG_SYS_SDRAM_BASE
,
285 #if !CONFIG_IS_ENABLED(SYSRESET)
291 static u8 __maybe_unused
zynqmp_get_bootmode(void)
297 ret
= zynqmp_mmio_read((ulong
)&crlapb_base
->boot_mode
, ®
);
301 debug("HW boot mode: %x\n", reg
& BOOT_MODES_MASK
);
302 debug("ALT boot mode: %x\n", reg
>> BOOT_MODE_ALT_SHIFT
);
304 if (reg
>> BOOT_MODE_ALT_SHIFT
)
305 reg
>>= BOOT_MODE_ALT_SHIFT
;
307 bootmode
= reg
& BOOT_MODES_MASK
;
312 #if defined(CONFIG_BOARD_LATE_INIT)
313 static const struct {
316 } reset_reasons
[] = {
317 { RESET_REASON_DEBUG_SYS
, "DEBUG" },
318 { RESET_REASON_SOFT
, "SOFT" },
319 { RESET_REASON_SRST
, "SRST" },
320 { RESET_REASON_PSONLY
, "PS-ONLY" },
321 { RESET_REASON_PMU
, "PMU" },
322 { RESET_REASON_INTERNAL
, "INTERNAL" },
323 { RESET_REASON_EXTERNAL
, "EXTERNAL" },
327 static int reset_reason(void)
331 const char *reason
= NULL
;
333 ret
= zynqmp_mmio_read((ulong
)&crlapb_base
->reset_reason
, ®
);
337 puts("Reset reason:\t");
339 for (i
= 0; i
< ARRAY_SIZE(reset_reasons
); i
++) {
340 if (reg
& reset_reasons
[i
].bit
) {
341 reason
= reset_reasons
[i
].name
;
342 printf("%s ", reset_reasons
[i
].name
);
349 env_set("reset_reason", reason
);
354 static int set_fdtfile(void)
356 char *compatible
, *fdtfile
;
357 const char *suffix
= ".dtb";
358 const char *vendor
= "xilinx/";
361 if (env_get("fdtfile"))
364 compatible
= (char *)fdt_getprop(gd
->fdt_blob
, 0, "compatible",
366 if (compatible
&& fdt_compat_len
) {
369 debug("Compatible: %s\n", compatible
);
371 name
= strchr(compatible
, ',');
377 fdtfile
= calloc(1, strlen(vendor
) + strlen(name
) +
382 sprintf(fdtfile
, "%s%s%s", vendor
, name
, suffix
);
384 env_set("fdtfile", fdtfile
);
391 static int boot_targets_setup(void)
397 int env_targets_len
= 0;
398 const char *mode
= NULL
;
402 bootmode
= zynqmp_get_bootmode();
408 mode
= "usb_dfu0 usb_dfu1";
409 env_set("modeboot", "usb_dfu_spl");
413 mode
= "jtag pxe dhcp";
414 env_set("modeboot", "jtagboot");
416 case QSPI_MODE_24BIT
:
417 case QSPI_MODE_32BIT
:
420 env_set("modeboot", "qspiboot");
424 if (uclass_get_device_by_name(UCLASS_MMC
,
425 "mmc@ff160000", &dev
) &&
426 uclass_get_device_by_name(UCLASS_MMC
,
427 "sdhci@ff160000", &dev
)) {
428 debug("SD0 driver for SD0 device is not present\n");
431 debug("mmc0 device found at %p, seq %d\n", dev
, dev_seq(dev
));
434 bootseq
= dev_seq(dev
);
435 env_set("modeboot", "emmcboot");
439 if (uclass_get_device_by_name(UCLASS_MMC
,
440 "mmc@ff160000", &dev
) &&
441 uclass_get_device_by_name(UCLASS_MMC
,
442 "sdhci@ff160000", &dev
)) {
443 debug("SD0 driver for SD0 device is not present\n");
446 debug("mmc0 device found at %p, seq %d\n", dev
, dev_seq(dev
));
449 bootseq
= dev_seq(dev
);
450 env_set("modeboot", "sdboot");
457 if (uclass_get_device_by_name(UCLASS_MMC
,
458 "mmc@ff170000", &dev
) &&
459 uclass_get_device_by_name(UCLASS_MMC
,
460 "sdhci@ff170000", &dev
)) {
461 debug("SD1 driver for SD1 device is not present\n");
464 debug("mmc1 device found at %p, seq %d\n", dev
, dev_seq(dev
));
467 bootseq
= dev_seq(dev
);
468 env_set("modeboot", "sdboot");
473 env_set("modeboot", "nandboot");
476 printf("Invalid Boot Mode:0x%x\n", bootmode
);
482 bootseq_len
= snprintf(NULL
, 0, "%i", bootseq
);
483 debug("Bootseq len: %x\n", bootseq_len
);
484 env_set_hex("bootseq", bootseq
);
488 * One terminating char + one byte for space between mode
489 * and default boot_targets
491 env_targets
= env_get("boot_targets");
493 env_targets_len
= strlen(env_targets
);
495 new_targets
= calloc(1, strlen(mode
) + env_targets_len
+ 2 +
501 sprintf(new_targets
, "%s%x %s", mode
, bootseq
,
502 env_targets
? env_targets
: "");
504 sprintf(new_targets
, "%s %s", mode
,
505 env_targets
? env_targets
: "");
507 env_set("boot_targets", new_targets
);
514 int board_late_init(void)
518 #if defined(CONFIG_USB_ETHER) && !defined(CONFIG_USB_GADGET_DOWNLOAD)
522 if (!(gd
->flags
& GD_FLG_ENV_DEFAULT
)) {
523 debug("Saved variables - Skipping\n");
527 if (!IS_ENABLED(CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
))
534 multiboot
= multi_boot();
536 env_set_hex("multiboot", multiboot
);
538 if (IS_ENABLED(CONFIG_DISTRO_DEFAULTS
)) {
539 ret
= boot_targets_setup();
546 return board_late_init_xilinx();
552 puts("Board: Xilinx ZynqMP\n");
556 int mmc_get_env_dev(void)
561 switch (zynqmp_get_bootmode()) {
564 if (uclass_get_device_by_name(UCLASS_MMC
,
565 "mmc@ff160000", &dev
) &&
566 uclass_get_device_by_name(UCLASS_MMC
,
567 "sdhci@ff160000", &dev
)) {
570 bootseq
= dev_seq(dev
);
574 if (uclass_get_device_by_name(UCLASS_MMC
,
575 "mmc@ff170000", &dev
) &&
576 uclass_get_device_by_name(UCLASS_MMC
,
577 "sdhci@ff170000", &dev
)) {
580 bootseq
= dev_seq(dev
);
586 debug("bootseq %d\n", bootseq
);
591 #if defined(CONFIG_ENV_IS_NOWHERE)
592 enum env_location
env_get_location(enum env_operation op
, int prio
)
594 u32 bootmode
= zynqmp_get_bootmode();
604 if (IS_ENABLED(CONFIG_ENV_IS_IN_FAT
))
606 if (IS_ENABLED(CONFIG_ENV_IS_IN_EXT4
))
610 if (IS_ENABLED(CONFIG_ENV_IS_IN_NAND
))
612 if (IS_ENABLED(CONFIG_ENV_IS_IN_UBI
))
615 case QSPI_MODE_24BIT
:
616 case QSPI_MODE_32BIT
:
617 if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH
))
618 return ENVL_SPI_FLASH
;
627 #if defined(CONFIG_SET_DFU_ALT_INFO)
629 #define DFU_ALT_BUF_LEN SZ_1K
631 static void mtd_found_part(u32
*base
, u32
*size
)
633 struct mtd_info
*part
, *mtd
;
637 mtd
= get_mtd_device_nm("nor0");
638 if (!IS_ERR_OR_NULL(mtd
)) {
639 list_for_each_entry(part
, &mtd
->partitions
, node
) {
640 debug("0x%012llx-0x%012llx : \"%s\"\n",
641 part
->offset
, part
->offset
+ part
->size
,
644 if (*base
>= part
->offset
&&
645 *base
< part
->offset
+ part
->size
) {
646 debug("Found my partition: %d/%s\n",
647 part
->index
, part
->name
);
648 *base
= part
->offset
;
656 void set_dfu_alt_info(char *interface
, char *devstr
)
658 int multiboot
, bootseq
= 0, len
= 0;
660 ALLOC_CACHE_ALIGN_BUFFER(char, buf
, DFU_ALT_BUF_LEN
);
662 if (env_get("dfu_alt_info"))
665 memset(buf
, 0, sizeof(buf
));
667 multiboot
= multi_boot();
671 multiboot
= env_get_hex("multiboot", multiboot
);
672 debug("Multiboot: %d\n", multiboot
);
674 switch (zynqmp_get_bootmode()) {
679 bootseq
= mmc_get_env_dev();
681 len
+= snprintf(buf
+ len
, DFU_ALT_BUF_LEN
, "mmc %d=boot",
685 len
+= snprintf(buf
+ len
, DFU_ALT_BUF_LEN
,
688 len
+= snprintf(buf
+ len
, DFU_ALT_BUF_LEN
, ".bin fat %d 1",
690 #if defined(CONFIG_SPL_FS_LOAD_PAYLOAD_NAME)
691 if (strlen(CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
))
692 len
+= snprintf(buf
+ len
, DFU_ALT_BUF_LEN
,
694 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
,
698 case QSPI_MODE_24BIT
:
699 case QSPI_MODE_32BIT
:
701 u32 base
= multiboot
* SZ_32K
;
702 u32 size
= 0x1500000;
705 mtd_found_part(&base
, &limit
);
707 #if defined(CONFIG_SYS_SPI_U_BOOT_OFFS)
709 limit
= CONFIG_SYS_SPI_U_BOOT_OFFS
;
712 len
+= snprintf(buf
+ len
, DFU_ALT_BUF_LEN
,
713 "sf 0:0=boot.bin raw 0x%x 0x%x",
715 #if defined(CONFIG_SPL_FS_LOAD_PAYLOAD_NAME) && defined(CONFIG_SYS_SPI_U_BOOT_OFFS)
716 if (strlen(CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
))
717 len
+= snprintf(buf
+ len
, DFU_ALT_BUF_LEN
,
719 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
,
720 base
+ limit
, size
- limit
);
728 env_set("dfu_alt_info", buf
);
729 puts("DFU alt info setting: done\n");
733 #if defined(CONFIG_SPL_SPI_LOAD)
734 unsigned int spl_spi_get_uboot_offs(struct spi_flash
*flash
)
737 int multiboot
= multi_boot();
739 offset
= multiboot
* SZ_32K
;
740 offset
+= CONFIG_SYS_SPI_U_BOOT_OFFS
;
742 log_info("SPI offset:\t0x%x\n", offset
);