diff options
author | Tom Rini <trini@konsulko.com> | 2023-06-12 23:42:37 +0300 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2023-06-12 23:42:37 +0300 |
commit | 7da82de916d6aaeeef62431810cb3335e1207b28 (patch) | |
tree | 9d994cb47482d2679acd701ebb09d0caf4b2122f /board/xilinx | |
parent | 260d4962e06c0a7d2713523c131416a3f70d7f2c (diff) | |
parent | 89240bc0c44b985e461a4220475cb462263df5be (diff) | |
download | u-boot-7da82de916d6aaeeef62431810cb3335e1207b28.tar.xz |
Merge tag 'xilinx-for-v2023.10-rc1' of https://source.denx.de/u-boot/custodians/u-boot-microblaze into next
Xilinx changes for v2023.10-rc1
global:
- Use proper U-Boot project name
Fix sparse warnings in zynqmp-clk, zynqmp handoff, board
cmd:
- Cover incorrect 0 length entries
Versal NET:
- Add bootmode logic
- Support SPP production version
- Add loadpdi command
ZynqMP:
- Clear pmufw node command ID handling
- Change power domain behavior around zynqmp_pmufw_node()
- Fix zynqmp cmd return values and pmufw command
- Fix R5 tcm init and modes
mmc:
- Sync Versal NET emmc DT binding
pcie:
- Add support for ZynqMP PCIe root port
video:
- Add support for ZynqMP DP
tools:
- Fix debug message in relocate-rela
Diffstat (limited to 'board/xilinx')
-rw-r--r-- | board/xilinx/common/board.h | 7 | ||||
-rw-r--r-- | board/xilinx/versal-net/Kconfig | 8 | ||||
-rw-r--r-- | board/xilinx/versal-net/Makefile | 1 | ||||
-rw-r--r-- | board/xilinx/versal-net/board.c | 149 | ||||
-rw-r--r-- | board/xilinx/versal-net/cmds.c | 81 | ||||
-rw-r--r-- | board/xilinx/zynqmp/cmds.c | 26 |
6 files changed, 255 insertions, 17 deletions
diff --git a/board/xilinx/common/board.h b/board/xilinx/common/board.h index 69e642429b..922c9d557a 100644 --- a/board/xilinx/common/board.h +++ b/board/xilinx/common/board.h @@ -11,4 +11,11 @@ int board_late_init_xilinx(void); int xilinx_read_eeprom(void); +char *board_name_decode(void); + +bool board_detection(void); + +char *soc_name_decode(void); + +bool soc_detection(void); #endif /* BOARD_XILINX_COMMON_BOARD_H */ diff --git a/board/xilinx/versal-net/Kconfig b/board/xilinx/versal-net/Kconfig index 8f94d2bb39..2484429d3c 100644 --- a/board/xilinx/versal-net/Kconfig +++ b/board/xilinx/versal-net/Kconfig @@ -6,4 +6,12 @@ if ARCH_VERSAL_NET +config CMD_VERSAL_NET + bool "Enable Versal NET specific commands" + default y + depends on ZYNQMP_FIRMWARE + help + Select this to enable Versal NET specific commands. + Commands like versalnet loadpdi are enabled by this. + endif diff --git a/board/xilinx/versal-net/Makefile b/board/xilinx/versal-net/Makefile index 2008d4e231..f9ff07c11c 100644 --- a/board/xilinx/versal-net/Makefile +++ b/board/xilinx/versal-net/Makefile @@ -7,3 +7,4 @@ # obj-y := board.o +obj-$(CONFIG_CMD_VERSAL_NET) += cmds.o diff --git a/board/xilinx/versal-net/board.c b/board/xilinx/versal-net/board.c index 6724c7290f..a68b608b82 100644 --- a/board/xilinx/versal-net/board.c +++ b/board/xilinx/versal-net/board.c @@ -10,6 +10,7 @@ #include <cpu_func.h> #include <fdtdec.h> #include <init.h> +#include <env_internal.h> #include <log.h> #include <malloc.h> #include <time.h> @@ -74,32 +75,45 @@ char *soc_name_decode(void) bool soc_detection(void) { - u32 version; + u32 version, ps_version; version = readl(PMC_TAP_VERSION); platform_id = FIELD_GET(PLATFORM_MASK, version); + ps_version = FIELD_GET(PS_VERSION_MASK, version); debug("idcode %x, version %x, usercode %x\n", readl(PMC_TAP_IDCODE), version, readl(PMC_TAP_USERCODE)); - debug("pmc_ver %lx, ps version %lx, rtl version %lx\n", + debug("pmc_ver %lx, ps version %x, rtl version %lx\n", FIELD_GET(PMC_VERSION_MASK, version), - FIELD_GET(PS_VERSION_MASK, version), + ps_version, FIELD_GET(RTL_VERSION_MASK, version)); platform_version = FIELD_GET(PLATFORM_VERSION_MASK, version); if (platform_id == VERSAL_NET_SPP || platform_id == VERSAL_NET_EMU) { - /* - * 9 is diff for - * 0 means 0.9 version - * 1 means 1.0 version - * 2 means 1.1 version - * etc, - */ - platform_version += 9; + if (ps_version == PS_VERSION_PRODUCTION) { + /* + * ES1 version ends at 1.9 version where there was +9 + * used because of IPP/SPP conversion. Production + * version have platform_version started from 0 again + * that's why adding +20 to continue with the same line. + * It means the last ES1 version ends at 1.9 version and + * new PRODUCTION line starts at 2.0. + */ + platform_version += 20; + } else { + /* + * 9 is diff for + * 0 means 0.9 version + * 1 means 1.0 version + * 2 means 1.1 version + * etc, + */ + platform_version += 9; + } } debug("Platform id: %d version: %d.%d\n", platform_id, @@ -165,8 +179,32 @@ int board_early_init_r(void) return 0; } +static u8 versal_net_get_bootmode(void) +{ + u8 bootmode; + u32 reg = 0; + + reg = readl(&crp_base->boot_mode_usr); + + if (reg >> BOOT_MODE_ALT_SHIFT) + reg >>= BOOT_MODE_ALT_SHIFT; + + bootmode = reg & BOOT_MODES_MASK; + + return bootmode; +} + int board_late_init(void) { + u8 bootmode; + struct udevice *dev; + int bootseq = -1; + int bootseq_len = 0; + int env_targets_len = 0; + const char *mode; + char *new_targets; + char *env_targets; + if (!(gd->flags & GD_FLG_ENV_DEFAULT)) { debug("Saved variables - Skipping\n"); return 0; @@ -175,6 +213,95 @@ int board_late_init(void) if (!IS_ENABLED(CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG)) return 0; + bootmode = versal_net_get_bootmode(); + + puts("Bootmode: "); + switch (bootmode) { + case USB_MODE: + puts("USB_MODE\n"); + mode = "usb_dfu0 usb_dfu1"; + break; + case JTAG_MODE: + puts("JTAG_MODE\n"); + mode = "jtag pxe dhcp"; + break; + case QSPI_MODE_24BIT: + puts("QSPI_MODE_24\n"); + mode = "xspi0"; + break; + case QSPI_MODE_32BIT: + puts("QSPI_MODE_32\n"); + mode = "xspi0"; + break; + case OSPI_MODE: + puts("OSPI_MODE\n"); + mode = "xspi0"; + break; + case EMMC_MODE: + puts("EMMC_MODE\n"); + mode = "mmc"; + bootseq = dev_seq(dev); + break; + case SD_MODE: + puts("SD_MODE\n"); + if (uclass_get_device_by_name(UCLASS_MMC, + "mmc@f1040000", &dev)) { + puts("Boot from SD0 but without SD0 enabled!\n"); + return -1; + } + debug("mmc0 device found at %p, seq %d\n", dev, dev_seq(dev)); + + mode = "mmc"; + bootseq = dev_seq(dev); + break; + case SD1_LSHFT_MODE: + puts("LVL_SHFT_"); + fallthrough; + case SD_MODE1: + puts("SD_MODE1\n"); + if (uclass_get_device_by_name(UCLASS_MMC, + "mmc@f1050000", &dev)) { + puts("Boot from SD1 but without SD1 enabled!\n"); + return -1; + } + debug("mmc1 device found at %p, seq %d\n", dev, dev_seq(dev)); + + mode = "mmc"; + bootseq = dev_seq(dev); + break; + default: + mode = ""; + printf("Invalid Boot Mode:0x%x\n", bootmode); + break; + } + + if (bootseq >= 0) { + bootseq_len = snprintf(NULL, 0, "%i", bootseq); + debug("Bootseq len: %x\n", bootseq_len); + } + + /* + * One terminating char + one byte for space between mode + * and default boot_targets + */ + env_targets = env_get("boot_targets"); + if (env_targets) + env_targets_len = strlen(env_targets); + + new_targets = calloc(1, strlen(mode) + env_targets_len + 2 + + bootseq_len); + if (!new_targets) + return -ENOMEM; + + if (bootseq >= 0) + sprintf(new_targets, "%s%x %s", mode, bootseq, + env_targets ? env_targets : ""); + else + sprintf(new_targets, "%s %s", mode, + env_targets ? env_targets : ""); + + env_set("boot_targets", new_targets); + return board_late_init_xilinx(); } diff --git a/board/xilinx/versal-net/cmds.c b/board/xilinx/versal-net/cmds.c new file mode 100644 index 0000000000..b18a71fe52 --- /dev/null +++ b/board/xilinx/versal-net/cmds.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2023, Advanced Micro Devices, Inc. + * + * Michal Simek <michal.simek@amd.com> + */ + +#include <cpu_func.h> +#include <command.h> +#include <common.h> +#include <log.h> +#include <memalign.h> +#include <versalpl.h> +#include <zynqmp_firmware.h> + +/** + * do_versalnet_load_pdi - Handle the "versalnet load pdi" command-line command + * @cmdtp: Command data struct pointer + * @flag: Command flag + * @argc: Command-line argument count + * @argv: Array of command-line arguments + * + * Processes the Versal NET load pdi command + * + * Return: return 0 on success, Error value if command fails. + * CMD_RET_USAGE incase of incorrect/missing parameters. + */ +static int do_versalnet_load_pdi(struct cmd_tbl *cmdtp, int flag, int argc, + char * const argv[]) +{ + u32 buf_lo, buf_hi; + u32 ret_payload[PAYLOAD_ARG_CNT]; + ulong addr, *pdi_buf; + size_t len; + int ret; + + if (argc != cmdtp->maxargs) { + debug("pdi_load: incorrect parameters passed\n"); + return CMD_RET_USAGE; + } + + addr = simple_strtol(argv[1], NULL, 16); + if (!addr) { + debug("pdi_load: zero pdi_data address\n"); + return CMD_RET_USAGE; + } + + len = hextoul(argv[2], NULL); + if (!len) { + debug("pdi_load: zero size\n"); + return CMD_RET_USAGE; + } + + pdi_buf = (ulong *)ALIGN((ulong)addr, ARCH_DMA_MINALIGN); + if ((ulong)addr != (ulong)pdi_buf) { + memcpy((void *)pdi_buf, (void *)addr, len); + debug("Pdi addr:0x%lx aligned to 0x%lx\n", + addr, (ulong)pdi_buf); + } + + flush_dcache_range((ulong)pdi_buf, (ulong)pdi_buf + len); + + buf_lo = lower_32_bits((ulong)pdi_buf); + buf_hi = upper_32_bits((ulong)pdi_buf); + + ret = xilinx_pm_request(VERSAL_PM_LOAD_PDI, VERSAL_PM_PDI_TYPE, buf_lo, + buf_hi, 0, ret_payload); + if (ret) + printf("PDI load failed with err: 0x%08x\n", ret); + + return cmd_process_error(cmdtp, ret); +} + +static char versalnet_help_text[] = + "loadpdi addr len - Load pdi image\n" + "load pdi image at ddr address 'addr' with pdi image size 'len'\n" +; + +U_BOOT_CMD_WITH_SUBCMDS(versalnet, "Versal NET sub-system", versalnet_help_text, + U_BOOT_SUBCMD_MKENT(loadpdi, 3, 1, + do_versalnet_load_pdi)); diff --git a/board/xilinx/zynqmp/cmds.c b/board/xilinx/zynqmp/cmds.c index e20030ecda..dd1ad66f90 100644 --- a/board/xilinx/zynqmp/cmds.c +++ b/board/xilinx/zynqmp/cmds.c @@ -187,6 +187,11 @@ static int do_zynqmp_tcm_init(struct cmd_tbl *cmdtp, int flag, int argc, if (argc != cmdtp->maxargs) return CMD_RET_USAGE; + if (strcmp(argv[2], "lockstep") && strcmp(argv[2], "split")) { + printf("mode param should be lockstep or split\n"); + return CMD_RET_FAILURE; + } + mode = hextoul(argv[2], NULL); if (mode != TCM_LOCK && mode != TCM_SPLIT) { printf("Mode should be either 0(lock)/1(split)\n"); @@ -211,15 +216,24 @@ static int do_zynqmp_pmufw(struct cmd_tbl *cmdtp, int flag, int argc, if (!strncmp(argv[2], "node", 4)) { u32 id; + int ret; if (!strncmp(argv[3], "close", 5)) return zynqmp_pmufw_config_close(); id = dectoul(argv[3], NULL); + if (!id) { + printf("Incorrect ID passed\n"); + return CMD_RET_USAGE; + } printf("Enable permission for node ID %d\n", id); - return zynqmp_pmufw_node(id); + ret = zynqmp_pmufw_node(id); + if (ret == -ENODEV) + ret = 0; + + return ret; } addr = hextoul(argv[2], NULL); @@ -390,17 +404,17 @@ static int do_zynqmp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { struct cmd_tbl *c; + int ret = CMD_RET_USAGE; if (argc < 2) return CMD_RET_USAGE; c = find_cmd_tbl(argv[1], &cmd_zynqmp_sub[0], ARRAY_SIZE(cmd_zynqmp_sub)); - if (c) - return c->cmd(c, flag, argc, argv); - else - return CMD_RET_USAGE; + ret = c->cmd(c, flag, argc, argv); + + return cmd_process_error(c, ret); } /***************************************************/ @@ -429,7 +443,7 @@ static char zynqmp_help_text[] = " lock(0)/split(1)\n" #endif "zynqmp pmufw address size - load PMU FW configuration object\n" - "zynqmp pmufw node <id> - load PMU FW configuration object\n" + "zynqmp pmufw node <id> - load PMU FW configuration object, <id> in dec\n" "zynqmp pmufw node close - disable config object loading\n" " node: keyword, id: NODE_ID in decimal format\n" "zynqmp rsa srcaddr srclen mod exp rsaop -\n" |