summaryrefslogtreecommitdiff
path: root/board/xilinx
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2023-06-12 23:42:37 +0300
committerTom Rini <trini@konsulko.com>2023-06-12 23:42:37 +0300
commit7da82de916d6aaeeef62431810cb3335e1207b28 (patch)
tree9d994cb47482d2679acd701ebb09d0caf4b2122f /board/xilinx
parent260d4962e06c0a7d2713523c131416a3f70d7f2c (diff)
parent89240bc0c44b985e461a4220475cb462263df5be (diff)
downloadu-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.h7
-rw-r--r--board/xilinx/versal-net/Kconfig8
-rw-r--r--board/xilinx/versal-net/Makefile1
-rw-r--r--board/xilinx/versal-net/board.c149
-rw-r--r--board/xilinx/versal-net/cmds.c81
-rw-r--r--board/xilinx/zynqmp/cmds.c26
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"