summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/boards/zynqmp.rst4
-rw-r--r--arch/arm/boards/Makefile1
-rw-r--r--arch/arm/boards/xilinx-zcu106/Makefile3
-rw-r--r--arch/arm/boards/xilinx-zcu106/board.c21
-rw-r--r--arch/arm/boards/xilinx-zcu106/lowlevel.c24
-rw-r--r--arch/arm/boards/xilinx-zcu106/lowlevel_init.S12
-rw-r--r--arch/arm/dts/Makefile1
-rw-r--r--arch/arm/dts/zynqmp-zcu106-revA.dts21
-rw-r--r--arch/arm/mach-zynqmp/Kconfig6
-rw-r--r--arch/arm/mach-zynqmp/zynqmp-bbu.c40
-rw-r--r--arch/arm/mach-zynqmp/zynqmp.c86
-rw-r--r--drivers/firmware/zynqmp-fpga.c55
-rw-r--r--images/Makefile.zynqmp4
13 files changed, 211 insertions, 67 deletions
diff --git a/Documentation/boards/zynqmp.rst b/Documentation/boards/zynqmp.rst
index 05d41c401d..98fcac017b 100644
--- a/Documentation/boards/zynqmp.rst
+++ b/Documentation/boards/zynqmp.rst
@@ -30,8 +30,8 @@ instructions for these tools how to prepare the BOOT.BIN image.
Create a FAT partition as the first partition of the SD card and copy the
produced BOOT.BIN into this partition.
-.. _FSBL: `https://github.com/Xilinx/embeddedsw/`
-.. _bootgen: `https://github.com/Xilinx/bootgen`
+.. _FSBL: https://github.com/Xilinx/embeddedsw/
+.. _bootgen: https://github.com/Xilinx/bootgen
Booting Barebox
---------------
diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile
index 810d94b7f0..a841053c20 100644
--- a/arch/arm/boards/Makefile
+++ b/arch/arm/boards/Makefile
@@ -171,6 +171,7 @@ obj-$(CONFIG_MACH_WARP7) += element14-warp7/
obj-$(CONFIG_MACH_WEBASTO_CCBV2) += webasto-ccbv2/
obj-$(CONFIG_MACH_VF610_TWR) += freescale-vf610-twr/
obj-$(CONFIG_MACH_XILINX_ZCU104) += xilinx-zcu104/
+obj-$(CONFIG_MACH_XILINX_ZCU106) += xilinx-zcu106/
obj-$(CONFIG_MACH_ZII_COMMON) += zii-common/
obj-$(CONFIG_MACH_ZII_RDU1) += zii-imx51-rdu1/
obj-$(CONFIG_MACH_ZII_RDU2) += zii-imx6q-rdu2/
diff --git a/arch/arm/boards/xilinx-zcu106/Makefile b/arch/arm/boards/xilinx-zcu106/Makefile
new file mode 100644
index 0000000000..297f77d57a
--- /dev/null
+++ b/arch/arm/boards/xilinx-zcu106/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+obj-y += board.o
+lwl-y += lowlevel.o lowlevel_init.o
diff --git a/arch/arm/boards/xilinx-zcu106/board.c b/arch/arm/boards/xilinx-zcu106/board.c
new file mode 100644
index 0000000000..0cb5ce86ea
--- /dev/null
+++ b/arch/arm/boards/xilinx-zcu106/board.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021, WolfVision GmbH
+ * Author: Michael Riesch <michael.riesch@wolfvision.net>
+ *
+ * Based on the barebox ZCU104 board support code.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <mach/zynqmp-bbu.h>
+
+static int zcu106_register_update_handler(void)
+{
+ if (!of_machine_is_compatible("xlnx,zynqmp-zcu106"))
+ return 0;
+
+ return zynqmp_bbu_register_handler("SD", "/boot/BOOT.BIN",
+ BBU_HANDLER_FLAG_DEFAULT);
+}
+device_initcall(zcu106_register_update_handler);
diff --git a/arch/arm/boards/xilinx-zcu106/lowlevel.c b/arch/arm/boards/xilinx-zcu106/lowlevel.c
new file mode 100644
index 0000000000..ccc8d61418
--- /dev/null
+++ b/arch/arm/boards/xilinx-zcu106/lowlevel.c
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021, WolfVision GmbH
+ * Author: Michael Riesch <michael.riesch@wolfvision.net>
+ *
+ * Based on the barebox ZCU104 board support code.
+ */
+
+#include <common.h>
+#include <debug_ll.h>
+#include <asm/barebox-arm.h>
+
+extern char __dtb_zynqmp_zcu106_revA_start[];
+
+void zynqmp_zcu106_start(uint32_t, uint32_t, uint32_t);
+
+void noinline zynqmp_zcu106_start(uint32_t r0, uint32_t r1, uint32_t r2)
+{
+ /* Assume that the first stage boot loader configured the UART */
+ putc_ll('>');
+
+ barebox_arm_entry(0, SZ_2G,
+ __dtb_zynqmp_zcu106_revA_start + global_variable_offset());
+}
diff --git a/arch/arm/boards/xilinx-zcu106/lowlevel_init.S b/arch/arm/boards/xilinx-zcu106/lowlevel_init.S
new file mode 100644
index 0000000000..f3d55dcef2
--- /dev/null
+++ b/arch/arm/boards/xilinx-zcu106/lowlevel_init.S
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include <linux/linkage.h>
+#include <asm/barebox-arm64.h>
+
+/* The DRAM is already setup */
+#define STACK_TOP 0x80000000
+
+ENTRY_PROC(start_zynqmp_zcu106)
+ mov x0, #STACK_TOP
+ mov sp, x0
+ b zynqmp_zcu106_start
+ENTRY_PROC_END(start_zynqmp_zcu106)
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 558f9990be..80caa738a9 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -173,6 +173,7 @@ lwl-$(CONFIG_MACH_SAMA5D27_SOM1) += at91-sama5d27_som1_ek.dtb.o
lwl-$(CONFIG_MACH_SAMA5D27_GIANTBOARD) += at91-sama5d27_giantboard.dtb.o
lwl-$(CONFIG_MACH_AT91SAM9X5EK) += at91sam9x5ek.dtb.o
lwl-$(CONFIG_MACH_XILINX_ZCU104) += zynqmp-zcu104-revA.dtb.o
+lwl-$(CONFIG_MACH_XILINX_ZCU106) += zynqmp-zcu106-revA.dtb.o
lwl-$(CONFIG_MACH_ZII_IMX7D_DEV) += imx7d-zii-rpu2.dtb.o imx7d-zii-rmu2.dtb.o
lwl-$(CONFIG_MACH_WAGO_PFC_AM35XX) += am35xx-pfc-750_820x.dtb.o
diff --git a/arch/arm/dts/zynqmp-zcu106-revA.dts b/arch/arm/dts/zynqmp-zcu106-revA.dts
new file mode 100644
index 0000000000..7c50588268
--- /dev/null
+++ b/arch/arm/dts/zynqmp-zcu106-revA.dts
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * dts file for Xilinx ZynqMP ZCU106
+ *
+ * Copyright (C) 2021, WolfVision GmbH
+ * Author: Michael Riesch <michael.riesch@wolfvision.net>
+ *
+ * Based on the dts for the Xilinx ZynqMP ZCU104.
+ */
+
+#include <arm64/xilinx/zynqmp-zcu106-revA.dts>
+
+/ {
+ chosen {
+ environment {
+ compatible = "barebox,environment";
+ device-path = &sdhci1, "partname:0";
+ file-path = "barebox.env";
+ };
+ };
+};
diff --git a/arch/arm/mach-zynqmp/Kconfig b/arch/arm/mach-zynqmp/Kconfig
index c9dc71c9e7..78cb901653 100644
--- a/arch/arm/mach-zynqmp/Kconfig
+++ b/arch/arm/mach-zynqmp/Kconfig
@@ -7,4 +7,10 @@ config MACH_XILINX_ZCU104
Say Y here if you are using the Xilinx Zynq UltraScale+ MPSoC ZCU104
evaluation board.
+config MACH_XILINX_ZCU106
+ bool "Xilinx Zynq UltraScale+ MPSoC ZCU106"
+ help
+ Say Y here if you are using the Xilinx Zynq UltraScale+ MPSoC ZCU106
+ evaluation board.
+
endif
diff --git a/arch/arm/mach-zynqmp/zynqmp-bbu.c b/arch/arm/mach-zynqmp/zynqmp-bbu.c
index d1197c01dc..7ac8c2b8a9 100644
--- a/arch/arm/mach-zynqmp/zynqmp-bbu.c
+++ b/arch/arm/mach-zynqmp/zynqmp-bbu.c
@@ -4,45 +4,11 @@
*/
#include <common.h>
-#include <libfile.h>
#include <mach/zynqmp-bbu.h>
-static int zynqmp_bbu_handler(struct bbu_handler *handler,
- struct bbu_data *data)
-{
- int ret = 0;
-
- ret = bbu_confirm(data);
- if (ret)
- return ret;
-
- ret = copy_file(data->imagefile, data->devicefile, 1);
- if (ret < 0) {
- pr_err("update failed: %s", strerror(-ret));
- return ret;
- }
-
- return ret;
-}
-
int zynqmp_bbu_register_handler(const char *name, char *devicefile,
- unsigned long flags)
+ unsigned long flags)
{
- struct bbu_handler *handler;
- int ret = 0;
-
- if (!name || !devicefile)
- return -EINVAL;
-
- handler = xzalloc(sizeof(*handler));
- handler->name = name;
- handler->devicefile = devicefile;
- handler->flags = flags;
- handler->handler = zynqmp_bbu_handler;
-
- ret = bbu_register_handler(handler);
- if (ret)
- free(handler);
-
- return ret;
+ return bbu_register_std_file_update(name, flags, devicefile,
+ filetype_zynq_image);
}
diff --git a/arch/arm/mach-zynqmp/zynqmp.c b/arch/arm/mach-zynqmp/zynqmp.c
index 5871c145be..610d4bba6e 100644
--- a/arch/arm/mach-zynqmp/zynqmp.c
+++ b/arch/arm/mach-zynqmp/zynqmp.c
@@ -6,11 +6,36 @@
#include <common.h>
#include <init.h>
#include <linux/types.h>
+#include <bootsource.h>
#include <reset_source.h>
#define ZYNQMP_CRL_APB_BASE 0xff5e0000
+#define ZYNQMP_CRL_APB_BOOT_MODE_USER (ZYNQMP_CRL_APB_BASE + 0x200)
#define ZYNQMP_CRL_APB_RESET_REASON (ZYNQMP_CRL_APB_BASE + 0x220)
+/* PSJTAG interface, PS dedicated pins. */
+#define ZYNQMP_CRL_APB_BOOT_MODE_PSJTAG 0x0
+/* SPI 24-bit addressing */
+#define ZYNQMP_CRL_APB_BOOT_MODE_QSPI24 0x1
+/* SPI 32-bit addressing */
+#define ZYNQMP_CRL_APB_BOOT_MODE_QSPI32 0x2
+/* SD 2.0 card @ controller 0 */
+#define ZYNQMP_CRL_APB_BOOT_MODE_SD0 0x3
+/* SPI NAND flash */
+#define ZYNQMP_CRL_APB_BOOT_MODE_NAND 0x4
+/* SD 2.0 card @ controller 1 */
+#define ZYNQMP_CRL_APB_BOOT_MODE_SD1 0x5
+/* eMMC @ controller 1 */
+#define ZYNQMP_CRL_APB_BOOT_MODE_EMMC 0x6
+/* USB 2.0 */
+#define ZYNQMP_CRL_APB_BOOT_MODE_USB 0x7
+/* PJTAG connection 0 option. */
+#define ZYNQMP_CRL_APB_BOOT_MODE_PJTAG0 0x8
+/* PJTAG connection 1 option. */
+#define ZYNQMP_CRL_APB_BOOT_MODE_PJTAG1 0x9
+/* SD 3.0 card (level-shifted) @ controller 1 */
+#define ZYNQMP_CRL_APB_BOOT_MODE_SD1LS 0xE
+
/* External POR: The PS_POR_B reset signal pin was asserted. */
#define ZYNQMP_CRL_APB_RESET_REASON_EXTERNAL BIT(0)
/* Internal POR: A system error triggered a POR reset. */
@@ -26,6 +51,60 @@
/* Software debugger reset: Write to BLOCKONLY_RST [debug_only]. */
#define ZYNQMP_CRL_APB_RESET_REASON_DEBUG_SYS BIT(6)
+static void zynqmp_get_bootsource(enum bootsource *src, int *instance)
+{
+ u32 v;
+
+ if (!src || !instance)
+ return;
+
+ v = readl(ZYNQMP_CRL_APB_BOOT_MODE_USER);
+ v &= 0x0F;
+
+ /* cf. Table 11-1 "Boot Modes" in UG1085 Zynq UltraScale+ Device TRM */
+ switch (v) {
+ case ZYNQMP_CRL_APB_BOOT_MODE_PSJTAG:
+ case ZYNQMP_CRL_APB_BOOT_MODE_PJTAG0:
+ case ZYNQMP_CRL_APB_BOOT_MODE_PJTAG1:
+ *src = BOOTSOURCE_JTAG;
+ *instance = 0;
+ break;
+
+ case ZYNQMP_CRL_APB_BOOT_MODE_QSPI24:
+ case ZYNQMP_CRL_APB_BOOT_MODE_QSPI32:
+ *src = BOOTSOURCE_SPI;
+ *instance = 0;
+ break;
+
+ case ZYNQMP_CRL_APB_BOOT_MODE_SD0:
+ *src = BOOTSOURCE_MMC;
+ *instance = 0;
+ break;
+
+ case ZYNQMP_CRL_APB_BOOT_MODE_NAND:
+ *src = BOOTSOURCE_SPI_NAND;
+ *instance = 0;
+ break;
+
+ case ZYNQMP_CRL_APB_BOOT_MODE_SD1:
+ case ZYNQMP_CRL_APB_BOOT_MODE_EMMC:
+ case ZYNQMP_CRL_APB_BOOT_MODE_SD1LS:
+ *src = BOOTSOURCE_MMC;
+ *instance = 1;
+ break;
+
+ case ZYNQMP_CRL_APB_BOOT_MODE_USB:
+ *src = BOOTSOURCE_USB;
+ *instance = 0;
+ break;
+
+ default:
+ *src = BOOTSOURCE_UNKNOWN;
+ *instance = BOOTSOURCE_INSTANCE_UNKNOWN;
+ break;
+ }
+}
+
struct zynqmp_reset_reason {
u32 mask;
enum reset_src_type type;
@@ -65,6 +144,13 @@ static enum reset_src_type zynqmp_get_reset_src(void)
static int zynqmp_init(void)
{
+ enum bootsource boot_src;
+ int boot_instance;
+
+ zynqmp_get_bootsource(&boot_src, &boot_instance);
+ bootsource_set(boot_src);
+ bootsource_set_instance(boot_instance);
+
reset_source_set(zynqmp_get_reset_src());
return 0;
diff --git a/drivers/firmware/zynqmp-fpga.c b/drivers/firmware/zynqmp-fpga.c
index 0fc229bfd3..b76607f7ee 100644
--- a/drivers/firmware/zynqmp-fpga.c
+++ b/drivers/firmware/zynqmp-fpga.c
@@ -197,15 +197,15 @@ static void zynqmp_fpga_show_header(const struct device_d *dev,
static int fpgamgr_program_finish(struct firmware_handler *fh)
{
struct fpgamgr *mgr = container_of(fh, struct fpgamgr, fh);
- char *buf_aligned;
- u32 *buf_size = NULL;
+ u32 *buf_aligned;
+ u32 buf_size;
u32 *body;
size_t body_length;
int header_length = 0;
enum xilinx_byte_order byte_order;
- u64 addr;
+ dma_addr_t addr;
int status = 0;
- u8 flags = 0;
+ u8 flags = ZYNQMP_FPGA_BIT_ONLY_BIN;
if (!mgr->buf) {
status = -ENOBUFS;
@@ -234,17 +234,13 @@ static int fpgamgr_program_finish(struct firmware_handler *fh)
goto err_free;
}
- if (!(mgr->features & ZYNQMP_PM_FEATURE_SIZE_NOT_NEEDED)) {
- buf_size = dma_alloc_coherent(sizeof(*buf_size),
- DMA_ADDRESS_BROKEN);
- if (!buf_size) {
- status = -ENOBUFS;
- goto err_free;
- }
- *buf_size = body_length;
- }
-
- buf_aligned = dma_alloc_coherent(body_length, DMA_ADDRESS_BROKEN);
+ /*
+ * The PMU FW variants without the ZYNQMP_PM_FEATURE_SIZE_NOT_NEEDED
+ * feature expect a pointer to the bitstream size, which is stored in
+ * memory. Allocate extra space at the end of the buffer for the
+ * bitstream size.
+ */
+ buf_aligned = dma_alloc(body_length + sizeof(buf_size));
if (!buf_aligned) {
status = -ENOBUFS;
goto err_free;
@@ -257,25 +253,28 @@ static int fpgamgr_program_finish(struct firmware_handler *fh)
else
memcpy((u32 *)buf_aligned, body, body_length);
- addr = (u64)buf_aligned;
-
- /* we do not provide a header */
- flags |= ZYNQMP_FPGA_BIT_ONLY_BIN;
-
- if (!(mgr->features & ZYNQMP_PM_FEATURE_SIZE_NOT_NEEDED) && buf_size) {
- status = mgr->eemi_ops->fpga_load(addr,
- (u32)(uintptr_t)buf_size,
- flags);
- dma_free_coherent(buf_size, 0, sizeof(*buf_size));
+ if (mgr->features & ZYNQMP_PM_FEATURE_SIZE_NOT_NEEDED) {
+ buf_size = body_length;
} else {
- status = mgr->eemi_ops->fpga_load(addr, (u32)(body_length),
- flags);
+ buf_aligned[body_length / sizeof(*buf_aligned)] = body_length;
+ buf_size = addr + body_length;
+ }
+
+ addr = dma_map_single(&mgr->dev, buf_aligned,
+ body_length + sizeof(buf_size), DMA_TO_DEVICE);
+ if (dma_mapping_error(&mgr->dev, addr)) {
+ status = -EFAULT;
+ goto err_free_dma;
}
+ status = mgr->eemi_ops->fpga_load((u64)addr, buf_size, flags);
+ dma_unmap_single(&mgr->dev, addr, body_length + sizeof(buf_size),
+ DMA_TO_DEVICE);
if (status < 0)
dev_err(&mgr->dev, "unable to load fpga\n");
- dma_free_coherent(buf_aligned, 0, body_length);
+err_free_dma:
+ dma_free(buf_aligned);
err_free:
free(mgr->buf);
diff --git a/images/Makefile.zynqmp b/images/Makefile.zynqmp
index da3e90b847..872f399883 100644
--- a/images/Makefile.zynqmp
+++ b/images/Makefile.zynqmp
@@ -6,3 +6,7 @@
pblb-$(CONFIG_MACH_XILINX_ZCU104) += start_zynqmp_zcu104
FILE_barebox-zynqmp-zcu104.img = start_zynqmp_zcu104.pblb
image-$(CONFIG_MACH_XILINX_ZCU104) += barebox-zynqmp-zcu104.img
+
+pblb-$(CONFIG_MACH_XILINX_ZCU106) += start_zynqmp_zcu106
+FILE_barebox-zynqmp-zcu106.img = start_zynqmp_zcu106.pblb
+image-$(CONFIG_MACH_XILINX_ZCU106) += barebox-zynqmp-zcu106.img