[U-Boot] [PATCH 1/4] ARM64: zynqmp: Add USB boot mode

Add USB boot mode.
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
arch/arm/include/asm/arch-zynqmp/hardware.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/include/asm/arch-zynqmp/hardware.h b/arch/arm/include/asm/arch-zynqmp/hardware.h index bcb243416a2a..10d67d0fb7b0 100644 --- a/arch/arm/include/asm/arch-zynqmp/hardware.h +++ b/arch/arm/include/asm/arch-zynqmp/hardware.h @@ -69,6 +69,7 @@ struct iou_scntr_secure { #define SD_MODE1 0x00000005 /* sd 1 */ #define NAND_MODE 0x00000004 #define EMMC_MODE 0x00000006 +#define USB_MODE 0x00000007 #define JTAG_MODE 0x00000000 #define BOOT_MODE_USE_ALT 0x100 #define BOOT_MODE_ALT_SHIFT 12

SPL needs to have bigger stack size because of USB. Simple malloc needs to be disabled because dfu code requires different allocation functions. There is no space in OCM that's why random place in DDR is used.
BOOTD must be disabled because it is causing compilation error.
All variables are disabled and used only variables valid for DFU because they are simple huge. Including automatic variables added by CONFIG_ENV_VARS_UBOOT_CONFIG. Hardcode addresses for u-boot, atf, kernel and dtb just for SPL DFU code.
Enable SPL DFU for zcu100. Create new usb_dfu_spl variable just to run Linux kernel loaded in SPL.
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
arch/arm/cpu/armv8/zynqmp/spl.c | 4 ++++ board/xilinx/zynqmp/zynqmp.c | 4 ++++ include/configs/xilinx_zynqmp.h | 30 ++++++++++++++++++++++++++++-- 3 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/arch/arm/cpu/armv8/zynqmp/spl.c b/arch/arm/cpu/armv8/zynqmp/spl.c index 4b6fdc259341..3ad5de140878 100644 --- a/arch/arm/cpu/armv8/zynqmp/spl.c +++ b/arch/arm/cpu/armv8/zynqmp/spl.c @@ -67,6 +67,10 @@ u32 spl_boot_device(void) case SD_MODE1: return BOOT_DEVICE_MMC1; #endif +#ifdef CONFIG_SPL_DFU_SUPPORT + case USB_MODE: + return BOOT_DEVICE_DFU; +#endif default: printf("Invalid Boot Mode:0x%x\n", bootmode); break; diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index 4aed97a72f3b..df4fc901c1c7 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/board/xilinx/zynqmp/zynqmp.c @@ -229,6 +229,10 @@ int board_late_init(void)
puts("Bootmode: "); switch (bootmode) { + case USB_MODE: + puts("USB_MODE\n"); + mode = "usb"; + break; case JTAG_MODE: puts("JTAG_MODE\n"); mode = "pxe dhcp"; diff --git a/include/configs/xilinx_zynqmp.h b/include/configs/xilinx_zynqmp.h index 6e4910535a5d..6273e17b279c 100644 --- a/include/configs/xilinx_zynqmp.h +++ b/include/configs/xilinx_zynqmp.h @@ -79,7 +79,9 @@
/* Diff from config_distro_defaults.h */ #define CONFIG_SUPPORT_RAW_INITRD +#if !defined(CONFIG_SPL_BUILD) #define CONFIG_ENV_VARS_UBOOT_CONFIG +#endif #define CONFIG_AUTO_COMPLETE
/* PXE */ @@ -140,7 +142,6 @@ # define DFU_ALT_INFO #endif
- #define CONFIG_BOARD_LATE_INIT
/* Do not preserve environment */ @@ -252,9 +253,20 @@ DFU_ALT_INFO #endif
+/* SPL can't handle all huge variables - define just DFU */ +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_DFU_SUPPORT) +#undef CONFIG_EXTRA_ENV_SETTINGS +# define CONFIG_EXTRA_ENV_SETTINGS \ + "dfu_alt_info_ram=uboot.bin ram 0x8000000 0x1000000;" \ + "atf-uboot.ub ram 0x10000000 0x1000000;" \ + "Image ram 0x80000 0x3f80000;" \ + "system.dtb ram 0x4000000 0x100000\0" \ + "dfu_bufsiz=0x1000\0" +#endif + #define CONFIG_SPL_TEXT_BASE 0xfffc0000 #define CONFIG_SPL_STACK 0xfffffffc -#define CONFIG_SPL_MAX_SIZE 0x20000 +#define CONFIG_SPL_MAX_SIZE 0x40000
/* Just random location in OCM */ #define CONFIG_SPL_BSS_START_ADDR 0x0 @@ -290,4 +302,18 @@ # define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.img" #endif
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_DFU_SUPPORT) +# undef CONFIG_CMD_BOOTD +# define CONFIG_SPL_ENV_SUPPORT +# define CONFIG_SPL_HASH_SUPPORT +# define CONFIG_ENV_MAX_ENTRIES 10 + +# define CONFIG_SYS_SPL_MALLOC_START 0x20000000 +# define CONFIG_SYS_SPL_MALLOC_SIZE 0x10000000 + +#ifdef CONFIG_SPL_SYS_MALLOC_SIMPLE +# error "Disable CONFIG_SPL_SYS_MALLOC_SIMPLE. Full malloc needs to be used" +#endif +#endif + #endif /* __XILINX_ZYNQMP_H */

Mode pins can be used as output for reset. Xilinx boards are using this feature as additional way how to reset USB phys and also others chips on the boards. Mode1 is used on all these boards for this feature. Let SPL toggle reset on this pin by default.
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
arch/arm/cpu/armv8/zynqmp/spl.c | 23 +++++++++++++++++++++++ arch/arm/include/asm/arch-zynqmp/hardware.h | 11 ++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/arch/arm/cpu/armv8/zynqmp/spl.c b/arch/arm/cpu/armv8/zynqmp/spl.c index 3ad5de140878..552f577b95d2 100644 --- a/arch/arm/cpu/armv8/zynqmp/spl.c +++ b/arch/arm/cpu/armv8/zynqmp/spl.c @@ -35,10 +35,33 @@ void board_init_f(ulong dummy) board_init_r(NULL, 0); }
+static void ps_mode_reset(ulong mode) +{ + writel(mode << ZYNQMP_CRL_APB_BOOT_PIN_CTRL_OUT_VAL_SHIFT | + mode << ZYNQMP_CRL_APB_BOOT_PIN_CTRL_OUT_EN_SHIFT, + &crlapb_base->boot_pin_ctrl); + udelay(1); + writel(mode << ZYNQMP_CRL_APB_BOOT_PIN_CTRL_OUT_EN_SHIFT, + &crlapb_base->boot_pin_ctrl); + udelay(5); + writel(mode << ZYNQMP_CRL_APB_BOOT_PIN_CTRL_OUT_VAL_SHIFT | + mode << ZYNQMP_CRL_APB_BOOT_PIN_CTRL_OUT_EN_SHIFT, + &crlapb_base->boot_pin_ctrl); +} + +/* + * Set default PS_MODE1 which is used for USB ULPI phy reset + * Also other resets can be connected to this certain pin + */ +#ifndef MODE_RESET +# define MODE_RESET PS_MODE1 +#endif + #ifdef CONFIG_SPL_BOARD_INIT void spl_board_init(void) { preloader_console_init(); + ps_mode_reset(MODE_RESET); board_init(); } #endif diff --git a/arch/arm/include/asm/arch-zynqmp/hardware.h b/arch/arm/include/asm/arch-zynqmp/hardware.h index 10d67d0fb7b0..456c1b0902e5 100644 --- a/arch/arm/include/asm/arch-zynqmp/hardware.h +++ b/arch/arm/include/asm/arch-zynqmp/hardware.h @@ -25,6 +25,13 @@
#define ZYNQMP_CRL_APB_BASEADDR 0xFF5E0000 #define ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT 0x1000000 +#define ZYNQMP_CRL_APB_BOOT_PIN_CTRL_OUT_EN_SHIFT 0 +#define ZYNQMP_CRL_APB_BOOT_PIN_CTRL_OUT_VAL_SHIFT 8 + +#define PS_MODE0 BIT(0) +#define PS_MODE1 BIT(1) +#define PS_MODE2 BIT(2) +#define PS_MODE3 BIT(3)
struct crlapb_regs { u32 reserved0[36]; @@ -35,7 +42,9 @@ struct crlapb_regs { u32 boot_mode; /* 0x200 */ u32 reserved3[14]; u32 rst_lpd_top; /* 0x23C */ - u32 reserved4[26]; + u32 reserved4[4]; + u32 boot_pin_ctrl; /* 0x250 */ + u32 reserved5[21]; };
#define crlapb_base ((struct crlapb_regs *)ZYNQMP_CRL_APB_BASEADDR)

It should be enough to call low(5us)->high pulse for all cases to provide proper reset. There is no need to call high->low->high.
Signed-off-by: Michal Simek michal.simek@xilinx.com ---
arch/arm/cpu/armv8/zynqmp/spl.c | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/arch/arm/cpu/armv8/zynqmp/spl.c b/arch/arm/cpu/armv8/zynqmp/spl.c index 552f577b95d2..04e190537d15 100644 --- a/arch/arm/cpu/armv8/zynqmp/spl.c +++ b/arch/arm/cpu/armv8/zynqmp/spl.c @@ -37,10 +37,6 @@ void board_init_f(ulong dummy)
static void ps_mode_reset(ulong mode) { - writel(mode << ZYNQMP_CRL_APB_BOOT_PIN_CTRL_OUT_VAL_SHIFT | - mode << ZYNQMP_CRL_APB_BOOT_PIN_CTRL_OUT_EN_SHIFT, - &crlapb_base->boot_pin_ctrl); - udelay(1); writel(mode << ZYNQMP_CRL_APB_BOOT_PIN_CTRL_OUT_EN_SHIFT, &crlapb_base->boot_pin_ctrl); udelay(5);
participants (1)
-
Michal Simek