diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2021-10-07 14:41:58 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2021-10-07 14:41:58 +0200 |
commit | 09d2b6c6103af3b47d6159a15873122d7818c473 (patch) | |
tree | b672bcacaae7824914ec393ba7eeaa977f426446 | |
parent | ac68239d18f227e56933773a68e2edbe92c6aac7 (diff) | |
parent | 2468a842885c8b75aed695bde59850bca0ecd4b6 (diff) | |
download | barebox-09d2b6c6103af3b47d6159a15873122d7818c473.tar.gz barebox-09d2b6c6103af3b47d6159a15873122d7818c473.tar.xz |
Merge branch 'for-next/zynqmp'
-rw-r--r-- | Documentation/boards/zynqmp.rst | 4 | ||||
-rw-r--r-- | arch/arm/boards/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/boards/xilinx-zcu106/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/boards/xilinx-zcu106/board.c | 21 | ||||
-rw-r--r-- | arch/arm/boards/xilinx-zcu106/lowlevel.c | 24 | ||||
-rw-r--r-- | arch/arm/boards/xilinx-zcu106/lowlevel_init.S | 12 | ||||
-rw-r--r-- | arch/arm/dts/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/dts/zynqmp-zcu106-revA.dts | 21 | ||||
-rw-r--r-- | arch/arm/mach-zynqmp/Kconfig | 6 | ||||
-rw-r--r-- | arch/arm/mach-zynqmp/zynqmp-bbu.c | 40 | ||||
-rw-r--r-- | arch/arm/mach-zynqmp/zynqmp.c | 86 | ||||
-rw-r--r-- | drivers/firmware/zynqmp-fpga.c | 55 | ||||
-rw-r--r-- | images/Makefile.zynqmp | 4 |
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 |