From 3b1ac08954d4518e019331fb34ba9b0677055145 Mon Sep 17 00:00:00 2001 From: Michael Tretter Date: Thu, 19 Aug 2021 10:12:49 +0200 Subject: firmware: zynqmp-fpga: initialize flags at function start The ZYNQMP_FPGA_BIT_ONLY_BIN flag is always set when programming the FPGA. Simplify the code by initializing the flags with ZYNQMP_FPGA_BIT_ONLY_BIN already set. Signed-off-by: Michael Tretter Link: https://lore.barebox.org/20210819081251.726840-2-m.tretter@pengutronix.de Signed-off-by: Sascha Hauer --- drivers/firmware/zynqmp-fpga.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/firmware/zynqmp-fpga.c b/drivers/firmware/zynqmp-fpga.c index 0fc229bfd3..736d1950fa 100644 --- a/drivers/firmware/zynqmp-fpga.c +++ b/drivers/firmware/zynqmp-fpga.c @@ -205,7 +205,7 @@ static int fpgamgr_program_finish(struct firmware_handler *fh) enum xilinx_byte_order byte_order; u64 addr; int status = 0; - u8 flags = 0; + u8 flags = ZYNQMP_FPGA_BIT_ONLY_BIN; if (!mgr->buf) { status = -ENOBUFS; @@ -259,9 +259,6 @@ static int fpgamgr_program_finish(struct firmware_handler *fh) 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, -- cgit v1.2.3 From 52bc1b99afbf4acced704ce67130455ee0f882a7 Mon Sep 17 00:00:00 2001 From: Michael Tretter Date: Thu, 19 Aug 2021 10:12:50 +0200 Subject: firmware: zynqmp-fpga: avoid additional buffer for size argument There are two different APIs for loading an FPGA via the pmu-fw as indicated by the ZYNQMP_PM_FEATURE_SIZE_NOT_NEEDED feature flag. The pmu-fw expects as second argument either the size of the bitstream or a pointer to the size of the bitstream. The driver allocates a separate buffer for the size, which results in the allocation of a 4k page for storing a 32 bit value. Allocate some more memory for the bitstream and append the size of the bitstream at the end of the bitstream to avoid the additional memory allocation. Add a comment to explain the surprising size of the allocation. Signed-off-by: Michael Tretter Link: https://lore.barebox.org/20210819081251.726840-3-m.tretter@pengutronix.de Signed-off-by: Sascha Hauer --- drivers/firmware/zynqmp-fpga.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/drivers/firmware/zynqmp-fpga.c b/drivers/firmware/zynqmp-fpga.c index 736d1950fa..667910479a 100644 --- a/drivers/firmware/zynqmp-fpga.c +++ b/drivers/firmware/zynqmp-fpga.c @@ -197,8 +197,8 @@ 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; @@ -234,17 +234,14 @@ 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 some extra space at the end of the buffer for the + * bitstream size. + */ + buf_aligned = dma_alloc_coherent(body_length + sizeof(buf_size), + DMA_ADDRESS_BROKEN); if (!buf_aligned) { status = -ENOBUFS; goto err_free; @@ -259,20 +256,18 @@ static int fpgamgr_program_finish(struct firmware_handler *fh) addr = (u64)buf_aligned; - 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; } + status = mgr->eemi_ops->fpga_load(addr, buf_size, flags); if (status < 0) dev_err(&mgr->dev, "unable to load fpga\n"); - dma_free_coherent(buf_aligned, 0, body_length); + dma_free_coherent(buf_aligned, 0, body_length + sizeof(buf_size)); err_free: free(mgr->buf); -- cgit v1.2.3 From 2f29ee311f1d9561b446baa5bc9f007420943aa6 Mon Sep 17 00:00:00 2001 From: Michael Tretter Date: Thu, 19 Aug 2021 10:12:51 +0200 Subject: firmware: zynqmp-fpga: do not use DMA coherent memory for bitstream Trying to do unaligned access of coherent memory on AArch64 will lead to an abort. This can happen when the FPGA loader copies the bitstream to the temporary buffer for the transfer to the FPGA. Convert the driver to use regular memory for the temporary buffer to prevent the issue. Signed-off-by: Michael Tretter Link: https://lore.barebox.org/20210819081251.726840-4-m.tretter@pengutronix.de Signed-off-by: Sascha Hauer --- drivers/firmware/zynqmp-fpga.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/firmware/zynqmp-fpga.c b/drivers/firmware/zynqmp-fpga.c index 667910479a..b76607f7ee 100644 --- a/drivers/firmware/zynqmp-fpga.c +++ b/drivers/firmware/zynqmp-fpga.c @@ -203,7 +203,7 @@ static int fpgamgr_program_finish(struct firmware_handler *fh) 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 = ZYNQMP_FPGA_BIT_ONLY_BIN; @@ -237,11 +237,10 @@ static int fpgamgr_program_finish(struct firmware_handler *fh) /* * 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 some extra space at the end of the buffer for the + * memory. Allocate extra space at the end of the buffer for the * bitstream size. */ - buf_aligned = dma_alloc_coherent(body_length + sizeof(buf_size), - DMA_ADDRESS_BROKEN); + buf_aligned = dma_alloc(body_length + sizeof(buf_size)); if (!buf_aligned) { status = -ENOBUFS; goto err_free; @@ -254,8 +253,6 @@ static int fpgamgr_program_finish(struct firmware_handler *fh) else memcpy((u32 *)buf_aligned, body, body_length); - addr = (u64)buf_aligned; - if (mgr->features & ZYNQMP_PM_FEATURE_SIZE_NOT_NEEDED) { buf_size = body_length; } else { @@ -263,11 +260,21 @@ static int fpgamgr_program_finish(struct firmware_handler *fh) buf_size = addr + body_length; } - status = mgr->eemi_ops->fpga_load(addr, buf_size, flags); + 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 + sizeof(buf_size)); +err_free_dma: + dma_free(buf_aligned); err_free: free(mgr->buf); -- cgit v1.2.3 From fda76b134cccd26507e96724cc55bb83a49a178e Mon Sep 17 00:00:00 2001 From: Michael Tretter Date: Wed, 18 Aug 2021 14:58:48 +0200 Subject: ARM: zynqmp: use std_file_update as update handler The update handler for zynqmp copies the boot.bin file into an existing fat partition. There is already a better implementation by bbu_register_std_file_update(). Drop the custom implementation. Keep the previous functions with its signature to have an obvious common update handler for all ZynqMP boards. Suggested-by: Ahmad Fatoum Signed-off-by: Michael Tretter Link: https://lore.barebox.org/20210818125848.560293-1-m.tretter@pengutronix.de Signed-off-by: Sascha Hauer --- arch/arm/mach-zynqmp/zynqmp-bbu.c | 40 +++------------------------------------ 1 file changed, 3 insertions(+), 37 deletions(-) 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 -#include #include -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); } -- cgit v1.2.3 From c4f26f29966f530efb21409a4dc9037e80b1828f Mon Sep 17 00:00:00 2001 From: Michael Riesch Date: Mon, 13 Sep 2021 14:13:48 +0200 Subject: arm: zynqmp: add support for xilinx zcu106 board Add support for the Xilinx Zynq UltraScale+ MPSoC ZCU106 evaluation board. The changes are derived from the ZCU104 board support by applying s/104/106/g (more or less). Signed-off-by: Michael Riesch Link: https://lore.barebox.org/20210913121350.9307-2-michael.riesch@wolfvision.net Signed-off-by: Sascha Hauer --- arch/arm/boards/Makefile | 1 + arch/arm/boards/xilinx-zcu106/Makefile | 3 +++ arch/arm/boards/xilinx-zcu106/board.c | 21 +++++++++++++++++++++ arch/arm/boards/xilinx-zcu106/lowlevel.c | 24 ++++++++++++++++++++++++ arch/arm/boards/xilinx-zcu106/lowlevel_init.S | 12 ++++++++++++ arch/arm/dts/Makefile | 1 + arch/arm/dts/zynqmp-zcu106-revA.dts | 21 +++++++++++++++++++++ arch/arm/mach-zynqmp/Kconfig | 6 ++++++ images/Makefile.zynqmp | 4 ++++ 9 files changed, 93 insertions(+) create mode 100644 arch/arm/boards/xilinx-zcu106/Makefile create mode 100644 arch/arm/boards/xilinx-zcu106/board.c create mode 100644 arch/arm/boards/xilinx-zcu106/lowlevel.c create mode 100644 arch/arm/boards/xilinx-zcu106/lowlevel_init.S create mode 100644 arch/arm/dts/zynqmp-zcu106-revA.dts diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile index 5aac64fce5..22dc9fe3d1 100644 --- a/arch/arm/boards/Makefile +++ b/arch/arm/boards/Makefile @@ -170,6 +170,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 + * + * Based on the barebox ZCU104 board support code. + */ + +#include +#include +#include + +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 + * + * Based on the barebox ZCU104 board support code. + */ + +#include +#include +#include + +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 +#include + +/* 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 ffa9fe88c1..14ca6c38ef 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -170,6 +170,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 + * + * Based on the dts for the Xilinx ZynqMP ZCU104. + */ + +#include + +/ { + 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/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 -- cgit v1.2.3 From 4304301019726ddabc1dfbf277159bbaeaa02529 Mon Sep 17 00:00:00 2001 From: Michael Riesch Date: Mon, 13 Sep 2021 14:13:49 +0200 Subject: Documentation: boards: zynqmp: fix broken links The external links are not properly recognized. Remove quotation marks as a fix. Signed-off-by: Michael Riesch Link: https://lore.barebox.org/20210913121350.9307-3-michael.riesch@wolfvision.net Signed-off-by: Sascha Hauer --- Documentation/boards/zynqmp.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 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 --------------- -- cgit v1.2.3 From 2468a842885c8b75aed695bde59850bca0ecd4b6 Mon Sep 17 00:00:00 2001 From: Michael Riesch Date: Mon, 13 Sep 2021 14:13:50 +0200 Subject: arm: zynqmp: add boot source support The ZynqMP reports the mode pins sampled at POR via the register ZYNQMP_CRL_APB_BOOT_MODE_USER. This commit adds a function that reads the register and populates the boot source. Signed-off-by: Michael Riesch Link: https://lore.barebox.org/20210913121350.9307-4-michael.riesch@wolfvision.net Signed-off-by: Sascha Hauer --- arch/arm/mach-zynqmp/zynqmp.c | 86 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) 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 #include #include +#include #include #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; -- cgit v1.2.3