1 // SPDX-License-Identifier: GPL-2.0+
3 * (C) Copyright 2014 - 2015 Xilinx, Inc.
4 * Michal Simek <michal.simek@xilinx.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 #define ZYNQMP_VERSION_SIZE 7
48 #define EFUSE_VCU_DIS_MASK 0x100
49 #define EFUSE_VCU_DIS_SHIFT 8
50 #define EFUSE_GPU_DIS_MASK 0x20
51 #define EFUSE_GPU_DIS_SHIFT 5
52 #define IDCODE2_PL_INIT_MASK 0x200
53 #define IDCODE2_PL_INIT_SHIFT 9
55 DECLARE_GLOBAL_DATA_PTR;
57 #if CONFIG_IS_ENABLED(FPGA) && defined(CONFIG_FPGA_ZYNQMPPL)
58 static xilinx_desc zynqmppl = XILINX_ZYNQMP_DESC;
61 ZYNQMP_VARIANT_EG = BIT(0U),
62 ZYNQMP_VARIANT_EV = BIT(1U),
63 ZYNQMP_VARIANT_CG = BIT(2U),
64 ZYNQMP_VARIANT_DR = BIT(3U),
71 } zynqmp_devices[] = {
75 .variants = ZYNQMP_VARIANT_EG,
80 .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
85 .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
90 .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG |
96 .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG |
102 .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
107 .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG |
113 .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
118 .variants = ZYNQMP_VARIANT_EG,
123 .variants = ZYNQMP_VARIANT_EG,
128 .variants = ZYNQMP_VARIANT_EG,
133 .variants = ZYNQMP_VARIANT_EG,
138 .variants = ZYNQMP_VARIANT_DR,
143 .variants = ZYNQMP_VARIANT_DR,
148 .variants = ZYNQMP_VARIANT_DR,
153 .variants = ZYNQMP_VARIANT_DR,
158 .variants = ZYNQMP_VARIANT_DR,
163 .variants = ZYNQMP_VARIANT_DR,
168 .variants = ZYNQMP_VARIANT_DR,
173 .variants = ZYNQMP_VARIANT_DR,
178 .variants = ZYNQMP_VARIANT_DR,
183 .variants = ZYNQMP_VARIANT_DR,
188 .variants = ZYNQMP_VARIANT_DR,
193 .variants = ZYNQMP_VARIANT_DR,
198 .variants = ZYNQMP_VARIANT_DR,
202 static const struct {
205 } zynqmp_svd_devices[] = {
216 static char *zynqmp_detect_svd_name(u32 idcode)
220 for (i = 0; i < ARRAY_SIZE(zynqmp_svd_devices); i++) {
221 if (zynqmp_svd_devices[i].id == (idcode & 0x0FFFFFFF))
222 return zynqmp_svd_devices[i].name;
228 static char *zynqmp_get_silicon_idcode_name(void)
232 char name[ZYNQMP_VERSION_SIZE];
233 u32 ret_payload[PAYLOAD_ARG_CNT];
236 ret = xilinx_pm_request(PM_GET_CHIPID, 0, 0, 0, 0, ret_payload);
238 debug("%s: Getting chipid failed\n", __func__);
244 * payload[0][31:0] = status of the operation
245 * payload[1]] = IDCODE
246 * payload[2][19:0] = Version
247 * payload[2][28:20] = EXTENDED_IDCODE
248 * payload[2][29] = PL_INIT
251 idcode = ret_payload[1];
252 idcode2 = ret_payload[2] >> ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
253 debug("%s, IDCODE: 0x%0x, IDCODE2: 0x%0x\r\n", __func__, idcode,
256 for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
257 if (zynqmp_devices[i].id == (idcode & 0x0FFFFFFF))
261 if (i >= ARRAY_SIZE(zynqmp_devices))
262 return zynqmp_detect_svd_name(idcode);
264 /* Add device prefix to the name */
265 ret = snprintf(name, ZYNQMP_VERSION_SIZE, "zu%d",
266 zynqmp_devices[i].device);
270 if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_EV) {
271 /* Devices with EV variant might be EG/CG/EV family */
272 if (idcode2 & IDCODE2_PL_INIT_MASK) {
273 u32 family = ((idcode2 & EFUSE_VCU_DIS_MASK) >>
274 EFUSE_VCU_DIS_SHIFT) << 1 |
275 ((idcode2 & EFUSE_GPU_DIS_MASK) >>
276 EFUSE_GPU_DIS_SHIFT);
279 * Get family name based on extended idcode values as
280 * determined on UG1087, EXTENDED_IDCODE register
285 strncat(name, "ev", 2);
288 strncat(name, "eg", 2);
291 strncat(name, "cg", 2);
294 /* Do not append family name*/
299 * When PL powered down the VCU Disable efuse cannot be
300 * read. So, ignore the bit and just findout if it is CG
303 strncat(name, (idcode2 & EFUSE_GPU_DIS_MASK) ? "cg" :
306 } else if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_CG) {
307 /* Devices with CG variant might be EG or CG family */
308 strncat(name, (idcode2 & EFUSE_GPU_DIS_MASK) ? "cg" : "eg", 2);
309 } else if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_EG) {
310 strncat(name, "eg", 2);
311 } else if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_DR) {
312 strncat(name, "dr", 2);
314 debug("Variant not identified\n");
321 int __maybe_unused psu_uboot_init(void)
330 * PS_SYSMON_ANALOG_BUS register determines mapping between SysMon
331 * supply sense channel to SysMon supply registers inside the IP.
332 * This register must be programmed to complete SysMon IP
333 * configuration. The default register configuration after
334 * power-up is incorrect. Hence, fix this by writing the
335 * correct value - 0x3210.
337 writel(ZYNQMP_PS_SYSMON_ANALOG_BUS_VAL,
338 ZYNQMP_AMS_PS_SYSMON_ANALOG_BUS);
340 /* Delay is required for clocks to be propagated */
346 #if !defined(CONFIG_SPL_BUILD)
347 # if defined(CONFIG_DEBUG_UART_BOARD_INIT)
348 void board_debug_uart_init(void)
350 # if defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED)
356 # if defined(CONFIG_BOARD_EARLY_INIT_F)
357 int board_early_init_f(void)
360 # if defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED) && !defined(CONFIG_DEBUG_UART_BOARD_INIT)
361 ret = psu_uboot_init();
368 static int multi_boot(void)
373 ret = zynqmp_mmio_read((ulong)&csu_base->multi_boot, &multiboot);
380 #if defined(CONFIG_SPL_BUILD)
381 static void restore_jtag(void)
383 if (current_el() != 3)
386 writel(CSU_JTAG_SEC_GATE_DISABLE, &csu_base->jtag_sec);
387 writel(CSU_JTAG_DAP_ENABLE_DEBUG, &csu_base->jtag_dap_cfg);
388 writel(CSU_JTAG_CHAIN_WR_SETUP, &csu_base->jtag_chain_status_wr);
389 writel(CRLAPB_DBG_LPD_CTRL_SETUP_CLK, &crlapb_base->dbg_lpd_ctrl);
390 writel(CRLAPB_RST_LPD_DBG_RESET, &crlapb_base->rst_lpd_dbg);
391 writel(CSU_PCAP_PROG_RELEASE_PL, &csu_base->pcap_prog);
395 static void print_secure_boot(void)
399 if (zynqmp_mmio_read((ulong)&csu_base->status, &status))
402 printf("Secure Boot:\t%sauthenticated, %sencrypted\n",
403 status & ZYNQMP_CSU_STATUS_AUTHENTICATED ? "" : "not ",
404 status & ZYNQMP_CSU_STATUS_ENCRYPTED ? "" : "not ");
409 #if defined(CONFIG_ZYNQMP_FIRMWARE)
412 uclass_get_device_by_name(UCLASS_FIRMWARE, "zynqmp-power", &dev);
414 panic("PMU Firmware device not found - Enable it");
417 #if defined(CONFIG_SPL_BUILD)
418 /* Check *at build time* if the filename is an non-empty string */
419 if (sizeof(CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE) > 1)
420 zynqmp_pmufw_load_config_object(zynqmp_pm_cfg_obj,
421 zynqmp_pm_cfg_obj_size);
422 printf("Silicon version:\t%d\n", zynqmp_get_silicon_version());
424 /* the CSU disables the JTAG interface when secure boot is enabled */
425 if (CONFIG_IS_ENABLED(ZYNQMP_RESTORE_JTAG))
428 if (CONFIG_IS_ENABLED(DM_I2C) && CONFIG_IS_ENABLED(I2C_EEPROM))
429 xilinx_read_eeprom();
432 printf("EL Level:\tEL%d\n", current_el());
434 #if CONFIG_IS_ENABLED(FPGA) && defined(CONFIG_FPGA_ZYNQMPPL)
435 zynqmppl.name = zynqmp_get_silicon_idcode_name();
436 printf("Chip ID:\t%s\n", zynqmppl.name);
438 fpga_add(fpga_xilinx, &zynqmppl);
441 /* display secure boot information */
443 if (current_el() == 3)
444 printf("Multiboot:\t%d\n", multi_boot());
449 int board_early_init_r(void)
453 if (current_el() != 3)
456 val = readl(&crlapb_base->timestamp_ref_ctrl);
457 val &= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT;
460 val = readl(&crlapb_base->timestamp_ref_ctrl);
461 val |= ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT;
462 writel(val, &crlapb_base->timestamp_ref_ctrl);
464 /* Program freq register in System counter */
465 writel(zynqmp_get_system_timer_freq(),
466 &iou_scntr_secure->base_frequency_id_register);
467 /* And enable system counter */
468 writel(ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_EN,
469 &iou_scntr_secure->counter_control_register);
474 unsigned long do_go_exec(ulong (*entry)(int, char * const []), int argc,
479 if (current_el() > 1) {
482 armv8_switch_to_el1(0x0, 0, 0, 0, (unsigned long)entry,
485 printf("FAIL: current EL is not above EL1\n");
491 #if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
492 int dram_init_banksize(void)
496 ret = fdtdec_setup_memory_banksize();
507 if (fdtdec_setup_mem_size_base() != 0)
513 ulong board_get_usable_ram_top(ulong total_size)
519 if (!IS_ALIGNED((ulong)gd->fdt_blob, 0x8))
520 panic("Not 64bit aligned DT location: %p\n", gd->fdt_blob);
522 /* found enough not-reserved memory to relocated U-Boot */
524 lmb_add(&lmb, gd->ram_base, gd->ram_size);
525 boot_fdt_add_mem_rsv_regions(&lmb, (void *)gd->fdt_blob);
526 size = ALIGN(CONFIG_SYS_MALLOC_LEN + total_size, MMU_SECTION_SIZE);
527 reg = lmb_alloc(&lmb, size, MMU_SECTION_SIZE);
530 reg = gd->ram_top - size;
535 int dram_init_banksize(void)
537 gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
538 gd->bd->bi_dram[0].size = get_effective_memsize();
547 gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
548 CONFIG_SYS_SDRAM_SIZE);
554 #if !CONFIG_IS_ENABLED(SYSRESET)
560 static u8 __maybe_unused zynqmp_get_bootmode(void)
566 ret = zynqmp_mmio_read((ulong)&crlapb_base->boot_mode, ®);
570 debug("HW boot mode: %x\n", reg & BOOT_MODES_MASK);
571 debug("ALT boot mode: %x\n", reg >> BOOT_MODE_ALT_SHIFT);
573 if (reg >> BOOT_MODE_ALT_SHIFT)
574 reg >>= BOOT_MODE_ALT_SHIFT;
576 bootmode = reg & BOOT_MODES_MASK;
581 #if defined(CONFIG_BOARD_LATE_INIT)
582 static const struct {
585 } reset_reasons[] = {
586 { RESET_REASON_DEBUG_SYS, "DEBUG" },
587 { RESET_REASON_SOFT, "SOFT" },
588 { RESET_REASON_SRST, "SRST" },
589 { RESET_REASON_PSONLY, "PS-ONLY" },
590 { RESET_REASON_PMU, "PMU" },
591 { RESET_REASON_INTERNAL, "INTERNAL" },
592 { RESET_REASON_EXTERNAL, "EXTERNAL" },
596 static int reset_reason(void)
600 const char *reason = NULL;
602 ret = zynqmp_mmio_read((ulong)&crlapb_base->reset_reason, ®);
606 puts("Reset reason:\t");
608 for (i = 0; i < ARRAY_SIZE(reset_reasons); i++) {
609 if (reg & reset_reasons[i].bit) {
610 reason = reset_reasons[i].name;
611 printf("%s ", reset_reasons[i].name);
618 env_set("reset_reason", reason);
623 static int set_fdtfile(void)
625 char *compatible, *fdtfile;
626 const char *suffix = ".dtb";
627 const char *vendor = "xilinx/";
630 if (env_get("fdtfile"))
633 compatible = (char *)fdt_getprop(gd->fdt_blob, 0, "compatible",
635 if (compatible && fdt_compat_len) {
638 debug("Compatible: %s\n", compatible);
640 name = strchr(compatible, ',');
646 fdtfile = calloc(1, strlen(vendor) + strlen(name) +
651 sprintf(fdtfile, "%s%s%s", vendor, name, suffix);
653 env_set("fdtfile", fdtfile);
660 int board_late_init(void)
666 int env_targets_len = 0;
672 #if defined(CONFIG_USB_ETHER) && !defined(CONFIG_USB_GADGET_DOWNLOAD)
676 if (!(gd->flags & GD_FLG_ENV_DEFAULT)) {
677 debug("Saved variables - Skipping\n");
681 if (!CONFIG_IS_ENABLED(ENV_VARS_UBOOT_RUNTIME_CONFIG))
688 multiboot = multi_boot();
690 env_set_hex("multiboot", multiboot);
692 bootmode = zynqmp_get_bootmode();
698 mode = "usb_dfu0 usb_dfu1";
699 env_set("modeboot", "usb_dfu_spl");
703 mode = "jtag pxe dhcp";
704 env_set("modeboot", "jtagboot");
706 case QSPI_MODE_24BIT:
707 case QSPI_MODE_32BIT:
710 env_set("modeboot", "qspiboot");
714 if (uclass_get_device_by_name(UCLASS_MMC,
715 "mmc@ff160000", &dev) &&
716 uclass_get_device_by_name(UCLASS_MMC,
717 "sdhci@ff160000", &dev)) {
718 puts("Boot from EMMC but without SD0 enabled!\n");
721 debug("mmc0 device found at %p, seq %d\n", dev, dev_seq(dev));
724 bootseq = dev_seq(dev);
725 env_set("modeboot", "emmcboot");
729 if (uclass_get_device_by_name(UCLASS_MMC,
730 "mmc@ff160000", &dev) &&
731 uclass_get_device_by_name(UCLASS_MMC,
732 "sdhci@ff160000", &dev)) {
733 puts("Boot from SD0 but without SD0 enabled!\n");
736 debug("mmc0 device found at %p, seq %d\n", dev, dev_seq(dev));
739 bootseq = dev_seq(dev);
740 env_set("modeboot", "sdboot");
747 if (uclass_get_device_by_name(UCLASS_MMC,
748 "mmc@ff170000", &dev) &&
749 uclass_get_device_by_name(UCLASS_MMC,
750 "sdhci@ff170000", &dev)) {
751 puts("Boot from SD1 but without SD1 enabled!\n");
754 debug("mmc1 device found at %p, seq %d\n", dev, dev_seq(dev));
757 bootseq = dev_seq(dev);
758 env_set("modeboot", "sdboot");
763 env_set("modeboot", "nandboot");
767 printf("Invalid Boot Mode:0x%x\n", bootmode);
772 bootseq_len = snprintf(NULL, 0, "%i", bootseq);
773 debug("Bootseq len: %x\n", bootseq_len);
774 env_set_hex("bootseq", bootseq);
778 * One terminating char + one byte for space between mode
779 * and default boot_targets
781 env_targets = env_get("boot_targets");
783 env_targets_len = strlen(env_targets);
785 new_targets = calloc(1, strlen(mode) + env_targets_len + 2 +
791 sprintf(new_targets, "%s%x %s", mode, bootseq,
792 env_targets ? env_targets : "");
794 sprintf(new_targets, "%s %s", mode,
795 env_targets ? env_targets : "");
797 env_set("boot_targets", new_targets);
802 return board_late_init_xilinx();
808 puts("Board: Xilinx ZynqMP\n");
812 int mmc_get_env_dev(void)
817 switch (zynqmp_get_bootmode()) {
820 if (uclass_get_device_by_name(UCLASS_MMC,
821 "mmc@ff160000", &dev) &&
822 uclass_get_device_by_name(UCLASS_MMC,
823 "sdhci@ff160000", &dev)) {
826 bootseq = dev_seq(dev);
830 if (uclass_get_device_by_name(UCLASS_MMC,
831 "mmc@ff170000", &dev) &&
832 uclass_get_device_by_name(UCLASS_MMC,
833 "sdhci@ff170000", &dev)) {
836 bootseq = dev_seq(dev);
842 debug("bootseq %d\n", bootseq);
847 enum env_location env_get_location(enum env_operation op, int prio)
849 u32 bootmode = zynqmp_get_bootmode();
859 if (IS_ENABLED(CONFIG_ENV_IS_IN_FAT))
861 if (IS_ENABLED(CONFIG_ENV_IS_IN_EXT4))
865 if (IS_ENABLED(CONFIG_ENV_IS_IN_NAND))
867 if (IS_ENABLED(CONFIG_ENV_IS_IN_UBI))
870 case QSPI_MODE_24BIT:
871 case QSPI_MODE_32BIT:
872 if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH))
873 return ENVL_SPI_FLASH;
881 #if defined(CONFIG_SET_DFU_ALT_INFO)
883 #define DFU_ALT_BUF_LEN SZ_1K
885 void set_dfu_alt_info(char *interface, char *devstr)
890 ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN);
892 if (env_get("dfu_alt_info"))
895 memset(buf, 0, sizeof(buf));
897 multiboot = multi_boot();
901 multiboot = env_get_hex("multiboot", multiboot);
902 debug("Multiboot: %d\n", multiboot);
904 switch (zynqmp_get_bootmode()) {
909 bootseq = mmc_get_env_dev();
911 snprintf(buf, DFU_ALT_BUF_LEN,
912 "mmc %d:1=boot.bin fat %d 1;"
915 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME, bootseq);
917 snprintf(buf, DFU_ALT_BUF_LEN,
918 "mmc %d:1=boot%04d.bin fat %d 1;"
920 bootseq, multiboot, bootseq,
921 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME, bootseq);
923 case QSPI_MODE_24BIT:
924 case QSPI_MODE_32BIT:
925 snprintf(buf, DFU_ALT_BUF_LEN,
926 "sf 0:0=boot.bin raw %x 0x1500000;"
927 "%s raw 0x%x 0x500000",
928 multiboot * SZ_32K, CONFIG_SPL_FS_LOAD_PAYLOAD_NAME,
929 CONFIG_SYS_SPI_U_BOOT_OFFS);
935 env_set("dfu_alt_info", buf);
936 puts("DFU alt info setting: done\n");