Explorar o código

Merge branch 'master' of git://www.denx.de/git/u-boot-microblaze

Tom Rini %!s(int64=9) %!d(string=hai) anos
pai
achega
ec8fb48ce9
Modificáronse 69 ficheiros con 1000 adicións e 159 borrados
  1. 1 0
      arch/arm/Kconfig
  2. 1 0
      arch/arm/cpu/armv8/zynqmp/Makefile
  3. 107 0
      arch/arm/cpu/armv8/zynqmp/spl.c
  4. 1 1
      arch/arm/dts/zynq-7000.dtsi
  5. 7 2
      arch/arm/dts/zynqmp.dtsi
  6. 2 0
      arch/arm/include/asm/arch-zynqmp/sys_proto.h
  7. 6 42
      arch/arm/mach-zynq/Kconfig
  8. 25 0
      arch/arm/mach-zynq/spl.c
  9. 1 11
      board/xilinx/zynq/Makefile
  10. 0 1
      board/xilinx/zynq/custom_hw_platform/.gitignore
  11. 0 0
      board/xilinx/zynq/zynq-microzed/ps7_init_gpl.c
  12. 0 0
      board/xilinx/zynq/zynq-microzed/ps7_init_gpl.h
  13. 0 0
      board/xilinx/zynq/zynq-zc702/ps7_init_gpl.c
  14. 0 0
      board/xilinx/zynq/zynq-zc702/ps7_init_gpl.h
  15. 0 0
      board/xilinx/zynq/zynq-zc706/ps7_init_gpl.c
  16. 0 0
      board/xilinx/zynq/zynq-zc706/ps7_init_gpl.h
  17. 0 0
      board/xilinx/zynq/zynq-zed/ps7_init_gpl.c
  18. 0 0
      board/xilinx/zynq/zynq-zed/ps7_init_gpl.h
  19. 0 0
      board/xilinx/zynq/zynq-zybo/ps7_init_gpl.c
  20. 0 0
      board/xilinx/zynq/zynq-zybo/ps7_init_gpl.h
  21. 22 1
      board/xilinx/zynqmp/Makefile
  22. 35 0
      board/xilinx/zynqmp/xil_io.h
  23. 17 0
      board/xilinx/zynqmp/zynqmp.c
  24. 10 0
      common/bootm.c
  25. 9 2
      common/image-fit.c
  26. 94 0
      common/image.c
  27. 42 9
      common/spl/spl.c
  28. 9 0
      configs/xilinx_zynqmp_ep_defconfig
  29. 8 0
      configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig
  30. 3 0
      configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig
  31. 3 0
      configs/xilinx_zynqmp_zc1751_xm019_dc5_defconfig
  32. 8 0
      configs/xilinx_zynqmp_zcu102_defconfig
  33. 8 0
      configs/xilinx_zynqmp_zcu102_revB_defconfig
  34. 1 1
      configs/zynq_microzed_defconfig
  35. 1 1
      configs/zynq_picozed_defconfig
  36. 1 0
      configs/zynq_zc702_defconfig
  37. 1 1
      configs/zynq_zc706_defconfig
  38. 1 1
      configs/zynq_zc770_xm010_defconfig
  39. 1 1
      configs/zynq_zc770_xm011_defconfig
  40. 1 1
      configs/zynq_zc770_xm012_defconfig
  41. 1 1
      configs/zynq_zc770_xm013_defconfig
  42. 1 1
      configs/zynq_zed_defconfig
  43. 1 1
      configs/zynq_zybo_defconfig
  44. 67 0
      doc/uImage.FIT/multi-with-fpga.its
  45. 3 0
      doc/uImage.FIT/source_file_format.txt
  46. 1 1
      drivers/fpga/fpga.c
  47. 22 0
      drivers/gpio/zynq_gpio.c
  48. 22 12
      drivers/net/phy/broadcom.c
  49. 6 3
      drivers/net/phy/davicom.c
  50. 7 3
      drivers/net/phy/et1011c.c
  51. 6 3
      drivers/net/phy/lxt.c
  52. 22 17
      drivers/net/phy/marvell.c
  53. 6 1
      drivers/net/phy/micrel.c
  54. 12 6
      drivers/net/phy/natsemi.c
  55. 8 7
      drivers/net/phy/phy.c
  56. 19 9
      drivers/net/phy/realtek.c
  57. 7 3
      drivers/net/phy/smsc.c
  58. 5 3
      drivers/net/phy/vitesse.c
  59. 4 2
      drivers/net/xilinx_emaclite.c
  60. 5 3
      drivers/net/zynq_gem.c
  61. 1 0
      include/bootstage.h
  62. 57 2
      include/configs/xilinx_zynqmp.h
  63. 6 0
      include/configs/xilinx_zynqmp_zcu102.h
  64. 1 5
      include/configs/zynq-common.h
  65. 6 1
      include/image.h
  66. 1 0
      include/spl.h
  67. 7 0
      scripts/Makefile.spl
  68. 1 0
      tools/Makefile
  69. 269 0
      tools/zynqmpimage.c

+ 1 - 0
arch/arm/Kconfig

@@ -594,6 +594,7 @@ config ARCH_ZYNQMP
 	select DM
 	select DM
 	select OF_CONTROL
 	select OF_CONTROL
 	select DM_SERIAL
 	select DM_SERIAL
+	select SUPPORT_SPL
 
 
 config TEGRA
 config TEGRA
 	bool "NVIDIA Tegra"
 	bool "NVIDIA Tegra"

+ 1 - 0
arch/arm/cpu/armv8/zynqmp/Makefile

@@ -9,3 +9,4 @@ obj-y	+= clk.o
 obj-y	+= cpu.o
 obj-y	+= cpu.o
 obj-$(CONFIG_MP)	+= mp.o
 obj-$(CONFIG_MP)	+= mp.o
 obj-y	+= slcr.o
 obj-y	+= slcr.o
+obj-$(CONFIG_SPL_BUILD) += spl.o

+ 107 - 0
arch/arm/cpu/armv8/zynqmp/spl.c

@@ -0,0 +1,107 @@
+/*
+ * Copyright 2015 - 2016 Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek@xilinx.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <spl.h>
+
+#include <asm/io.h>
+#include <asm/spl.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
+
+void board_init_f(ulong dummy)
+{
+	psu_init();
+	board_early_init_r();
+
+#ifdef CONFIG_DEBUG_UART
+	/* Uart debug for sure */
+	debug_uart_init();
+	puts("Debug uart enabled\n"); /* or printch() */
+#endif
+	/* Delay is required for clocks to be propagated */
+	udelay(1000000);
+
+	/* Clear the BSS */
+	memset(__bss_start, 0, __bss_end - __bss_start);
+
+	/* No need to call timer init - it is empty for ZynqMP */
+	board_init_r(NULL, 0);
+}
+
+#ifdef CONFIG_SPL_BOARD_INIT
+void spl_board_init(void)
+{
+	preloader_console_init();
+	board_init();
+}
+#endif
+
+u32 spl_boot_device(void)
+{
+	u32 reg = 0;
+	u8 bootmode;
+
+	reg = readl(&crlapb_base->boot_mode);
+	bootmode = reg & BOOT_MODES_MASK;
+
+	switch (bootmode) {
+	case JTAG_MODE:
+		return BOOT_DEVICE_RAM;
+#ifdef CONFIG_SPL_MMC_SUPPORT
+	case EMMC_MODE:
+	case SD_MODE:
+	case SD_MODE1:
+		return BOOT_DEVICE_MMC1;
+#endif
+	default:
+		printf("Invalid Boot Mode:0x%x\n", bootmode);
+		break;
+	}
+
+	return 0;
+}
+
+u32 spl_boot_mode(void)
+{
+	switch (spl_boot_device()) {
+	case BOOT_DEVICE_RAM:
+		return 0;
+	case BOOT_DEVICE_MMC1:
+		return MMCSD_MODE_FS;
+	default:
+		puts("spl: error: unsupported device\n");
+		hang();
+	}
+}
+
+__weak void psu_init(void)
+{
+	 /*
+	  * This function is overridden by the one in
+	  * board/xilinx/zynqmp/(platform)/psu_init_gpl.c, if it exists.
+	  */
+}
+
+#ifdef CONFIG_SPL_OS_BOOT
+int spl_start_uboot(void)
+{
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_SPL_LOAD_FIT
+int board_fit_config_name_match(const char *name)
+{
+	/* Just empty function now - can't decide what to choose */
+	debug("%s: %s\n", __func__, name);
+
+	return 0;
+}
+#endif

+ 1 - 1
arch/arm/dts/zynq-7000.dtsi

@@ -251,7 +251,7 @@
 		slcr: slcr@f8000000 {
 		slcr: slcr@f8000000 {
 			#address-cells = <1>;
 			#address-cells = <1>;
 			#size-cells = <1>;
 			#size-cells = <1>;
-			compatible = "xlnx,zynq-slcr", "syscon", "simple-bus";
+			compatible = "xlnx,zynq-slcr", "syscon", "simple-mfd";
 			reg = <0xF8000000 0x1000>;
 			reg = <0xF8000000 0x1000>;
 			ranges;
 			ranges;
 			clkc: clkc@100 {
 			clkc: clkc@100 {

+ 7 - 2
arch/arm/dts/zynqmp.dtsi

@@ -253,9 +253,9 @@
 			compatible = "arm,gic-400", "arm,cortex-a15-gic";
 			compatible = "arm,gic-400", "arm,cortex-a15-gic";
 			#interrupt-cells = <3>;
 			#interrupt-cells = <3>;
 			reg = <0x0 0xf9010000 0x10000>,
 			reg = <0x0 0xf9010000 0x10000>,
-			      <0x0 0xf902f000 0x2000>,
+			      <0x0 0xf9020000 0x20000>,
 			      <0x0 0xf9040000 0x20000>,
 			      <0x0 0xf9040000 0x20000>,
-			      <0x0 0xf906f000 0x2000>;
+			      <0x0 0xf9060000 0x20000>;
 			interrupt-controller;
 			interrupt-controller;
 			interrupt-parent = <&gic>;
 			interrupt-parent = <&gic>;
 			interrupts = <1 9 0xf04>;
 			interrupts = <1 9 0xf04>;
@@ -264,6 +264,7 @@
 
 
 	amba: amba {
 	amba: amba {
 		compatible = "simple-bus";
 		compatible = "simple-bus";
+		u-boot,dm-pre-reloc;
 		#address-cells = <2>;
 		#address-cells = <2>;
 		#size-cells = <1>;
 		#size-cells = <1>;
 		ranges = <0 0 0 0 0xffffffff>;
 		ranges = <0 0 0 0 0xffffffff>;
@@ -674,6 +675,7 @@
 		};
 		};
 
 
 		sdhci0: sdhci@ff160000 {
 		sdhci0: sdhci@ff160000 {
+			u-boot,dm-pre-reloc;
 			compatible = "arasan,sdhci-8.9a";
 			compatible = "arasan,sdhci-8.9a";
 			status = "disabled";
 			status = "disabled";
 			interrupt-parent = <&gic>;
 			interrupt-parent = <&gic>;
@@ -685,6 +687,7 @@
 		};
 		};
 
 
 		sdhci1: sdhci@ff170000 {
 		sdhci1: sdhci@ff170000 {
+			u-boot,dm-pre-reloc;
 			compatible = "arasan,sdhci-8.9a";
 			compatible = "arasan,sdhci-8.9a";
 			status = "disabled";
 			status = "disabled";
 			interrupt-parent = <&gic>;
 			interrupt-parent = <&gic>;
@@ -776,6 +779,7 @@
 		};
 		};
 
 
 		uart0: serial@ff000000 {
 		uart0: serial@ff000000 {
+			u-boot,dm-pre-reloc;
 			compatible = "cdns,uart-r1p12", "xlnx,xuartps";
 			compatible = "cdns,uart-r1p12", "xlnx,xuartps";
 			status = "disabled";
 			status = "disabled";
 			interrupt-parent = <&gic>;
 			interrupt-parent = <&gic>;
@@ -786,6 +790,7 @@
 		};
 		};
 
 
 		uart1: serial@ff010000 {
 		uart1: serial@ff010000 {
+			u-boot,dm-pre-reloc;
 			compatible = "cdns,uart-r1p12", "xlnx,xuartps";
 			compatible = "cdns,uart-r1p12", "xlnx,xuartps";
 			status = "disabled";
 			status = "disabled";
 			interrupt-parent = <&gic>;
 			interrupt-parent = <&gic>;

+ 2 - 0
arch/arm/include/asm/arch-zynqmp/sys_proto.h

@@ -17,4 +17,6 @@ int zynq_slcr_get_mio_pin_status(const char *periph);
 
 
 unsigned int zynqmp_get_silicon_version(void);
 unsigned int zynqmp_get_silicon_version(void);
 
 
+void psu_init(void);
+
 #endif /* _ASM_ARCH_SYS_PROTO_H */
 #endif /* _ASM_ARCH_SYS_PROTO_H */

+ 6 - 42
arch/arm/mach-zynq/Kconfig

@@ -1,41 +1,5 @@
 if ARCH_ZYNQ
 if ARCH_ZYNQ
 
 
-config ZYNQ_CUSTOM_INIT
-	bool "Use custom ps7_init provided by Xilinx tool"
-	help
-	  U-Boot includes ps7_init_gpl.[ch] for some Zynq board variants.
-	  If you want to override them with customized ones
-	  or ps7_init code for your board is missing, please say Y here
-	  and add ones into board/xilinx/zynq/custom_hw_platform/ directory.
-
-choice
-	prompt "Xilinx Zynq board select"
-	default TARGET_ZYNQ_ZC702
-
-config TARGET_ZYNQ_ZED
-	bool "Zynq ZedBoard"
-
-config TARGET_ZYNQ_MICROZED
-	bool "Zynq MicroZed"
-
-config TARGET_ZYNQ_PICOZED
-	bool "Zynq PicoZed"
-
-config TARGET_ZYNQ_ZC702
-	bool "Zynq ZC702 Board"
-
-config TARGET_ZYNQ_ZC706
-	bool "Zynq ZC706 Board"
-
-config TARGET_ZYNQ_ZC770
-	bool "Zynq ZC770 Board"
-	select ZYNQ_CUSTOM_INIT
-
-config TARGET_ZYNQ_ZYBO
-	bool "Zynq Zybo Board"
-
-endchoice
-
 config SYS_BOARD
 config SYS_BOARD
 	default "zynq"
 	default "zynq"
 
 
@@ -46,11 +10,11 @@ config SYS_SOC
 	default "zynq"
 	default "zynq"
 
 
 config SYS_CONFIG_NAME
 config SYS_CONFIG_NAME
-	default "zynq_zed" if TARGET_ZYNQ_ZED
-	default "zynq_microzed" if TARGET_ZYNQ_MICROZED
-	default "zynq_picozed" if TARGET_ZYNQ_PICOZED
-	default "zynq_zc70x" if TARGET_ZYNQ_ZC702 || TARGET_ZYNQ_ZC706
-	default "zynq_zc770" if TARGET_ZYNQ_ZC770
-	default "zynq_zybo" if TARGET_ZYNQ_ZYBO
+	string "Board configuration name"
+	default "zynq-common"
+	help
+	  This option contains information about board configuration name.
+	  Based on this option include/configs/<CONFIG_SYS_CONFIG_NAME>.h header
+	  will be used for board configuration.
 
 
 endif
 endif

+ 25 - 0
arch/arm/mach-zynq/spl.c

@@ -90,3 +90,28 @@ __weak void ps7_init(void)
 	 * board/xilinx/zynq/(platform)/ps7_init_gpl.c, if it exists.
 	 * board/xilinx/zynq/(platform)/ps7_init_gpl.c, if it exists.
 	 */
 	 */
 }
 }
+
+__weak int ps7_post_config(void)
+{
+	/*
+	 * This function is overridden by the one in
+	 * board/xilinx/zynq/(platform)/ps7_init_gpl.c, if it exists.
+	 */
+	return 0;
+}
+
+void spl_board_prepare_for_boot(void)
+{
+	ps7_post_config();
+	debug("SPL bye\n");
+}
+
+#ifdef CONFIG_SPL_LOAD_FIT
+int board_fit_config_name_match(const char *name)
+{
+	/* Just empty function now - can't decide what to choose */
+	debug("%s: %s\n", __func__, name);
+
+	return 0;
+}
+#endif

+ 1 - 11
board/xilinx/zynq/Makefile

@@ -7,17 +7,7 @@
 
 
 obj-y	:= board.o
 obj-y	:= board.o
 
 
-# Copied from Xilinx SDK 2014.4
-hw-platform-$(CONFIG_TARGET_ZYNQ_ZED)		:= zed_hw_platform
-hw-platform-$(CONFIG_TARGET_ZYNQ_MICROZED)	:= MicroZed_hw_platform
-hw-platform-$(CONFIG_TARGET_ZYNQ_ZC702)		:= ZC702_hw_platform
-hw-platform-$(CONFIG_TARGET_ZYNQ_ZC706)		:= ZC706_hw_platform
-hw-platform-$(CONFIG_TARGET_ZYNQ_ZYBO)		:= zybo_hw_platform
-# If you want to use customized ps7_init_gpl.c/h,
-# enable CONFIG_ZYNQ_CUSTOM_INIT and put them into custom_hw_platform/.
-# This line must be placed at the bottom of the list because
-# it takes precedence over the default ones.
-hw-platform-$(CONFIG_ZYNQ_CUSTOM_INIT)		:= custom_hw_platform
+hw-platform-y :=$(shell echo $(CONFIG_DEFAULT_DEVICE_TREE))
 
 
 init-objs := $(if $(wildcard $(srctree)/$(src)/$(hw-platform-y)/ps7_init_gpl.c),\
 init-objs := $(if $(wildcard $(srctree)/$(src)/$(hw-platform-y)/ps7_init_gpl.c),\
 	$(hw-platform-y)/ps7_init_gpl.o)
 	$(hw-platform-y)/ps7_init_gpl.o)

+ 0 - 1
board/xilinx/zynq/custom_hw_platform/.gitignore

@@ -1 +0,0 @@
-ps7_init_gpl.[ch]

+ 0 - 0
board/xilinx/zynq/MicroZed_hw_platform/ps7_init_gpl.c → board/xilinx/zynq/zynq-microzed/ps7_init_gpl.c


+ 0 - 0
board/xilinx/zynq/MicroZed_hw_platform/ps7_init_gpl.h → board/xilinx/zynq/zynq-microzed/ps7_init_gpl.h


+ 0 - 0
board/xilinx/zynq/ZC702_hw_platform/ps7_init_gpl.c → board/xilinx/zynq/zynq-zc702/ps7_init_gpl.c


+ 0 - 0
board/xilinx/zynq/ZC702_hw_platform/ps7_init_gpl.h → board/xilinx/zynq/zynq-zc702/ps7_init_gpl.h


+ 0 - 0
board/xilinx/zynq/ZC706_hw_platform/ps7_init_gpl.c → board/xilinx/zynq/zynq-zc706/ps7_init_gpl.c


+ 0 - 0
board/xilinx/zynq/ZC706_hw_platform/ps7_init_gpl.h → board/xilinx/zynq/zynq-zc706/ps7_init_gpl.h


+ 0 - 0
board/xilinx/zynq/zed_hw_platform/ps7_init_gpl.c → board/xilinx/zynq/zynq-zed/ps7_init_gpl.c


+ 0 - 0
board/xilinx/zynq/zed_hw_platform/ps7_init_gpl.h → board/xilinx/zynq/zynq-zed/ps7_init_gpl.h


+ 0 - 0
board/xilinx/zynq/zybo_hw_platform/ps7_init_gpl.c → board/xilinx/zynq/zynq-zybo/ps7_init_gpl.c


+ 0 - 0
board/xilinx/zynq/zybo_hw_platform/ps7_init_gpl.h → board/xilinx/zynq/zynq-zybo/ps7_init_gpl.h


+ 22 - 1
board/xilinx/zynqmp/Makefile

@@ -1,8 +1,29 @@
 #
 #
-# (C) Copyright 2014 - 2015 Xilinx, Inc.
+# (C) Copyright 2014 - 2016 Xilinx, Inc.
 # Michal Simek <michal.simek@xilinx.com>
 # Michal Simek <michal.simek@xilinx.com>
 #
 #
 # SPDX-License-Identifier:	GPL-2.0+
 # SPDX-License-Identifier:	GPL-2.0+
 #
 #
 
 
 obj-y	:= zynqmp.o
 obj-y	:= zynqmp.o
+
+hw-platform-y :=$(shell echo $(CONFIG_SYS_CONFIG_NAME))
+
+init-objs := $(if $(wildcard $(srctree)/$(src)/$(hw-platform-y)/psu_init_gpl.c),\
+	$(hw-platform-y)/psu_init_gpl.o)
+
+ifeq ($(init-objs),)
+ifneq ($(wildcard $(srctree)/$(src)/psu_init_gpl.c),)
+init-objs := psu_init_gpl.o
+$(if $(CONFIG_SPL_BUILD),\
+$(warning Put custom psu_init_gpl.c/h to board/xilinx/zynqmp/custom_hw_platform/))
+endif
+endif
+
+obj-$(CONFIG_SPL_BUILD) += $(init-objs)
+
+# Suppress "warning: function declaration isn't a prototype"
+CFLAGS_REMOVE_psu_init_gpl.o := -Wstrict-prototypes
+
+# To include xil_io.h
+CFLAGS_psu_init_gpl.o := -I$(srctree)/$(src)

+ 35 - 0
board/xilinx/zynqmp/xil_io.h

@@ -0,0 +1,35 @@
+/*
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef XIL_IO_H /* prevent circular inclusions */
+#define XIL_IO_H
+
+/* FIXME remove this when vivado is fixed */
+#include <asm/io.h>
+
+#define xil_printf(...)
+
+void Xil_ICacheEnable(void)
+{}
+
+void Xil_DCacheEnable(void)
+{}
+
+void Xil_ICacheDisable(void)
+{}
+
+void Xil_DCacheDisable(void)
+{}
+
+void Xil_Out32(unsigned long addr, unsigned long val)
+{
+	writel(val, addr);
+}
+
+int Xil_In32(unsigned long addr)
+{
+	return readl(addr);
+}
+
+#endif /* XIL_IO_H */

+ 17 - 0
board/xilinx/zynqmp/zynqmp.c

@@ -15,6 +15,7 @@
 #include <asm/io.h>
 #include <asm/io.h>
 #include <usb.h>
 #include <usb.h>
 #include <dwc3-uboot.h>
 #include <dwc3-uboot.h>
+#include <i2c.h>
 
 
 DECLARE_GLOBAL_DATA_PTR;
 DECLARE_GLOBAL_DATA_PTR;
 
 
@@ -50,6 +51,22 @@ int board_early_init_r(void)
 	return 0;
 	return 0;
 }
 }
 
 
+int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
+{
+#if defined(CONFIG_ZYNQ_GEM_EEPROM_ADDR) && \
+    defined(CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET) && \
+    defined(CONFIG_ZYNQ_EEPROM_BUS)
+	i2c_set_bus_num(CONFIG_ZYNQ_EEPROM_BUS);
+
+	if (eeprom_read(CONFIG_ZYNQ_GEM_EEPROM_ADDR,
+			CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET,
+			ethaddr, 6))
+		printf("I2C EEPROM MAC address read failed\n");
+#endif
+
+	return 0;
+}
+
 #if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
 #if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
 /*
 /*
  * fdt_get_reg - Fill buffer by information from DT
  * fdt_get_reg - Fill buffer by information from DT

+ 10 - 0
common/bootm.c

@@ -246,6 +246,16 @@ int bootm_find_images(int flag, int argc, char * const argv[])
 #endif
 #endif
 
 
 #if IMAGE_ENABLE_FIT
 #if IMAGE_ENABLE_FIT
+#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_XILINX)
+	/* find bitstreams */
+	ret = boot_get_fpga(argc, argv, &images, IH_ARCH_DEFAULT,
+			    NULL, NULL);
+	if (ret) {
+		printf("FPGA image is corrupted or invalid\n");
+		return 1;
+	}
+#endif
+
 	/* find all of the loadables */
 	/* find all of the loadables */
 	ret = boot_get_loadable(argc, argv, &images, IH_ARCH_DEFAULT,
 	ret = boot_get_loadable(argc, argv, &images, IH_ARCH_DEFAULT,
 			       NULL, NULL);
 			       NULL, NULL);

+ 9 - 2
common/image-fit.c

@@ -422,7 +422,8 @@ void fit_image_print(const void *fit, int image_noffset, const char *p)
 	}
 	}
 
 
 	if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
 	if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
-	    (type == IH_TYPE_FIRMWARE) || (type == IH_TYPE_RAMDISK)) {
+	    (type == IH_TYPE_FIRMWARE) || (type == IH_TYPE_RAMDISK) ||
+	    (type == IH_TYPE_FPGA)) {
 		ret = fit_image_get_load(fit, image_noffset, &load);
 		ret = fit_image_get_load(fit, image_noffset, &load);
 		printf("%s  Load Address: ", p);
 		printf("%s  Load Address: ", p);
 		if (ret)
 		if (ret)
@@ -1483,6 +1484,10 @@ void fit_conf_print(const void *fit, int noffset, const char *p)
 	if (uname)
 	if (uname)
 		printf("%s  FDT:          %s\n", p, uname);
 		printf("%s  FDT:          %s\n", p, uname);
 
 
+	uname = (char *)fdt_getprop(fit, noffset, FIT_FPGA_PROP, NULL);
+	if (uname)
+		printf("%s  FPGA:         %s\n", p, uname);
+
 	/* Print out all of the specified loadables */
 	/* Print out all of the specified loadables */
 	for (loadables_index = 0;
 	for (loadables_index = 0;
 	     fdt_get_string_index(fit, noffset,
 	     fdt_get_string_index(fit, noffset,
@@ -1567,6 +1572,8 @@ static const char *fit_get_image_type_property(int type)
 		return FIT_SETUP_PROP;
 		return FIT_SETUP_PROP;
 	case IH_TYPE_LOADABLE:
 	case IH_TYPE_LOADABLE:
 		return FIT_LOADABLE_PROP;
 		return FIT_LOADABLE_PROP;
+	case IH_TYPE_FPGA:
+		return FIT_FPGA_PROP;
 	}
 	}
 
 
 	return "unknown";
 	return "unknown";
@@ -1681,7 +1688,7 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
 			fit_image_check_type(fit, noffset,
 			fit_image_check_type(fit, noffset,
 					     IH_TYPE_KERNEL_NOLOAD));
 					     IH_TYPE_KERNEL_NOLOAD));
 
 
-	os_ok = image_type == IH_TYPE_FLATDT ||
+	os_ok = image_type == IH_TYPE_FLATDT || IH_TYPE_FPGA ||
 		fit_image_check_os(fit, noffset, IH_OS_LINUX) ||
 		fit_image_check_os(fit, noffset, IH_OS_LINUX) ||
 		fit_image_check_os(fit, noffset, IH_OS_OPENRTOS);
 		fit_image_check_os(fit, noffset, IH_OS_OPENRTOS);
 
 

+ 94 - 0
common/image.c

@@ -32,6 +32,8 @@
 #if IMAGE_ENABLE_FIT || IMAGE_ENABLE_OF_LIBFDT
 #if IMAGE_ENABLE_FIT || IMAGE_ENABLE_OF_LIBFDT
 #include <libfdt.h>
 #include <libfdt.h>
 #include <fdt_support.h>
 #include <fdt_support.h>
+#include <fpga.h>
+#include <xilinx.h>
 #endif
 #endif
 
 
 #include <u-boot/md5.h>
 #include <u-boot/md5.h>
@@ -159,6 +161,8 @@ static const table_entry_t uimage_type[] = {
 	{	IH_TYPE_RKSD,       "rksd",       "Rockchip SD Boot Image" },
 	{	IH_TYPE_RKSD,       "rksd",       "Rockchip SD Boot Image" },
 	{	IH_TYPE_RKSPI,      "rkspi",      "Rockchip SPI Boot Image" },
 	{	IH_TYPE_RKSPI,      "rkspi",      "Rockchip SPI Boot Image" },
 	{	IH_TYPE_ZYNQIMAGE,  "zynqimage",  "Xilinx Zynq Boot Image" },
 	{	IH_TYPE_ZYNQIMAGE,  "zynqimage",  "Xilinx Zynq Boot Image" },
+	{	IH_TYPE_ZYNQMPIMAGE, "zynqmpimage", "Xilinx ZynqMP Boot Image" },
+	{	IH_TYPE_FPGA,       "fpga",       "FPGA Image" },
 	{	-1,		    "",		  "",			},
 	{	-1,		    "",		  "",			},
 };
 };
 
 
@@ -1210,6 +1214,96 @@ int boot_get_setup(bootm_headers_t *images, uint8_t arch,
 }
 }
 
 
 #if IMAGE_ENABLE_FIT
 #if IMAGE_ENABLE_FIT
+#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_XILINX)
+int boot_get_fpga(int argc, char * const argv[], bootm_headers_t *images,
+		  uint8_t arch, const ulong *ld_start, ulong * const ld_len)
+{
+	ulong tmp_img_addr, img_data, img_len;
+	void *buf;
+	int conf_noffset;
+	int fit_img_result;
+	char *uname, *name;
+	int err;
+	int devnum = 0; /* TODO support multi fpga platforms */
+	const fpga_desc * const desc = fpga_get_desc(devnum);
+	xilinx_desc *desc_xilinx = desc->devdesc;
+
+	/* Check to see if the images struct has a FIT configuration */
+	if (!genimg_has_config(images)) {
+		debug("## FIT configuration was not specified\n");
+		return 0;
+	}
+
+	/*
+	 * Obtain the os FIT header from the images struct
+	 * copy from dataflash if needed
+	 */
+	tmp_img_addr = map_to_sysmem(images->fit_hdr_os);
+	tmp_img_addr = genimg_get_image(tmp_img_addr);
+	buf = map_sysmem(tmp_img_addr, 0);
+	/*
+	 * Check image type. For FIT images get FIT node
+	 * and attempt to locate a generic binary.
+	 */
+	switch (genimg_get_format(buf)) {
+	case IMAGE_FORMAT_FIT:
+		conf_noffset = fit_conf_get_node(buf, images->fit_uname_cfg);
+
+		err = fdt_get_string_index(buf, conf_noffset, FIT_FPGA_PROP, 0,
+					   (const char **)&uname);
+		if (err < 0) {
+			debug("## FPGA image is not specified\n");
+			return 0;
+		}
+		fit_img_result = fit_image_load(images,
+						tmp_img_addr,
+						(const char **)&uname,
+						&(images->fit_uname_cfg),
+						arch,
+						IH_TYPE_FPGA,
+						BOOTSTAGE_ID_FPGA_INIT,
+						FIT_LOAD_OPTIONAL_NON_ZERO,
+						&img_data, &img_len);
+
+		debug("FPGA image (%s) loaded to 0x%lx/size 0x%lx\n",
+		      uname, img_data, img_len);
+
+		if (fit_img_result < 0) {
+			/* Something went wrong! */
+			return fit_img_result;
+		}
+
+		if (img_len >= desc_xilinx->size) {
+			name = "full";
+			err = fpga_loadbitstream(devnum, (char *)img_data,
+						 img_len, BIT_FULL);
+			if (err)
+				err = fpga_load(devnum, (const void *)img_data,
+						img_len, BIT_FULL);
+		} else {
+			name = "partial";
+			err = fpga_loadbitstream(devnum, (char *)img_data,
+						 img_len, BIT_PARTIAL);
+			if (err)
+				err = fpga_load(devnum, (const void *)img_data,
+						img_len, BIT_PARTIAL);
+		}
+
+		printf("   Programming %s bitstream... ", name);
+		if (err)
+			printf("failed\n");
+		else
+			printf("OK\n");
+		break;
+	default:
+		printf("The given image format is not supported (corrupt?)\n");
+		return 1;
+	}
+
+	return 0;
+}
+#endif
+
 int boot_get_loadable(int argc, char * const argv[], bootm_headers_t *images,
 int boot_get_loadable(int argc, char * const argv[], bootm_headers_t *images,
 		uint8_t arch, const ulong *ld_start, ulong * const ld_len)
 		uint8_t arch, const ulong *ld_start, ulong * const ld_len)
 {
 {

+ 42 - 9
common/spl/spl.c

@@ -64,6 +64,11 @@ __weak void spl_board_prepare_for_linux(void)
 	/* Nothing to do! */
 	/* Nothing to do! */
 }
 }
 
 
+__weak void spl_board_prepare_for_boot(void)
+{
+	/* Nothing to do! */
+}
+
 void spl_set_header_raw_uboot(void)
 void spl_set_header_raw_uboot(void)
 {
 {
 	spl_image.size = CONFIG_SYS_MONITOR_LEN;
 	spl_image.size = CONFIG_SYS_MONITOR_LEN;
@@ -135,20 +140,47 @@ __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
 	image_entry();
 	image_entry();
 }
 }
 
 
+#ifndef CONFIG_SPL_LOAD_FIT_ADDRESS
+# define CONFIG_SPL_LOAD_FIT_ADDRESS	0
+#endif
+
 #ifdef CONFIG_SPL_RAM_DEVICE
 #ifdef CONFIG_SPL_RAM_DEVICE
+static ulong spl_ram_load_read(struct spl_load_info *load, ulong sector,
+			       ulong count, void *buf)
+{
+	debug("%s: sector %lx, count %lx, buf %lx\n",
+	      __func__, sector, count, (ulong)buf);
+	memcpy(buf, (void *)(CONFIG_SPL_LOAD_FIT_ADDRESS + sector), count);
+	return count;
+}
+
 static int spl_ram_load_image(void)
 static int spl_ram_load_image(void)
 {
 {
-	const struct image_header *header;
+	struct image_header *header;
 
 
-	/*
-	 * Get the header.  It will point to an address defined by handoff
-	 * which will tell where the image located inside the flash. For
-	 * now, it will temporary fixed to address pointed by U-Boot.
-	 */
-	header = (struct image_header *)
-		(CONFIG_SYS_TEXT_BASE -	sizeof(struct image_header));
+	header = (struct image_header *)CONFIG_SPL_LOAD_FIT_ADDRESS;
+
+	if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
+	    image_get_magic(header) == FDT_MAGIC) {
+		struct spl_load_info load;
+
+		debug("Found FIT\n");
+		load.bl_len = 1;
+		load.read = spl_ram_load_read;
+		spl_load_simple_fit(&load, 0, header);
+	} else {
+		debug("Legacy image\n");
+		/*
+		 * Get the header.  It will point to an address defined by
+		 * handoff which will tell where the image located inside
+		 * the flash. For now, it will temporary fixed to address
+		 * pointed by U-Boot.
+		 */
+		header = (struct image_header *)
+			(CONFIG_SYS_TEXT_BASE -	sizeof(struct image_header));
 
 
-	spl_parse_image_header(header);
+		spl_parse_image_header(header);
+	}
 
 
 	return 0;
 	return 0;
 }
 }
@@ -404,6 +436,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
 #endif
 #endif
 
 
 	debug("loaded - jumping to U-Boot...");
 	debug("loaded - jumping to U-Boot...");
+	spl_board_prepare_for_boot();
 	jump_to_image_no_args(&spl_image);
 	jump_to_image_no_args(&spl_image);
 }
 }
 
 

+ 9 - 0
configs/xilinx_zynqmp_ep_defconfig

@@ -40,12 +40,21 @@ CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_EMBED=y
 CONFIG_OF_EMBED=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
 CONFIG_SYS_I2C_CADENCE=y
 CONFIG_SYS_I2C_CADENCE=y
 CONFIG_DM_MMC=y
 CONFIG_DM_MMC=y
 CONFIG_ZYNQ_SDHCI=y
 CONFIG_ZYNQ_SDHCI=y
 CONFIG_NAND_ARASAN=y
 CONFIG_NAND_ARASAN=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
 CONFIG_DM_ETH=y
 CONFIG_DM_ETH=y
 CONFIG_ZYNQ_GEM=y
 CONFIG_ZYNQ_GEM=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_ZYNQ=y
+CONFIG_DEBUG_UART_BASE=0xff000000
+CONFIG_DEBUG_UART_CLOCK=25000000
+CONFIG_DEBUG_UART_ANNOUNCE=y
 CONFIG_USB=y
 CONFIG_USB=y
 CONFIG_USB_DWC3=y
 CONFIG_USB_DWC3=y
 CONFIG_USB_DWC3_GADGET=y
 CONFIG_USB_DWC3_GADGET=y

+ 8 - 0
configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig

@@ -8,6 +8,7 @@ CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm015-dc1"
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm015-dc1"
 CONFIG_FIT=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
+CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="ZynqMP> "
 CONFIG_SYS_PROMPT="ZynqMP> "
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_IMLS is not set
 CONFIG_CMD_MEMTEST=y
 CONFIG_CMD_MEMTEST=y
@@ -30,6 +31,8 @@ CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_EMBED=y
 CONFIG_OF_EMBED=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
 CONFIG_SYS_I2C_CADENCE=y
 CONFIG_SYS_I2C_CADENCE=y
 CONFIG_DM_MMC=y
 CONFIG_DM_MMC=y
 CONFIG_ZYNQ_SDHCI=y
 CONFIG_ZYNQ_SDHCI=y
@@ -40,6 +43,11 @@ CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_DM_ETH=y
 CONFIG_DM_ETH=y
 CONFIG_ZYNQ_GEM=y
 CONFIG_ZYNQ_GEM=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_ZYNQ=y
+CONFIG_DEBUG_UART_BASE=0xff000000
+CONFIG_DEBUG_UART_CLOCK=100000000
+CONFIG_DEBUG_UART_ANNOUNCE=y
 CONFIG_USB=y
 CONFIG_USB=y
 CONFIG_USB_DWC3=y
 CONFIG_USB_DWC3=y
 CONFIG_USB_DWC3_GADGET=y
 CONFIG_USB_DWC3_GADGET=y

+ 3 - 0
configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig

@@ -8,6 +8,7 @@ CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm016-dc2"
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm016-dc2"
 CONFIG_FIT=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
+CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="ZynqMP> "
 CONFIG_SYS_PROMPT="ZynqMP> "
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_IMLS is not set
 CONFIG_CMD_MEMTEST=y
 CONFIG_CMD_MEMTEST=y
@@ -29,6 +30,8 @@ CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_EMBED=y
 CONFIG_OF_EMBED=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
 CONFIG_SYS_I2C_CADENCE=y
 CONFIG_SYS_I2C_CADENCE=y
 CONFIG_DM_MMC=y
 CONFIG_DM_MMC=y
 CONFIG_NAND_ARASAN=y
 CONFIG_NAND_ARASAN=y

+ 3 - 0
configs/xilinx_zynqmp_zc1751_xm019_dc5_defconfig

@@ -7,6 +7,7 @@ CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm019-dc5"
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm019-dc5"
 CONFIG_FIT=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
+CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="ZynqMP> "
 CONFIG_SYS_PROMPT="ZynqMP> "
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_IMLS is not set
 CONFIG_CMD_MEMTEST=y
 CONFIG_CMD_MEMTEST=y
@@ -25,6 +26,8 @@ CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_EMBED=y
 CONFIG_OF_EMBED=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
 CONFIG_SYS_I2C_CADENCE=y
 CONFIG_SYS_I2C_CADENCE=y
 CONFIG_DM_MMC=y
 CONFIG_DM_MMC=y
 CONFIG_ZYNQ_SDHCI=y
 CONFIG_ZYNQ_SDHCI=y

+ 8 - 0
configs/xilinx_zynqmp_zcu102_defconfig

@@ -7,6 +7,7 @@ CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102"
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102"
 CONFIG_FIT=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
+CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="ZynqMP> "
 CONFIG_SYS_PROMPT="ZynqMP> "
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_IMLS is not set
 CONFIG_CMD_MEMTEST=y
 CONFIG_CMD_MEMTEST=y
@@ -29,6 +30,8 @@ CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_EMBED=y
 CONFIG_OF_EMBED=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
 CONFIG_DM_MMC=y
 CONFIG_DM_MMC=y
 CONFIG_ZYNQ_SDHCI=y
 CONFIG_ZYNQ_SDHCI=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
@@ -38,6 +41,11 @@ CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_DM_ETH=y
 CONFIG_DM_ETH=y
 CONFIG_ZYNQ_GEM=y
 CONFIG_ZYNQ_GEM=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_ZYNQ=y
+CONFIG_DEBUG_UART_BASE=0xff000000
+CONFIG_DEBUG_UART_CLOCK=100000000
+CONFIG_DEBUG_UART_ANNOUNCE=y
 CONFIG_USB=y
 CONFIG_USB=y
 CONFIG_USB_DWC3=y
 CONFIG_USB_DWC3=y
 CONFIG_USB_DWC3_GADGET=y
 CONFIG_USB_DWC3_GADGET=y

+ 8 - 0
configs/xilinx_zynqmp_zcu102_revB_defconfig

@@ -7,6 +7,7 @@ CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102-revB"
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102-revB"
 CONFIG_FIT=y
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
+CONFIG_HUSH_PARSER=y
 CONFIG_SYS_PROMPT="ZynqMP> "
 CONFIG_SYS_PROMPT="ZynqMP> "
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_IMLS is not set
 CONFIG_CMD_MEMTEST=y
 CONFIG_CMD_MEMTEST=y
@@ -29,6 +30,8 @@ CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_EMBED=y
 CONFIG_OF_EMBED=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
 CONFIG_DM_MMC=y
 CONFIG_DM_MMC=y
 CONFIG_ZYNQ_SDHCI=y
 CONFIG_ZYNQ_SDHCI=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
@@ -38,6 +41,11 @@ CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_DM_ETH=y
 CONFIG_DM_ETH=y
 CONFIG_ZYNQ_GEM=y
 CONFIG_ZYNQ_GEM=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_ZYNQ=y
+CONFIG_DEBUG_UART_BASE=0xff000000
+CONFIG_DEBUG_UART_CLOCK=100000000
+CONFIG_DEBUG_UART_ANNOUNCE=y
 CONFIG_USB=y
 CONFIG_USB=y
 CONFIG_USB_DWC3=y
 CONFIG_USB_DWC3=y
 CONFIG_USB_DWC3_GADGET=y
 CONFIG_USB_DWC3_GADGET=y

+ 1 - 1
configs/zynq_microzed_defconfig

@@ -1,6 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARM=y
+CONFIG_SYS_CONFIG_NAME="zynq_microzed"
 CONFIG_ARCH_ZYNQ=y
 CONFIG_ARCH_ZYNQ=y
-CONFIG_TARGET_ZYNQ_MICROZED=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-microzed"
 CONFIG_DEFAULT_DEVICE_TREE="zynq-microzed"
 CONFIG_SPL=y
 CONFIG_SPL=y
 CONFIG_FIT=y
 CONFIG_FIT=y

+ 1 - 1
configs/zynq_picozed_defconfig

@@ -1,6 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARM=y
+CONFIG_SYS_CONFIG_NAME="zynq_picozed"
 CONFIG_ARCH_ZYNQ=y
 CONFIG_ARCH_ZYNQ=y
-CONFIG_TARGET_ZYNQ_PICOZED=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-picozed"
 CONFIG_DEFAULT_DEVICE_TREE="zynq-picozed"
 CONFIG_SPL=y
 CONFIG_SPL=y
 CONFIG_HUSH_PARSER=y
 CONFIG_HUSH_PARSER=y

+ 1 - 0
configs/zynq_zc702_defconfig

@@ -1,4 +1,5 @@
 CONFIG_ARM=y
 CONFIG_ARM=y
+CONFIG_SYS_CONFIG_NAME="zynq_zc70x"
 CONFIG_ARCH_ZYNQ=y
 CONFIG_ARCH_ZYNQ=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc702"
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc702"
 CONFIG_SPL=y
 CONFIG_SPL=y

+ 1 - 1
configs/zynq_zc706_defconfig

@@ -1,6 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARM=y
+CONFIG_SYS_CONFIG_NAME="zynq_zc70x"
 CONFIG_ARCH_ZYNQ=y
 CONFIG_ARCH_ZYNQ=y
-CONFIG_TARGET_ZYNQ_ZC706=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc706"
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc706"
 CONFIG_SPL=y
 CONFIG_SPL=y
 CONFIG_FIT=y
 CONFIG_FIT=y

+ 1 - 1
configs/zynq_zc770_xm010_defconfig

@@ -1,6 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARM=y
+CONFIG_SYS_CONFIG_NAME="zynq_zc770"
 CONFIG_ARCH_ZYNQ=y
 CONFIG_ARCH_ZYNQ=y
-CONFIG_TARGET_ZYNQ_ZC770=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm010"
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm010"
 CONFIG_SPL=y
 CONFIG_SPL=y
 CONFIG_FIT=y
 CONFIG_FIT=y

+ 1 - 1
configs/zynq_zc770_xm011_defconfig

@@ -1,6 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARM=y
+CONFIG_SYS_CONFIG_NAME="zynq_zc770"
 CONFIG_ARCH_ZYNQ=y
 CONFIG_ARCH_ZYNQ=y
-CONFIG_TARGET_ZYNQ_ZC770=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm011"
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm011"
 CONFIG_SPL=y
 CONFIG_SPL=y
 CONFIG_FIT=y
 CONFIG_FIT=y

+ 1 - 1
configs/zynq_zc770_xm012_defconfig

@@ -1,6 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARM=y
+CONFIG_SYS_CONFIG_NAME="zynq_zc770"
 CONFIG_ARCH_ZYNQ=y
 CONFIG_ARCH_ZYNQ=y
-CONFIG_TARGET_ZYNQ_ZC770=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm012"
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm012"
 CONFIG_SPL=y
 CONFIG_SPL=y
 CONFIG_FIT=y
 CONFIG_FIT=y

+ 1 - 1
configs/zynq_zc770_xm013_defconfig

@@ -1,6 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARM=y
+CONFIG_SYS_CONFIG_NAME="zynq_zc770"
 CONFIG_ARCH_ZYNQ=y
 CONFIG_ARCH_ZYNQ=y
-CONFIG_TARGET_ZYNQ_ZC770=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm013"
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm013"
 CONFIG_SPL=y
 CONFIG_SPL=y
 CONFIG_FIT=y
 CONFIG_FIT=y

+ 1 - 1
configs/zynq_zed_defconfig

@@ -1,6 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARM=y
+CONFIG_SYS_CONFIG_NAME="zynq_zed"
 CONFIG_ARCH_ZYNQ=y
 CONFIG_ARCH_ZYNQ=y
-CONFIG_TARGET_ZYNQ_ZED=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zed"
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zed"
 CONFIG_SPL=y
 CONFIG_SPL=y
 CONFIG_FIT=y
 CONFIG_FIT=y

+ 1 - 1
configs/zynq_zybo_defconfig

@@ -1,6 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARM=y
+CONFIG_SYS_CONFIG_NAME="zynq_zybo"
 CONFIG_ARCH_ZYNQ=y
 CONFIG_ARCH_ZYNQ=y
-CONFIG_TARGET_ZYNQ_ZYBO=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zybo"
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zybo"
 CONFIG_SPL=y
 CONFIG_SPL=y
 CONFIG_FIT=y
 CONFIG_FIT=y

+ 67 - 0
doc/uImage.FIT/multi-with-fpga.its

@@ -0,0 +1,67 @@
+/*
+ * U-Boot uImage source file with multiple kernels, ramdisks and FDT blobs
+ * This example makes use of the 'loadables' field
+ */
+
+/dts-v1/;
+
+/ {
+	description = "Configuration to load fpga before Kernel";
+	#address-cells = <1>;
+
+	images {
+		fdt@1 {
+			description = "zc706";
+			data = /incbin/("/tftpboot/devicetree.dtb");
+			type = "flat_dt";
+			arch = "arm";
+			compression = "none";
+			load = <0x10000000>;
+			hash@1 {
+				algo = "md5";
+			};
+		};
+
+		fpga@1 {
+			description = "FPGA";
+			data = /incbin/("/tftpboot/download.bit");
+			type = "fpga";
+			arch = "arm";
+			compression = "none";
+			load = <0x30000000>;
+			hash@1 {
+				algo = "md5";
+			};
+		};
+
+		linux_kernel@1 {
+			description = "Linux";
+			data = /incbin/("/tftpboot/zImage");
+			type = "kernel";
+			arch = "arm";
+			os = "linux";
+			compression = "none";
+			load = <0x8000>;
+			entry = <0x8000>;
+			hash@1 {
+				algo = "md5";
+			};
+		};
+	};
+
+	configurations {
+		default = "config@2";
+		config@1 {
+			description = "Linux";
+			kernel = "linux_kernel@1";
+			fdt = "fdt@1";
+		};
+
+		config@2 {
+			description = "Linux with fpga";
+			kernel = "linux_kernel@1";
+			fdt = "fdt@1";
+			fpga = "fpga@1";
+		};
+	};
+};

+ 3 - 0
doc/uImage.FIT/source_file_format.txt

@@ -236,6 +236,7 @@ o config@1
   |- kernel = "kernel sub-node unit name"
   |- kernel = "kernel sub-node unit name"
   |- ramdisk = "ramdisk sub-node unit name"
   |- ramdisk = "ramdisk sub-node unit name"
   |- fdt = "fdt sub-node unit-name"
   |- fdt = "fdt sub-node unit-name"
+  |- fpga = "fpga sub-node unit-name"
   |- loadables = "loadables sub-node unit-name"
   |- loadables = "loadables sub-node unit-name"
 
 
 
 
@@ -251,6 +252,8 @@ o config@1
     "fdt type").
     "fdt type").
   - setup : Unit name of the corresponding setup binary (used for booting
   - setup : Unit name of the corresponding setup binary (used for booting
     an x86 kernel). This contains the setup.bin file built by the kernel.
     an x86 kernel). This contains the setup.bin file built by the kernel.
+  - fpga : Unit name of the corresponding fpga bitstream blob
+    (component image node of a "fpga type").
   - loadables : Unit name containing a list of additional binaries to be
   - loadables : Unit name containing a list of additional binaries to be
     loaded at their given locations.  "loadables" is a comma-separated list
     loaded at their given locations.  "loadables" is a comma-separated list
     of strings. U-Boot will load each binary at its given start-address.
     of strings. U-Boot will load each binary at its given start-address.

+ 1 - 1
drivers/fpga/fpga.c

@@ -120,7 +120,7 @@ static int fpga_dev_info(int devnum)
 }
 }
 
 
 /*
 /*
- * fgpa_init is usually called from misc_init_r() and MUST be called
+ * fpga_init is usually called from misc_init_r() and MUST be called
  * before any of the other fpga functions are used.
  * before any of the other fpga functions are used.
  */
  */
 void fpga_init(void)
 void fpga_init(void)

+ 22 - 0
drivers/gpio/zynq_gpio.c

@@ -299,11 +299,33 @@ static int zynq_gpio_direction_output(struct udevice *dev, unsigned gpio,
 	return 0;
 	return 0;
 }
 }
 
 
+static int zynq_gpio_get_function(struct udevice *dev, unsigned offset)
+{
+	u32 reg;
+	unsigned int bank_num, bank_pin_num;
+	struct zynq_gpio_privdata *priv = dev_get_priv(dev);
+
+	if (check_gpio(offset, dev) < 0)
+		return -1;
+
+	zynq_gpio_get_bank_pin(offset, &bank_num, &bank_pin_num, dev);
+
+	/* set the GPIO pin as output */
+	reg = readl(priv->base + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
+	reg &= BIT(bank_pin_num);
+	if (reg)
+		return GPIOF_OUTPUT;
+	else
+		return GPIOF_INPUT;
+}
+
 static const struct dm_gpio_ops gpio_zynq_ops = {
 static const struct dm_gpio_ops gpio_zynq_ops = {
 	.direction_input	= zynq_gpio_direction_input,
 	.direction_input	= zynq_gpio_direction_input,
 	.direction_output	= zynq_gpio_direction_output,
 	.direction_output	= zynq_gpio_direction_output,
 	.get_value		= zynq_gpio_get_value,
 	.get_value		= zynq_gpio_get_value,
 	.set_value		= zynq_gpio_set_value,
 	.set_value		= zynq_gpio_set_value,
+	.get_function		= zynq_gpio_get_function,
+
 };
 };
 
 
 static const struct udevice_id zynq_gpio_ids[] = {
 static const struct udevice_id zynq_gpio_ids[] = {

+ 22 - 12
drivers/net/phy/broadcom.c

@@ -84,11 +84,14 @@ static int bcm54xx_parse_status(struct phy_device *phydev)
 
 
 static int bcm54xx_startup(struct phy_device *phydev)
 static int bcm54xx_startup(struct phy_device *phydev)
 {
 {
+	int ret;
+
 	/* Read the Status (2x to make sure link is right) */
 	/* Read the Status (2x to make sure link is right) */
-	genphy_update_link(phydev);
-	bcm54xx_parse_status(phydev);
+	ret = genphy_update_link(phydev);
+	if (ret)
+		return ret;
 
 
-	return 0;
+	return bcm54xx_parse_status(phydev);
 }
 }
 
 
 /* Broadcom BCM5482S */
 /* Broadcom BCM5482S */
@@ -139,11 +142,14 @@ static int bcm5482_config(struct phy_device *phydev)
 
 
 static int bcm_cygnus_startup(struct phy_device *phydev)
 static int bcm_cygnus_startup(struct phy_device *phydev)
 {
 {
+	int ret;
+
 	/* Read the Status (2x to make sure link is right) */
 	/* Read the Status (2x to make sure link is right) */
-	genphy_update_link(phydev);
-	genphy_parse_link(phydev);
+	ret = genphy_update_link(phydev);
+	if (ret)
+		return ret;
 
 
-	return 0;
+	return genphy_parse_link(phydev);
 }
 }
 
 
 static int bcm_cygnus_config(struct phy_device *phydev)
 static int bcm_cygnus_config(struct phy_device *phydev)
@@ -239,17 +245,21 @@ static u32 bcm5482_parse_serdes_sr(struct phy_device *phydev)
  */
  */
 static int bcm5482_startup(struct phy_device *phydev)
 static int bcm5482_startup(struct phy_device *phydev)
 {
 {
+	int ret;
+
 	if (bcm5482_is_serdes(phydev)) {
 	if (bcm5482_is_serdes(phydev)) {
 		bcm5482_parse_serdes_sr(phydev);
 		bcm5482_parse_serdes_sr(phydev);
 		phydev->port = PORT_FIBRE;
 		phydev->port = PORT_FIBRE;
-	} else {
-		/* Wait for auto-negotiation to complete or fail */
-		genphy_update_link(phydev);
-		/* Parse BCM54xx copper aux status register */
-		bcm54xx_parse_status(phydev);
+		return 0;
 	}
 	}
 
 
-	return 0;
+	/* Wait for auto-negotiation to complete or fail */
+	ret = genphy_update_link(phydev);
+	if (ret)
+		return ret;
+
+	/* Parse BCM54xx copper aux status register */
+	return bcm54xx_parse_status(phydev);
 }
 }
 
 
 static struct phy_driver BCM5461S_driver = {
 static struct phy_driver BCM5461S_driver = {

+ 6 - 3
drivers/net/phy/davicom.c

@@ -60,10 +60,13 @@ static int dm9161_parse_status(struct phy_device *phydev)
 
 
 static int dm9161_startup(struct phy_device *phydev)
 static int dm9161_startup(struct phy_device *phydev)
 {
 {
-	genphy_update_link(phydev);
-	dm9161_parse_status(phydev);
+	int ret;
 
 
-	return 0;
+	ret = genphy_update_link(phydev);
+	if (ret)
+		return ret;
+
+	return dm9161_parse_status(phydev);
 }
 }
 
 
 static struct phy_driver DM9161_driver = {
 static struct phy_driver DM9161_driver = {

+ 7 - 3
drivers/net/phy/et1011c.c

@@ -79,9 +79,13 @@ static int et1011c_parse_status(struct phy_device *phydev)
 
 
 static int et1011c_startup(struct phy_device *phydev)
 static int et1011c_startup(struct phy_device *phydev)
 {
 {
-	genphy_update_link(phydev);
-	et1011c_parse_status(phydev);
-	return 0;
+	int ret;
+
+	ret = genphy_update_link(phydev);
+	if (ret)
+		return ret;
+
+	return et1011c_parse_status(phydev);
 }
 }
 
 
 static struct phy_driver et1011c_driver = {
 static struct phy_driver et1011c_driver = {

+ 6 - 3
drivers/net/phy/lxt.c

@@ -49,10 +49,13 @@ static int lxt971_parse_status(struct phy_device *phydev)
 
 
 static int lxt971_startup(struct phy_device *phydev)
 static int lxt971_startup(struct phy_device *phydev)
 {
 {
-	genphy_update_link(phydev);
-	lxt971_parse_status(phydev);
+	int ret;
 
 
-	return 0;
+	ret = genphy_update_link(phydev);
+	if (ret)
+		return ret;
+
+	return lxt971_parse_status(phydev);
 }
 }
 
 
 static struct phy_driver LXT971_driver = {
 static struct phy_driver LXT971_driver = {

+ 22 - 17
drivers/net/phy/marvell.c

@@ -103,7 +103,7 @@ static int m88e1011s_config(struct phy_device *phydev)
 /* Parse the 88E1011's status register for speed and duplex
 /* Parse the 88E1011's status register for speed and duplex
  * information
  * information
  */
  */
-static uint m88e1xxx_parse_status(struct phy_device *phydev)
+static int m88e1xxx_parse_status(struct phy_device *phydev)
 {
 {
 	unsigned int speed;
 	unsigned int speed;
 	unsigned int mii_reg;
 	unsigned int mii_reg;
@@ -120,7 +120,7 @@ static uint m88e1xxx_parse_status(struct phy_device *phydev)
 			if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
 			if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
 				puts(" TIMEOUT !\n");
 				puts(" TIMEOUT !\n");
 				phydev->link = 0;
 				phydev->link = 0;
-				break;
+				return -ETIMEDOUT;
 			}
 			}
 
 
 			if ((i++ % 1000) == 0)
 			if ((i++ % 1000) == 0)
@@ -162,10 +162,13 @@ static uint m88e1xxx_parse_status(struct phy_device *phydev)
 
 
 static int m88e1011s_startup(struct phy_device *phydev)
 static int m88e1011s_startup(struct phy_device *phydev)
 {
 {
-	genphy_update_link(phydev);
-	m88e1xxx_parse_status(phydev);
+	int ret;
 
 
-	return 0;
+	ret = genphy_update_link(phydev);
+	if (ret)
+		return ret;
+
+	return m88e1xxx_parse_status(phydev);
 }
 }
 
 
 /* Marvell 88E1111S */
 /* Marvell 88E1111S */
@@ -349,22 +352,21 @@ static int m88e1118_config(struct phy_device *phydev)
 	/* Change Page Number */
 	/* Change Page Number */
 	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0000);
 	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0000);
 
 
-	genphy_config_aneg(phydev);
-
-	phy_reset(phydev);
-
-	return 0;
+	return genphy_config_aneg(phydev);
 }
 }
 
 
 static int m88e1118_startup(struct phy_device *phydev)
 static int m88e1118_startup(struct phy_device *phydev)
 {
 {
+	int ret;
+
 	/* Change Page Number */
 	/* Change Page Number */
 	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0000);
 	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0000);
 
 
-	genphy_update_link(phydev);
-	m88e1xxx_parse_status(phydev);
+	ret = genphy_update_link(phydev);
+	if (ret)
+		return ret;
 
 
-	return 0;
+	return m88e1xxx_parse_status(phydev);
 }
 }
 
 
 /* Marvell 88E1121R */
 /* Marvell 88E1121R */
@@ -421,12 +423,15 @@ static int m88e1145_config(struct phy_device *phydev)
 
 
 static int m88e1145_startup(struct phy_device *phydev)
 static int m88e1145_startup(struct phy_device *phydev)
 {
 {
-	genphy_update_link(phydev);
+	int ret;
+
+	ret = genphy_update_link(phydev);
+	if (ret)
+		return ret;
+
 	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_LED_CONTROL,
 	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_LED_CONTROL,
 			MIIM_88E1145_PHY_LED_DIRECT);
 			MIIM_88E1145_PHY_LED_DIRECT);
-	m88e1xxx_parse_status(phydev);
-
-	return 0;
+	return m88e1xxx_parse_status(phydev);
 }
 }
 
 
 /* Marvell 88E1149S */
 /* Marvell 88E1149S */

+ 6 - 1
drivers/net/phy/micrel.c

@@ -181,7 +181,12 @@ static struct phy_driver KS8721_driver = {
 static int ksz90xx_startup(struct phy_device *phydev)
 static int ksz90xx_startup(struct phy_device *phydev)
 {
 {
 	unsigned phy_ctl;
 	unsigned phy_ctl;
-	genphy_update_link(phydev);
+	int ret;
+
+	ret = genphy_update_link(phydev);
+	if (ret)
+		return ret;
+
 	phy_ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ90xx_PHY_CTL);
 	phy_ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ90xx_PHY_CTL);
 
 
 	if (phy_ctl & MIIM_KSZ90xx_PHYCTL_DUPLEX)
 	if (phy_ctl & MIIM_KSZ90xx_PHYCTL_DUPLEX)

+ 12 - 6
drivers/net/phy/natsemi.c

@@ -93,10 +93,13 @@ static int dp83865_parse_status(struct phy_device *phydev)
 
 
 static int dp83865_startup(struct phy_device *phydev)
 static int dp83865_startup(struct phy_device *phydev)
 {
 {
-	genphy_update_link(phydev);
-	dp83865_parse_status(phydev);
+	int ret;
 
 
-	return 0;
+	ret = genphy_update_link(phydev);
+	if (ret)
+		return ret;
+
+	return dp83865_parse_status(phydev);
 }
 }
 
 
 
 
@@ -134,10 +137,13 @@ static int dp83848_parse_status(struct phy_device *phydev)
 
 
 static int dp83848_startup(struct phy_device *phydev)
 static int dp83848_startup(struct phy_device *phydev)
 {
 {
-	genphy_update_link(phydev);
-	dp83848_parse_status(phydev);
+	int ret;
 
 
-	return 0;
+	ret = genphy_update_link(phydev);
+	if (ret)
+		return ret;
+
+	return dp83848_parse_status(phydev);
 }
 }
 
 
 static struct phy_driver DP83848_driver = {
 static struct phy_driver DP83848_driver = {

+ 8 - 7
drivers/net/phy/phy.c

@@ -248,7 +248,7 @@ int genphy_update_link(struct phy_device *phydev)
 			if (i > PHY_ANEG_TIMEOUT) {
 			if (i > PHY_ANEG_TIMEOUT) {
 				printf(" TIMEOUT !\n");
 				printf(" TIMEOUT !\n");
 				phydev->link = 0;
 				phydev->link = 0;
-				return 0;
+				return -ETIMEDOUT;
 			}
 			}
 
 
 			if (ctrlc()) {
 			if (ctrlc()) {
@@ -431,10 +431,13 @@ int genphy_config(struct phy_device *phydev)
 
 
 int genphy_startup(struct phy_device *phydev)
 int genphy_startup(struct phy_device *phydev)
 {
 {
-	genphy_update_link(phydev);
-	genphy_parse_link(phydev);
+	int ret;
 
 
-	return 0;
+	ret = genphy_update_link(phydev);
+	if (ret)
+		return ret;
+
+	return genphy_parse_link(phydev);
 }
 }
 
 
 int genphy_shutdown(struct phy_device *phydev)
 int genphy_shutdown(struct phy_device *phydev)
@@ -876,9 +879,7 @@ __weak int board_phy_config(struct phy_device *phydev)
 int phy_config(struct phy_device *phydev)
 int phy_config(struct phy_device *phydev)
 {
 {
 	/* Invoke an optional board-specific helper */
 	/* Invoke an optional board-specific helper */
-	board_phy_config(phydev);
-
-	return 0;
+	return board_phy_config(phydev);
 }
 }
 
 
 int phy_shutdown(struct phy_device *phydev)
 int phy_shutdown(struct phy_device *phydev)

+ 19 - 9
drivers/net/phy/realtek.c

@@ -208,28 +208,38 @@ static int rtl8211f_parse_status(struct phy_device *phydev)
 
 
 static int rtl8211x_startup(struct phy_device *phydev)
 static int rtl8211x_startup(struct phy_device *phydev)
 {
 {
+	int ret;
+
 	/* Read the Status (2x to make sure link is right) */
 	/* Read the Status (2x to make sure link is right) */
-	genphy_update_link(phydev);
-	rtl8211x_parse_status(phydev);
+	ret = genphy_update_link(phydev);
+	if (ret)
+		return ret;
 
 
-	return 0;
+	return rtl8211x_parse_status(phydev);
 }
 }
 
 
 static int rtl8211e_startup(struct phy_device *phydev)
 static int rtl8211e_startup(struct phy_device *phydev)
 {
 {
-	genphy_update_link(phydev);
-	genphy_parse_link(phydev);
+	int ret;
 
 
-	return 0;
+	ret = genphy_update_link(phydev);
+	if (ret)
+		return ret;
+
+	return genphy_parse_link(phydev);
 }
 }
 
 
 static int rtl8211f_startup(struct phy_device *phydev)
 static int rtl8211f_startup(struct phy_device *phydev)
 {
 {
+	int ret;
+
+	/* Read the Status (2x to make sure link is right) */
+	ret = genphy_update_link(phydev);
+	if (ret)
+		return ret;
 	/* Read the Status (2x to make sure link is right) */
 	/* Read the Status (2x to make sure link is right) */
-	genphy_update_link(phydev);
-	rtl8211f_parse_status(phydev);
 
 
-	return 0;
+	return rtl8211f_parse_status(phydev);
 }
 }
 
 
 /* Support for RTL8211B PHY */
 /* Support for RTL8211B PHY */

+ 7 - 3
drivers/net/phy/smsc.c

@@ -34,9 +34,13 @@ static int smsc_parse_status(struct phy_device *phydev)
 
 
 static int smsc_startup(struct phy_device *phydev)
 static int smsc_startup(struct phy_device *phydev)
 {
 {
-	genphy_update_link(phydev);
-	smsc_parse_status(phydev);
-	return 0;
+	int ret;
+
+	ret = genphy_update_link(phydev);
+	if (ret)
+		return ret;
+
+	return smsc_parse_status(phydev);
 }
 }
 
 
 static struct phy_driver lan8700_driver = {
 static struct phy_driver lan8700_driver = {

+ 5 - 3
drivers/net/phy/vitesse.c

@@ -112,10 +112,12 @@ static int vitesse_parse_status(struct phy_device *phydev)
 
 
 static int vitesse_startup(struct phy_device *phydev)
 static int vitesse_startup(struct phy_device *phydev)
 {
 {
-	genphy_update_link(phydev);
-	vitesse_parse_status(phydev);
+	int ret;
 
 
-	return 0;
+	ret = genphy_update_link(phydev);
+	if (ret)
+		return ret;
+	return vitesse_parse_status(phydev);
 }
 }
 
 
 static int cis8204_config(struct phy_device *phydev)
 static int cis8204_config(struct phy_device *phydev)

+ 4 - 2
drivers/net/xilinx_emaclite.c

@@ -250,7 +250,7 @@ static void emaclite_stop(struct udevice *dev)
 
 
 static int setup_phy(struct udevice *dev)
 static int setup_phy(struct udevice *dev)
 {
 {
-	int i;
+	int i, ret;
 	u16 phyreg;
 	u16 phyreg;
 	struct xemaclite *emaclite = dev_get_priv(dev);
 	struct xemaclite *emaclite = dev_get_priv(dev);
 	struct phy_device *phydev;
 	struct phy_device *phydev;
@@ -302,7 +302,9 @@ static int setup_phy(struct udevice *dev)
 	phydev->advertising = supported;
 	phydev->advertising = supported;
 	emaclite->phydev = phydev;
 	emaclite->phydev = phydev;
 	phy_config(phydev);
 	phy_config(phydev);
-	phy_startup(phydev);
+	ret = phy_startup(phydev);
+	if (ret)
+		return ret;
 
 
 	if (!phydev->link) {
 	if (!phydev->link) {
 		printf("%s: No link.\n", phydev->dev->name);
 		printf("%s: No link.\n", phydev->dev->name);

+ 5 - 3
drivers/net/zynq_gem.c

@@ -352,14 +352,14 @@ static int zynq_phy_init(struct udevice *dev)
 	priv->phydev->supported = supported | ADVERTISED_Pause |
 	priv->phydev->supported = supported | ADVERTISED_Pause |
 				  ADVERTISED_Asym_Pause;
 				  ADVERTISED_Asym_Pause;
 	priv->phydev->advertising = priv->phydev->supported;
 	priv->phydev->advertising = priv->phydev->supported;
-	phy_config(priv->phydev);
 
 
-	return 0;
+	return phy_config(priv->phydev);
 }
 }
 
 
 static int zynq_gem_init(struct udevice *dev)
 static int zynq_gem_init(struct udevice *dev)
 {
 {
 	u32 i, nwconfig;
 	u32 i, nwconfig;
+	int ret;
 	unsigned long clk_rate = 0;
 	unsigned long clk_rate = 0;
 	struct zynq_gem_priv *priv = dev_get_priv(dev);
 	struct zynq_gem_priv *priv = dev_get_priv(dev);
 	struct zynq_gem_regs *regs = priv->iobase;
 	struct zynq_gem_regs *regs = priv->iobase;
@@ -427,7 +427,9 @@ static int zynq_gem_init(struct udevice *dev)
 		priv->init++;
 		priv->init++;
 	}
 	}
 
 
-	phy_startup(priv->phydev);
+	ret = phy_startup(priv->phydev);
+	if (ret)
+		return ret;
 
 
 	if (!priv->phydev->link) {
 	if (!priv->phydev->link) {
 		printf("%s: No link.\n", priv->phydev->dev->name);
 		printf("%s: No link.\n", priv->phydev->dev->name);

+ 1 - 0
include/bootstage.h

@@ -198,6 +198,7 @@ enum bootstage_id {
 	BOOTSTAGE_ID_ACCUM_SCSI,
 	BOOTSTAGE_ID_ACCUM_SCSI,
 	BOOTSTAGE_ID_ACCUM_SPI,
 	BOOTSTAGE_ID_ACCUM_SPI,
 	BOOTSTAGE_ID_ACCUM_DECOMP,
 	BOOTSTAGE_ID_ACCUM_DECOMP,
+	BOOTSTAGE_ID_FPGA_INIT,
 
 
 	/* a few spare for the user, from here */
 	/* a few spare for the user, from here */
 	BOOTSTAGE_ID_USER,
 	BOOTSTAGE_ID_USER,

+ 57 - 2
include/configs/xilinx_zynqmp.h

@@ -41,7 +41,7 @@
 # define CONFIG_IDENT_STRING		" Xilinx ZynqMP"
 # define CONFIG_IDENT_STRING		" Xilinx ZynqMP"
 #endif
 #endif
 
 
-#define CONFIG_SYS_INIT_SP_ADDR		CONFIG_SYS_TEXT_BASE
+#define CONFIG_SYS_INIT_SP_ADDR		0xfffffffc
 
 
 /* Generic Timer Definitions - setup in EL3. Setup by ATF for other cases */
 /* Generic Timer Definitions - setup in EL3. Setup by ATF for other cases */
 #if !defined(COUNTER_FREQUENCY)
 #if !defined(COUNTER_FREQUENCY)
@@ -65,6 +65,9 @@
 #define CONFIG_CMD_ENV
 #define CONFIG_CMD_ENV
 #define CONFIG_DOS_PARTITION
 #define CONFIG_DOS_PARTITION
 #define CONFIG_EFI_PARTITION
 #define CONFIG_EFI_PARTITION
+#ifndef CONFIG_SPL_BUILD
+# define CONFIG_ISO_PARTITION
+#endif
 #define CONFIG_MP
 #define CONFIG_MP
 
 
 /* BOOTP options */
 /* BOOTP options */
@@ -74,10 +77,24 @@
 #define CONFIG_BOOTP_HOSTNAME
 #define CONFIG_BOOTP_HOSTNAME
 #define CONFIG_BOOTP_MAY_FAIL
 #define CONFIG_BOOTP_MAY_FAIL
 #define CONFIG_BOOTP_SERVERIP
 #define CONFIG_BOOTP_SERVERIP
+#define CONFIG_BOOTP_DNS
+#define CONFIG_BOOTP_PXE
+#define CONFIG_BOOTP_SUBNETMASK
+#define CONFIG_BOOTP_PXE_CLIENTARCH     0x100
+
+/* Diff from config_distro_defaults.h */
+#define CONFIG_SUPPORT_RAW_INITRD
+#define CONFIG_ENV_VARS_UBOOT_CONFIG
+#define CONFIG_AUTO_COMPLETE
+
+/* PXE */
+#define CONFIG_CMD_PXE
+#define CONFIG_MENU
 
 
 #if defined(CONFIG_ZYNQ_SDHCI)
 #if defined(CONFIG_ZYNQ_SDHCI)
 # define CONFIG_MMC
 # define CONFIG_MMC
 # define CONFIG_GENERIC_MMC
 # define CONFIG_GENERIC_MMC
+# define CONFIG_SUPPORT_EMMC_BOOT
 # define CONFIG_SDHCI
 # define CONFIG_SDHCI
 # ifndef CONFIG_ZYNQ_SDHCI_MAX_FREQ
 # ifndef CONFIG_ZYNQ_SDHCI_MAX_FREQ
 #  define CONFIG_ZYNQ_SDHCI_MAX_FREQ	200000000
 #  define CONFIG_ZYNQ_SDHCI_MAX_FREQ	200000000
@@ -133,6 +150,7 @@
 #endif
 #endif
 
 
 /* Initial environment variables */
 /* Initial environment variables */
+#ifndef CONFIG_EXTRA_ENV_SETTINGS
 #define CONFIG_EXTRA_ENV_SETTINGS \
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"kernel_addr=0x80000\0" \
 	"kernel_addr=0x80000\0" \
 	"fdt_addr=0x7000000\0" \
 	"fdt_addr=0x7000000\0" \
@@ -143,8 +161,8 @@
 		"load mmc $sdbootdev:$partid $kernel_addr Image && " \
 		"load mmc $sdbootdev:$partid $kernel_addr Image && " \
 		"booti $kernel_addr - $fdt_addr\0" \
 		"booti $kernel_addr - $fdt_addr\0" \
 	DFU_ALT_INFO
 	DFU_ALT_INFO
+#endif
 
 
-#define CONFIG_PREBOOT		"run bootargs"
 #define CONFIG_BOOTCOMMAND	"run $modeboot"
 #define CONFIG_BOOTCOMMAND	"run $modeboot"
 #define CONFIG_BOOTDELAY	3
 #define CONFIG_BOOTDELAY	3
 
 
@@ -212,4 +230,41 @@
 #define CONFIG_BOARD_EARLY_INIT_R
 #define CONFIG_BOARD_EARLY_INIT_R
 #define CONFIG_CLOCKS
 #define CONFIG_CLOCKS
 
 
+#define CONFIG_SPL_TEXT_BASE		0xfffc0000
+#define CONFIG_SPL_MAX_SIZE		0x20000
+
+/* Just random location in OCM */
+#define CONFIG_SPL_BSS_START_ADDR	0x1000000
+#define CONFIG_SPL_BSS_MAX_SIZE		0x2000000
+
+#define CONFIG_SPL_FRAMEWORK
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_BOARD_INIT
+#define CONFIG_SPL_RAM_DEVICE
+
+#define CONFIG_SPL_OS_BOOT
+/* u-boot is like dtb */
+#define CONFIG_SPL_FS_LOAD_ARGS_NAME	"u-boot.bin"
+#define CONFIG_SYS_SPL_ARGS_ADDR	0x8000000
+
+/* ATF is my kernel image */
+#define CONFIG_SPL_FS_LOAD_KERNEL_NAME	"atf.ub"
+
+/* FIT load address for RAM boot */
+#define CONFIG_SPL_LOAD_FIT_ADDRESS	0x10000000
+
+/* MMC support */
+#ifdef CONFIG_ZYNQ_SDHCI
+# define CONFIG_SPL_MMC_SUPPORT
+# define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION	1
+# define CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR	0 /* unused */
+# define CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS	0 /* unused */
+# define CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR	0 /* unused */
+# define CONFIG_SPL_LIBDISK_SUPPORT
+# define CONFIG_SPL_FAT_SUPPORT
+# define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME	"u-boot.img"
+#endif
+
 #endif /* __XILINX_ZYNQMP_H */
 #endif /* __XILINX_ZYNQMP_H */

+ 6 - 0
include/configs/xilinx_zynqmp_zcu102.h

@@ -48,6 +48,12 @@
 
 
 #define CONFIG_IDENT_STRING	" Xilinx ZynqMP ZCU102"
 #define CONFIG_IDENT_STRING	" Xilinx ZynqMP ZCU102"
 
 
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN	1
+#define CONFIG_CMD_EEPROM
+#define CONFIG_ZYNQ_EEPROM_BUS		5
+#define CONFIG_ZYNQ_GEM_EEPROM_ADDR	0x54
+#define CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET	0x20
+
 #define CONFIG_KERNEL_FDT_OFST_SIZE \
 #define CONFIG_KERNEL_FDT_OFST_SIZE \
 	"kernel_offset=0x180000\0" \
 	"kernel_offset=0x180000\0" \
 	"fdt_offset=0x100000\0" \
 	"fdt_offset=0x100000\0" \

+ 1 - 5
include/configs/zynq-common.h

@@ -315,11 +315,7 @@
 #define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION     1
 #define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION     1
 #define CONFIG_SPL_LIBDISK_SUPPORT
 #define CONFIG_SPL_LIBDISK_SUPPORT
 #define CONFIG_SPL_FAT_SUPPORT
 #define CONFIG_SPL_FAT_SUPPORT
-#ifdef CONFIG_OF_SEPARATE
-# define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME     "u-boot-dtb.img"
-#else
-# define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME     "u-boot.img"
-#endif
+#define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME     "u-boot.img"
 #endif
 #endif
 
 
 /* Disable dcache for SPL just for sure */
 /* Disable dcache for SPL just for sure */

+ 6 - 1
include/image.h

@@ -246,8 +246,10 @@ struct lmb;
 #define IH_TYPE_RKSD		24	/* Rockchip SD card		*/
 #define IH_TYPE_RKSD		24	/* Rockchip SD card		*/
 #define IH_TYPE_RKSPI		25	/* Rockchip SPI image		*/
 #define IH_TYPE_RKSPI		25	/* Rockchip SPI image		*/
 #define IH_TYPE_ZYNQIMAGE	26	/* Xilinx Zynq Boot Image */
 #define IH_TYPE_ZYNQIMAGE	26	/* Xilinx Zynq Boot Image */
+#define IH_TYPE_ZYNQMPIMAGE	27	/* Xilinx ZynqMP Boot Image */
+#define IH_TYPE_FPGA		28	/* FPGA Image */
 
 
-#define IH_TYPE_COUNT		27	/* Number of image types */
+#define IH_TYPE_COUNT		29	/* Number of image types */
 
 
 /*
 /*
  * Compression Types
  * Compression Types
@@ -494,6 +496,8 @@ int genimg_get_format(const void *img_addr);
 int genimg_has_config(bootm_headers_t *images);
 int genimg_has_config(bootm_headers_t *images);
 ulong genimg_get_image(ulong img_addr);
 ulong genimg_get_image(ulong img_addr);
 
 
+int boot_get_fpga(int argc, char * const argv[], bootm_headers_t *images,
+		uint8_t arch, const ulong *ld_start, ulong * const ld_len);
 int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,
 int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,
 		uint8_t arch, ulong *rd_start, ulong *rd_end);
 		uint8_t arch, ulong *rd_start, ulong *rd_end);
 
 
@@ -809,6 +813,7 @@ int bootz_setup(ulong image, ulong *start, ulong *end);
 #define FIT_LOADABLE_PROP	"loadables"
 #define FIT_LOADABLE_PROP	"loadables"
 #define FIT_DEFAULT_PROP	"default"
 #define FIT_DEFAULT_PROP	"default"
 #define FIT_SETUP_PROP		"setup"
 #define FIT_SETUP_PROP		"setup"
+#define FIT_FPGA_PROP		"fpga"
 
 
 #define FIT_MAX_HASH_LEN	HASH_MAX_DIGEST_SIZE
 #define FIT_MAX_HASH_LEN	HASH_MAX_DIGEST_SIZE
 
 

+ 1 - 0
include/spl.h

@@ -58,6 +58,7 @@ u32 spl_boot_mode(void);
 void spl_set_header_raw_uboot(void);
 void spl_set_header_raw_uboot(void);
 int spl_parse_image_header(const struct image_header *header);
 int spl_parse_image_header(const struct image_header *header);
 void spl_board_prepare_for_linux(void);
 void spl_board_prepare_for_linux(void);
+void spl_board_prepare_for_boot(void);
 void __noreturn jump_to_image_linux(void *arg);
 void __noreturn jump_to_image_linux(void *arg);
 int spl_start_uboot(void);
 int spl_start_uboot(void);
 void spl_display_print(void);
 void spl_display_print(void);

+ 7 - 0
scripts/Makefile.spl

@@ -129,7 +129,12 @@ endif
 boot.bin: $(obj)/u-boot-spl.bin FORCE
 boot.bin: $(obj)/u-boot-spl.bin FORCE
 	$(call if_changed,mkimage)
 	$(call if_changed,mkimage)
 else
 else
+ifdef CONFIG_ARCH_ZYNQ
 MKIMAGEFLAGS_boot.bin = -T zynqimage
 MKIMAGEFLAGS_boot.bin = -T zynqimage
+endif
+ifdef CONFIG_ARCH_ZYNQMP
+MKIMAGEFLAGS_boot.bin = -T zynqmpimage
+endif
 
 
 spl/boot.bin: $(obj)/u-boot-spl.bin FORCE
 spl/boot.bin: $(obj)/u-boot-spl.bin FORCE
 	$(call if_changed,mkimage)
 	$(call if_changed,mkimage)
@@ -157,6 +162,8 @@ ifdef CONFIG_ARCH_ZYNQ
 ALL-y	+= $(obj)/boot.bin
 ALL-y	+= $(obj)/boot.bin
 endif
 endif
 
 
+ALL-(CONFIG_ARCH_ZYNQMP)	+= $(obj)/boot.bin
+
 all:	$(ALL-y)
 all:	$(ALL-y)
 
 
 quiet_cmd_cat = CAT     $@
 quiet_cmd_cat = CAT     $@

+ 1 - 0
tools/Makefile

@@ -98,6 +98,7 @@ dumpimage-mkimage-objs := aisimage.o \
 			common/hash.o \
 			common/hash.o \
 			ublimage.o \
 			ublimage.o \
 			zynqimage.o \
 			zynqimage.o \
+			zynqmpimage.o \
 			$(LIBFDT_OBJS) \
 			$(LIBFDT_OBJS) \
 			$(RSA_OBJS-y)
 			$(RSA_OBJS-y)
 
 

+ 269 - 0
tools/zynqmpimage.c

@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2016 Michal Simek <michals@xilinx.com>
+ * Copyright (C) 2015 Nathan Rossi <nathan@nathanrossi.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * The following Boot Header format/structures and values are defined in the
+ * following documents:
+ *   * ug1085 ZynqMP TRM (Chapter 9, Table 9-3)
+ *
+ * Expected Header Size = 0x9C0
+ * Forced as 'little' endian, 32-bit words
+ *
+ *  0x  0 - Interrupt table (8 words)
+ *  ...     (Default value = 0xeafffffe)
+ *  0x 1f
+ *  0x 20 - Width detection
+ *         * DEFAULT_WIDTHDETECTION    0xaa995566
+ *  0x 24 - Image identifier
+ *         * DEFAULT_IMAGEIDENTIFIER   0x584c4e58
+ *  0x 28 - Encryption
+ *         * 0x00000000 - None
+ *         * 0xa5c3c5a3 - eFuse
+ *         * 0xa5c3c5a7 - obfuscated key in eFUSE
+ *         * 0x3a5c3c5a - bbRam
+ *         * 0xa35c7ca5 - obfuscated key in boot header
+ *  0x 2C - Image load
+ *  0x 30 - Image offset
+ *  0x 34 - PFW image length
+ *  0x 38 - Total PFW image length
+ *  0x 3C - Image length
+ *  0x 40 - Total image length
+ *  0x 44 - Image attributes
+ *  0x 48 - Header checksum
+ *  0x 4c - Obfuscated key
+ *  ...
+ *  0x 68
+ *  0x 6c - Reserved
+ *  0x 70 - User defined
+ *  ...
+ *  0x 9c
+ *  0x a0 - Secure header initialization vector
+ *  ...
+ *  0x a8
+ *  0x ac - Obfuscated key initialization vector
+ *  ...
+ *  0x b4
+ *  0x b8 - Register Initialization, 511 Address and Data word pairs
+ *         * List is terminated with an address of 0xffffffff or
+ *  ...    * at the max number of entries
+ *  0x8b4
+ *  0x8b8 - Reserved
+ *  ...
+ *  0x9bf
+ *  0x9c0 - Data/Image starts here or above
+ */
+
+#include "imagetool.h"
+#include "mkimage.h"
+#include <image.h>
+
+#define HEADER_INTERRUPT_DEFAULT (cpu_to_le32(0xeafffffe))
+#define HEADER_REGINIT_NULL (cpu_to_le32(0xffffffff))
+#define HEADER_WIDTHDETECTION (cpu_to_le32(0xaa995566))
+#define HEADER_IMAGEIDENTIFIER (cpu_to_le32(0x584c4e58))
+
+enum {
+	ENCRYPTION_EFUSE = 0xa5c3c5a3,
+	ENCRYPTION_OEFUSE = 0xa5c3c5a7,
+	ENCRYPTION_BBRAM = 0x3a5c3c5a,
+	ENCRYPTION_OBBRAM = 0xa35c7ca5,
+	ENCRYPTION_NONE = 0x0,
+};
+
+struct zynqmp_reginit {
+	uint32_t address;
+	uint32_t data;
+};
+
+#define HEADER_INTERRUPT_VECTORS	8
+#define HEADER_REGINITS			256
+
+struct zynqmp_header {
+	uint32_t interrupt_vectors[HEADER_INTERRUPT_VECTORS]; /* 0x0 */
+	uint32_t width_detection; /* 0x20 */
+	uint32_t image_identifier; /* 0x24 */
+	uint32_t encryption; /* 0x28 */
+	uint32_t image_load; /* 0x2c */
+	uint32_t image_offset; /* 0x30 */
+	uint32_t pfw_image_length; /* 0x34 */
+	uint32_t total_pfw_image_length; /* 0x38 */
+	uint32_t image_size; /* 0x3c */
+	uint32_t image_stored_size; /* 0x40 */
+	uint32_t image_attributes; /* 0x44 */
+	uint32_t checksum; /* 0x48 */
+	uint32_t __reserved1[27]; /* 0x4c */
+	struct zynqmp_reginit register_init[HEADER_REGINITS]; /* 0xb8 */
+	uint32_t __reserved4[66]; /* 0x9c0 */
+};
+
+static struct zynqmp_header zynqmpimage_header;
+
+static uint32_t zynqmpimage_checksum(struct zynqmp_header *ptr)
+{
+	uint32_t checksum = 0;
+
+	if (ptr == NULL)
+		return 0;
+
+	checksum += le32_to_cpu(ptr->width_detection);
+	checksum += le32_to_cpu(ptr->image_identifier);
+	checksum += le32_to_cpu(ptr->encryption);
+	checksum += le32_to_cpu(ptr->image_load);
+	checksum += le32_to_cpu(ptr->image_offset);
+	checksum += le32_to_cpu(ptr->pfw_image_length);
+	checksum += le32_to_cpu(ptr->total_pfw_image_length);
+	checksum += le32_to_cpu(ptr->image_size);
+	checksum += le32_to_cpu(ptr->image_stored_size);
+	checksum += le32_to_cpu(ptr->image_attributes);
+	checksum = ~checksum;
+
+	return cpu_to_le32(checksum);
+}
+
+static void zynqmpimage_default_header(struct zynqmp_header *ptr)
+{
+	int i;
+
+	if (ptr == NULL)
+		return;
+
+	ptr->width_detection = HEADER_WIDTHDETECTION;
+	ptr->image_attributes = 0x800;
+	ptr->image_identifier = HEADER_IMAGEIDENTIFIER;
+	ptr->encryption = cpu_to_le32(ENCRYPTION_NONE);
+
+	/* Setup not-supported/constant/reserved fields */
+	for (i = 0; i < HEADER_INTERRUPT_VECTORS; i++)
+		ptr->interrupt_vectors[i] = HEADER_INTERRUPT_DEFAULT;
+
+	for (i = 0; i < HEADER_REGINITS; i++) {
+		ptr->register_init[i].address = HEADER_REGINIT_NULL;
+		ptr->register_init[i].data = 0;
+	}
+
+	/*
+	 * Certain reserved fields are required to be set to 0, ensure they are
+	 * set as such.
+	 */
+	ptr->pfw_image_length = 0x0;
+	ptr->total_pfw_image_length = 0x0;
+}
+
+/* mkimage glue functions */
+static int zynqmpimage_verify_header(unsigned char *ptr, int image_size,
+		struct image_tool_params *params)
+{
+	struct zynqmp_header *zynqhdr = (struct zynqmp_header *)ptr;
+
+	if (image_size < sizeof(struct zynqmp_header))
+		return -1;
+
+	if (zynqhdr->width_detection != HEADER_WIDTHDETECTION)
+		return -1;
+	if (zynqhdr->image_identifier != HEADER_IMAGEIDENTIFIER)
+		return -1;
+
+	if (zynqmpimage_checksum(zynqhdr) != zynqhdr->checksum)
+		return -1;
+
+	return 0;
+}
+
+static void zynqmpimage_print_header(const void *ptr)
+{
+	struct zynqmp_header *zynqhdr = (struct zynqmp_header *)ptr;
+	int i;
+
+	printf("Image Type   : Xilinx Zynq Boot Image support\n");
+	printf("Image Offset : 0x%08x\n", le32_to_cpu(zynqhdr->image_offset));
+	printf("Image Size   : %lu bytes (%lu bytes packed)\n",
+	       (unsigned long)le32_to_cpu(zynqhdr->image_size),
+	       (unsigned long)le32_to_cpu(zynqhdr->image_stored_size));
+	printf("Image Load   : 0x%08x\n", le32_to_cpu(zynqhdr->image_load));
+	printf("Checksum     : 0x%08x\n", le32_to_cpu(zynqhdr->checksum));
+
+	for (i = 0; i < HEADER_INTERRUPT_VECTORS; i++) {
+		if (zynqhdr->interrupt_vectors[i] == HEADER_INTERRUPT_DEFAULT)
+			continue;
+
+		printf("Modified Interrupt Vector Address [%d]: 0x%08x\n", i,
+		       le32_to_cpu(zynqhdr->interrupt_vectors[i]));
+	}
+
+	for (i = 0; i < HEADER_REGINITS; i++) {
+		if (zynqhdr->register_init[i].address == HEADER_REGINIT_NULL)
+			break;
+
+		if (i == 0)
+			printf("Custom Register Initialization:\n");
+
+		printf("    @ 0x%08x -> 0x%08x\n",
+		       le32_to_cpu(zynqhdr->register_init[i].address),
+		       le32_to_cpu(zynqhdr->register_init[i].data));
+	}
+}
+
+static int zynqmpimage_check_params(struct image_tool_params *params)
+{
+	if (!params)
+		return 0;
+
+	if (params->addr != 0x0) {
+		fprintf(stderr, "Error: Load Address cannot be specified.\n");
+		return -1;
+	}
+
+	/*
+	 * If the entry point is specified ensure it is 64 byte aligned.
+	 */
+	if (params->eflag && (params->ep % 64 != 0)) {
+		fprintf(stderr,
+			"Error: Entry Point must be aligned to a 64-byte boundary.\n");
+		return -1;
+	}
+
+	return !(params->lflag || params->dflag);
+}
+
+static int zynqmpimage_check_image_types(uint8_t type)
+{
+	if (type == IH_TYPE_ZYNQMPIMAGE)
+		return EXIT_SUCCESS;
+	return EXIT_FAILURE;
+}
+
+static void zynqmpimage_set_header(void *ptr, struct stat *sbuf, int ifd,
+		struct image_tool_params *params)
+{
+	struct zynqmp_header *zynqhdr = (struct zynqmp_header *)ptr;
+	zynqmpimage_default_header(zynqhdr);
+
+	/* place image directly after header */
+	zynqhdr->image_offset =
+		cpu_to_le32((uint32_t)sizeof(struct zynqmp_header));
+	zynqhdr->image_size = cpu_to_le32(params->file_size -
+					  sizeof(struct zynqmp_header));
+	zynqhdr->image_stored_size = zynqhdr->image_size;
+	zynqhdr->image_load = 0xfffc0000;
+	if (params->eflag)
+		zynqhdr->image_load = cpu_to_le32((uint32_t)params->ep);
+
+	zynqhdr->checksum = zynqmpimage_checksum(zynqhdr);
+}
+
+U_BOOT_IMAGE_TYPE(
+	zynqmpimage,
+	"Xilinx ZynqMP Boot Image support",
+	sizeof(struct zynqmp_header),
+	(void *)&zynqmpimage_header,
+	zynqmpimage_check_params,
+	zynqmpimage_verify_header,
+	zynqmpimage_print_header,
+	zynqmpimage_set_header,
+	NULL,
+	zynqmpimage_check_image_types,
+	NULL,
+	NULL
+);