summaryrefslogtreecommitdiff
path: root/board/xilinx
diff options
context:
space:
mode:
Diffstat (limited to 'board/xilinx')
-rw-r--r--board/xilinx/common/board.c21
-rw-r--r--board/xilinx/versal/Kconfig14
-rw-r--r--board/xilinx/versal/Makefile1
-rw-r--r--board/xilinx/versal/board.c5
-rw-r--r--board/xilinx/versal/cmds.c105
-rw-r--r--board/xilinx/zynq/board.c9
-rw-r--r--board/xilinx/zynqmp/zynqmp.c116
7 files changed, 187 insertions, 84 deletions
diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c
index 0469e2e7ac9..eab389d049f 100644
--- a/board/xilinx/common/board.c
+++ b/board/xilinx/common/board.c
@@ -13,11 +13,10 @@
#include <linux/sizes.h>
#include "board.h"
+#if defined(CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET)
int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
{
int ret = -EINVAL;
-
-#if defined(CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET)
struct udevice *dev;
ofnode eeprom;
@@ -37,10 +36,10 @@ int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
debug("%s: I2C EEPROM MAC address read failed\n", __func__);
else
debug("%s: I2C EEPROM MAC %pM\n", __func__, ethaddr);
-#endif
return ret;
}
+#endif
#if defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE)
void *board_fdt_blob_setup(void)
@@ -78,13 +77,19 @@ void *board_fdt_blob_setup(void)
int board_late_init_xilinx(void)
{
- ulong initrd_hi;
+ u32 ret = 0;
+ phys_size_t bootm_size = gd->ram_size;
+
+ if (CONFIG_IS_ENABLED(ARCH_ZYNQ))
+ bootm_size = min(bootm_size, (phys_size_t)(SZ_512M + SZ_256M));
- env_set_hex("script_offset_f", CONFIG_BOOT_SCRIPT_OFFSET);
+ ret |= env_set_hex("script_offset_f", CONFIG_BOOT_SCRIPT_OFFSET);
- initrd_hi = gd->start_addr_sp - CONFIG_STACK_SIZE;
- initrd_hi = round_down(initrd_hi, SZ_16M);
- env_set_addr("initrd_high", (void *)initrd_hi);
+ ret |= env_set_addr("bootm_low", (void *)gd->ram_base);
+ ret |= env_set_addr("bootm_size", (void *)bootm_size);
+
+ if (ret)
+ printf("%s: Saving run time variables FAILED\n", __func__);
return 0;
}
diff --git a/board/xilinx/versal/Kconfig b/board/xilinx/versal/Kconfig
new file mode 100644
index 00000000000..c0cccc2068b
--- /dev/null
+++ b/board/xilinx/versal/Kconfig
@@ -0,0 +1,14 @@
+# Copyright (c) 2020, Xilinx, Inc.
+#
+# SPDX-License-Identifier: GPL-2.0
+
+if ARCH_VERSAL
+
+config CMD_VERSAL
+ bool "Enable Versal specific commands"
+ default y
+ depends on ZYNQMP_FIRMWARE
+ help
+ Enable Versal specific commands.
+
+endif
diff --git a/board/xilinx/versal/Makefile b/board/xilinx/versal/Makefile
index e9307d7fa69..90e03431540 100644
--- a/board/xilinx/versal/Makefile
+++ b/board/xilinx/versal/Makefile
@@ -5,4 +5,5 @@
#
obj-y := board.o
+obj-$(CONFIG_CMD_VERSAL) += cmds.o
obj-y += ../common/board.o
diff --git a/board/xilinx/versal/board.c b/board/xilinx/versal/board.c
index 45cf1d2d0ca..a5ca4ca8740 100644
--- a/board/xilinx/versal/board.c
+++ b/board/xilinx/versal/board.c
@@ -116,6 +116,9 @@ int board_late_init(void)
return 0;
}
+ if (!CONFIG_IS_ENABLED(ENV_VARS_UBOOT_RUNTIME_CONFIG))
+ return 0;
+
bootmode = versal_get_bootmode();
puts("Bootmode: ");
@@ -229,7 +232,7 @@ int dram_init_banksize(void)
int dram_init(void)
{
- if (fdtdec_setup_mem_size_base() != 0)
+ if (fdtdec_setup_mem_size_base_lowest() != 0)
return -EINVAL;
return 0;
diff --git a/board/xilinx/versal/cmds.c b/board/xilinx/versal/cmds.c
new file mode 100644
index 00000000000..f5735d0c62c
--- /dev/null
+++ b/board/xilinx/versal/cmds.c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2020 Xilinx, Inc.
+ * Michal Simek <michal.simek@xilinx.com>
+ */
+
+#include <cpu_func.h>
+#include <command.h>
+#include <common.h>
+#include <log.h>
+#include <memalign.h>
+#include <versalpl.h>
+#include <zynqmp_firmware.h>
+
+static int do_versal_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[2], NULL, 16);
+ if (!addr) {
+ debug("pdi_load: zero pdi_data address\n");
+ return CMD_RET_USAGE;
+ }
+
+ len = simple_strtoul(argv[3], NULL, 16);
+ 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 ret;
+}
+
+static struct cmd_tbl cmd_versal_sub[] = {
+ U_BOOT_CMD_MKENT(loadpdi, 4, 1, do_versal_load_pdi, "", ""),
+};
+
+/**
+ * do_versal - Handle the "versal" 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 specific commands
+ *
+ * Return: return 0 on success, Error value if command fails.
+ * CMD_RET_USAGE incase of incorrect/missing parameters.
+ */
+static int do_versal(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_versal_sub[0],
+ ARRAY_SIZE(cmd_versal_sub));
+ if (c)
+ ret = c->cmd(c, flag, argc, argv);
+
+ return cmd_process_error(c, ret);
+}
+
+#ifdef CONFIG_SYS_LONGHELP
+static char versal_help_text[] =
+ "loadpdi addr len - Load pdi image\n"
+ "load pdi image at ddr address 'addr' with pdi image size 'len'\n"
+;
+#endif
+
+U_BOOT_CMD(versal, 4, 1, do_versal,
+ "versal sub-system",
+ versal_help_text
+)
+
diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c
index 2164eac8d51..7ac069aaafd 100644
--- a/board/xilinx/zynq/board.c
+++ b/board/xilinx/zynq/board.c
@@ -6,6 +6,7 @@
#include <common.h>
#include <init.h>
+#include <log.h>
#include <dm/uclass.h>
#include <env.h>
#include <fdtdec.h>
@@ -33,6 +34,14 @@ int board_late_init(void)
char *new_targets;
char *env_targets;
+ if (!(gd->flags & GD_FLG_ENV_DEFAULT)) {
+ debug("Saved variables - Skipping\n");
+ return 0;
+ }
+
+ if (!CONFIG_IS_ENABLED(ENV_VARS_UBOOT_RUNTIME_CONFIG))
+ return 0;
+
switch ((zynq_slcr_get_boot_mode()) & ZYNQ_BM_MASK) {
case ZYNQ_BM_QSPI:
mode = "qspi";
diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index ebb71729081..b4e7301d509 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -197,67 +197,6 @@ static const struct {
};
#endif
-int chip_id(unsigned char id)
-{
- struct pt_regs regs;
- int val = -EINVAL;
-
- if (current_el() != 3) {
- regs.regs[0] = ZYNQMP_SIP_SVC_CSU_DMA_CHIPID;
- regs.regs[1] = 0;
- regs.regs[2] = 0;
- regs.regs[3] = 0;
-
- smc_call(&regs);
-
- /*
- * SMC returns:
- * regs[0][31:0] = status of the operation
- * regs[0][63:32] = CSU.IDCODE register
- * regs[1][31:0] = CSU.version register
- * regs[1][63:32] = CSU.IDCODE2 register
- */
- switch (id) {
- case IDCODE:
- regs.regs[0] = upper_32_bits(regs.regs[0]);
- regs.regs[0] &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
- ZYNQMP_CSU_IDCODE_SVD_MASK;
- regs.regs[0] >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
- val = regs.regs[0];
- break;
- case VERSION:
- regs.regs[1] = lower_32_bits(regs.regs[1]);
- regs.regs[1] &= ZYNQMP_CSU_SILICON_VER_MASK;
- val = regs.regs[1];
- break;
- case IDCODE2:
- regs.regs[1] = lower_32_bits(regs.regs[1]);
- regs.regs[1] >>= ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
- val = regs.regs[1];
- break;
- default:
- printf("%s, Invalid Req:0x%x\n", __func__, id);
- }
- } else {
- switch (id) {
- case IDCODE:
- val = readl(ZYNQMP_CSU_IDCODE_ADDR);
- val &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
- ZYNQMP_CSU_IDCODE_SVD_MASK;
- val >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
- break;
- case VERSION:
- val = readl(ZYNQMP_CSU_VER_ADDR);
- val &= ZYNQMP_CSU_SILICON_VER_MASK;
- break;
- default:
- printf("%s, Invalid Req:0x%x\n", __func__, id);
- }
- }
-
- return val;
-}
-
#define ZYNQMP_VERSION_SIZE 9
#define ZYNQMP_PL_STATUS_BIT 9
#define ZYNQMP_IPDIS_VCU_BIT 8
@@ -274,9 +213,28 @@ static char *zynqmp_get_silicon_idcode_name(void)
u32 i, id, ver, j;
char *buf;
static char name[ZYNQMP_VERSION_SIZE];
+ u32 ret_payload[PAYLOAD_ARG_CNT];
+
+ xilinx_pm_request(PM_GET_CHIPID, 0, 0, 0, 0, ret_payload);
+
+ /*
+ * Firmware returns:
+ * payload[0][31:0] = status of the operation
+ * payload[1]] = IDCODE
+ * payload[2][19:0] = Version
+ * payload[2][28:20] = EXTENDED_IDCODE
+ * payload[2][29] = PL_INIT
+ */
+
+ /* Get IDCODE field */
+ id = ret_payload[1];
+ id &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK | ZYNQMP_CSU_IDCODE_SVD_MASK;
+ id >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
- id = chip_id(IDCODE);
- ver = chip_id(IDCODE2);
+ /* Shift silicon version info */
+ ver = ret_payload[2] >> ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
+
+ debug("%s, ID: 0x%0X, Ver: 0x%0X\r\n", __func__, id, ver);
for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
if (zynqmp_devices[i].id == id) {
@@ -387,12 +345,10 @@ int board_init(void)
#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
!defined(CONFIG_SPL_BUILD) || (defined(CONFIG_SPL_FPGA_SUPPORT) && \
defined(CONFIG_SPL_BUILD))
- if (current_el() != 3) {
- zynqmppl.name = zynqmp_get_silicon_idcode_name();
- printf("Chip ID:\t%s\n", zynqmppl.name);
- fpga_init();
- fpga_add(fpga_xilinx, &zynqmppl);
- }
+ zynqmppl.name = zynqmp_get_silicon_idcode_name();
+ printf("Chip ID:\t%s\n", zynqmppl.name);
+ fpga_init();
+ fpga_add(fpga_xilinx, &zynqmppl);
#endif
if (current_el() == 3)
@@ -541,23 +497,30 @@ static int set_fdtfile(void)
char *compatible, *fdtfile;
const char *suffix = ".dtb";
const char *vendor = "xilinx/";
+ int fdt_compat_len;
if (env_get("fdtfile"))
return 0;
- compatible = (char *)fdt_getprop(gd->fdt_blob, 0, "compatible", NULL);
- if (compatible) {
+ compatible = (char *)fdt_getprop(gd->fdt_blob, 0, "compatible",
+ &fdt_compat_len);
+ if (compatible && fdt_compat_len) {
+ char *name;
+
debug("Compatible: %s\n", compatible);
- /* Discard vendor prefix */
- strsep(&compatible, ",");
+ name = strchr(compatible, ',');
+ if (!name)
+ return -EINVAL;
- fdtfile = calloc(1, strlen(vendor) + strlen(compatible) +
+ name++;
+
+ fdtfile = calloc(1, strlen(vendor) + strlen(name) +
strlen(suffix) + 1);
if (!fdtfile)
return -ENOMEM;
- sprintf(fdtfile, "%s%s%s", vendor, compatible, suffix);
+ sprintf(fdtfile, "%s%s%s", vendor, name, suffix);
env_set("fdtfile", fdtfile);
free(fdtfile);
@@ -605,6 +568,9 @@ int board_late_init(void)
return 0;
}
+ if (!CONFIG_IS_ENABLED(ENV_VARS_UBOOT_RUNTIME_CONFIG))
+ return 0;
+
ret = set_fdtfile();
if (ret)
return ret;