diff options
Diffstat (limited to 'arch/arm/mach-zynqmp')
-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 |
3 files changed, 95 insertions, 37 deletions
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; |