Browse Source

Merge tag 'xilinx-for-v2018.07' of git://www.denx.de/git/u-boot-microblaze

Xilinx changes for v2018.07

microblaze:
- Align defconfig

zynq:
- Rework fpga initialization and cpuinfo handling

zynqmp:
- Add ZynqMP R5 support
- Wire and enable watchdog on zcu100-revC
- Setup MMU map for DDR at run time
- Show board info based on DT and cleanup IDENT_STRING

zynqmp tools:
- Add read partition support
- Add initial support for Xilinx bif format for boot.bin generation

mmc:
- Fix get_timer usage on 64bit cpus
- Add support for SD3.0 UHS mode

nand-zynq:
- Add support for 16bit buswidth
- Use address cycles from onfi params

scsi:
- convert ceva sata to UCLASS_AHCI

timer:
- Add Cadence TTC for ZynqMP r5

watchdog:
- Minor cadence driver cleanup
Tom Rini 6 years ago
parent
commit
3b52847a45
85 changed files with 3176 additions and 314 deletions
  1. 9 2
      MAINTAINERS
  2. 11 0
      arch/arm/Kconfig
  3. 1 0
      arch/arm/Makefile
  4. 52 32
      arch/arm/cpu/armv8/zynqmp/cpu.c
  5. 3 0
      arch/arm/dts/Makefile
  6. 1 1
      arch/arm/dts/zynqmp-clk.dtsi
  7. 73 0
      arch/arm/dts/zynqmp-r5.dts
  8. 79 0
      arch/arm/dts/zynqmp-zc1275-revB.dts
  9. 1 0
      arch/arm/dts/zynqmp-zcu100-revC.dts
  10. 1 1
      arch/arm/include/asm/arch-zynqmp/sys_proto.h
  11. 84 1
      arch/arm/mach-zynq/cpu.c
  12. 6 5
      arch/arm/mach-zynq/spl.c
  13. 27 0
      arch/arm/mach-zynqmp-r5/Kconfig
  14. 3 0
      arch/arm/mach-zynqmp-r5/Makefile
  15. 37 0
      arch/arm/mach-zynqmp-r5/cpu.c
  16. 0 80
      board/xilinx/zynq/board.c
  17. 2 0
      board/xilinx/zynqmp/Makefile
  18. 229 0
      board/xilinx/zynqmp/tap_delays.c
  19. 523 0
      board/xilinx/zynqmp/zynqmp-zc1275-revB/psu_init_gpl.c
  20. 1 1
      board/xilinx/zynqmp/zynqmp-zcu100-revC/psu_init_gpl.c
  21. 71 9
      board/xilinx/zynqmp/zynqmp.c
  22. 7 0
      board/xilinx/zynqmp_r5/MAINTAINERS
  23. 6 0
      board/xilinx/zynqmp_r5/Makefile
  24. 25 0
      board/xilinx/zynqmp_r5/board.c
  25. 1 0
      common/image.c
  26. 0 4
      configs/microblaze-generic_defconfig
  27. 0 1
      configs/syzygy_hub_defconfig
  28. 0 1
      configs/topic_miami_defconfig
  29. 0 1
      configs/topic_miamilite_defconfig
  30. 0 1
      configs/topic_miamiplus_defconfig
  31. 16 0
      configs/xilinx_zynqmp_r5_defconfig
  32. 0 2
      configs/xilinx_zynqmp_zc1232_revA_defconfig
  33. 0 2
      configs/xilinx_zynqmp_zc1254_revA_defconfig
  34. 0 2
      configs/xilinx_zynqmp_zc1275_revA_defconfig
  35. 53 0
      configs/xilinx_zynqmp_zc1275_revB_defconfig
  36. 0 2
      configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig
  37. 0 2
      configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig
  38. 0 2
      configs/xilinx_zynqmp_zc1751_xm017_dc3_defconfig
  39. 0 2
      configs/xilinx_zynqmp_zc1751_xm018_dc4_defconfig
  40. 0 2
      configs/xilinx_zynqmp_zc1751_xm019_dc5_defconfig
  41. 2 2
      configs/xilinx_zynqmp_zcu100_revC_defconfig
  42. 2 2
      configs/xilinx_zynqmp_zcu102_rev1_0_defconfig
  43. 0 2
      configs/xilinx_zynqmp_zcu102_revA_defconfig
  44. 0 2
      configs/xilinx_zynqmp_zcu102_revB_defconfig
  45. 0 2
      configs/xilinx_zynqmp_zcu104_revA_defconfig
  46. 0 2
      configs/xilinx_zynqmp_zcu104_revC_defconfig
  47. 0 2
      configs/xilinx_zynqmp_zcu106_revA_defconfig
  48. 0 2
      configs/xilinx_zynqmp_zcu111_revA_defconfig
  49. 0 1
      configs/zynq_cc108_defconfig
  50. 1 0
      configs/zynq_cse_qspi_defconfig
  51. 0 1
      configs/zynq_microzed_defconfig
  52. 0 1
      configs/zynq_picozed_defconfig
  53. 0 1
      configs/zynq_z_turn_defconfig
  54. 0 1
      configs/zynq_zc702_defconfig
  55. 0 1
      configs/zynq_zc706_defconfig
  56. 0 1
      configs/zynq_zc770_xm010_defconfig
  57. 0 1
      configs/zynq_zc770_xm011_defconfig
  58. 0 1
      configs/zynq_zc770_xm011_x16_defconfig
  59. 0 1
      configs/zynq_zc770_xm012_defconfig
  60. 0 1
      configs/zynq_zc770_xm013_defconfig
  61. 0 1
      configs/zynq_zed_defconfig
  62. 0 1
      configs/zynq_zybo_defconfig
  63. 20 16
      drivers/ata/sata_ceva.c
  64. 2 2
      drivers/mmc/mmc.c
  65. 61 4
      drivers/mmc/sdhci.c
  66. 226 5
      drivers/mmc/zynq_sdhci.c
  67. 53 1
      drivers/mtd/nand/zynq_nand.c
  68. 1 1
      drivers/serial/Kconfig
  69. 0 1
      drivers/serial/serial_zynq.c
  70. 7 0
      drivers/timer/Kconfig
  71. 1 0
      drivers/timer/Makefile
  72. 91 0
      drivers/timer/cadence-ttc.c
  73. 2 2
      drivers/watchdog/cdns_wdt.c
  74. 51 0
      include/configs/xilinx_zynqmp_r5.h
  75. 16 0
      include/configs/xilinx_zynqmp_zc1275_revB.h
  76. 1 0
      include/image.h
  77. 8 0
      include/sdhci.h
  78. 19 0
      include/zynqmp_tap_delay.h
  79. 34 55
      include/zynqpl.h
  80. 1 0
      tools/Makefile
  81. 1 0
      tools/imagetool.h
  82. 7 0
      tools/mkimage.c
  83. 1008 0
      tools/zynqmpbif.c
  84. 100 42
      tools/zynqmpimage.c
  85. 139 0
      tools/zynqmpimage.h

+ 9 - 2
MAINTAINERS

@@ -274,7 +274,7 @@ ARM ZYNQMP
 M:	Michal Simek <michal.simek@xilinx.com>
 M:	Michal Simek <michal.simek@xilinx.com>
 S:	Maintained
 S:	Maintained
 T:	git git://git.denx.de/u-boot-microblaze.git
 T:	git git://git.denx.de/u-boot-microblaze.git
-F:	arch/arm/mach-zynq/
+F:	arch/arm/cpu/armv8/zynqmp/
 F:	drivers/clk/clk_zynqmp.c
 F:	drivers/clk/clk_zynqmp.c
 F:	drivers/fpga/zynqpl.c
 F:	drivers/fpga/zynqpl.c
 F:	drivers/gpio/zynq_gpio.c
 F:	drivers/gpio/zynq_gpio.c
@@ -288,12 +288,19 @@ F:	drivers/net/zynq_gem.c
 F:	drivers/serial/serial_zynq.c
 F:	drivers/serial/serial_zynq.c
 F:	drivers/spi/zynq_qspi.c
 F:	drivers/spi/zynq_qspi.c
 F:	drivers/spi/zynq_spi.c
 F:	drivers/spi/zynq_spi.c
+F:	drivers/timer/cadence-ttc.c
 F:	drivers/usb/host/ehci-zynq.c
 F:	drivers/usb/host/ehci-zynq.c
 F:	drivers/watchdog/cdns_wdt.c
 F:	drivers/watchdog/cdns_wdt.c
 F:	include/zynqmppl.h
 F:	include/zynqmppl.h
-F:	tools/zynqimage.c
+F:	tools/zynqmp*
 N:	zynqmp
 N:	zynqmp
 
 
+ARM ZYNQMP R5
+M:	Michal Simek <michal.simek@xilinx.com>
+S:	Maintained
+T:	git git://git.denx.de/u-boot-microblaze.git
+F:	arch/arm/mach-zynqmp-r5/
+
 BUILDMAN
 BUILDMAN
 M:	Simon Glass <sjg@chromium.org>
 M:	Simon Glass <sjg@chromium.org>
 S:	Maintained
 S:	Maintained

+ 11 - 0
arch/arm/Kconfig

@@ -821,6 +821,15 @@ config ARCH_ZYNQ
 	imply CMD_CLK
 	imply CMD_CLK
 	imply FAT_WRITE
 	imply FAT_WRITE
 	imply CMD_SPL
 	imply CMD_SPL
+	imply ARCH_EARLY_INIT_R
+
+config ARCH_ZYNQMP_R5
+	bool "Xilinx ZynqMP R5 based platform"
+	select CPU_V7R
+	select OF_CONTROL
+	select DM
+	select DM_SERIAL
+	select CLK
 
 
 config ARCH_ZYNQMP
 config ARCH_ZYNQMP
 	bool "Xilinx ZynqMP based platform"
 	bool "Xilinx ZynqMP based platform"
@@ -1344,6 +1353,8 @@ source "arch/arm/cpu/armv7/vf610/Kconfig"
 
 
 source "arch/arm/mach-zynq/Kconfig"
 source "arch/arm/mach-zynq/Kconfig"
 
 
+source "arch/arm/mach-zynqmp-r5/Kconfig"
+
 source "arch/arm/cpu/armv7/Kconfig"
 source "arch/arm/cpu/armv7/Kconfig"
 
 
 source "arch/arm/cpu/armv8/zynqmp/Kconfig"
 source "arch/arm/cpu/armv8/zynqmp/Kconfig"

+ 1 - 0
arch/arm/Makefile

@@ -76,6 +76,7 @@ machine-$(CONFIG_ARCH_STM32MP)		+= stm32mp
 machine-$(CONFIG_TEGRA)			+= tegra
 machine-$(CONFIG_TEGRA)			+= tegra
 machine-$(CONFIG_ARCH_UNIPHIER)		+= uniphier
 machine-$(CONFIG_ARCH_UNIPHIER)		+= uniphier
 machine-$(CONFIG_ARCH_ZYNQ)		+= zynq
 machine-$(CONFIG_ARCH_ZYNQ)		+= zynq
+machine-$(CONFIG_ARCH_ZYNQMP_R5)	+= zynqmp-r5
 
 
 machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
 machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
 
 

+ 52 - 32
arch/arm/cpu/armv8/zynqmp/cpu.c

@@ -15,16 +15,28 @@
 
 
 DECLARE_GLOBAL_DATA_PTR;
 DECLARE_GLOBAL_DATA_PTR;
 
 
-static struct mm_region zynqmp_mem_map[] = {
+/*
+ * Number of filled static entries and also the first empty
+ * slot in zynqmp_mem_map.
+ */
+#define ZYNQMP_MEM_MAP_USED	4
+
 #if !defined(CONFIG_ZYNQMP_NO_DDR)
 #if !defined(CONFIG_ZYNQMP_NO_DDR)
-	{
-		.virt = 0x0UL,
-		.phys = 0x0UL,
-		.size = 0x80000000UL,
-		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
-			 PTE_BLOCK_INNER_SHARE
-	},
+#define DRAM_BANKS CONFIG_NR_DRAM_BANKS
+#else
+#define DRAM_BANKS 0
 #endif
 #endif
+
+#if defined(CONFIG_DEFINE_TCM_OCM_MMAP)
+#define TCM_MAP 1
+#else
+#define TCM_MAP 0
+#endif
+
+/* +1 is end of list which needs to be empty */
+#define ZYNQMP_MEM_MAP_MAX (ZYNQMP_MEM_MAP_USED + DRAM_BANKS + TCM_MAP + 1)
+
+static struct mm_region zynqmp_mem_map[ZYNQMP_MEM_MAP_MAX] = {
 	{
 	{
 		.virt = 0x80000000UL,
 		.virt = 0x80000000UL,
 		.phys = 0x80000000UL,
 		.phys = 0x80000000UL,
@@ -32,8 +44,7 @@ static struct mm_region zynqmp_mem_map[] = {
 		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 			 PTE_BLOCK_NON_SHARE |
 			 PTE_BLOCK_NON_SHARE |
 			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
 			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
-	},
-	{
+	}, {
 		.virt = 0xf8000000UL,
 		.virt = 0xf8000000UL,
 		.phys = 0xf8000000UL,
 		.phys = 0xf8000000UL,
 		.size = 0x07e00000UL,
 		.size = 0x07e00000UL,
@@ -41,42 +52,51 @@ static struct mm_region zynqmp_mem_map[] = {
 			 PTE_BLOCK_NON_SHARE |
 			 PTE_BLOCK_NON_SHARE |
 			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
 			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
 	}, {
 	}, {
-#if defined(CONFIG_DEFINE_TCM_OCM_MMAP)
-		.virt = 0xffe00000UL,
-		.phys = 0xffe00000UL,
-		.size = 0x00200000UL,
-		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
-			 PTE_BLOCK_INNER_SHARE
-	}, {
-#endif
 		.virt = 0x400000000UL,
 		.virt = 0x400000000UL,
 		.phys = 0x400000000UL,
 		.phys = 0x400000000UL,
 		.size = 0x400000000UL,
 		.size = 0x400000000UL,
 		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 			 PTE_BLOCK_NON_SHARE |
 			 PTE_BLOCK_NON_SHARE |
 			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
 			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
-	},
-#if !defined(CONFIG_ZYNQMP_NO_DDR)
-	{
-		.virt = 0x800000000UL,
-		.phys = 0x800000000UL,
-		.size = 0x800000000UL,
-		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
-			 PTE_BLOCK_INNER_SHARE
-	},
-#endif
-	{
+	}, {
 		.virt = 0x1000000000UL,
 		.virt = 0x1000000000UL,
 		.phys = 0x1000000000UL,
 		.phys = 0x1000000000UL,
 		.size = 0xf000000000UL,
 		.size = 0xf000000000UL,
 		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 			 PTE_BLOCK_NON_SHARE |
 			 PTE_BLOCK_NON_SHARE |
 			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
 			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
-	}, {
-		/* List terminator */
-		0,
 	}
 	}
 };
 };
+
+void mem_map_fill(void)
+{
+	int banks = ZYNQMP_MEM_MAP_USED;
+
+#if defined(CONFIG_DEFINE_TCM_OCM_MMAP)
+	zynqmp_mem_map[banks].virt = 0xffe00000UL;
+	zynqmp_mem_map[banks].phys = 0xffe00000UL;
+	zynqmp_mem_map[banks].size = 0x00200000UL;
+	zynqmp_mem_map[banks].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+				      PTE_BLOCK_INNER_SHARE;
+	banks = banks + 1;
+#endif
+
+#if !defined(CONFIG_ZYNQMP_NO_DDR)
+	for (int i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		/* Zero size means no more DDR that's this is end */
+		if (!gd->bd->bi_dram[i].size)
+			break;
+
+		zynqmp_mem_map[banks].virt = gd->bd->bi_dram[i].start;
+		zynqmp_mem_map[banks].phys = gd->bd->bi_dram[i].start;
+		zynqmp_mem_map[banks].size = gd->bd->bi_dram[i].size;
+		zynqmp_mem_map[banks].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+					      PTE_BLOCK_INNER_SHARE;
+		banks = banks + 1;
+	}
+#endif
+}
+
 struct mm_region *mem_map = zynqmp_mem_map;
 struct mm_region *mem_map = zynqmp_mem_map;
 
 
 u64 get_page_table_size(void)
 u64 get_page_table_size(void)

+ 3 - 0
arch/arm/dts/Makefile

@@ -157,11 +157,14 @@ dtb-$(CONFIG_ARCH_ZYNQMP) += \
 	zynqmp-zc1232-revA.dtb			\
 	zynqmp-zc1232-revA.dtb			\
 	zynqmp-zc1254-revA.dtb			\
 	zynqmp-zc1254-revA.dtb			\
 	zynqmp-zc1275-revA.dtb			\
 	zynqmp-zc1275-revA.dtb			\
+	zynqmp-zc1275-revB.dtb			\
 	zynqmp-zc1751-xm015-dc1.dtb		\
 	zynqmp-zc1751-xm015-dc1.dtb		\
 	zynqmp-zc1751-xm016-dc2.dtb		\
 	zynqmp-zc1751-xm016-dc2.dtb		\
 	zynqmp-zc1751-xm017-dc3.dtb		\
 	zynqmp-zc1751-xm017-dc3.dtb		\
 	zynqmp-zc1751-xm018-dc4.dtb		\
 	zynqmp-zc1751-xm018-dc4.dtb		\
 	zynqmp-zc1751-xm019-dc5.dtb
 	zynqmp-zc1751-xm019-dc5.dtb
+dtb-$(CONFIG_ARCH_ZYNQMP_R5) += \
+	zynqmp-r5.dtb
 dtb-$(CONFIG_AM33XX) += am335x-boneblack.dtb am335x-bone.dtb \
 dtb-$(CONFIG_AM33XX) += am335x-boneblack.dtb am335x-bone.dtb \
 	am335x-draco.dtb \
 	am335x-draco.dtb \
 	am335x-evm.dtb \
 	am335x-evm.dtb \

+ 1 - 1
arch/arm/dts/zynqmp-clk.dtsi

@@ -219,7 +219,7 @@
 };
 };
 
 
 &watchdog0 {
 &watchdog0 {
-	clocks = <&clk250>;
+	clocks = <&clk100>;
 };
 };
 
 
 &xilinx_drm {
 &xilinx_drm {

+ 73 - 0
arch/arm/dts/zynqmp-r5.dts

@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * dts file for Xilinx ZynqMP R5
+ *
+ * (C) Copyright 2018, Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek@xilinx.com>
+ */
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "xlnx,zynqmp-r5";
+	model = "Xilinx ZynqMP R5";
+
+	cpus {
+		#address-cells = <0x1>;
+		#size-cells = <0x0>;
+
+		cpu@0 {
+			compatible = "arm,cortex-r5";
+			device_type = "cpu";
+			reg = <0>;
+		};
+	};
+
+	aliases {
+		serial0 = &uart1;
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x00000000 0x20000000>;
+	};
+
+	chosen {
+		bootargs = "";
+		stdout-path = "serial0:115200n8";
+	};
+
+	clk100: clk100 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <100000000>;
+		u-boot,dm-pre-reloc;
+	};
+
+	amba {
+		u-boot,dm-pre-reloc;
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		ttc0: timer@ff110000 {
+			compatible = "cdns,ttc";
+			status = "okay";
+			reg = <0xff110000 0x1000>;
+			timer-width = <32>;
+			clocks = <&clk100>;
+		};
+
+		uart1: serial@ff010000 {
+			u-boot,dm-pre-reloc;
+			compatible = "cdns,uart-r1p12", "xlnx,xuartps";
+			reg = <0xff010000 0x1000>;
+			clock-names = "uart_clk", "pclk";
+			clocks = <&clk100 &clk100>;
+		};
+	};
+};

+ 79 - 0
arch/arm/dts/zynqmp-zc1275-revB.dts

@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * dts file for Xilinx ZynqMP ZC1275 RevB
+ *
+ * (C) Copyright 2018, Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek@xilinx.com>
+ * Siva Durga Prasad Paladugu <sivadur@xilinx.com>
+ */
+
+/dts-v1/;
+
+#include "zynqmp.dtsi"
+#include "zynqmp-clk-ccf.dtsi"
+
+/ {
+	model = "ZynqMP ZC1275 RevB";
+	compatible = "xlnx,zynqmp-zc1275-revB", "xlnx,zynqmp-zc1275", "xlnx,zynqmp";
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &dcc;
+		spi0 = &qspi;
+		mmc0 = &sdhci1;
+	};
+
+	chosen {
+		bootargs = "earlycon";
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x80000000>;
+	};
+};
+
+&dcc {
+	status = "okay";
+};
+
+&qspi {
+	status = "okay";
+	flash@0 {
+		compatible = "m25p80"; /* 32MB */
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x0>;
+		spi-tx-bus-width = <1>;
+		spi-rx-bus-width = <4>;
+		spi-max-frequency = <108000000>; /* Based on DC1 spec */
+		partition@qspi-fsbl-uboot { /* for testing purpose */
+			label = "qspi-fsbl-uboot";
+			reg = <0x0 0x100000>;
+		};
+		partition@qspi-linux { /* for testing purpose */
+			label = "qspi-linux";
+			reg = <0x100000 0x500000>;
+		};
+		partition@qspi-device-tree { /* for testing purpose */
+			label = "qspi-device-tree";
+			reg = <0x600000 0x20000>;
+		};
+		partition@qspi-rootfs { /* for testing purpose */
+			label = "qspi-rootfs";
+			reg = <0x620000 0x5E0000>;
+		};
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&sdhci1 {
+	status = "okay";
+	no-1-8-v;
+	xlnx,mio_bank = <1>;
+};

+ 1 - 0
arch/arm/dts/zynqmp-zcu100-revC.dts

@@ -332,6 +332,7 @@
 
 
 &watchdog0 {
 &watchdog0 {
 	status = "okay";
 	status = "okay";
+	reset-on-timeout;
 };
 };
 
 
 &xilinx_ams {
 &xilinx_ams {

+ 1 - 1
arch/arm/include/asm/arch-zynqmp/sys_proto.h

@@ -45,7 +45,7 @@ int invoke_smc(u32 pm_api_id, u32 arg0, u32 arg1, u32 arg2, u32 arg3,
 	       u32 *ret_payload);
 	       u32 *ret_payload);
 
 
 void initialize_tcm(bool mode);
 void initialize_tcm(bool mode);
-
+void mem_map_fill(void);
 int chip_id(unsigned char id);
 int chip_id(unsigned char id);
 
 
 #endif /* _ASM_ARCH_SYS_PROTO_H */
 #endif /* _ASM_ARCH_SYS_PROTO_H */

+ 84 - 1
arch/arm/mach-zynq/cpu.c

@@ -4,14 +4,45 @@
  * Copyright (C) 2012 Xilinx, Inc. All rights reserved.
  * Copyright (C) 2012 Xilinx, Inc. All rights reserved.
  */
  */
 #include <common.h>
 #include <common.h>
+#include <zynqpl.h>
 #include <asm/io.h>
 #include <asm/io.h>
 #include <asm/arch/clk.h>
 #include <asm/arch/clk.h>
-#include <asm/arch/sys_proto.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/hardware.h>
+#include <asm/arch/ps7_init_gpl.h>
+#include <asm/arch/sys_proto.h>
 
 
 #define ZYNQ_SILICON_VER_MASK	0xF0000000
 #define ZYNQ_SILICON_VER_MASK	0xF0000000
 #define ZYNQ_SILICON_VER_SHIFT	28
 #define ZYNQ_SILICON_VER_SHIFT	28
 
 
+#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \
+    (defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD))
+xilinx_desc fpga = {
+	.family = xilinx_zynq,
+	.iface = devcfg,
+	.operations = &zynq_op,
+};
+#endif
+
+static const struct {
+	u8 idcode;
+#if defined(CONFIG_FPGA)
+	u32 fpga_size;
+#endif
+	char *devicename;
+} zynq_fpga_descs[] = {
+	ZYNQ_DESC(7Z007S),
+	ZYNQ_DESC(7Z010),
+	ZYNQ_DESC(7Z012S),
+	ZYNQ_DESC(7Z014S),
+	ZYNQ_DESC(7Z015),
+	ZYNQ_DESC(7Z020),
+	ZYNQ_DESC(7Z030),
+	ZYNQ_DESC(7Z035),
+	ZYNQ_DESC(7Z045),
+	ZYNQ_DESC(7Z100),
+	{ /* Sentinel */ },
+};
+
 int arch_cpu_init(void)
 int arch_cpu_init(void)
 {
 {
 	zynq_slcr_unlock();
 	zynq_slcr_unlock();
@@ -59,3 +90,55 @@ void enable_caches(void)
 	dcache_enable();
 	dcache_enable();
 }
 }
 #endif
 #endif
+
+static int __maybe_unused cpu_desc_id(void)
+{
+	u32 idcode;
+	u8 i;
+
+	idcode = zynq_slcr_get_idcode();
+	for (i = 0; zynq_fpga_descs[i].idcode; i++) {
+		if (zynq_fpga_descs[i].idcode == idcode)
+			return i;
+	}
+
+	return -ENODEV;
+}
+
+#if defined(CONFIG_ARCH_EARLY_INIT_R)
+int arch_early_init_r(void)
+{
+#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \
+    (defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD))
+	int cpu_id = cpu_desc_id();
+
+	if (cpu_id < 0)
+		return 0;
+
+	fpga.size = zynq_fpga_descs[cpu_id].fpga_size;
+	fpga.name = zynq_fpga_descs[cpu_id].devicename;
+	fpga_init();
+	fpga_add(fpga_xilinx, &fpga);
+#endif
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_DISPLAY_CPUINFO
+int print_cpuinfo(void)
+{
+	u32 version;
+	int cpu_id = cpu_desc_id();
+
+	if (cpu_id < 0)
+		return 0;
+
+	version = zynq_get_silicon_version() << 1;
+	if (version > (PCW_SILICON_VERSION_3 << 1))
+		version += 1;
+
+	printf("CPU:   Zynq %s\n", zynq_fpga_descs[cpu_id].devicename);
+	printf("Silicon: v%d.%d\n", version >> 1, version & 1);
+	return 0;
+}
+#endif

+ 6 - 5
arch/arm/mach-zynq/spl.c

@@ -17,11 +17,12 @@ void board_init_f(ulong dummy)
 	ps7_init();
 	ps7_init();
 
 
 	arch_cpu_init();
 	arch_cpu_init();
-	/*
-	 * The debug UART can be used from this point:
-	 * debug_uart_init();
-	 * printch('x');
-	 */
+
+#ifdef CONFIG_DEBUG_UART
+	/* Uart debug for sure */
+	debug_uart_init();
+	puts("Debug uart enabled\n"); /* or printch() */
+#endif
 }
 }
 
 
 #ifdef CONFIG_SPL_BOARD_INIT
 #ifdef CONFIG_SPL_BOARD_INIT

+ 27 - 0
arch/arm/mach-zynqmp-r5/Kconfig

@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: GPL-2.0
+
+if ARCH_ZYNQMP_R5
+
+config SYS_BOARD
+	string "Board name"
+	default "zynqmp_r5"
+
+config SYS_VENDOR
+	string "Vendor name"
+	default "xilinx"
+
+config SYS_SOC
+	default "zynqmp-r5"
+
+config SYS_CONFIG_NAME
+	string "Board configuration name"
+	default "xilinx_zynqmp_r5"
+	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.
+
+config SYS_MALLOC_F_LEN
+	default 0x600
+
+endif

+ 3 - 0
arch/arm/mach-zynqmp-r5/Makefile

@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y	+= cpu.o

+ 37 - 0
arch/arm/mach-zynqmp-r5/cpu.c

@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 Xilinx, Inc. (Michal Simek)
+ */
+
+#include <common.h>
+#include <asm/armv7_mpu.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct mpu_region_config region_config[] = {
+	{ 0x00000000, REGION_0, XN_DIS, PRIV_RW_USR_RW,
+	  O_I_WB_RD_WR_ALLOC, REGION_1GB },
+	{ 0x20000000, REGION_1, XN_EN, PRIV_RO_USR_RO,
+	  O_I_WB_RD_WR_ALLOC, REGION_512MB },
+	{ 0x40000000, REGION_2, XN_EN, PRIV_RO_USR_RO,
+	  O_I_WB_RD_WR_ALLOC, REGION_1GB },
+};
+
+int arch_cpu_init(void)
+{
+	gd->cpu_clk = CONFIG_CPU_FREQ_HZ;
+
+	setup_mpu_regions(region_config, sizeof(region_config) /
+			  sizeof(struct mpu_region_config));
+
+	return 0;
+}
+
+/*
+ * Perform the low-level reset.
+ */
+void reset_cpu(ulong addr)
+{
+	while (1)
+		;
+}

+ 0 - 80
board/xilinx/zynq/board.c

@@ -13,27 +13,9 @@
 #include <zynqpl.h>
 #include <zynqpl.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/arch/sys_proto.h>
-#include <asm/arch/ps7_init_gpl.h>
 
 
 DECLARE_GLOBAL_DATA_PTR;
 DECLARE_GLOBAL_DATA_PTR;
 
 
-#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \
-    (defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD))
-static xilinx_desc fpga;
-
-/* It can be done differently */
-static xilinx_desc fpga007s = XILINX_XC7Z007S_DESC(0x7);
-static xilinx_desc fpga010 = XILINX_XC7Z010_DESC(0x10);
-static xilinx_desc fpga012s = XILINX_XC7Z012S_DESC(0x12);
-static xilinx_desc fpga014s = XILINX_XC7Z014S_DESC(0x14);
-static xilinx_desc fpga015 = XILINX_XC7Z015_DESC(0x15);
-static xilinx_desc fpga020 = XILINX_XC7Z020_DESC(0x20);
-static xilinx_desc fpga030 = XILINX_XC7Z030_DESC(0x30);
-static xilinx_desc fpga035 = XILINX_XC7Z035_DESC(0x35);
-static xilinx_desc fpga045 = XILINX_XC7Z045_DESC(0x45);
-static xilinx_desc fpga100 = XILINX_XC7Z100_DESC(0x100);
-#endif
-
 #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT)
 #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT)
 static struct udevice *watchdog_dev;
 static struct udevice *watchdog_dev;
 #endif
 #endif
@@ -52,46 +34,6 @@ int board_early_init_f(void)
 
 
 int board_init(void)
 int board_init(void)
 {
 {
-#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \
-    (defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD))
-	u32 idcode;
-
-	idcode = zynq_slcr_get_idcode();
-
-	switch (idcode) {
-	case XILINX_ZYNQ_7007S:
-		fpga = fpga007s;
-		break;
-	case XILINX_ZYNQ_7010:
-		fpga = fpga010;
-		break;
-	case XILINX_ZYNQ_7012S:
-		fpga = fpga012s;
-		break;
-	case XILINX_ZYNQ_7014S:
-		fpga = fpga014s;
-		break;
-	case XILINX_ZYNQ_7015:
-		fpga = fpga015;
-		break;
-	case XILINX_ZYNQ_7020:
-		fpga = fpga020;
-		break;
-	case XILINX_ZYNQ_7030:
-		fpga = fpga030;
-		break;
-	case XILINX_ZYNQ_7035:
-		fpga = fpga035;
-		break;
-	case XILINX_ZYNQ_7045:
-		fpga = fpga045;
-		break;
-	case XILINX_ZYNQ_7100:
-		fpga = fpga100;
-		break;
-	}
-#endif
-
 #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT)
 #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT)
 	if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) {
 	if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) {
 		puts("Watchdog: Not found!\n");
 		puts("Watchdog: Not found!\n");
@@ -101,12 +43,6 @@ int board_init(void)
 	}
 	}
 # endif
 # endif
 
 
-#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \
-    (defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD))
-	fpga_init();
-	fpga_add(fpga_xilinx, &fpga);
-#endif
-
 	return 0;
 	return 0;
 }
 }
 
 
@@ -136,22 +72,6 @@ int board_late_init(void)
 	return 0;
 	return 0;
 }
 }
 
 
-#ifdef CONFIG_DISPLAY_BOARDINFO
-int checkboard(void)
-{
-	u32 version = zynq_get_silicon_version();
-
-	version <<= 1;
-	if (version > (PCW_SILICON_VERSION_3 << 1))
-		version += 1;
-
-	puts("Board: Xilinx Zynq\n");
-	printf("Silicon: v%d.%d\n", version >> 1, version & 1);
-
-	return 0;
-}
-#endif
-
 int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
 int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
 {
 {
 #if defined(CONFIG_ZYNQ_GEM_EEPROM_ADDR) && \
 #if defined(CONFIG_ZYNQ_GEM_EEPROM_ADDR) && \

+ 2 - 0
board/xilinx/zynqmp/Makefile

@@ -24,6 +24,8 @@ ifneq ($(call ifdef_any_of, CONFIG_ZYNQMP_PSU_INIT_ENABLED CONFIG_SPL_BUILD),)
 obj-y += $(init-objs)
 obj-y += $(init-objs)
 endif
 endif
 
 
+obj-$(CONFIG_MMC_SDHCI_ZYNQ) += tap_delays.o
+
 ifndef CONFIG_SPL_BUILD
 ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_CMD_ZYNQMP) += cmds.o
 obj-$(CONFIG_CMD_ZYNQMP) += cmds.o
 endif
 endif

+ 229 - 0
board/xilinx/zynqmp/tap_delays.c

@@ -0,0 +1,229 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx ZynqMP SoC Tap Delay Programming
+ *
+ * Copyright (C) 2018 Xilinx, Inc.
+ */
+
+#include <common.h>
+#include <asm/arch/sys_proto.h>
+
+#define SD_DLL_CTRL			0xFF180358
+#define SD_ITAP_DLY			0xFF180314
+#define SD_OTAP_DLY			0xFF180318
+#define SD0_DLL_RST_MASK		0x00000004
+#define SD0_DLL_RST			0x00000004
+#define SD1_DLL_RST_MASK		0x00040000
+#define SD1_DLL_RST			0x00040000
+#define SD0_ITAPCHGWIN_MASK		0x00000200
+#define SD0_ITAPCHGWIN			0x00000200
+#define SD1_ITAPCHGWIN_MASK		0x02000000
+#define SD1_ITAPCHGWIN			0x02000000
+#define SD0_ITAPDLYENA_MASK		0x00000100
+#define SD0_ITAPDLYENA			0x00000100
+#define SD1_ITAPDLYENA_MASK		0x01000000
+#define SD1_ITAPDLYENA			0x01000000
+#define SD0_ITAPDLYSEL_MASK		0x000000FF
+#define SD0_ITAPDLYSEL_HSD		0x00000015
+#define SD0_ITAPDLYSEL_SD_DDR50		0x0000003D
+#define SD0_ITAPDLYSEL_MMC_DDR50	0x00000012
+
+#define SD1_ITAPDLYSEL_MASK		0x00FF0000
+#define SD1_ITAPDLYSEL_HSD		0x00150000
+#define SD1_ITAPDLYSEL_SD_DDR50		0x003D0000
+#define SD1_ITAPDLYSEL_MMC_DDR50	0x00120000
+
+#define SD0_OTAPDLYSEL_MASK		0x0000003F
+#define SD0_OTAPDLYSEL_MMC_HSD		0x00000006
+#define SD0_OTAPDLYSEL_SD_HSD		0x00000005
+#define SD0_OTAPDLYSEL_SDR50		0x00000003
+#define SD0_OTAPDLYSEL_SDR104_B0	0x00000003
+#define SD0_OTAPDLYSEL_SDR104_B2	0x00000002
+#define SD0_OTAPDLYSEL_SD_DDR50		0x00000004
+#define SD0_OTAPDLYSEL_MMC_DDR50	0x00000006
+
+#define SD1_OTAPDLYSEL_MASK		0x003F0000
+#define SD1_OTAPDLYSEL_MMC_HSD		0x00060000
+#define SD1_OTAPDLYSEL_SD_HSD		0x00050000
+#define SD1_OTAPDLYSEL_SDR50		0x00030000
+#define SD1_OTAPDLYSEL_SDR104_B0	0x00030000
+#define SD1_OTAPDLYSEL_SDR104_B2	0x00020000
+#define SD1_OTAPDLYSEL_SD_DDR50		0x00040000
+#define SD1_OTAPDLYSEL_MMC_DDR50	0x00060000
+
+#define MMC_BANK2		0x2
+
+#define MMC_TIMING_UHS_SDR25		1
+#define MMC_TIMING_UHS_SDR50		2
+#define MMC_TIMING_UHS_SDR104		3
+#define MMC_TIMING_UHS_DDR50		4
+#define MMC_TIMING_MMC_HS200		5
+#define MMC_TIMING_SD_HS		6
+#define MMC_TIMING_MMC_DDR52		7
+#define MMC_TIMING_MMC_HS		8
+
+void zynqmp_dll_reset(u8 deviceid)
+{
+	/* Issue DLL Reset */
+	if (deviceid == 0)
+		zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK,
+				  SD0_DLL_RST);
+	else
+		zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK,
+				  SD1_DLL_RST);
+
+	mdelay(1);
+
+	/* Release DLL Reset */
+	if (deviceid == 0)
+		zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, 0x0);
+	else
+		zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, 0x0);
+}
+
+static void arasan_zynqmp_tap_sdr104(u8 deviceid, u8 timing, u8 bank)
+{
+	if (deviceid == 0) {
+		/* Program OTAP */
+		if (bank == MMC_BANK2)
+			zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
+					  SD0_OTAPDLYSEL_SDR104_B2);
+		else
+			zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
+					  SD0_OTAPDLYSEL_SDR104_B0);
+	} else {
+		/* Program OTAP */
+		if (bank == MMC_BANK2)
+			zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
+					  SD1_OTAPDLYSEL_SDR104_B2);
+		else
+			zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
+					  SD1_OTAPDLYSEL_SDR104_B0);
+	}
+}
+
+static void arasan_zynqmp_tap_hs(u8 deviceid, u8 timing, u8 bank)
+{
+	if (deviceid == 0) {
+		/* Program ITAP */
+		zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK,
+				  SD0_ITAPCHGWIN);
+		zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYENA_MASK,
+				  SD0_ITAPDLYENA);
+		zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYSEL_MASK,
+				  SD0_ITAPDLYSEL_HSD);
+		zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK, 0x0);
+		/* Program OTAP */
+		if (timing == MMC_TIMING_MMC_HS)
+			zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
+					  SD0_OTAPDLYSEL_MMC_HSD);
+		else
+			zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
+					  SD0_OTAPDLYSEL_SD_HSD);
+	} else {
+		/* Program ITAP */
+		zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK,
+				  SD1_ITAPCHGWIN);
+		zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYENA_MASK,
+				  SD1_ITAPDLYENA);
+		zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYSEL_MASK,
+				  SD1_ITAPDLYSEL_HSD);
+		zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK, 0x0);
+		/* Program OTAP */
+		if (timing == MMC_TIMING_MMC_HS)
+			zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
+					  SD1_OTAPDLYSEL_MMC_HSD);
+		else
+			zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
+					  SD1_OTAPDLYSEL_SD_HSD);
+	}
+}
+
+static void arasan_zynqmp_tap_ddr50(u8 deviceid, u8 timing, u8 bank)
+{
+	if (deviceid == 0) {
+		/* Program ITAP */
+		zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK,
+				  SD0_ITAPCHGWIN);
+		zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYENA_MASK,
+				  SD0_ITAPDLYENA);
+		if (timing == MMC_TIMING_UHS_DDR50)
+			zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYSEL_MASK,
+					  SD0_ITAPDLYSEL_SD_DDR50);
+		else
+			zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYSEL_MASK,
+					  SD0_ITAPDLYSEL_MMC_DDR50);
+		zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK, 0x0);
+		/* Program OTAP */
+		if (timing == MMC_TIMING_UHS_DDR50)
+			zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
+					  SD0_OTAPDLYSEL_SD_DDR50);
+		else
+			zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
+					  SD0_OTAPDLYSEL_MMC_DDR50);
+	} else {
+		/* Program ITAP */
+		zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK,
+				  SD1_ITAPCHGWIN);
+		zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYENA_MASK,
+				  SD1_ITAPDLYENA);
+		if (timing == MMC_TIMING_UHS_DDR50)
+			zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYSEL_MASK,
+					  SD1_ITAPDLYSEL_SD_DDR50);
+		else
+			zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYSEL_MASK,
+					  SD1_ITAPDLYSEL_MMC_DDR50);
+		zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK, 0x0);
+		/* Program OTAP */
+		if (timing == MMC_TIMING_UHS_DDR50)
+			zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
+					  SD1_OTAPDLYSEL_SD_DDR50);
+		else
+			zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
+					  SD1_OTAPDLYSEL_MMC_DDR50);
+	}
+}
+
+static void arasan_zynqmp_tap_sdr50(u8 deviceid, u8 timing, u8 bank)
+{
+	if (deviceid == 0) {
+		/* Program OTAP */
+		zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK,
+				  SD0_OTAPDLYSEL_SDR50);
+	} else {
+		/* Program OTAP */
+		zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
+				  SD1_OTAPDLYSEL_SDR50);
+	}
+}
+
+void arasan_zynqmp_set_tapdelay(u8 deviceid, u8 timing, u8 bank)
+{
+	if (deviceid == 0)
+		zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK,
+				  SD0_DLL_RST);
+	else
+		zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK,
+				  SD1_DLL_RST);
+
+	switch (timing) {
+	case MMC_TIMING_UHS_SDR25:
+		arasan_zynqmp_tap_hs(deviceid, timing, bank);
+		break;
+	case MMC_TIMING_UHS_SDR50:
+		arasan_zynqmp_tap_sdr50(deviceid, timing, bank);
+		break;
+	case MMC_TIMING_UHS_SDR104:
+	case MMC_TIMING_MMC_HS200:
+		arasan_zynqmp_tap_sdr104(deviceid, timing, bank);
+		break;
+	case MMC_TIMING_UHS_DDR50:
+		arasan_zynqmp_tap_ddr50(deviceid, timing, bank);
+		break;
+	}
+
+	if (deviceid == 0)
+		zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, 0x0);
+	else
+		zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, 0x0);
+}

+ 523 - 0
board/xilinx/zynqmp/zynqmp-zc1275-revB/psu_init_gpl.c

@@ -0,0 +1,523 @@
+/*
+ * (c) Copyright 2015 Xilinx, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm/arch/psu_init_gpl.h>
+#include <xil_io.h>
+
+static unsigned long psu_pll_init_data(void)
+{
+	psu_mask_write(0xFF5E0034, 0xFE7FEDEFU, 0x7E4E2C62U);
+	psu_mask_write(0xFF5E0030, 0x00717F00U, 0x00013C00U);
+	psu_mask_write(0xFF5E0030, 0x00000008U, 0x00000008U);
+	psu_mask_write(0xFF5E0030, 0x00000001U, 0x00000001U);
+	psu_mask_write(0xFF5E0030, 0x00000001U, 0x00000000U);
+	mask_poll(0xFF5E0040, 0x00000002U);
+	psu_mask_write(0xFF5E0030, 0x00000008U, 0x00000000U);
+	psu_mask_write(0xFF5E0048, 0x00003F00U, 0x00000200U);
+	psu_mask_write(0xFF5E0024, 0xFE7FEDEFU, 0x7E4B0C82U);
+	psu_mask_write(0xFF5E0020, 0x00717F00U, 0x00015A00U);
+	psu_mask_write(0xFF5E0020, 0x00000008U, 0x00000008U);
+	psu_mask_write(0xFF5E0020, 0x00000001U, 0x00000001U);
+	psu_mask_write(0xFF5E0020, 0x00000001U, 0x00000000U);
+	mask_poll(0xFF5E0040, 0x00000001U);
+	psu_mask_write(0xFF5E0020, 0x00000008U, 0x00000000U);
+	psu_mask_write(0xFF5E0044, 0x00003F00U, 0x00000300U);
+	psu_mask_write(0xFD1A0024, 0xFE7FEDEFU, 0x7E4B0C62U);
+	psu_mask_write(0xFD1A0020, 0x00717F00U, 0x00014200U);
+	psu_mask_write(0xFD1A0020, 0x00000008U, 0x00000008U);
+	psu_mask_write(0xFD1A0020, 0x00000001U, 0x00000001U);
+	psu_mask_write(0xFD1A0020, 0x00000001U, 0x00000000U);
+	mask_poll(0xFD1A0044, 0x00000001U);
+	psu_mask_write(0xFD1A0020, 0x00000008U, 0x00000000U);
+	psu_mask_write(0xFD1A0048, 0x00003F00U, 0x00000300U);
+	psu_mask_write(0xFD1A0030, 0xFE7FEDEFU, 0x7E4B0C62U);
+	psu_mask_write(0xFD1A002C, 0x00717F00U, 0x00014800U);
+	psu_mask_write(0xFD1A002C, 0x00000008U, 0x00000008U);
+	psu_mask_write(0xFD1A002C, 0x00000001U, 0x00000001U);
+	psu_mask_write(0xFD1A002C, 0x00000001U, 0x00000000U);
+	mask_poll(0xFD1A0044, 0x00000002U);
+	psu_mask_write(0xFD1A002C, 0x00000008U, 0x00000000U);
+	psu_mask_write(0xFD1A004C, 0x00003F00U, 0x00000300U);
+	psu_mask_write(0xFD1A003C, 0xFE7FEDEFU, 0x7E4B0C62U);
+	psu_mask_write(0xFD1A0038, 0x00717F00U, 0x00014000U);
+	psu_mask_write(0xFD1A0038, 0x00000008U, 0x00000008U);
+	psu_mask_write(0xFD1A0038, 0x00000001U, 0x00000001U);
+	psu_mask_write(0xFD1A0038, 0x00000001U, 0x00000000U);
+	mask_poll(0xFD1A0044, 0x00000004U);
+	psu_mask_write(0xFD1A0038, 0x00000008U, 0x00000000U);
+	psu_mask_write(0xFD1A0050, 0x00003F00U, 0x00000200U);
+
+	return 1;
+}
+
+static unsigned long psu_clock_init_data(void)
+{
+	psu_mask_write(0xFF5E0068, 0x013F3F07U, 0x01010C00U);
+	psu_mask_write(0xFF5E0070, 0x013F3F07U, 0x01010502U);
+	psu_mask_write(0xFF18030C, 0x00020000U, 0x00000000U);
+	psu_mask_write(0xFF5E0074, 0x013F3F07U, 0x01010F00U);
+	psu_mask_write(0xFF5E0120, 0x013F3F07U, 0x01010F00U);
+	psu_mask_write(0xFF5E0090, 0x01003F07U, 0x01000302U);
+	psu_mask_write(0xFF5E009C, 0x01003F07U, 0x01000400U);
+	psu_mask_write(0xFF5E00A4, 0x01003F07U, 0x01000900U);
+	psu_mask_write(0xFF5E00A8, 0x01003F07U, 0x01000302U);
+	psu_mask_write(0xFF5E00AC, 0x01003F07U, 0x01000F02U);
+	psu_mask_write(0xFF5E00B0, 0x01003F07U, 0x01000602U);
+	psu_mask_write(0xFF5E00B8, 0x01003F07U, 0x01000302U);
+	psu_mask_write(0xFF5E00C0, 0x013F3F07U, 0x01010A02U);
+	psu_mask_write(0xFF5E00C4, 0x013F3F07U, 0x01010402U);
+	psu_mask_write(0xFF5E00C8, 0x013F3F07U, 0x01010802U);
+	psu_mask_write(0xFF5E0108, 0x013F3F07U, 0x01011D02U);
+	psu_mask_write(0xFF5E0104, 0x00000007U, 0x00000000U);
+	psu_mask_write(0xFF5E0128, 0x01003F07U, 0x01000104U);
+	psu_mask_write(0xFD1A0060, 0x03003F07U, 0x03000100U);
+	psu_mask_write(0xFD1A0068, 0x01003F07U, 0x01000200U);
+	psu_mask_write(0xFD1A0080, 0x00003F07U, 0x00000600U);
+	psu_mask_write(0xFD1A0084, 0x07003F07U, 0x07000203U);
+	psu_mask_write(0xFD1A00B8, 0x01003F07U, 0x01000203U);
+	psu_mask_write(0xFD1A00BC, 0x01003F07U, 0x01000203U);
+	psu_mask_write(0xFD1A00C0, 0x01003F07U, 0x01000202U);
+	psu_mask_write(0xFD1A00C4, 0x01003F07U, 0x01000502U);
+	psu_mask_write(0xFD1A00F8, 0x00003F07U, 0x00000200U);
+	psu_mask_write(0xFF180380, 0x000000FFU, 0x00000000U);
+	psu_mask_write(0xFD610100, 0x00000001U, 0x00000000U);
+	psu_mask_write(0xFF180300, 0x00000001U, 0x00000000U);
+	psu_mask_write(0xFF410050, 0x00000001U, 0x00000000U);
+
+	return 1;
+}
+
+static unsigned long psu_ddr_init_data(void)
+{
+	psu_mask_write(0xFD1A0108, 0x00000008U, 0x00000008U);
+	psu_mask_write(0xFD070000, 0xE30FBE3DU, 0x81040001U);
+	psu_mask_write(0xFD070010, 0x8000F03FU, 0x00000030U);
+	psu_mask_write(0xFD070020, 0x000003F3U, 0x00000100U);
+	psu_mask_write(0xFD070024, 0xFFFFFFFFU, 0x00800000U);
+	psu_mask_write(0xFD070030, 0x0000007FU, 0x00000000U);
+	psu_mask_write(0xFD070034, 0x00FFFF1FU, 0x00403210U);
+	psu_mask_write(0xFD070050, 0x00F1F1F4U, 0x00210000U);
+	psu_mask_write(0xFD070054, 0x0FFF0FFFU, 0x00000000U);
+	psu_mask_write(0xFD070060, 0x00000073U, 0x00000001U);
+	psu_mask_write(0xFD070064, 0x0FFF83FFU, 0x00308034U);
+	psu_mask_write(0xFD070070, 0x00000017U, 0x00000010U);
+	psu_mask_write(0xFD070074, 0x00000003U, 0x00000000U);
+	psu_mask_write(0xFD0700C4, 0x3F000391U, 0x10000200U);
+	psu_mask_write(0xFD0700C8, 0x01FF1F3FU, 0x0030051FU);
+	psu_mask_write(0xFD0700D0, 0xC3FF0FFFU, 0x00020063U);
+	psu_mask_write(0xFD0700D4, 0x01FF7F0FU, 0x00290000U);
+	psu_mask_write(0xFD0700D8, 0x0000FF0FU, 0x00000E05U);
+	psu_mask_write(0xFD0700DC, 0xFFFFFFFFU, 0x05200004U);
+	psu_mask_write(0xFD0700E0, 0xFFFFFFFFU, 0x00000000U);
+	psu_mask_write(0xFD0700E4, 0x00FF03FFU, 0x00110004U);
+	psu_mask_write(0xFD0700E8, 0xFFFFFFFFU, 0x00000000U);
+	psu_mask_write(0xFD0700EC, 0xFFFF0000U, 0x00000000U);
+	psu_mask_write(0xFD0700F0, 0x0000003FU, 0x00000010U);
+	psu_mask_write(0xFD0700F4, 0x00000FFFU, 0x0000066FU);
+	psu_mask_write(0xFD070100, 0x7F3F7F3FU, 0x07080D07U);
+	psu_mask_write(0xFD070104, 0x001F1F7FU, 0x0005020BU);
+	psu_mask_write(0xFD070108, 0x3F3F3F3FU, 0x03030607U);
+	psu_mask_write(0xFD07010C, 0x3FF3F3FFU, 0x00502006U);
+	psu_mask_write(0xFD070110, 0x1F0F0F1FU, 0x13020206U);
+	psu_mask_write(0xFD070114, 0x0F0F3F1FU, 0x03030202U);
+	psu_mask_write(0xFD070118, 0x0F0F000FU, 0x01010003U);
+	psu_mask_write(0xFD07011C, 0x00000F0FU, 0x00000303U);
+	psu_mask_write(0xFD070120, 0x7F7F7F7FU, 0x02020909U);
+	psu_mask_write(0xFD070124, 0x40070F3FU, 0x0004040DU);
+	psu_mask_write(0xFD07012C, 0x7F1F031FU, 0x440C011CU);
+	psu_mask_write(0xFD070130, 0x00030F1FU, 0x00020608U);
+	psu_mask_write(0xFD070180, 0xF7FF03FFU, 0x80800020U);
+	psu_mask_write(0xFD070184, 0x3FFFFFFFU, 0x02009896U);
+	psu_mask_write(0xFD070190, 0x1FBFBF3FU, 0x04828202U);
+	psu_mask_write(0xFD070194, 0xF31F0F0FU, 0x00020304U);
+	psu_mask_write(0xFD070198, 0x0FF1F1F1U, 0x07000101U);
+	psu_mask_write(0xFD07019C, 0x000000F1U, 0x00000021U);
+	psu_mask_write(0xFD0701A0, 0xC3FF03FFU, 0x00400003U);
+	psu_mask_write(0xFD0701A4, 0x00FF00FFU, 0x00C800FFU);
+	psu_mask_write(0xFD0701B0, 0x00000007U, 0x00000000U);
+	psu_mask_write(0xFD0701B4, 0x00003F3FU, 0x00000000U);
+	psu_mask_write(0xFD0701C0, 0x00000007U, 0x00000000U);
+	psu_mask_write(0xFD070200, 0x0000001FU, 0x0000001FU);
+	psu_mask_write(0xFD070204, 0x001F1F1FU, 0x00080808U);
+	psu_mask_write(0xFD070208, 0x0F0F0F0FU, 0x00000000U);
+	psu_mask_write(0xFD07020C, 0x0F0F0F0FU, 0x00000000U);
+	psu_mask_write(0xFD070210, 0x00000F0FU, 0x00000F0FU);
+	psu_mask_write(0xFD070214, 0x0F0F0F0FU, 0x070F0707U);
+	psu_mask_write(0xFD070218, 0x8F0F0F0FU, 0x0F070707U);
+	psu_mask_write(0xFD07021C, 0x00000F0FU, 0x00000F0FU);
+	psu_mask_write(0xFD070220, 0x00001F1FU, 0x00000000U);
+	psu_mask_write(0xFD070224, 0x0F0F0F0FU, 0x07070707U);
+	psu_mask_write(0xFD070228, 0x0F0F0F0FU, 0x07070707U);
+	psu_mask_write(0xFD07022C, 0x0000000FU, 0x00000007U);
+	psu_mask_write(0xFD070240, 0x0F1F0F7CU, 0x06000604U);
+	psu_mask_write(0xFD070244, 0x00003333U, 0x00000001U);
+	psu_mask_write(0xFD070250, 0x7FFF3F07U, 0x01002001U);
+	psu_mask_write(0xFD070264, 0xFF00FFFFU, 0x08000040U);
+	psu_mask_write(0xFD07026C, 0xFF00FFFFU, 0x08000040U);
+	psu_mask_write(0xFD070280, 0xFFFFFFFFU, 0x00000000U);
+	psu_mask_write(0xFD070284, 0xFFFFFFFFU, 0x00000000U);
+	psu_mask_write(0xFD070288, 0xFFFFFFFFU, 0x00000000U);
+	psu_mask_write(0xFD07028C, 0xFFFFFFFFU, 0x00000000U);
+	psu_mask_write(0xFD070290, 0x0000FFFFU, 0x00000000U);
+	psu_mask_write(0xFD070294, 0x00000001U, 0x00000001U);
+	psu_mask_write(0xFD070300, 0x00000011U, 0x00000000U);
+	psu_mask_write(0xFD07030C, 0x80000033U, 0x00000000U);
+	psu_mask_write(0xFD070320, 0x00000001U, 0x00000000U);
+	psu_mask_write(0xFD070400, 0x00000111U, 0x00000001U);
+	psu_mask_write(0xFD070404, 0x000073FFU, 0x0000200FU);
+	psu_mask_write(0xFD070408, 0x000073FFU, 0x0000200FU);
+	psu_mask_write(0xFD070490, 0x00000001U, 0x00000001U);
+	psu_mask_write(0xFD070494, 0x0033000FU, 0x0020000BU);
+	psu_mask_write(0xFD070498, 0x07FF07FFU, 0x00000000U);
+	psu_mask_write(0xFD0704B4, 0x000073FFU, 0x0000200FU);
+	psu_mask_write(0xFD0704B8, 0x000073FFU, 0x0000200FU);
+	psu_mask_write(0xFD070540, 0x00000001U, 0x00000001U);
+	psu_mask_write(0xFD070544, 0x03330F0FU, 0x02000B03U);
+	psu_mask_write(0xFD070548, 0x07FF07FFU, 0x00000000U);
+	psu_mask_write(0xFD070564, 0x000073FFU, 0x0000200FU);
+	psu_mask_write(0xFD070568, 0x000073FFU, 0x0000200FU);
+	psu_mask_write(0xFD0705F0, 0x00000001U, 0x00000001U);
+	psu_mask_write(0xFD0705F4, 0x03330F0FU, 0x02000B03U);
+	psu_mask_write(0xFD0705F8, 0x07FF07FFU, 0x00000000U);
+	psu_mask_write(0xFD070614, 0x000073FFU, 0x0000200FU);
+	psu_mask_write(0xFD070618, 0x000073FFU, 0x0000200FU);
+	psu_mask_write(0xFD0706A0, 0x00000001U, 0x00000001U);
+	psu_mask_write(0xFD0706A4, 0x0033000FU, 0x00100003U);
+	psu_mask_write(0xFD0706A8, 0x07FF07FFU, 0x0000004FU);
+	psu_mask_write(0xFD0706AC, 0x0033000FU, 0x00100003U);
+	psu_mask_write(0xFD0706B0, 0x000007FFU, 0x0000004FU);
+	psu_mask_write(0xFD0706C4, 0x000073FFU, 0x0000200FU);
+	psu_mask_write(0xFD0706C8, 0x000073FFU, 0x0000200FU);
+	psu_mask_write(0xFD070750, 0x00000001U, 0x00000001U);
+	psu_mask_write(0xFD070754, 0x0033000FU, 0x00100003U);
+	psu_mask_write(0xFD070758, 0x07FF07FFU, 0x0000004FU);
+	psu_mask_write(0xFD07075C, 0x0033000FU, 0x00100003U);
+	psu_mask_write(0xFD070760, 0x000007FFU, 0x0000004FU);
+	psu_mask_write(0xFD070774, 0x000073FFU, 0x0000200FU);
+	psu_mask_write(0xFD070778, 0x000073FFU, 0x0000200FU);
+	psu_mask_write(0xFD070800, 0x00000001U, 0x00000001U);
+	psu_mask_write(0xFD070804, 0x0033000FU, 0x00100003U);
+	psu_mask_write(0xFD070808, 0x07FF07FFU, 0x0000004FU);
+	psu_mask_write(0xFD07080C, 0x0033000FU, 0x00100003U);
+	psu_mask_write(0xFD070810, 0x000007FFU, 0x0000004FU);
+	psu_mask_write(0xFD070F04, 0x000001FFU, 0x00000000U);
+	psu_mask_write(0xFD070F08, 0x000000FFU, 0x00000000U);
+	psu_mask_write(0xFD070F0C, 0x000001FFU, 0x00000010U);
+	psu_mask_write(0xFD070F10, 0x000000FFU, 0x0000000FU);
+	psu_mask_write(0xFD072190, 0x1FBFBF3FU, 0x07828002U);
+	psu_mask_write(0xFD1A0108, 0x0000000CU, 0x00000000U);
+	psu_mask_write(0xFD080010, 0xFFFFFFFFU, 0x07001E00U);
+	psu_mask_write(0xFD080018, 0xFFFFFFFFU, 0x00F05D90U);
+	psu_mask_write(0xFD08001C, 0xFFFFFFFFU, 0x55AA5480U);
+	psu_mask_write(0xFD080024, 0xFFFFFFFFU, 0x010100F4U);
+	psu_mask_write(0xFD080040, 0xFFFFFFFFU, 0x1900C810U);
+	psu_mask_write(0xFD080044, 0xFFFFFFFFU, 0x4E200708U);
+	psu_mask_write(0xFD080068, 0xFFFFFFFFU, 0x06124000U);
+	psu_mask_write(0xFD080090, 0xFFFFFFFFU, 0x02A04061U);
+	psu_mask_write(0xFD0800C0, 0xFFFFFFFFU, 0x00000000U);
+	psu_mask_write(0xFD0800C4, 0xFFFFFFFFU, 0x000000DAU);
+	psu_mask_write(0xFD080100, 0xFFFFFFFFU, 0x0800040BU);
+	psu_mask_write(0xFD080110, 0xFFFFFFFFU, 0x040E0A04U);
+	psu_mask_write(0xFD080114, 0xFFFFFFFFU, 0x28100004U);
+	psu_mask_write(0xFD080118, 0xFFFFFFFFU, 0x000F0200U);
+	psu_mask_write(0xFD08011C, 0xFFFFFFFFU, 0x82000800U);
+	psu_mask_write(0xFD080120, 0xFFFFFFFFU, 0x00682B0AU);
+	psu_mask_write(0xFD080124, 0xFFFFFFFFU, 0x00152504U);
+	psu_mask_write(0xFD080128, 0xFFFFFFFFU, 0x00000506U);
+	psu_mask_write(0xFD080140, 0xFFFFFFFFU, 0x08400020U);
+	psu_mask_write(0xFD080144, 0xFFFFFFFFU, 0x00000C80U);
+	psu_mask_write(0xFD080150, 0xFFFFFFFFU, 0x00000000U);
+	psu_mask_write(0xFD080154, 0xFFFFFFFFU, 0x00000000U);
+	psu_mask_write(0xFD080180, 0xFFFFFFFFU, 0x00000520U);
+	psu_mask_write(0xFD080184, 0xFFFFFFFFU, 0x00000004U);
+	psu_mask_write(0xFD080188, 0xFFFFFFFFU, 0x00000000U);
+	psu_mask_write(0xFD08018C, 0xFFFFFFFFU, 0x00000000U);
+	psu_mask_write(0xFD080190, 0xFFFFFFFFU, 0x00000000U);
+	psu_mask_write(0xFD080194, 0xFFFFFFFFU, 0x00000000U);
+	psu_mask_write(0xFD080198, 0xFFFFFFFFU, 0x00000000U);
+	psu_mask_write(0xFD0801AC, 0xFFFFFFFFU, 0x00000000U);
+	psu_mask_write(0xFD0801B0, 0xFFFFFFFFU, 0x0000004DU);
+	psu_mask_write(0xFD0801B4, 0xFFFFFFFFU, 0x00000008U);
+	psu_mask_write(0xFD0801B8, 0xFFFFFFFFU, 0x0000004DU);
+	psu_mask_write(0xFD0801D8, 0xFFFFFFFFU, 0x00000000U);
+	psu_mask_write(0xFD080200, 0xFFFFFFFFU, 0x800081C7U);
+	psu_mask_write(0xFD080204, 0xFFFFFFFFU, 0x00010236U);
+	psu_mask_write(0xFD080240, 0xFFFFFFFFU, 0x00141054U);
+	psu_mask_write(0xFD080250, 0xFFFFFFFFU, 0x00088000U);
+	psu_mask_write(0xFD080414, 0xFFFFFFFFU, 0x12340800U);
+	psu_mask_write(0xFD0804F4, 0xFFFFFFFFU, 0x00000005U);
+	psu_mask_write(0xFD080500, 0xFFFFFFFFU, 0x30000028U);
+	psu_mask_write(0xFD080508, 0xFFFFFFFFU, 0x0A000000U);
+	psu_mask_write(0xFD08050C, 0xFFFFFFFFU, 0x00000009U);
+	psu_mask_write(0xFD080510, 0xFFFFFFFFU, 0x0A000000U);
+	psu_mask_write(0xFD080520, 0xFFFFFFFFU, 0x0300B0B0U);
+	psu_mask_write(0xFD080528, 0xFFFFFFFFU, 0xF1032019U);
+	psu_mask_write(0xFD08052C, 0xFFFFFFFFU, 0x07F001E3U);
+	psu_mask_write(0xFD080544, 0xFFFFFFFFU, 0x00000000U);
+	psu_mask_write(0xFD080548, 0xFFFFFFFFU, 0x00000000U);
+	psu_mask_write(0xFD080558, 0xFFFFFFFFU, 0x00000000U);
+	psu_mask_write(0xFD08055C, 0xFFFFFFFFU, 0x00000000U);
+	psu_mask_write(0xFD080560, 0xFFFFFFFFU, 0x00000000U);
+	psu_mask_write(0xFD080564, 0xFFFFFFFFU, 0x00000000U);
+	psu_mask_write(0xFD080680, 0xFFFFFFFFU, 0x0088E858U);
+	psu_mask_write(0xFD080684, 0xFFFFFFFFU, 0x000077BBU);
+	psu_mask_write(0xFD080694, 0xFFFFFFFFU, 0x01E10210U);
+	psu_mask_write(0xFD080698, 0xFFFFFFFFU, 0x01E10000U);
+	psu_mask_write(0xFD0806A4, 0xFFFFFFFFU, 0x000076BBU);
+	psu_mask_write(0xFD080700, 0xFFFFFFFFU, 0x40800604U);
+	psu_mask_write(0xFD080704, 0xFFFFFFFFU, 0x00007FFFU);
+	psu_mask_write(0xFD08070C, 0xFFFFFFFFU, 0x3F000008U);
+	psu_mask_write(0xFD080710, 0xFFFFFFFFU, 0x0E00B00CU);
+	psu_mask_write(0xFD080714, 0xFFFFFFFFU, 0x09093030U);
+	psu_mask_write(0xFD080718, 0xFFFFFFFFU, 0x09092B2BU);
+	psu_mask_write(0xFD080800, 0xFFFFFFFFU, 0x40800604U);
+	psu_mask_write(0xFD080804, 0xFFFFFFFFU, 0x00007FFFU);
+	psu_mask_write(0xFD08080C, 0xFFFFFFFFU, 0x3F000008U);
+	psu_mask_write(0xFD080810, 0xFFFFFFFFU, 0x0E00B00CU);
+	psu_mask_write(0xFD080814, 0xFFFFFFFFU, 0x09093030U);
+	psu_mask_write(0xFD080818, 0xFFFFFFFFU, 0x09092B2BU);
+	psu_mask_write(0xFD080900, 0xFFFFFFFFU, 0x40800604U);
+	psu_mask_write(0xFD080904, 0xFFFFFFFFU, 0x00007FFFU);
+	psu_mask_write(0xFD08090C, 0xFFFFFFFFU, 0x3F000008U);
+	psu_mask_write(0xFD080910, 0xFFFFFFFFU, 0x0E00B00CU);
+	psu_mask_write(0xFD080914, 0xFFFFFFFFU, 0x09093030U);
+	psu_mask_write(0xFD080918, 0xFFFFFFFFU, 0x09092B2BU);
+	psu_mask_write(0xFD080A00, 0xFFFFFFFFU, 0x40800604U);
+	psu_mask_write(0xFD080A04, 0xFFFFFFFFU, 0x00007FFFU);
+	psu_mask_write(0xFD080A0C, 0xFFFFFFFFU, 0x3F000008U);
+	psu_mask_write(0xFD080A10, 0xFFFFFFFFU, 0x0E00B00CU);
+	psu_mask_write(0xFD080A14, 0xFFFFFFFFU, 0x09093030U);
+	psu_mask_write(0xFD080A18, 0xFFFFFFFFU, 0x09092B2BU);
+	psu_mask_write(0xFD080B00, 0xFFFFFFFFU, 0x40800604U);
+	psu_mask_write(0xFD080B04, 0xFFFFFFFFU, 0x00007FFFU);
+	psu_mask_write(0xFD080B08, 0xFFFFFFFFU, 0x00000000U);
+	psu_mask_write(0xFD080B0C, 0xFFFFFFFFU, 0x3F000008U);
+	psu_mask_write(0xFD080B10, 0xFFFFFFFFU, 0x0E00B004U);
+	psu_mask_write(0xFD080B14, 0xFFFFFFFFU, 0x09093030U);
+	psu_mask_write(0xFD080B18, 0xFFFFFFFFU, 0x09092B2BU);
+	psu_mask_write(0xFD080C00, 0xFFFFFFFFU, 0x40800604U);
+	psu_mask_write(0xFD080C04, 0xFFFFFFFFU, 0x00007FFFU);
+	psu_mask_write(0xFD080C08, 0xFFFFFFFFU, 0x00000000U);
+	psu_mask_write(0xFD080C0C, 0xFFFFFFFFU, 0x3F000008U);
+	psu_mask_write(0xFD080C10, 0xFFFFFFFFU, 0x0E00B00CU);
+	psu_mask_write(0xFD080C14, 0xFFFFFFFFU, 0x09093030U);
+	psu_mask_write(0xFD080C18, 0xFFFFFFFFU, 0x09092B2BU);
+	psu_mask_write(0xFD080D00, 0xFFFFFFFFU, 0x40800604U);
+	psu_mask_write(0xFD080D04, 0xFFFFFFFFU, 0x00007FFFU);
+	psu_mask_write(0xFD080D08, 0xFFFFFFFFU, 0x00000000U);
+	psu_mask_write(0xFD080D0C, 0xFFFFFFFFU, 0x3F000008U);
+	psu_mask_write(0xFD080D10, 0xFFFFFFFFU, 0x0E00B004U);
+	psu_mask_write(0xFD080D14, 0xFFFFFFFFU, 0x09093030U);
+	psu_mask_write(0xFD080D18, 0xFFFFFFFFU, 0x09092B2BU);
+	psu_mask_write(0xFD080E00, 0xFFFFFFFFU, 0x40800604U);
+	psu_mask_write(0xFD080E04, 0xFFFFFFFFU, 0x00007FFFU);
+	psu_mask_write(0xFD080E08, 0xFFFFFFFFU, 0x00000000U);
+	psu_mask_write(0xFD080E0C, 0xFFFFFFFFU, 0x3F000008U);
+	psu_mask_write(0xFD080E10, 0xFFFFFFFFU, 0x0E00B00CU);
+	psu_mask_write(0xFD080E14, 0xFFFFFFFFU, 0x09093030U);
+	psu_mask_write(0xFD080E18, 0xFFFFFFFFU, 0x09092B2BU);
+	psu_mask_write(0xFD080F00, 0xFFFFFFFFU, 0x40803660U);
+	psu_mask_write(0xFD080F04, 0xFFFFFFFFU, 0x55556000U);
+	psu_mask_write(0xFD080F08, 0xFFFFFFFFU, 0xAAAAAAAAU);
+	psu_mask_write(0xFD080F0C, 0xFFFFFFFFU, 0x0029A4A4U);
+	psu_mask_write(0xFD080F10, 0xFFFFFFFFU, 0x0C00B000U);
+	psu_mask_write(0xFD080F14, 0xFFFFFFFFU, 0x09093030U);
+	psu_mask_write(0xFD080F18, 0xFFFFFFFFU, 0x09092B2BU);
+	psu_mask_write(0xFD081400, 0xFFFFFFFFU, 0x2A019FFEU);
+	psu_mask_write(0xFD081404, 0xFFFFFFFFU, 0x06124000U);
+	psu_mask_write(0xFD08141C, 0xFFFFFFFFU, 0x01264300U);
+	psu_mask_write(0xFD08142C, 0xFFFFFFFFU, 0x00041800U);
+	psu_mask_write(0xFD081430, 0xFFFFFFFFU, 0x70000000U);
+	psu_mask_write(0xFD081440, 0xFFFFFFFFU, 0x2A019FFEU);
+	psu_mask_write(0xFD081444, 0xFFFFFFFFU, 0x06124000U);
+	psu_mask_write(0xFD08145C, 0xFFFFFFFFU, 0x01264300U);
+	psu_mask_write(0xFD08146C, 0xFFFFFFFFU, 0x00041800U);
+	psu_mask_write(0xFD081470, 0xFFFFFFFFU, 0x70000000U);
+	psu_mask_write(0xFD081480, 0xFFFFFFFFU, 0x2A019FFEU);
+	psu_mask_write(0xFD081484, 0xFFFFFFFFU, 0x06124000U);
+	psu_mask_write(0xFD08149C, 0xFFFFFFFFU, 0x01264300U);
+	psu_mask_write(0xFD0814AC, 0xFFFFFFFFU, 0x00041800U);
+	psu_mask_write(0xFD0814B0, 0xFFFFFFFFU, 0x70000000U);
+	psu_mask_write(0xFD0814C0, 0xFFFFFFFFU, 0x2A019FFEU);
+	psu_mask_write(0xFD0814C4, 0xFFFFFFFFU, 0x06124000U);
+	psu_mask_write(0xFD0814DC, 0xFFFFFFFFU, 0x01264300U);
+	psu_mask_write(0xFD0814EC, 0xFFFFFFFFU, 0x00041800U);
+	psu_mask_write(0xFD0814F0, 0xFFFFFFFFU, 0x70000000U);
+	psu_mask_write(0xFD081500, 0xFFFFFFFFU, 0x15019FFEU);
+	psu_mask_write(0xFD081504, 0xFFFFFFFFU, 0x06124000U);
+	psu_mask_write(0xFD08151C, 0xFFFFFFFFU, 0x01264300U);
+	psu_mask_write(0xFD08152C, 0xFFFFFFFFU, 0x00041800U);
+	psu_mask_write(0xFD081530, 0xFFFFFFFFU, 0x70000000U);
+	psu_mask_write(0xFD0817C4, 0xFFFFFFFFU, 0x06124000U);
+	psu_mask_write(0xFD0817DC, 0xFFFFFFFFU, 0x012643C4U);
+
+	return 1;
+}
+
+static unsigned long psu_mio_init_data(void)
+{
+	psu_mask_write(0xFF180000, 0x000000FEU, 0x00000002U);
+	psu_mask_write(0xFF180004, 0x000000FEU, 0x00000002U);
+	psu_mask_write(0xFF180010, 0x000000FEU, 0x00000002U);
+	psu_mask_write(0xFF180014, 0x000000FEU, 0x00000002U);
+	psu_mask_write(0xFF180018, 0x000000FEU, 0x00000002U);
+	psu_mask_write(0xFF180088, 0x000000FEU, 0x000000C0U);
+	psu_mask_write(0xFF18008C, 0x000000FEU, 0x000000C0U);
+	psu_mask_write(0xFF18009C, 0x000000FEU, 0x00000010U);
+	psu_mask_write(0xFF1800A0, 0x000000FEU, 0x00000010U);
+	psu_mask_write(0xFF1800A4, 0x000000FEU, 0x00000010U);
+	psu_mask_write(0xFF1800A8, 0x000000FEU, 0x00000010U);
+	psu_mask_write(0xFF1800AC, 0x000000FEU, 0x00000010U);
+	psu_mask_write(0xFF1800B0, 0x000000FEU, 0x00000010U);
+	psu_mask_write(0xFF1800B4, 0x000000FEU, 0x00000010U);
+	psu_mask_write(0xFF1800B8, 0x000000FEU, 0x00000010U);
+	psu_mask_write(0xFF1800BC, 0x000000FEU, 0x00000010U);
+	psu_mask_write(0xFF1800C0, 0x000000FEU, 0x00000010U);
+	psu_mask_write(0xFF1800C4, 0x000000FEU, 0x00000010U);
+	psu_mask_write(0xFF1800C8, 0x000000FEU, 0x00000010U);
+	psu_mask_write(0xFF1800CC, 0x000000FEU, 0x00000010U);
+	psu_mask_write(0xFF180204, 0x0000007FU, 0x00000002U);
+	psu_mask_write(0xFF180208, 0x000FFF8CU, 0x00003004U);
+	psu_mask_write(0xFF180138, 0x03FFFFFFU, 0x03FFFFFFU);
+	psu_mask_write(0xFF18013C, 0x03FFFFFFU, 0x03FFFFFFU);
+	psu_mask_write(0xFF180140, 0x03FFFFFFU, 0x00000000U);
+	psu_mask_write(0xFF180144, 0x03FFFFFFU, 0x03FFFFFFU);
+	psu_mask_write(0xFF180148, 0x03FFFFFFU, 0x03FFFFFFU);
+	psu_mask_write(0xFF18014C, 0x03FFFFFFU, 0x00000000U);
+	psu_mask_write(0xFF180154, 0x03FFFFFFU, 0x03FFFFFFU);
+	psu_mask_write(0xFF180158, 0x03FFFFFFU, 0x03FFFFFFU);
+	psu_mask_write(0xFF18015C, 0x03FFFFFFU, 0x00000000U);
+	psu_mask_write(0xFF180160, 0x03FFFFFFU, 0x03FFFFFFU);
+	psu_mask_write(0xFF180164, 0x03FFFFFFU, 0x03FFFFFFU);
+	psu_mask_write(0xFF180168, 0x03FFFFFFU, 0x00000000U);
+	psu_mask_write(0xFF180170, 0x03FFFFFFU, 0x03FFFFFFU);
+	psu_mask_write(0xFF180174, 0x03FFFFFFU, 0x03FFFFFFU);
+	psu_mask_write(0xFF180178, 0x03FFFFFFU, 0x00000000U);
+	psu_mask_write(0xFF18017C, 0x03FFFFFFU, 0x03FFFFFFU);
+	psu_mask_write(0xFF180180, 0x03FFFFFFU, 0x03FFFFFFU);
+	psu_mask_write(0xFF180184, 0x03FFFFFFU, 0x00000000U);
+	psu_mask_write(0xFF180200, 0x0000000FU, 0x00000000U);
+
+	return 1;
+}
+
+static unsigned long psu_peripherals_pre_init_data(void)
+{
+	psu_mask_write(0xFF5E0108, 0x013F3F07U, 0x00012302U);
+
+	return 1;
+}
+
+static unsigned long psu_peripherals_init_data(void)
+{
+	psu_mask_write(0xFD1A0100, 0x0000807CU, 0x00000000U);
+	psu_mask_write(0xFF5E0238, 0x001A0000U, 0x00000000U);
+	psu_mask_write(0xFF5E023C, 0x0093C018U, 0x00000000U);
+	psu_mask_write(0xFF5E0238, 0x00000001U, 0x00000000U);
+	psu_mask_write(0xFF180390, 0x00000004U, 0x00000004U);
+	psu_mask_write(0xFF5E0238, 0x00000040U, 0x00000000U);
+	psu_mask_write(0xFF180310, 0x00008000U, 0x00000000U);
+	psu_mask_write(0xFF180320, 0x33800000U, 0x02800000U);
+	psu_mask_write(0xFF18031C, 0x7FFE0000U, 0x64500000U);
+	psu_mask_write(0xFF180358, 0x00000008U, 0x00000008U);
+	psu_mask_write(0xFF180324, 0x03C00000U, 0x00000000U);
+	psu_mask_write(0xFF5E0238, 0x00000200U, 0x00000000U);
+	psu_mask_write(0xFF5E0238, 0x00008000U, 0x00000000U);
+	psu_mask_write(0xFF5E0238, 0x00000800U, 0x00000000U);
+	psu_mask_write(0xFF5E0238, 0x00000002U, 0x00000000U);
+	psu_mask_write(0xFF000034, 0x000000FFU, 0x00000005U);
+	psu_mask_write(0xFF000018, 0x0000FFFFU, 0x0000008FU);
+	psu_mask_write(0xFF000000, 0x000001FFU, 0x00000017U);
+	psu_mask_write(0xFF000004, 0x000003FFU, 0x00000020U);
+	psu_mask_write(0xFF5E0238, 0x00040000U, 0x00000000U);
+	psu_mask_write(0xFF4B0024, 0x000000FFU, 0x000000FFU);
+	psu_mask_write(0xFFCA5000, 0x00001FFFU, 0x00000000U);
+	psu_mask_write(0xFD5C0060, 0x000F000FU, 0x00000000U);
+	psu_mask_write(0xFFA60040, 0x80000000U, 0x80000000U);
+	psu_mask_write(0xFF260020, 0xFFFFFFFFU, 0x01FC9F08U);
+	psu_mask_write(0xFF260000, 0x00000001U, 0x00000001U);
+
+	return 1;
+}
+
+static unsigned long psu_afi_config(void)
+{
+	psu_mask_write(0xFD1A0100, 0x00001F80U, 0x00000000U);
+	psu_mask_write(0xFF5E023C, 0x00080000U, 0x00000000U);
+	psu_mask_write(0xFD615000, 0x00000300U, 0x00000200U);
+
+	return 1;
+}
+
+static unsigned long psu_ddr_phybringup_data(void)
+{
+	unsigned int regval = 0;
+	unsigned int pll_retry = 10;
+	unsigned int pll_locked = 0;
+
+	while ((pll_retry > 0) && (!pll_locked)) {
+		Xil_Out32(0xFD080004, 0x00040010);
+		Xil_Out32(0xFD080004, 0x00040011);
+
+		while ((Xil_In32(0xFD080030) & 0x1) != 1)
+			;
+
+		pll_locked = (Xil_In32(0xFD080030) & 0x80000000) >> 31;
+		pll_locked &= (Xil_In32(0xFD0807E0) & 0x10000) >> 16;
+		pll_locked &= (Xil_In32(0xFD0809E0) & 0x10000) >> 16;
+		pll_locked &= (Xil_In32(0xFD080BE0) & 0x10000) >> 16;
+		pll_locked &= (Xil_In32(0xFD080DE0) & 0x10000) >> 16;
+		pll_retry--;
+	}
+	Xil_Out32(0xFD0800C0, Xil_In32(0xFD0800C0) | (pll_retry << 16));
+	Xil_Out32(0xFD080004U, 0x00040063U);
+
+	while ((Xil_In32(0xFD080030U) & 0x0000000FU) != 0x0000000FU)
+		;
+	prog_reg(0xFD080004U, 0x00000001U, 0x00000000U, 0x00000001U);
+
+	while ((Xil_In32(0xFD080030U) & 0x000000FFU) != 0x0000001FU)
+		;
+	Xil_Out32(0xFD0701B0U, 0x00000001U);
+	Xil_Out32(0xFD070320U, 0x00000001U);
+	while ((Xil_In32(0xFD070004U) & 0x0000000FU) != 0x00000001U)
+		;
+	prog_reg(0xFD080014U, 0x00000040U, 0x00000006U, 0x00000001U);
+	Xil_Out32(0xFD080004, 0x0004FE01);
+	regval = Xil_In32(0xFD080030);
+	while (regval != 0x80000FFF)
+		regval = Xil_In32(0xFD080030);
+	Xil_Out32(0xFD070180U, 0x00800020U);
+	Xil_Out32(0xFD070060U, 0x00000000U);
+	prog_reg(0xFD080014U, 0x00000040U, 0x00000006U, 0x00000000U);
+
+	return 1;
+}
+
+static void init_peripheral(void)
+{
+	psu_mask_write(0xFD5F0018, 0x8000001FU, 0x8000001FU);
+}
+
+int psu_init(void)
+{
+	int status = 1;
+
+	status &= psu_mio_init_data();
+	status &= psu_peripherals_pre_init_data();
+	status &= psu_pll_init_data();
+	status &= psu_clock_init_data();
+	status &= psu_ddr_init_data();
+	status &= psu_ddr_phybringup_data();
+	status &= psu_peripherals_init_data();
+	init_peripheral();
+
+	status &= psu_afi_config();
+
+	if (status == 0)
+		return 1;
+	return 0;
+}

+ 1 - 1
board/xilinx/zynqmp/zynqmp-zcu100-revC/psu_init_gpl.c

@@ -481,7 +481,7 @@ static unsigned long psu_mio_init_data(void)
 
 
 static unsigned long psu_peripherals_init_data(void)
 static unsigned long psu_peripherals_init_data(void)
 {
 {
-	psu_mask_write(0xFD1A0100, 0x0001007CU, 0x00000000U);
+	psu_mask_write(0xFD1A0100, 0x0001807CU, 0x00000000U);
 	psu_mask_write(0xFF5E0238, 0x001A0000U, 0x00000000U);
 	psu_mask_write(0xFF5E0238, 0x001A0000U, 0x00000000U);
 	psu_mask_write(0xFF5E023C, 0x0093C018U, 0x00000000U);
 	psu_mask_write(0xFF5E023C, 0x0093C018U, 0x00000000U);
 	psu_mask_write(0xFF5E023C, 0x00000FC0U, 0x00000000U);
 	psu_mask_write(0xFF5E023C, 0x00000FC0U, 0x00000000U);

+ 71 - 9
board/xilinx/zynqmp/zynqmp.c

@@ -9,11 +9,13 @@
 #include <ahci.h>
 #include <ahci.h>
 #include <scsi.h>
 #include <scsi.h>
 #include <malloc.h>
 #include <malloc.h>
+#include <wdt.h>
 #include <asm/arch/clk.h>
 #include <asm/arch/clk.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/arch/psu_init_gpl.h>
 #include <asm/arch/psu_init_gpl.h>
 #include <asm/io.h>
 #include <asm/io.h>
+#include <dm/uclass.h>
 #include <usb.h>
 #include <usb.h>
 #include <dwc3-uboot.h>
 #include <dwc3-uboot.h>
 #include <zynqmppl.h>
 #include <zynqmppl.h>
@@ -22,6 +24,10 @@
 
 
 DECLARE_GLOBAL_DATA_PTR;
 DECLARE_GLOBAL_DATA_PTR;
 
 
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT)
+static struct udevice *watchdog_dev;
+#endif
+
 #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
 #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
     !defined(CONFIG_SPL_BUILD)
     !defined(CONFIG_SPL_BUILD)
 static xilinx_desc zynqmppl = XILINX_ZYNQMP_DESC;
 static xilinx_desc zynqmppl = XILINX_ZYNQMP_DESC;
@@ -281,6 +287,11 @@ int board_early_init_f(void)
 	ret = psu_init();
 	ret = psu_init();
 #endif
 #endif
 
 
+#if defined(CONFIG_WDT) && !defined(CONFIG_SPL_BUILD)
+	/* bss is not cleared at time when watchdog_reset() is called */
+	watchdog_dev = NULL;
+#endif
+
 	return ret;
 	return ret;
 }
 }
 
 
@@ -299,9 +310,40 @@ int board_init(void)
 	}
 	}
 #endif
 #endif
 
 
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT)
+	if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) {
+		puts("Watchdog: Not found!\n");
+	} else {
+		wdt_start(watchdog_dev, 0, 0);
+		puts("Watchdog: Started\n");
+	}
+#endif
+
 	return 0;
 	return 0;
 }
 }
 
 
+#ifdef CONFIG_WATCHDOG
+/* Called by macro WATCHDOG_RESET */
+void watchdog_reset(void)
+{
+# if !defined(CONFIG_SPL_BUILD)
+	static ulong next_reset;
+	ulong now;
+
+	if (!watchdog_dev)
+		return;
+
+	now = timer_get_us();
+
+	/* Do not reset the watchdog too often */
+	if (now > next_reset) {
+		wdt_reset(watchdog_dev);
+		next_reset = now + 1000;
+	}
+# endif
+}
+#endif
+
 int board_early_init_r(void)
 int board_early_init_r(void)
 {
 {
 	u32 val;
 	u32 val;
@@ -363,7 +405,15 @@ unsigned long do_go_exec(ulong (*entry)(int, char * const []), int argc,
 #if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
 #if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
 int dram_init_banksize(void)
 int dram_init_banksize(void)
 {
 {
-	return fdtdec_setup_memory_banksize();
+	int ret;
+
+	ret = fdtdec_setup_memory_banksize();
+	if (ret)
+		return ret;
+
+	mem_map_fill();
+
+	return 0;
 }
 }
 
 
 int dram_init(void)
 int dram_init(void)
@@ -374,6 +424,18 @@ int dram_init(void)
 	return 0;
 	return 0;
 }
 }
 #else
 #else
+int dram_init_banksize(void)
+{
+#if defined(CONFIG_NR_DRAM_BANKS)
+	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+	gd->bd->bi_dram[0].size = get_effective_memsize();
+#endif
+
+	mem_map_fill();
+
+	return 0;
+}
+
 int dram_init(void)
 int dram_init(void)
 {
 {
 	gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
 	gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
@@ -391,6 +453,7 @@ int board_late_init(void)
 {
 {
 	u32 reg = 0;
 	u32 reg = 0;
 	u8 bootmode;
 	u8 bootmode;
+	int env_targets_len = 0;
 	const char *mode;
 	const char *mode;
 	char *new_targets;
 	char *new_targets;
 	char *env_targets;
 	char *env_targets;
@@ -467,14 +530,13 @@ int board_late_init(void)
 	 * and default boot_targets
 	 * and default boot_targets
 	 */
 	 */
 	env_targets = env_get("boot_targets");
 	env_targets = env_get("boot_targets");
-	if (env_targets) {
-		new_targets = calloc(1, strlen(mode) +
-				     strlen(env_targets) + 2);
-		sprintf(new_targets, "%s %s", mode, env_targets);
-	} else {
-		new_targets = calloc(1, strlen(mode) + 2);
-		sprintf(new_targets, "%s", mode);
-	}
+	if (env_targets)
+		env_targets_len = strlen(env_targets);
+
+	new_targets = calloc(1, strlen(mode) + env_targets_len + 2);
+
+	sprintf(new_targets, "%s %s", mode,
+		env_targets ? env_targets : "");
 
 
 	env_set("boot_targets", new_targets);
 	env_set("boot_targets", new_targets);
 
 

+ 7 - 0
board/xilinx/zynqmp_r5/MAINTAINERS

@@ -0,0 +1,7 @@
+XILINX_ZYNQMP_R5 BOARDS
+M:	Michal Simek <michal.simek@xilinx.com>
+S:	Maintained
+F:	arch/arm/dts/zynqmp-r5*
+F:	board/xilinx/zynqmp_r5/
+F:	include/configs/xilinx_zynqmp_r5_*
+F:	configs/xilinx_zynqmp_r5_*

+ 6 - 0
board/xilinx/zynqmp_r5/Makefile

@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# (C) Copyright 2018 Xilinx, Inc. (Michal Simek)
+#
+
+obj-y	:= board.o

+ 25 - 0
board/xilinx/zynqmp_r5/board.c

@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2018 Xilinx, Inc. (Michal Simek)
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+
+int board_init(void)
+{
+	return 0;
+}
+
+int dram_init_banksize(void)
+{
+	return fdtdec_setup_memory_banksize();
+}
+
+int dram_init(void)
+{
+	if (fdtdec_setup_memory_size() != 0)
+		return -EINVAL;
+
+	return 0;
+}

+ 1 - 0
common/image.c

@@ -159,6 +159,7 @@ static const table_entry_t uimage_type[] = {
 	{	IH_TYPE_VYBRIDIMAGE, "vybridimage",  "Vybrid Boot Image", },
 	{	IH_TYPE_VYBRIDIMAGE, "vybridimage",  "Vybrid 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_ZYNQMPIMAGE, "zynqmpimage", "Xilinx ZynqMP Boot Image" },
+	{	IH_TYPE_ZYNQMPBIF,  "zynqmpbif",  "Xilinx ZynqMP Boot Image (bif)" },
 	{	IH_TYPE_FPGA,       "fpga",       "FPGA Image" },
 	{	IH_TYPE_FPGA,       "fpga",       "FPGA Image" },
 	{       IH_TYPE_TEE,        "tee",        "Trusted Execution Environment Image",},
 	{       IH_TYPE_TEE,        "tee",        "Trusted Execution Environment Image",},
 	{	IH_TYPE_FIRMWARE_IVT, "firmware_ivt", "Firmware with HABv4 IVT" },
 	{	IH_TYPE_FIRMWARE_IVT, "firmware_ivt", "Firmware with HABv4 IVT" },

+ 0 - 4
configs/microblaze-generic_defconfig

@@ -35,10 +35,6 @@ CONFIG_CMD_TFTPPUT=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
 CONFIG_CMD_PING=y
 CONFIG_CMD_JFFS2=y
 CONFIG_CMD_JFFS2=y
-CONFIG_MTDIDS_DEFAULT="nor0=flash-0"
-CONFIG_MTDPARTS_DEFAULT="mtdparts=flash-0:256k(u-boot),256k(env),3m(kernel),1m(romfs),1m(cramfs),-(jffs2)"
-CONFIG_CMD_UBI=y
-# CONFIG_CMD_UBIFS is not set
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_EMBED=y
 CONFIG_OF_EMBED=y
 CONFIG_NETCONSOLE=y
 CONFIG_NETCONSOLE=y

+ 0 - 1
configs/syzygy_hub_defconfig

@@ -13,7 +13,6 @@ CONFIG_FIT_SIGNATURE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SYS_PROMPT="Zynq> "
 CONFIG_SYS_PROMPT="Zynq> "

+ 0 - 1
configs/topic_miami_defconfig

@@ -11,7 +11,6 @@ CONFIG_DEBUG_UART=y
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_BOOTDELAY=0
 CONFIG_BOOTDELAY=0
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SYS_PROMPT="zynq-uboot> "
 CONFIG_SYS_PROMPT="zynq-uboot> "

+ 0 - 1
configs/topic_miamilite_defconfig

@@ -11,7 +11,6 @@ CONFIG_DEBUG_UART=y
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_BOOTDELAY=0
 CONFIG_BOOTDELAY=0
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SYS_PROMPT="zynq-uboot> "
 CONFIG_SYS_PROMPT="zynq-uboot> "

+ 0 - 1
configs/topic_miamiplus_defconfig

@@ -11,7 +11,6 @@ CONFIG_DEBUG_UART=y
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_BOOTDELAY=0
 CONFIG_BOOTDELAY=0
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SYS_PROMPT="zynq-uboot> "
 CONFIG_SYS_PROMPT="zynq-uboot> "

+ 16 - 0
configs/xilinx_zynqmp_r5_defconfig

@@ -0,0 +1,16 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ZYNQMP_R5=y
+CONFIG_SYS_TEXT_BASE=0x10000000
+CONFIG_DEFAULT_DEVICE_TREE="zynqmp-r5"
+CONFIG_DEBUG_UART=y
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_SYS_PROMPT="ZynqMP r5> "
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_OF_EMBED=y
+CONFIG_DEBUG_UART_ZYNQ=y
+CONFIG_DEBUG_UART_BASE=0xff010000
+CONFIG_DEBUG_UART_CLOCK=100000000
+CONFIG_ZYNQ_SERIAL=y
+CONFIG_TIMER=y
+CONFIG_CADENCE_TTC_TIMER=y

+ 0 - 2
configs/xilinx_zynqmp_zc1232_revA_defconfig

@@ -4,7 +4,6 @@ CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 # CONFIG_SPL_LIBDISK_SUPPORT is not set
 # CONFIG_SPL_LIBDISK_SUPPORT is not set
 CONFIG_SPL=y
 CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZC1232 revA"
 # CONFIG_SPL_FAT_SUPPORT is not set
 # CONFIG_SPL_FAT_SUPPORT is not set
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1232-revA"
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1232-revA"
 CONFIG_DEBUG_UART=y
 CONFIG_DEBUG_UART=y
@@ -13,7 +12,6 @@ CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT=y
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_DEVICE=y
 CONFIG_SPL_RAM_DEVICE=y

+ 0 - 2
configs/xilinx_zynqmp_zc1254_revA_defconfig

@@ -4,7 +4,6 @@ CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 # CONFIG_SPL_LIBDISK_SUPPORT is not set
 # CONFIG_SPL_LIBDISK_SUPPORT is not set
 CONFIG_SPL=y
 CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZC1254 revA"
 # CONFIG_SPL_FAT_SUPPORT is not set
 # CONFIG_SPL_FAT_SUPPORT is not set
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1254-revA"
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1254-revA"
 CONFIG_DEBUG_UART=y
 CONFIG_DEBUG_UART=y
@@ -13,7 +12,6 @@ CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT=y
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_DEVICE=y
 CONFIG_SPL_RAM_DEVICE=y

+ 0 - 2
configs/xilinx_zynqmp_zc1275_revA_defconfig

@@ -4,7 +4,6 @@ CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 # CONFIG_SPL_LIBDISK_SUPPORT is not set
 # CONFIG_SPL_LIBDISK_SUPPORT is not set
 CONFIG_SPL=y
 CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZC1275 revA"
 # CONFIG_SPL_FAT_SUPPORT is not set
 # CONFIG_SPL_FAT_SUPPORT is not set
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1275-revA"
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1275-revA"
 CONFIG_DEBUG_UART=y
 CONFIG_DEBUG_UART=y
@@ -13,7 +12,6 @@ CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT=y
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_DEVICE=y
 CONFIG_SPL_RAM_DEVICE=y

+ 53 - 0
configs/xilinx_zynqmp_zc1275_revB_defconfig

@@ -0,0 +1,53 @@
+CONFIG_ARM=y
+CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_zc1275_revB"
+CONFIG_ARCH_ZYNQMP=y
+CONFIG_SYS_TEXT_BASE=0x8000000
+CONFIG_SYS_MALLOC_F_LEN=0x8000
+# CONFIG_SPL_LIBDISK_SUPPORT is not set
+CONFIG_SPL=y
+# CONFIG_SPL_FAT_SUPPORT is not set
+CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1275-revB"
+CONFIG_DEBUG_UART=y
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_SPL_LOAD_FIT=y
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_SPL_OS_BOOT=y
+CONFIG_SPL_RAM_SUPPORT=y
+CONFIG_SPL_RAM_DEVICE=y
+CONFIG_SPL_ATF=y
+CONFIG_SYS_PROMPT="ZynqMP> "
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_CLK=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_FPGA_LOADBP=y
+CONFIG_CMD_FPGA_LOADP=y
+CONFIG_CMD_MMC=y
+# CONFIG_CMD_NET is not set
+CONFIG_CMD_TIME=y
+CONFIG_CMD_TIMER=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_EMBED=y
+CONFIG_SPL_DM=y
+CONFIG_CLK_ZYNQMP=y
+CONFIG_FPGA_XILINX=y
+CONFIG_FPGA_ZYNQMPPL=y
+CONFIG_MISC=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ZYNQ=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
+CONFIG_SF_DUAL_FLASH=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_WINBOND=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
+CONFIG_DEBUG_UART_ZYNQ=y
+CONFIG_DEBUG_UART_BASE=0xff000000
+CONFIG_DEBUG_UART_CLOCK=100000000
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_ZYNQ_SERIAL=y
+CONFIG_EFI_LOADER_BOUNCE_BUFFER=y

+ 0 - 2
configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig

@@ -4,7 +4,6 @@ CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SPL=y
 CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZC1751 xm015 dc1"
 CONFIG_ZYNQMP_USB=y
 CONFIG_ZYNQMP_USB=y
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm015-dc1"
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm015-dc1"
 CONFIG_DEBUG_UART=y
 CONFIG_DEBUG_UART=y
@@ -14,7 +13,6 @@ CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT=y
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_BOARD_EARLY_INIT_R=y
 CONFIG_BOARD_EARLY_INIT_R=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_SUPPORT=y

+ 0 - 2
configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig

@@ -5,7 +5,6 @@ CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 # CONFIG_SPL_LIBDISK_SUPPORT is not set
 # CONFIG_SPL_LIBDISK_SUPPORT is not set
 CONFIG_SPL=y
 CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZC1751 xm016 dc2"
 # CONFIG_SPL_FAT_SUPPORT is not set
 # CONFIG_SPL_FAT_SUPPORT is not set
 CONFIG_ZYNQMP_USB=y
 CONFIG_ZYNQMP_USB=y
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm016-dc2"
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm016-dc2"
@@ -15,7 +14,6 @@ CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT=y
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_BOARD_EARLY_INIT_R=y
 CONFIG_BOARD_EARLY_INIT_R=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_SUPPORT=y

+ 0 - 2
configs/xilinx_zynqmp_zc1751_xm017_dc3_defconfig

@@ -4,7 +4,6 @@ CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SPL=y
 CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZC1751 xm017 dc3"
 CONFIG_ZYNQMP_USB=y
 CONFIG_ZYNQMP_USB=y
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm017-dc3"
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm017-dc3"
 CONFIG_DEBUG_UART=y
 CONFIG_DEBUG_UART=y
@@ -14,7 +13,6 @@ CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT=y
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_DEVICE=y
 CONFIG_SPL_RAM_DEVICE=y

+ 0 - 2
configs/xilinx_zynqmp_zc1751_xm018_dc4_defconfig

@@ -3,7 +3,6 @@ CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SPL=y
 CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZC1751 xm018 dc4"
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm018-dc4"
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm018-dc4"
 CONFIG_DEBUG_UART=y
 CONFIG_DEBUG_UART=y
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_DISTRO_DEFAULTS=y
@@ -11,7 +10,6 @@ CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT=y
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_BOARD_EARLY_INIT_R=y
 CONFIG_BOARD_EARLY_INIT_R=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_SUPPORT=y

+ 0 - 2
configs/xilinx_zynqmp_zc1751_xm019_dc5_defconfig

@@ -4,7 +4,6 @@ CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SPL=y
 CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZC1751 xm019 dc5"
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm019-dc5"
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm019-dc5"
 CONFIG_DEBUG_UART=y
 CONFIG_DEBUG_UART=y
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_DISTRO_DEFAULTS=y
@@ -12,7 +11,6 @@ CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT=y
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_BOARD_EARLY_INIT_R=y
 CONFIG_BOARD_EARLY_INIT_R=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_SUPPORT=y

+ 2 - 2
configs/xilinx_zynqmp_zcu100_revC_defconfig

@@ -4,7 +4,6 @@ CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SPL=y
 CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZCU100 RevC"
 CONFIG_ZYNQ_SDHCI_MAX_FREQ=15000000
 CONFIG_ZYNQ_SDHCI_MAX_FREQ=15000000
 CONFIG_ZYNQMP_USB=y
 CONFIG_ZYNQMP_USB=y
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu100-revC"
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu100-revC"
@@ -14,7 +13,6 @@ CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT=y
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_DEVICE=y
 CONFIG_SPL_RAM_DEVICE=y
@@ -80,5 +78,7 @@ CONFIG_USB_ULPI=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_DOWNLOAD=y
 CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_WDT=y
+CONFIG_WDT_CDNS=y
 CONFIG_OF_LIBFDT_OVERLAY=y
 CONFIG_OF_LIBFDT_OVERLAY=y
 CONFIG_EFI_LOADER_BOUNCE_BUFFER=y
 CONFIG_EFI_LOADER_BOUNCE_BUFFER=y

+ 2 - 2
configs/xilinx_zynqmp_zcu102_rev1_0_defconfig

@@ -4,7 +4,6 @@ CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SPL=y
 CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZCU102 rev1.0"
 CONFIG_ZYNQMP_USB=y
 CONFIG_ZYNQMP_USB=y
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102-rev1.0"
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102-rev1.0"
 CONFIG_DEBUG_UART=y
 CONFIG_DEBUG_UART=y
@@ -14,7 +13,6 @@ CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT=y
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_BOARD_EARLY_INIT_R=y
 CONFIG_BOARD_EARLY_INIT_R=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_SUPPORT=y
@@ -62,6 +60,8 @@ CONFIG_ZYNQ_I2C1=y
 CONFIG_MISC=y
 CONFIG_MISC=y
 CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0x20
 CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0x20
 CONFIG_DM_MMC=y
 CONFIG_DM_MMC=y
+CONFIG_MMC_IO_VOLTAGE=y
+CONFIG_MMC_UHS_SUPPORT=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ZYNQ=y
 CONFIG_MMC_SDHCI_ZYNQ=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH=y

+ 0 - 2
configs/xilinx_zynqmp_zcu102_revA_defconfig

@@ -4,7 +4,6 @@ CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SPL=y
 CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZCU102 revA"
 CONFIG_ZYNQMP_USB=y
 CONFIG_ZYNQMP_USB=y
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102-revA"
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102-revA"
 CONFIG_DEBUG_UART=y
 CONFIG_DEBUG_UART=y
@@ -14,7 +13,6 @@ CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT=y
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_BOARD_EARLY_INIT_R=y
 CONFIG_BOARD_EARLY_INIT_R=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_SUPPORT=y

+ 0 - 2
configs/xilinx_zynqmp_zcu102_revB_defconfig

@@ -4,7 +4,6 @@ CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SPL=y
 CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZCU102 revB"
 CONFIG_ZYNQMP_USB=y
 CONFIG_ZYNQMP_USB=y
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102-revB"
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102-revB"
 CONFIG_DEBUG_UART=y
 CONFIG_DEBUG_UART=y
@@ -14,7 +13,6 @@ CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT=y
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_BOARD_EARLY_INIT_R=y
 CONFIG_BOARD_EARLY_INIT_R=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_SUPPORT=y

+ 0 - 2
configs/xilinx_zynqmp_zcu104_revA_defconfig

@@ -4,7 +4,6 @@ CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SPL=y
 CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZCU104 revA"
 CONFIG_ZYNQMP_USB=y
 CONFIG_ZYNQMP_USB=y
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu104-revA"
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu104-revA"
 CONFIG_DEBUG_UART=y
 CONFIG_DEBUG_UART=y
@@ -14,7 +13,6 @@ CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT=y
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_DEVICE=y
 CONFIG_SPL_RAM_DEVICE=y

+ 0 - 2
configs/xilinx_zynqmp_zcu104_revC_defconfig

@@ -4,7 +4,6 @@ CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SPL=y
 CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZCU104 revC"
 CONFIG_ZYNQMP_USB=y
 CONFIG_ZYNQMP_USB=y
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu104-revC"
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu104-revC"
 CONFIG_DEBUG_UART=y
 CONFIG_DEBUG_UART=y
@@ -14,7 +13,6 @@ CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT=y
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_DEVICE=y
 CONFIG_SPL_RAM_DEVICE=y

+ 0 - 2
configs/xilinx_zynqmp_zcu106_revA_defconfig

@@ -4,7 +4,6 @@ CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SPL=y
 CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZCU106 revA"
 CONFIG_ZYNQMP_USB=y
 CONFIG_ZYNQMP_USB=y
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu106-revA"
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu106-revA"
 CONFIG_DEBUG_UART=y
 CONFIG_DEBUG_UART=y
@@ -14,7 +13,6 @@ CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT=y
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_DEVICE=y
 CONFIG_SPL_RAM_DEVICE=y

+ 0 - 2
configs/xilinx_zynqmp_zcu111_revA_defconfig

@@ -4,7 +4,6 @@ CONFIG_ARCH_ZYNQMP=y
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_TEXT_BASE=0x8000000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SPL=y
 CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZCU111"
 CONFIG_ZYNQMP_USB=y
 CONFIG_ZYNQMP_USB=y
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu111-revA"
 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu111-revA"
 CONFIG_DEBUG_UART=y
 CONFIG_DEBUG_UART=y
@@ -14,7 +13,6 @@ CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_LOAD_FIT=y
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_SUPPORT=y
 CONFIG_SPL_RAM_DEVICE=y
 CONFIG_SPL_RAM_DEVICE=y

+ 0 - 1
configs/zynq_cc108_defconfig

@@ -11,7 +11,6 @@ CONFIG_FIT_SIGNATURE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SYS_PROMPT="Zynq> "
 CONFIG_SYS_PROMPT="Zynq> "

+ 1 - 0
configs/zynq_cse_qspi_defconfig

@@ -12,6 +12,7 @@ CONFIG_DISTRO_DEFAULTS=y
 CONFIG_BOOTDELAY=-1
 CONFIG_BOOTDELAY=-1
 # CONFIG_USE_BOOTCOMMAND is not set
 # CONFIG_USE_BOOTCOMMAND is not set
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_ARCH_EARLY_INIT_R is not set
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SYS_PROMPT="Zynq> "
 CONFIG_SYS_PROMPT="Zynq> "

+ 0 - 1
configs/zynq_microzed_defconfig

@@ -10,7 +10,6 @@ CONFIG_FIT_SIGNATURE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SPL_SPI_LOAD=y

+ 0 - 1
configs/zynq_picozed_defconfig

@@ -6,7 +6,6 @@ CONFIG_SPL_STACK_R_ADDR=0x200000
 CONFIG_DEFAULT_DEVICE_TREE="zynq-picozed"
 CONFIG_DEFAULT_DEVICE_TREE="zynq-picozed"
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SYS_PROMPT="Zynq> "
 CONFIG_SYS_PROMPT="Zynq> "

+ 0 - 1
configs/zynq_z_turn_defconfig

@@ -11,7 +11,6 @@ CONFIG_FIT_SIGNATURE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SPL_SPI_LOAD=y

+ 0 - 1
configs/zynq_zc702_defconfig

@@ -13,7 +13,6 @@ CONFIG_FIT_SIGNATURE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SPL_SPI_LOAD=y

+ 0 - 1
configs/zynq_zc706_defconfig

@@ -13,7 +13,6 @@ CONFIG_FIT_SIGNATURE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SPL_SPI_LOAD=y

+ 0 - 1
configs/zynq_zc770_xm010_defconfig

@@ -12,7 +12,6 @@ CONFIG_FIT_SIGNATURE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SPL_SPI_LOAD=y

+ 0 - 1
configs/zynq_zc770_xm011_defconfig

@@ -13,7 +13,6 @@ CONFIG_FIT_SIGNATURE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SYS_PROMPT="Zynq> "
 CONFIG_SYS_PROMPT="Zynq> "

+ 0 - 1
configs/zynq_zc770_xm011_x16_defconfig

@@ -13,7 +13,6 @@ CONFIG_FIT_SIGNATURE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SYS_PROMPT="Zynq> "
 CONFIG_SYS_PROMPT="Zynq> "

+ 0 - 1
configs/zynq_zc770_xm012_defconfig

@@ -12,7 +12,6 @@ CONFIG_FIT_SIGNATURE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SYS_PROMPT="Zynq> "
 CONFIG_SYS_PROMPT="Zynq> "

+ 0 - 1
configs/zynq_zc770_xm013_defconfig

@@ -12,7 +12,6 @@ CONFIG_FIT_SIGNATURE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SPL_SPI_LOAD=y

+ 0 - 1
configs/zynq_zed_defconfig

@@ -11,7 +11,6 @@ CONFIG_FIT_SIGNATURE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SPL_SPI_LOAD=y

+ 0 - 1
configs/zynq_zybo_defconfig

@@ -12,7 +12,6 @@ CONFIG_FIT_SIGNATURE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_IMAGE_FORMAT_LEGACY=y
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
 CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_SPI_LOAD=y
 CONFIG_SPL_SPI_LOAD=y

+ 20 - 16
drivers/ata/sata_ceva.c

@@ -72,6 +72,10 @@
 #define DRV_NAME	"ahci-ceva"
 #define DRV_NAME	"ahci-ceva"
 #define CEVA_FLAG_BROKEN_GEN2	1
 #define CEVA_FLAG_BROKEN_GEN2	1
 
 
+struct ceva_sata_priv {
+	ulong base;
+};
+
 static int ceva_init_sata(ulong mmio)
 static int ceva_init_sata(ulong mmio)
 {
 {
 	ulong tmp;
 	ulong tmp;
@@ -110,18 +114,20 @@ static int ceva_init_sata(ulong mmio)
 	return 0;
 	return 0;
 }
 }
 
 
-static int sata_ceva_probe(struct udevice *dev)
+static int sata_ceva_bind(struct udevice *dev)
 {
 {
-	int ret;
-	struct scsi_platdata *plat = dev_get_uclass_platdata(dev);
+	struct udevice *scsi_dev;
+
+	return ahci_bind_scsi(dev, &scsi_dev);
+}
 
 
-	ceva_init_sata(plat->base);
+static int sata_ceva_probe(struct udevice *dev)
+{
+	struct ceva_sata_priv *priv = dev_get_priv(dev);
 
 
-	ret = ahci_init_one_dm(dev);
-	if (ret)
-		return ret;
+	ceva_init_sata(priv->base);
 
 
-	return ahci_start_ports_dm(dev);
+	return ahci_probe_scsi(dev, priv->base);
 }
 }
 
 
 static const struct udevice_id sata_ceva_ids[] = {
 static const struct udevice_id sata_ceva_ids[] = {
@@ -131,24 +137,22 @@ static const struct udevice_id sata_ceva_ids[] = {
 
 
 static int sata_ceva_ofdata_to_platdata(struct udevice *dev)
 static int sata_ceva_ofdata_to_platdata(struct udevice *dev)
 {
 {
-	struct scsi_platdata *plat = dev_get_uclass_platdata(dev);
+	struct ceva_sata_priv *priv = dev_get_priv(dev);
 
 
-	plat->base = devfdt_get_addr(dev);
-	if (plat->base == FDT_ADDR_T_NONE)
+	priv->base = devfdt_get_addr(dev);
+	if (priv->base == FDT_ADDR_T_NONE)
 		return -EINVAL;
 		return -EINVAL;
 
 
-	/* Hardcode number for ceva sata controller */
-	plat->max_lun = 1; /* Actually two but untested */
-	plat->max_id = 2;
-
 	return 0;
 	return 0;
 }
 }
 
 
 U_BOOT_DRIVER(ceva_host_blk) = {
 U_BOOT_DRIVER(ceva_host_blk) = {
 	.name = "ceva_sata",
 	.name = "ceva_sata",
-	.id = UCLASS_SCSI,
+	.id = UCLASS_AHCI,
 	.of_match = sata_ceva_ids,
 	.of_match = sata_ceva_ids,
+	.bind = sata_ceva_bind,
 	.ops = &scsi_ops,
 	.ops = &scsi_ops,
+	.priv_auto_alloc_size = sizeof(struct ceva_sata_priv),
 	.probe = sata_ceva_probe,
 	.probe = sata_ceva_probe,
 	.ofdata_to_platdata = sata_ceva_ofdata_to_platdata,
 	.ofdata_to_platdata = sata_ceva_ofdata_to_platdata,
 };
 };

+ 2 - 2
drivers/mmc/mmc.c

@@ -679,7 +679,7 @@ static int mmc_complete_op_cond(struct mmc *mmc)
 {
 {
 	struct mmc_cmd cmd;
 	struct mmc_cmd cmd;
 	int timeout = 1000;
 	int timeout = 1000;
-	uint start;
+	ulong start;
 	int err;
 	int err;
 
 
 	mmc->op_cond_pending = 0;
 	mmc->op_cond_pending = 0;
@@ -2611,7 +2611,7 @@ static int mmc_complete_init(struct mmc *mmc)
 int mmc_init(struct mmc *mmc)
 int mmc_init(struct mmc *mmc)
 {
 {
 	int err = 0;
 	int err = 0;
-	__maybe_unused unsigned start;
+	__maybe_unused ulong start;
 #if CONFIG_IS_ENABLED(DM_MMC)
 #if CONFIG_IS_ENABLED(DM_MMC)
 	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
 	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
 
 

+ 61 - 4
drivers/mmc/sdhci.c

@@ -151,7 +151,7 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
 	u32 mask, flags, mode;
 	u32 mask, flags, mode;
 	unsigned int time = 0, start_addr = 0;
 	unsigned int time = 0, start_addr = 0;
 	int mmc_dev = mmc_get_blk_desc(mmc)->devnum;
 	int mmc_dev = mmc_get_blk_desc(mmc)->devnum;
-	unsigned start = get_timer(0);
+	ulong start = get_timer(0);
 
 
 	/* Timeout unit - ms */
 	/* Timeout unit - ms */
 	static unsigned int cmd_timeout = SDHCI_CMD_DEFAULT_TIMEOUT;
 	static unsigned int cmd_timeout = SDHCI_CMD_DEFAULT_TIMEOUT;
@@ -160,7 +160,8 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
 
 
 	/* We shouldn't wait for data inihibit for stop commands, even
 	/* We shouldn't wait for data inihibit for stop commands, even
 	   though they might use busy signaling */
 	   though they might use busy signaling */
-	if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
+	if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION ||
+	    cmd->cmdidx ==  MMC_CMD_SEND_TUNING_BLOCK)
 		mask &= ~SDHCI_DATA_INHIBIT;
 		mask &= ~SDHCI_DATA_INHIBIT;
 
 
 	while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
 	while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
@@ -182,6 +183,9 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
 	sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_STATUS);
 	sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_STATUS);
 
 
 	mask = SDHCI_INT_RESPONSE;
 	mask = SDHCI_INT_RESPONSE;
+	if (cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK)
+		mask = SDHCI_INT_DATA_AVAIL;
+
 	if (!(cmd->resp_type & MMC_RSP_PRESENT))
 	if (!(cmd->resp_type & MMC_RSP_PRESENT))
 		flags = SDHCI_CMD_RESP_NONE;
 		flags = SDHCI_CMD_RESP_NONE;
 	else if (cmd->resp_type & MMC_RSP_136)
 	else if (cmd->resp_type & MMC_RSP_136)
@@ -197,7 +201,7 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
 		flags |= SDHCI_CMD_CRC;
 		flags |= SDHCI_CMD_CRC;
 	if (cmd->resp_type & MMC_RSP_OPCODE)
 	if (cmd->resp_type & MMC_RSP_OPCODE)
 		flags |= SDHCI_CMD_INDEX;
 		flags |= SDHCI_CMD_INDEX;
-	if (data)
+	if (data || cmd->cmdidx ==  MMC_CMD_SEND_TUNING_BLOCK)
 		flags |= SDHCI_CMD_DATA;
 		flags |= SDHCI_CMD_DATA;
 
 
 	/* Set Transfer mode regarding to data flag */
 	/* Set Transfer mode regarding to data flag */
@@ -301,6 +305,24 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
 		return -ECOMM;
 		return -ECOMM;
 }
 }
 
 
+#if defined(CONFIG_DM_MMC) && defined(MMC_SUPPORTS_TUNING)
+static int sdhci_execute_tuning(struct udevice *dev, uint opcode)
+{
+	int err;
+	struct mmc *mmc = mmc_get_mmc_dev(dev);
+	struct sdhci_host *host = mmc->priv;
+
+	debug("%s\n", __func__);
+
+	if (host->ops->platform_execute_tuning) {
+		err = host->ops->platform_execute_tuning(mmc, opcode);
+		if (err)
+			return err;
+		return 0;
+	}
+	return 0;
+}
+#endif
 static int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
 static int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
 {
 {
 	struct sdhci_host *host = mmc->priv;
 	struct sdhci_host *host = mmc->priv;
@@ -325,6 +347,9 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
 	if (clock == 0)
 	if (clock == 0)
 		return 0;
 		return 0;
 
 
+	if (host->ops->set_delay)
+		host->ops->set_delay(host);
+
 	if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
 	if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
 		/*
 		/*
 		 * Check if the Host Controller supports Programmable Clock
 		 * Check if the Host Controller supports Programmable Clock
@@ -439,6 +464,9 @@ static int sdhci_set_ios(struct mmc *mmc)
 	if (mmc->clock != host->clock)
 	if (mmc->clock != host->clock)
 		sdhci_set_clock(mmc, mmc->clock);
 		sdhci_set_clock(mmc, mmc->clock);
 
 
+	if (mmc->clk_disable)
+		sdhci_set_clock(mmc, 0);
+
 	/* Set bus width */
 	/* Set bus width */
 	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
 	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
 	if (mmc->bus_width == 8) {
 	if (mmc->bus_width == 8) {
@@ -514,6 +542,9 @@ int sdhci_probe(struct udevice *dev)
 const struct dm_mmc_ops sdhci_ops = {
 const struct dm_mmc_ops sdhci_ops = {
 	.send_cmd	= sdhci_send_command,
 	.send_cmd	= sdhci_send_command,
 	.set_ios	= sdhci_set_ios,
 	.set_ios	= sdhci_set_ios,
+#ifdef MMC_SUPPORTS_TUNING
+	.execute_tuning	= sdhci_execute_tuning,
+#endif
 };
 };
 #else
 #else
 static const struct mmc_ops sdhci_ops = {
 static const struct mmc_ops sdhci_ops = {
@@ -526,7 +557,7 @@ static const struct mmc_ops sdhci_ops = {
 int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
 int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
 		u32 f_max, u32 f_min)
 		u32 f_max, u32 f_min)
 {
 {
-	u32 caps, caps_1;
+	u32 caps, caps_1 = 0;
 
 
 	caps = sdhci_readl(host, SDHCI_CAPABILITIES);
 	caps = sdhci_readl(host, SDHCI_CAPABILITIES);
 
 
@@ -607,6 +638,32 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
 		cfg->host_caps &= ~MMC_MODE_HS_52MHz;
 		cfg->host_caps &= ~MMC_MODE_HS_52MHz;
 	}
 	}
 
 
+	if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300)
+		caps_1 = sdhci_readl(host, SDHCI_CAPABILITIES_1);
+
+	if (!(cfg->voltages & MMC_VDD_165_195) ||
+	    (host->quirks & SDHCI_QUIRK_NO_1_8_V))
+		caps_1 &= ~(SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 |
+			    SDHCI_SUPPORT_DDR50);
+
+	if (caps_1 & (SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 |
+		      SDHCI_SUPPORT_DDR50))
+		cfg->host_caps |= MMC_CAP(UHS_SDR12) | MMC_CAP(UHS_SDR25);
+
+	if (caps_1 & SDHCI_SUPPORT_SDR104) {
+		cfg->host_caps |= MMC_CAP(UHS_SDR104) | MMC_CAP(UHS_SDR50);
+		/*
+		 * SD3.0: SDR104 is supported so (for eMMC) the caps2
+		 * field can be promoted to support HS200.
+		 */
+		cfg->host_caps |= MMC_CAP(MMC_HS_200);
+	} else if (caps_1 & SDHCI_SUPPORT_SDR50) {
+		cfg->host_caps |= MMC_CAP(UHS_SDR50);
+	}
+
+	if (caps_1 & SDHCI_SUPPORT_DDR50)
+		cfg->host_caps |= MMC_CAP(UHS_DDR50);
+
 	if (host->host_caps)
 	if (host->host_caps)
 		cfg->host_caps |= host->host_caps;
 		cfg->host_caps |= host->host_caps;
 
 

+ 226 - 5
drivers/mmc/zynq_sdhci.c

@@ -9,9 +9,11 @@
 #include <common.h>
 #include <common.h>
 #include <dm.h>
 #include <dm.h>
 #include <fdtdec.h>
 #include <fdtdec.h>
+#include "mmc_private.h"
 #include <linux/libfdt.h>
 #include <linux/libfdt.h>
 #include <malloc.h>
 #include <malloc.h>
 #include <sdhci.h>
 #include <sdhci.h>
+#include <zynqmp_tap_delay.h>
 
 
 DECLARE_GLOBAL_DATA_PTR;
 DECLARE_GLOBAL_DATA_PTR;
 
 
@@ -21,15 +23,212 @@ struct arasan_sdhci_plat {
 	unsigned int f_max;
 	unsigned int f_max;
 };
 };
 
 
+struct arasan_sdhci_priv {
+	struct sdhci_host *host;
+	u8 deviceid;
+	u8 bank;
+	u8 no_1p8;
+	bool pwrseq;
+};
+
+#if defined(CONFIG_ARCH_ZYNQMP)
+static const u8 mode2timing[] = {
+	     [UHS_SDR12] = UHS_SDR12_BUS_SPEED,
+	     [UHS_SDR25] = UHS_SDR25_BUS_SPEED,
+	     [UHS_SDR50] = UHS_SDR50_BUS_SPEED,
+	     [UHS_SDR104] = UHS_SDR104_BUS_SPEED,
+	     [UHS_DDR50] = UHS_DDR50_BUS_SPEED,
+};
+
+#define SDHCI_HOST_CTRL2	0x3E
+#define SDHCI_CTRL2_MODE_MASK	0x7
+#define SDHCI_18V_SIGNAL	0x8
+#define SDHCI_CTRL_EXEC_TUNING	0x0040
+#define SDHCI_CTRL_TUNED_CLK	0x80
+#define SDHCI_TUNING_LOOP_COUNT	40
+
+static void arasan_zynqmp_dll_reset(struct sdhci_host *host, u8 deviceid)
+{
+	u16 clk;
+	unsigned long timeout;
+
+	clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
+	clk &= ~(SDHCI_CLOCK_CARD_EN);
+	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+
+	/* Issue DLL Reset */
+	zynqmp_dll_reset(deviceid);
+
+	/* Wait max 20 ms */
+	timeout = 100;
+	while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
+				& SDHCI_CLOCK_INT_STABLE)) {
+		if (timeout == 0) {
+			dev_err(mmc_dev(host->mmc),
+				": Internal clock never stabilised.\n");
+			return;
+		}
+		timeout--;
+		udelay(1000);
+	}
+
+	clk |= SDHCI_CLOCK_CARD_EN;
+	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+}
+
+static int arasan_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
+{
+	struct mmc_cmd cmd;
+	struct mmc_data data;
+	u32 ctrl;
+	struct sdhci_host *host;
+	struct arasan_sdhci_priv *priv = dev_get_priv(mmc->dev);
+	u8 tuning_loop_counter = SDHCI_TUNING_LOOP_COUNT;
+	u8 deviceid;
+
+	debug("%s\n", __func__);
+
+	host = priv->host;
+	deviceid = priv->deviceid;
+
+	ctrl = sdhci_readw(host, SDHCI_HOST_CTRL2);
+	ctrl |= SDHCI_CTRL_EXEC_TUNING;
+	sdhci_writew(host, ctrl, SDHCI_HOST_CTRL2);
+
+	mdelay(1);
+
+	arasan_zynqmp_dll_reset(host, deviceid);
+
+	sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_INT_ENABLE);
+	sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_SIGNAL_ENABLE);
+
+	do {
+		cmd.cmdidx = opcode;
+		cmd.resp_type = MMC_RSP_R1;
+		cmd.cmdarg = 0;
+
+		data.blocksize = 64;
+		data.blocks = 1;
+		data.flags = MMC_DATA_READ;
+
+		if (tuning_loop_counter-- == 0)
+			break;
+
+		if (cmd.cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200 &&
+		    mmc->bus_width == 8)
+			data.blocksize = 128;
+
+		sdhci_writew(host, SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG,
+						    data.blocksize),
+			     SDHCI_BLOCK_SIZE);
+		sdhci_writew(host, data.blocks, SDHCI_BLOCK_COUNT);
+		sdhci_writew(host, SDHCI_TRNS_READ, SDHCI_TRANSFER_MODE);
+
+		mmc_send_cmd(mmc, &cmd, NULL);
+		ctrl = sdhci_readw(host, SDHCI_HOST_CTRL2);
+
+		if (cmd.cmdidx == MMC_CMD_SEND_TUNING_BLOCK)
+			udelay(1);
+
+	} while (ctrl & SDHCI_CTRL_EXEC_TUNING);
+
+	if (tuning_loop_counter < 0) {
+		ctrl &= ~SDHCI_CTRL_TUNED_CLK;
+		sdhci_writel(host, ctrl, SDHCI_HOST_CTRL2);
+	}
+
+	if (!(ctrl & SDHCI_CTRL_TUNED_CLK)) {
+		printf("%s:Tuning failed\n", __func__);
+		return -1;
+	}
+
+	udelay(1);
+	arasan_zynqmp_dll_reset(host, deviceid);
+
+	/* Enable only interrupts served by the SD controller */
+	sdhci_writel(host, SDHCI_INT_DATA_MASK | SDHCI_INT_CMD_MASK,
+		     SDHCI_INT_ENABLE);
+	/* Mask all sdhci interrupt sources */
+	sdhci_writel(host, 0x0, SDHCI_SIGNAL_ENABLE);
+
+	return 0;
+}
+
+static void arasan_sdhci_set_tapdelay(struct sdhci_host *host)
+{
+	struct arasan_sdhci_priv *priv = dev_get_priv(host->mmc->dev);
+	struct mmc *mmc = (struct mmc *)host->mmc;
+	u8 uhsmode;
+
+	if (!IS_SD(mmc))
+		return;
+
+	uhsmode = mode2timing[mmc->selected_mode];
+
+	if (uhsmode >= UHS_SDR25_BUS_SPEED)
+		arasan_zynqmp_set_tapdelay(priv->deviceid, uhsmode,
+					   priv->bank);
+}
+
+static void arasan_sdhci_set_control_reg(struct sdhci_host *host)
+{
+	struct mmc *mmc = (struct mmc *)host->mmc;
+	u32 reg;
+
+	if (mmc->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
+		reg = sdhci_readw(host, SDHCI_HOST_CTRL2);
+		reg |= SDHCI_18V_SIGNAL;
+		sdhci_writew(host, reg, SDHCI_HOST_CTRL2);
+	}
+
+	if (mmc->selected_mode > SD_HS &&
+	    mmc->selected_mode <= UHS_DDR50) {
+		reg = sdhci_readw(host, SDHCI_HOST_CTRL2);
+		reg &= ~SDHCI_CTRL2_MODE_MASK;
+		switch (mmc->selected_mode) {
+		case UHS_SDR12:
+			reg |= UHS_SDR12_BUS_SPEED;
+			break;
+		case UHS_SDR25:
+			reg |= UHS_SDR25_BUS_SPEED;
+			break;
+		case UHS_SDR50:
+			reg |= UHS_SDR50_BUS_SPEED;
+			break;
+		case UHS_SDR104:
+			reg |= UHS_SDR104_BUS_SPEED;
+			break;
+		case UHS_DDR50:
+			reg |= UHS_DDR50_BUS_SPEED;
+			break;
+		default:
+			break;
+		}
+		sdhci_writew(host, reg, SDHCI_HOST_CTRL2);
+	}
+}
+#endif
+
+#if defined(CONFIG_DM_MMC) && defined(CONFIG_ARCH_ZYNQMP)
+const struct sdhci_ops arasan_ops = {
+	.platform_execute_tuning	= &arasan_sdhci_execute_tuning,
+	.set_delay = &arasan_sdhci_set_tapdelay,
+	.set_control_reg = &arasan_sdhci_set_control_reg,
+};
+#endif
+
 static int arasan_sdhci_probe(struct udevice *dev)
 static int arasan_sdhci_probe(struct udevice *dev)
 {
 {
 	struct arasan_sdhci_plat *plat = dev_get_platdata(dev);
 	struct arasan_sdhci_plat *plat = dev_get_platdata(dev);
 	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
 	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
-	struct sdhci_host *host = dev_get_priv(dev);
+	struct arasan_sdhci_priv *priv = dev_get_priv(dev);
+	struct sdhci_host *host;
 	struct clk clk;
 	struct clk clk;
 	unsigned long clock;
 	unsigned long clock;
 	int ret;
 	int ret;
 
 
+	host = priv->host;
+
 	ret = clk_get_by_index(dev, 0, &clk);
 	ret = clk_get_by_index(dev, 0, &clk);
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(dev, "failed to get clock\n");
 		dev_err(dev, "failed to get clock\n");
@@ -41,6 +240,7 @@ static int arasan_sdhci_probe(struct udevice *dev)
 		dev_err(dev, "failed to get rate\n");
 		dev_err(dev, "failed to get rate\n");
 		return clock;
 		return clock;
 	}
 	}
+
 	debug("%s: CLK %ld\n", __func__, clock);
 	debug("%s: CLK %ld\n", __func__, clock);
 
 
 	ret = clk_enable(&clk);
 	ret = clk_enable(&clk);
@@ -56,6 +256,9 @@ static int arasan_sdhci_probe(struct udevice *dev)
 	host->quirks |= SDHCI_QUIRK_BROKEN_HISPD_MODE;
 	host->quirks |= SDHCI_QUIRK_BROKEN_HISPD_MODE;
 #endif
 #endif
 
 
+	if (priv->no_1p8)
+		host->quirks |= SDHCI_QUIRK_NO_1_8_V;
+
 	host->max_clk = clock;
 	host->max_clk = clock;
 
 
 	ret = sdhci_setup_cfg(&plat->cfg, host, plat->f_max,
 	ret = sdhci_setup_cfg(&plat->cfg, host, plat->f_max,
@@ -73,10 +276,28 @@ static int arasan_sdhci_probe(struct udevice *dev)
 static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev)
 static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev)
 {
 {
 	struct arasan_sdhci_plat *plat = dev_get_platdata(dev);
 	struct arasan_sdhci_plat *plat = dev_get_platdata(dev);
-	struct sdhci_host *host = dev_get_priv(dev);
+	struct arasan_sdhci_priv *priv = dev_get_priv(dev);
+
+	priv->host = calloc(1, sizeof(struct sdhci_host));
+	if (!priv->host)
+		return -1;
 
 
-	host->name = dev->name;
-	host->ioaddr = (void *)devfdt_get_addr(dev);
+	priv->host->name = dev->name;
+	priv->host->ioaddr = (void *)devfdt_get_addr(dev);
+
+	priv->deviceid = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+					"xlnx,device_id", -1);
+	priv->bank = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+				    "xlnx,mio_bank", -1);
+	if (fdt_get_property(gd->fdt_blob, dev_of_offset(dev),
+			     "no-1-8-v", NULL))
+		priv->no_1p8 = 1;
+	else
+		priv->no_1p8 = 0;
+
+#if defined(CONFIG_DM_MMC) && defined(CONFIG_ARCH_ZYNQMP)
+	priv->host->ops = &arasan_ops;
+#endif
 
 
 	plat->f_max = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 	plat->f_max = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 				"max-frequency", CONFIG_ZYNQ_SDHCI_MAX_FREQ);
 				"max-frequency", CONFIG_ZYNQ_SDHCI_MAX_FREQ);
@@ -104,6 +325,6 @@ U_BOOT_DRIVER(arasan_sdhci_drv) = {
 	.ops		= &sdhci_ops,
 	.ops		= &sdhci_ops,
 	.bind		= arasan_sdhci_bind,
 	.bind		= arasan_sdhci_bind,
 	.probe		= arasan_sdhci_probe,
 	.probe		= arasan_sdhci_probe,
-	.priv_auto_alloc_size = sizeof(struct sdhci_host),
+	.priv_auto_alloc_size = sizeof(struct arasan_sdhci_priv),
 	.platdata_auto_alloc_size = sizeof(struct arasan_sdhci_plat),
 	.platdata_auto_alloc_size = sizeof(struct arasan_sdhci_plat),
 };
 };

+ 53 - 1
drivers/mtd/nand/zynq_nand.c

@@ -16,6 +16,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/nand_ecc.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
 
 
 /* The NAND flash driver defines */
 /* The NAND flash driver defines */
 #define ZYNQ_NAND_CMD_PHASE		1
 #define ZYNQ_NAND_CMD_PHASE		1
@@ -83,6 +84,18 @@
 #define ZYNQ_NAND_ECC_BUSY	(1 << 6)	/* ECC block is busy */
 #define ZYNQ_NAND_ECC_BUSY	(1 << 6)	/* ECC block is busy */
 #define ZYNQ_NAND_ECC_MASK	0x00FFFFFF	/* ECC value mask */
 #define ZYNQ_NAND_ECC_MASK	0x00FFFFFF	/* ECC value mask */
 
 
+#define ZYNQ_NAND_ROW_ADDR_CYCL_MASK	0x0F
+#define ZYNQ_NAND_COL_ADDR_CYCL_MASK	0xF0
+
+#define ZYNQ_NAND_MIO_NUM_NAND_8BIT	13
+#define ZYNQ_NAND_MIO_NUM_NAND_16BIT	8
+
+enum zynq_nand_bus_width {
+	NAND_BW_UNKNOWN = -1,
+	NAND_BW_8BIT,
+	NAND_BW_16BIT,
+};
+
 #ifndef NAND_CMD_LOCK_TIGHT
 #ifndef NAND_CMD_LOCK_TIGHT
 #define NAND_CMD_LOCK_TIGHT 0x2c
 #define NAND_CMD_LOCK_TIGHT 0x2c
 #endif
 #endif
@@ -768,6 +781,7 @@ static void zynq_nand_cmd_function(struct mtd_info *mtd, unsigned int command,
 {
 {
 	struct nand_chip *chip = mtd->priv;
 	struct nand_chip *chip = mtd->priv;
 	const struct zynq_nand_command_format *curr_cmd = NULL;
 	const struct zynq_nand_command_format *curr_cmd = NULL;
+	u8 addr_cycles = 0;
 	struct zynq_nand_info *xnand = (struct zynq_nand_info *)chip->priv;
 	struct zynq_nand_info *xnand = (struct zynq_nand_info *)chip->priv;
 	void *cmd_addr;
 	void *cmd_addr;
 	unsigned long cmd_data = 0;
 	unsigned long cmd_data = 0;
@@ -818,8 +832,18 @@ static void zynq_nand_cmd_function(struct mtd_info *mtd, unsigned int command,
 	else
 	else
 		end_cmd = curr_cmd->end_cmd;
 		end_cmd = curr_cmd->end_cmd;
 
 
+	if (command == NAND_CMD_READ0 ||
+	    command == NAND_CMD_SEQIN) {
+		addr_cycles = chip->onfi_params.addr_cycles &
+				ZYNQ_NAND_ROW_ADDR_CYCL_MASK;
+		addr_cycles += ((chip->onfi_params.addr_cycles &
+				ZYNQ_NAND_COL_ADDR_CYCL_MASK) >> 4);
+	} else {
+		addr_cycles = curr_cmd->addr_cycles;
+	}
+
 	cmd_phase_addr = (unsigned long)xnand->nand_base	|
 	cmd_phase_addr = (unsigned long)xnand->nand_base	|
-			(curr_cmd->addr_cycles << ADDR_CYCLES_SHIFT)	|
+			(addr_cycles << ADDR_CYCLES_SHIFT)	|
 			(end_cmd_valid << END_CMD_VALID_SHIFT)		|
 			(end_cmd_valid << END_CMD_VALID_SHIFT)		|
 			(COMMAND_PHASE)					|
 			(COMMAND_PHASE)					|
 			(end_cmd << END_CMD_SHIFT)			|
 			(end_cmd << END_CMD_SHIFT)			|
@@ -1005,6 +1029,23 @@ static int zynq_nand_device_ready(struct mtd_info *mtd)
 	return 0;
 	return 0;
 }
 }
 
 
+static int zynq_nand_check_is_16bit_bw_flash(void)
+{
+	int is_16bit_bw = NAND_BW_UNKNOWN;
+	int mio_num_8bit = 0, mio_num_16bit = 0;
+
+	mio_num_8bit = zynq_slcr_get_mio_pin_status("nand8");
+	if (mio_num_8bit == ZYNQ_NAND_MIO_NUM_NAND_8BIT)
+		is_16bit_bw = NAND_BW_8BIT;
+
+	mio_num_16bit = zynq_slcr_get_mio_pin_status("nand16");
+	if (mio_num_8bit == ZYNQ_NAND_MIO_NUM_NAND_8BIT &&
+	    mio_num_16bit == ZYNQ_NAND_MIO_NUM_NAND_16BIT)
+		is_16bit_bw = NAND_BW_16BIT;
+
+	return is_16bit_bw;
+}
+
 static int zynq_nand_init(struct nand_chip *nand_chip, int devnum)
 static int zynq_nand_init(struct nand_chip *nand_chip, int devnum)
 {
 {
 	struct zynq_nand_info *xnand;
 	struct zynq_nand_info *xnand;
@@ -1016,6 +1057,7 @@ static int zynq_nand_init(struct nand_chip *nand_chip, int devnum)
 	unsigned long ecc_cfg;
 	unsigned long ecc_cfg;
 	int ondie_ecc_enabled = 0;
 	int ondie_ecc_enabled = 0;
 	int err = -1;
 	int err = -1;
+	int is_16bit_bw;
 
 
 	xnand = calloc(1, sizeof(struct zynq_nand_info));
 	xnand = calloc(1, sizeof(struct zynq_nand_info));
 	if (!xnand) {
 	if (!xnand) {
@@ -1045,6 +1087,16 @@ static int zynq_nand_init(struct nand_chip *nand_chip, int devnum)
 	nand_chip->read_buf = zynq_nand_read_buf;
 	nand_chip->read_buf = zynq_nand_read_buf;
 	nand_chip->write_buf = zynq_nand_write_buf;
 	nand_chip->write_buf = zynq_nand_write_buf;
 
 
+	is_16bit_bw = zynq_nand_check_is_16bit_bw_flash();
+	if (is_16bit_bw == NAND_BW_UNKNOWN) {
+		printf("%s: Unable detect NAND based on MIO settings\n",
+		       __func__);
+		goto fail;
+	}
+
+	if (is_16bit_bw == NAND_BW_16BIT)
+		nand_chip->options = NAND_BUSWIDTH_16;
+
 	nand_chip->bbt_options = NAND_BBT_USE_FLASH;
 	nand_chip->bbt_options = NAND_BBT_USE_FLASH;
 
 
 	/* Initialize the NAND flash interface on NAND controller */
 	/* Initialize the NAND flash interface on NAND controller */

+ 1 - 1
drivers/serial/Kconfig

@@ -624,7 +624,7 @@ config STM32_SERIAL
 
 
 config ZYNQ_SERIAL
 config ZYNQ_SERIAL
 	bool "Cadence (Xilinx Zynq) UART support"
 	bool "Cadence (Xilinx Zynq) UART support"
-	depends on DM_SERIAL && (MICROBLAZE || ARCH_ZYNQ || ARCH_ZYNQMP)
+	depends on DM_SERIAL && (MICROBLAZE || ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_ZYNQMP_R5)
 	help
 	help
 	  This driver supports the Cadence UART. It is found e.g. in Xilinx
 	  This driver supports the Cadence UART. It is found e.g. in Xilinx
 	  Zynq/ZynqMP.
 	  Zynq/ZynqMP.

+ 0 - 1
drivers/serial/serial_zynq.c

@@ -14,7 +14,6 @@
 #include <asm/io.h>
 #include <asm/io.h>
 #include <linux/compiler.h>
 #include <linux/compiler.h>
 #include <serial.h>
 #include <serial.h>
-#include <asm/arch/hardware.h>
 
 
 #define ZYNQ_UART_SR_TXEMPTY	(1 << 3) /* TX FIFO empty */
 #define ZYNQ_UART_SR_TXEMPTY	(1 << 3) /* TX FIFO empty */
 #define ZYNQ_UART_SR_TXACTIVE	(1 << 11)  /* TX active */
 #define ZYNQ_UART_SR_TXACTIVE	(1 << 11)  /* TX active */

+ 7 - 0
drivers/timer/Kconfig

@@ -52,6 +52,13 @@ config ATMEL_PIT_TIMER
 	  it is designed to offer maximum accuracy and efficient management,
 	  it is designed to offer maximum accuracy and efficient management,
 	  even for systems with long response time.
 	  even for systems with long response time.
 
 
+config CADENCE_TTC_TIMER
+	bool "Cadence TTC (Triple Timer Counter)"
+	depends on TIMER
+	help
+	  Enables support for the cadence ttc driver. This driver is present
+	  on Xilinx Zynq and ZynqMP SoCs.
+
 config SANDBOX_TIMER
 config SANDBOX_TIMER
 	bool "Sandbox timer support"
 	bool "Sandbox timer support"
 	depends on SANDBOX && TIMER
 	depends on SANDBOX && TIMER

+ 1 - 0
drivers/timer/Makefile

@@ -4,6 +4,7 @@
 
 
 obj-y += timer-uclass.o
 obj-y += timer-uclass.o
 obj-$(CONFIG_ALTERA_TIMER)	+= altera_timer.o
 obj-$(CONFIG_ALTERA_TIMER)	+= altera_timer.o
+obj-$(CONFIG_CADENCE_TTC_TIMER)	+= cadence-ttc.o
 obj-$(CONFIG_SANDBOX_TIMER)	+= sandbox_timer.o
 obj-$(CONFIG_SANDBOX_TIMER)	+= sandbox_timer.o
 obj-$(CONFIG_X86_TSC_TIMER)	+= tsc_timer.o
 obj-$(CONFIG_X86_TSC_TIMER)	+= tsc_timer.o
 obj-$(CONFIG_OMAP_TIMER)	+= omap-timer.o
 obj-$(CONFIG_OMAP_TIMER)	+= omap-timer.o

+ 91 - 0
drivers/timer/cadence-ttc.c

@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 Xilinx, Inc. (Michal Simek)
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <timer.h>
+#include <asm/io.h>
+
+#define CNT_CNTRL_RESET		BIT(4)
+
+struct cadence_ttc_regs {
+	u32 clk_cntrl1; /* 0x0 - Clock Control 1 */
+	u32 clk_cntrl2; /* 0x4 - Clock Control 2 */
+	u32 clk_cntrl3; /* 0x8 - Clock Control 3 */
+	u32 counter_cntrl1; /* 0xC - Counter Control 1 */
+	u32 counter_cntrl2; /* 0x10 - Counter Control 2 */
+	u32 counter_cntrl3; /* 0x14 - Counter Control 3 */
+	u32 counter_val1; /* 0x18 - Counter Control 1 */
+	u32 counter_val2; /* 0x1C - Counter Control 2 */
+	u32 counter_val3; /* 0x20 - Counter Control 3 */
+	u32 reserved[15];
+	u32 interrupt_enable1; /* 0x60 - Interrupt Enable 1 */
+	u32 interrupt_enable2; /* 0x64 - Interrupt Enable 2 */
+	u32 interrupt_enable3; /* 0x68 - Interrupt Enable 3 */
+};
+
+struct cadence_ttc_priv {
+	struct cadence_ttc_regs *regs;
+};
+
+static int cadence_ttc_get_count(struct udevice *dev, u64 *count)
+{
+	struct cadence_ttc_priv *priv = dev_get_priv(dev);
+
+	*count = readl(&priv->regs->counter_val1);
+
+	return 0;
+}
+
+static int cadence_ttc_probe(struct udevice *dev)
+{
+	struct cadence_ttc_priv *priv = dev_get_priv(dev);
+
+	/* Disable interrupts for sure */
+	writel(0, &priv->regs->interrupt_enable1);
+	writel(0, &priv->regs->interrupt_enable2);
+	writel(0, &priv->regs->interrupt_enable3);
+
+	/* Make sure that clocks are configured properly without prescaller */
+	writel(0, &priv->regs->clk_cntrl1);
+	writel(0, &priv->regs->clk_cntrl2);
+	writel(0, &priv->regs->clk_cntrl3);
+
+	/* Reset and enable this counter */
+	writel(CNT_CNTRL_RESET, &priv->regs->counter_cntrl1);
+
+	return 0;
+}
+
+static int cadence_ttc_ofdata_to_platdata(struct udevice *dev)
+{
+	struct cadence_ttc_priv *priv = dev_get_priv(dev);
+
+	priv->regs = map_physmem(devfdt_get_addr(dev),
+				 sizeof(struct cadence_ttc_regs), MAP_NOCACHE);
+
+	return 0;
+}
+
+static const struct timer_ops cadence_ttc_ops = {
+	.get_count = cadence_ttc_get_count,
+};
+
+static const struct udevice_id cadence_ttc_ids[] = {
+	{ .compatible = "cdns,ttc" },
+	{}
+};
+
+U_BOOT_DRIVER(cadence_ttc) = {
+	.name = "cadence_ttc",
+	.id = UCLASS_TIMER,
+	.of_match = cadence_ttc_ids,
+	.ofdata_to_platdata = cadence_ttc_ofdata_to_platdata,
+	.priv_auto_alloc_size = sizeof(struct cadence_ttc_priv),
+	.probe = cadence_ttc_probe,
+	.ops = &cadence_ttc_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};

+ 2 - 2
drivers/watchdog/cdns_wdt.c

@@ -142,13 +142,13 @@ static int cdns_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
 		return -1;
 		return -1;
 	}
 	}
 
 
-	debug("%s: CLK_FREQ %ld, timeout %lld\n", __func__, clk_f, timeout);
-
 	if ((timeout < CDNS_WDT_MIN_TIMEOUT) ||
 	if ((timeout < CDNS_WDT_MIN_TIMEOUT) ||
 	    (timeout > CDNS_WDT_MAX_TIMEOUT)) {
 	    (timeout > CDNS_WDT_MAX_TIMEOUT)) {
 		timeout = priv->timeout;
 		timeout = priv->timeout;
 	}
 	}
 
 
+	debug("%s: CLK_FREQ %ld, timeout %lld\n", __func__, clk_f, timeout);
+
 	if (clk_f <= CDNS_WDT_CLK_75MHZ) {
 	if (clk_f <= CDNS_WDT_CLK_75MHZ) {
 		prescaler = CDNS_WDT_PRESCALE_512;
 		prescaler = CDNS_WDT_PRESCALE_512;
 		ctrl_clksel = CDNS_WDT_PRESCALE_SELECT_512;
 		ctrl_clksel = CDNS_WDT_PRESCALE_SELECT_512;

+ 51 - 0
include/configs/xilinx_zynqmp_r5.h

@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * (C) Copyright 2018 Xilinx, Inc. (Michal Simek)
+ */
+
+#ifndef __CONFIG_ZYNQMP_R5_H
+#define __CONFIG_ZYNQMP_R5_H
+
+#define CONFIG_EXTRA_ENV_SETTINGS
+
+/* CPU clock */
+#define CONFIG_CPU_FREQ_HZ	500000000
+
+/* Serial drivers */
+/* The following table includes the supported baudrates */
+#define CONFIG_SYS_BAUDRATE_TABLE  \
+	{300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400}
+
+# define CONFIG_ENV_SIZE	(128 << 10)
+
+/* Allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+
+/* Boot configuration */
+#define CONFIG_SYS_LOAD_ADDR		0 /* default? */
+
+#define CONFIG_SYS_MAXARGS		32 /* max number of command args */
+
+#define CONFIG_NR_DRAM_BANKS		1
+
+#define CONFIG_SYS_MALLOC_LEN		0x1400000
+
+#define CONFIG_SYS_INIT_RAM_ADDR	0xFFFF0000
+#define CONFIG_SYS_INIT_RAM_SIZE	0x1000
+#define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_INIT_RAM_ADDR + \
+					CONFIG_SYS_INIT_RAM_SIZE - \
+					GENERATED_GBL_DATA_SIZE)
+
+/* Extend size of kernel image for uncompression */
+#define CONFIG_SYS_BOOTM_LEN	(60 * 1024 * 1024)
+
+#define CONFIG_SYS_UBOOT_START	CONFIG_SYS_TEXT_BASE
+
+#define CONFIG_SKIP_LOWLEVEL_INIT
+
+/* 0x0 - 0x40 is used for placing exception vectors */
+#define CONFIG_SYS_MEMTEST_START	0x40
+#define CONFIG_SYS_MEMTEST_END		0x100
+#define CONFIG_SYS_MEMTEST_SCRATCH	0
+
+#endif /* __CONFIG_ZYNQ_ZYNQMP_R5_H */

+ 16 - 0
include/configs/xilinx_zynqmp_zc1275_revB.h

@@ -0,0 +1,16 @@
+/*
+ * Configuration for Xilinx ZynqMP zc1275 RevB
+ *
+ * (C) Copyright 2018 Xilinx, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __CONFIG_ZYNQMP_ZC1275_REVB_H
+#define __CONFIG_ZYNQMP_ZC1275_REVB_H
+
+#define CONFIG_ZYNQ_SDHCI1
+
+#include <configs/xilinx_zynqmp.h>
+
+#endif /* __CONFIG_ZYNQMP_ZC1275_REVB_H */

+ 1 - 0
include/image.h

@@ -268,6 +268,7 @@ enum {
 	IH_TYPE_RKSPI,			/* Rockchip SPI image		*/
 	IH_TYPE_RKSPI,			/* Rockchip SPI image		*/
 	IH_TYPE_ZYNQIMAGE,		/* Xilinx Zynq Boot Image */
 	IH_TYPE_ZYNQIMAGE,		/* Xilinx Zynq Boot Image */
 	IH_TYPE_ZYNQMPIMAGE,		/* Xilinx ZynqMP Boot Image */
 	IH_TYPE_ZYNQMPIMAGE,		/* Xilinx ZynqMP Boot Image */
+	IH_TYPE_ZYNQMPBIF,		/* Xilinx ZynqMP Boot Image (bif) */
 	IH_TYPE_FPGA,			/* FPGA Image */
 	IH_TYPE_FPGA,			/* FPGA Image */
 	IH_TYPE_VYBRIDIMAGE,	/* VYBRID .vyb Image */
 	IH_TYPE_VYBRIDIMAGE,	/* VYBRID .vyb Image */
 	IH_TYPE_TEE,            /* Trusted Execution Environment OS Image */
 	IH_TYPE_TEE,            /* Trusted Execution Environment OS Image */

+ 8 - 0
include/sdhci.h

@@ -166,6 +166,11 @@
 #define  SDHCI_CAN_64BIT	BIT(28)
 #define  SDHCI_CAN_64BIT	BIT(28)
 
 
 #define SDHCI_CAPABILITIES_1	0x44
 #define SDHCI_CAPABILITIES_1	0x44
+#define  SDHCI_SUPPORT_SDR50	0x00000001
+#define  SDHCI_SUPPORT_SDR104	0x00000002
+#define  SDHCI_SUPPORT_DDR50	0x00000004
+#define  SDHCI_USE_SDR50_TUNING	0x00002000
+
 #define  SDHCI_CLOCK_MUL_MASK	0x00FF0000
 #define  SDHCI_CLOCK_MUL_MASK	0x00FF0000
 #define  SDHCI_CLOCK_MUL_SHIFT	16
 #define  SDHCI_CLOCK_MUL_SHIFT	16
 
 
@@ -220,6 +225,7 @@
 #define SDHCI_QUIRK_BROKEN_HISPD_MODE	BIT(5)
 #define SDHCI_QUIRK_BROKEN_HISPD_MODE	BIT(5)
 #define SDHCI_QUIRK_WAIT_SEND_CMD	(1 << 6)
 #define SDHCI_QUIRK_WAIT_SEND_CMD	(1 << 6)
 #define SDHCI_QUIRK_USE_WIDE8		(1 << 8)
 #define SDHCI_QUIRK_USE_WIDE8		(1 << 8)
+#define SDHCI_QUIRK_NO_1_8_V		(1 << 9)
 
 
 /* to make gcc happy */
 /* to make gcc happy */
 struct sdhci_host;
 struct sdhci_host;
@@ -242,6 +248,8 @@ struct sdhci_ops {
 	void	(*set_control_reg)(struct sdhci_host *host);
 	void	(*set_control_reg)(struct sdhci_host *host);
 	void	(*set_ios_post)(struct sdhci_host *host);
 	void	(*set_ios_post)(struct sdhci_host *host);
 	void	(*set_clock)(struct sdhci_host *host, u32 div);
 	void	(*set_clock)(struct sdhci_host *host, u32 div);
+	int (*platform_execute_tuning)(struct mmc *host, u8 opcode);
+	void (*set_delay)(struct sdhci_host *host);
 };
 };
 
 
 struct sdhci_host {
 struct sdhci_host {

+ 19 - 0
include/zynqmp_tap_delay.h

@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Xilinx ZynqMP SoC Tap Delay Programming
+ *
+ * Copyright (C) 2018 Xilinx, Inc.
+ */
+
+#ifndef __ZYNQMP_TAP_DELAY_H__
+#define __ZYNQMP_TAP_DELAY_H__
+
+#ifdef CONFIG_ARCH_ZYNQMP
+void zynqmp_dll_reset(u8 deviceid);
+void arasan_zynqmp_set_tapdelay(u8 device_id, u8 uhsmode, u8 bank);
+#else
+inline void zynqmp_dll_reset(u8 deviceid) {}
+inline void arasan_zynqmp_set_tapdelay(u8 device_id, u8 uhsmode, u8 bank) {}
+#endif
+
+#endif

+ 34 - 55
include/zynqpl.h

@@ -11,23 +11,18 @@
 
 
 #include <xilinx.h>
 #include <xilinx.h>
 
 
-#if defined(CONFIG_FPGA_ZYNQPL)
 extern struct xilinx_fpga_op zynq_op;
 extern struct xilinx_fpga_op zynq_op;
-# define FPGA_ZYNQPL_OPS	&zynq_op
-#else
-# define FPGA_ZYNQPL_OPS	NULL
-#endif
 
 
-#define XILINX_ZYNQ_7007S	0x3
-#define XILINX_ZYNQ_7010	0x2
-#define XILINX_ZYNQ_7012S	0x1c
-#define XILINX_ZYNQ_7014S	0x8
-#define XILINX_ZYNQ_7015	0x1b
-#define XILINX_ZYNQ_7020	0x7
-#define XILINX_ZYNQ_7030	0xc
-#define XILINX_ZYNQ_7035	0x12
-#define XILINX_ZYNQ_7045	0x11
-#define XILINX_ZYNQ_7100	0x16
+#define XILINX_ZYNQ_XC7Z007S	0x3
+#define XILINX_ZYNQ_XC7Z010	0x2
+#define XILINX_ZYNQ_XC7Z012S	0x1c
+#define XILINX_ZYNQ_XC7Z014S	0x8
+#define XILINX_ZYNQ_XC7Z015	0x1b
+#define XILINX_ZYNQ_XC7Z020	0x7
+#define XILINX_ZYNQ_XC7Z030	0xc
+#define XILINX_ZYNQ_XC7Z035	0x12
+#define XILINX_ZYNQ_XC7Z045	0x11
+#define XILINX_ZYNQ_XC7Z100	0x16
 
 
 /* Device Image Sizes */
 /* Device Image Sizes */
 #define XILINX_XC7Z007S_SIZE	16669920/8
 #define XILINX_XC7Z007S_SIZE	16669920/8
@@ -41,45 +36,29 @@ extern struct xilinx_fpga_op zynq_op;
 #define XILINX_XC7Z045_SIZE	106571232/8
 #define XILINX_XC7Z045_SIZE	106571232/8
 #define XILINX_XC7Z100_SIZE	139330784/8
 #define XILINX_XC7Z100_SIZE	139330784/8
 
 
-/* Descriptor Macros */
-#define XILINX_XC7Z007S_DESC(cookie) \
-{ xilinx_zynq, devcfg, XILINX_XC7Z007S_SIZE, NULL, cookie, FPGA_ZYNQPL_OPS, \
-	"7z007s" }
-
-#define XILINX_XC7Z010_DESC(cookie) \
-{ xilinx_zynq, devcfg, XILINX_XC7Z010_SIZE, NULL, cookie, FPGA_ZYNQPL_OPS, \
-	"7z010" }
-
-#define XILINX_XC7Z012S_DESC(cookie) \
-{ xilinx_zynq, devcfg, XILINX_XC7Z012S_SIZE, NULL, cookie, FPGA_ZYNQPL_OPS, \
-	"7z012s" }
-
-#define XILINX_XC7Z014S_DESC(cookie) \
-{ xilinx_zynq, devcfg, XILINX_XC7Z014S_SIZE, NULL, cookie, FPGA_ZYNQPL_OPS, \
-	"7z014s" }
-
-#define XILINX_XC7Z015_DESC(cookie) \
-{ xilinx_zynq, devcfg, XILINX_XC7Z015_SIZE, NULL, cookie, FPGA_ZYNQPL_OPS, \
-	"7z015" }
-
-#define XILINX_XC7Z020_DESC(cookie) \
-{ xilinx_zynq, devcfg, XILINX_XC7Z020_SIZE, NULL, cookie, FPGA_ZYNQPL_OPS, \
-	"7z020" }
-
-#define XILINX_XC7Z030_DESC(cookie) \
-{ xilinx_zynq, devcfg, XILINX_XC7Z030_SIZE, NULL, cookie, FPGA_ZYNQPL_OPS, \
-	"7z030" }
-
-#define XILINX_XC7Z035_DESC(cookie) \
-{ xilinx_zynq, devcfg, XILINX_XC7Z035_SIZE, NULL, cookie, FPGA_ZYNQPL_OPS, \
-	"7z035" }
-
-#define XILINX_XC7Z045_DESC(cookie) \
-{ xilinx_zynq, devcfg, XILINX_XC7Z045_SIZE, NULL, cookie, FPGA_ZYNQPL_OPS, \
-	"7z045" }
-
-#define XILINX_XC7Z100_DESC(cookie) \
-{ xilinx_zynq, devcfg, XILINX_XC7Z100_SIZE, NULL, cookie, FPGA_ZYNQPL_OPS, \
-	"7z100" }
+/* Device Names */
+#define XILINX_XC7Z007S_NAME	"7z007s"
+#define XILINX_XC7Z010_NAME	"7z010"
+#define XILINX_XC7Z012S_NAME	"7z012s"
+#define XILINX_XC7Z014S_NAME	"7z014s"
+#define XILINX_XC7Z015_NAME	"7z015"
+#define XILINX_XC7Z020_NAME	"7z020"
+#define XILINX_XC7Z030_NAME	"7z030"
+#define XILINX_XC7Z035_NAME	"7z035"
+#define XILINX_XC7Z045_NAME	"7z045"
+#define XILINX_XC7Z100_NAME	"7z100"
+
+#if defined(CONFIG_FPGA)
+#define ZYNQ_DESC(name) { \
+	.idcode = XILINX_ZYNQ_XC##name, \
+	.fpga_size = XILINX_XC##name##_SIZE, \
+	.devicename = XILINX_XC##name##_NAME \
+	}
+#else
+#define ZYNQ_DESC(name) { \
+	.idcode = XILINX_ZYNQ_XC##name, \
+	.devicename = XILINX_XC##name##_NAME \
+	}
+#endif
 
 
 #endif /* _ZYNQPL_H_ */
 #endif /* _ZYNQPL_H_ */

+ 1 - 0
tools/Makefile

@@ -111,6 +111,7 @@ dumpimage-mkimage-objs := aisimage.o \
 			ublimage.o \
 			ublimage.o \
 			zynqimage.o \
 			zynqimage.o \
 			zynqmpimage.o \
 			zynqmpimage.o \
+			zynqmpbif.o \
 			$(LIBFDT_OBJS) \
 			$(LIBFDT_OBJS) \
 			gpimage.o \
 			gpimage.o \
 			gpimage-common.o \
 			gpimage-common.o \

+ 1 - 0
tools/imagetool.h

@@ -231,6 +231,7 @@ time_t imagetool_get_source_date(
 
 
 
 
 void pbl_load_uboot(int fd, struct image_tool_params *mparams);
 void pbl_load_uboot(int fd, struct image_tool_params *mparams);
+int zynqmpbif_copy_image(int fd, struct image_tool_params *mparams);
 
 
 #define ___cat(a, b) a ## b
 #define ___cat(a, b) a ## b
 #define __cat(a, b) ___cat(a, b)
 #define __cat(a, b) ___cat(a, b)

+ 7 - 0
tools/mkimage.c

@@ -515,6 +515,13 @@ int main(int argc, char **argv)
 		} else if (params.type == IH_TYPE_PBLIMAGE) {
 		} else if (params.type == IH_TYPE_PBLIMAGE) {
 			/* PBL has special Image format, implements its' own */
 			/* PBL has special Image format, implements its' own */
 			pbl_load_uboot(ifd, &params);
 			pbl_load_uboot(ifd, &params);
+		} else if (params.type == IH_TYPE_ZYNQMPBIF) {
+			/* Image file is meta, walk through actual targets */
+			int ret;
+
+			ret = zynqmpbif_copy_image(ifd, &params);
+			if (ret)
+				return ret;
 		} else {
 		} else {
 			copy_file(ifd, params.datafile, pad_len);
 			copy_file(ifd, params.datafile, pad_len);
 		}
 		}

+ 1008 - 0
tools/zynqmpbif.c

@@ -0,0 +1,1008 @@
+/*
+ * Copyright (C) 2018 Alexander Graf <agraf@suse.de>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include "imagetool.h"
+#include "mkimage.h"
+#include "zynqmpimage.h"
+#include <elf.h>
+#include <image.h>
+
+struct bif_entry {
+	const char *filename;
+	uint64_t flags;
+	uint64_t dest_cpu;
+	uint64_t exp_lvl;
+	uint64_t dest_dev;
+	uint64_t load;
+	uint64_t entry;
+	size_t offset;
+};
+
+enum bif_flag {
+	BIF_FLAG_AESKEYFILE,
+	BIF_FLAG_INIT,
+	BIF_FLAG_UDF_BH,
+	BIF_FLAG_HEADERSIGNATURE,
+	BIF_FLAG_PPKFILE,
+	BIF_FLAG_PSKFILE,
+	BIF_FLAG_SPKFILE,
+	BIF_FLAG_SSKFILE,
+	BIF_FLAG_SPKSIGNATURE,
+	BIF_FLAG_FSBL_CONFIG,
+	BIF_FLAG_AUTH_PARAMS,
+	BIF_FLAG_KEYSRC_ENCRYPTION,
+	BIF_FLAG_PMUFW_IMAGE,
+	BIF_FLAG_BOOTLOADER,
+	BIF_FLAG_TZ,
+	BIF_FLAG_BH_KEY_IV,
+	BIF_FLAG_BH_KEYFILE,
+	BIF_FLAG_PUF_FILE,
+	BIF_FLAG_AARCH32,
+	BIF_FLAG_PART_OWNER_UBOOT,
+
+	/* Internal flags */
+	BIF_FLAG_BIT_FILE,
+	BIF_FLAG_ELF_FILE,
+	BIF_FLAG_BIN_FILE,
+};
+
+struct bif_flags {
+	const char name[32];
+	uint64_t flag;
+	char *(*parse)(char *line, struct bif_entry *bf);
+};
+
+struct bif_file_type {
+	const char name[32];
+	uint32_t header;
+	int (*add)(struct bif_entry *bf);
+};
+
+struct bif_output {
+	size_t data_len;
+	char *data;
+	struct image_header_table *imgheader;
+	struct zynqmp_header *header;
+	struct partition_header *last_part;
+};
+
+struct bif_output bif_output;
+
+static uint32_t zynqmp_csum(void *start, void *end)
+{
+	uint32_t checksum = 0;
+	uint32_t *ptr32 = start;
+
+	while (ptr32 != end) {
+		checksum += le32_to_cpu(*ptr32);
+		ptr32++;
+	}
+
+	return ~checksum;
+}
+
+static int zynqmpbif_check_params(struct image_tool_params *params)
+{
+	if (!params)
+		return 0;
+
+	if (params->addr != 0x0) {
+		fprintf(stderr, "Error: Load Address can not be specified.\n");
+		return -1;
+	}
+
+	if (params->eflag) {
+		fprintf(stderr, "Error: Entry Point can not be specified.\n");
+		return -1;
+	}
+
+	return !(params->lflag || params->dflag);
+}
+
+static int zynqmpbif_check_image_types(uint8_t type)
+{
+	return (type == IH_TYPE_ZYNQMPBIF) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+static char *parse_dest_cpu(char *line, struct bif_entry *bf)
+{
+	uint64_t i;
+
+	for (i = 0; i < ARRAY_SIZE(dest_cpus); i++) {
+		if (!strncmp(line, dest_cpus[i], strlen(dest_cpus[i]))) {
+			bf->dest_cpu = i << PART_ATTR_DEST_CPU_SHIFT;
+			return line + strlen(dest_cpus[i]);
+		}
+
+		/* a5x can also be written as a53 */
+		if (!strncmp(dest_cpus[i], "a5x", 3)) {
+			char a53[] = "a53-X";
+
+			a53[4] = dest_cpus[i][4];
+			if (!strncmp(line, a53, strlen(a53))) {
+				bf->dest_cpu = i << PART_ATTR_DEST_CPU_SHIFT;
+				return line + strlen(a53);
+			}
+		}
+	}
+
+	return line;
+}
+
+static char *parse_el(char *line, struct bif_entry *bf)
+{
+	const char *dest_els[] = { "none", "el-0", "el-1", "el-2", "el-3" };
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(dest_els); i++) {
+		if (!strncmp(line, dest_els[i], strlen(dest_els[i]))) {
+			bf->exp_lvl = i;
+			return line + strlen(dest_els[i]);
+		}
+	}
+
+	return line;
+}
+
+static char *parse_load(char *line, struct bif_entry *bf)
+{
+	char *endptr;
+
+	bf->load = strtoll(line, &endptr, 0);
+
+	return endptr;
+}
+
+static char *parse_entry(char *line, struct bif_entry *bf)
+{
+	char *endptr;
+
+	bf->entry = strtoll(line, &endptr, 0);
+
+	return endptr;
+}
+
+static char *parse_offset(char *line, struct bif_entry *bf)
+{
+	char *endptr;
+
+	bf->offset = strtoll(line, &endptr, 0);
+
+	return endptr;
+}
+
+static char *parse_partition_owner(char *line, struct bif_entry *bf)
+{
+	char *endptr = NULL;
+
+	if (!strncmp(line, "fsbl", 4)) {
+		endptr = line + 4;
+	} else if (!strncmp(line, "uboot", 5)) {
+		bf->flags |= 1ULL << BIF_FLAG_PART_OWNER_UBOOT;
+		endptr = line + 5;
+	} else {
+		printf("ERROR: Unknown partition type '%s'\n", line);
+	}
+
+	return endptr;
+}
+
+static const struct bif_flags bif_flags[] = {
+	{ "fsbl_config", BIF_FLAG_FSBL_CONFIG },
+	{ "trustzone", BIF_FLAG_TZ },
+	{ "pmufw_image", BIF_FLAG_PMUFW_IMAGE },
+	{ "bootloader", BIF_FLAG_BOOTLOADER },
+	{ "destination_cpu=", 0, parse_dest_cpu },
+	{ "exception_level=", 0, parse_el },
+	{ "load=", 0, parse_load },
+	{ "startup=", 0, parse_entry },
+	{ "offset=", 0, parse_offset },
+	{ "partition_owner=", 0, parse_partition_owner },
+};
+
+static char *read_full_file(const char *filename, size_t *size)
+{
+	char *buf, *bufp;
+	struct stat sbuf;
+	int len = 0, r, fd;
+
+	fd = open(filename, O_RDONLY);
+	if (fd < 0)
+		return NULL;
+
+	if (fstat(fd, &sbuf) < 0)
+		return NULL;
+
+	if (size)
+		*size = sbuf.st_size;
+
+	buf = malloc(sbuf.st_size);
+	if (!buf)
+		return NULL;
+
+	bufp = buf;
+	while (len < sbuf.st_size) {
+		r = read(fd, bufp, sbuf.st_size - len);
+		if (r < 0)
+			return NULL;
+		len += r;
+		bufp += r;
+	}
+
+	close(fd);
+
+	return buf;
+}
+
+static int bif_add_blob(const void *data, size_t len, size_t *offset)
+{
+	size_t new_size;
+	uintptr_t header_off;
+	uintptr_t last_part_off;
+	uintptr_t imgheader_off;
+	uintptr_t old_data = (uintptr_t)bif_output.data;
+	void *new_data;
+
+	header_off = (uintptr_t)bif_output.header - old_data;
+	last_part_off = (uintptr_t)bif_output.last_part - old_data;
+	imgheader_off = (uintptr_t)bif_output.imgheader - old_data;
+
+	if (offset && *offset) {
+		/* Pad to a given offset */
+		if (bif_output.data_len > *offset) {
+			printf("Can not pad to offset %zx\n", *offset);
+			return -1;
+		}
+
+		bif_output.data_len = *offset;
+	}
+
+	new_size = ROUND(bif_output.data_len + len, 64);
+	new_data = realloc(bif_output.data, new_size);
+	memcpy(new_data + bif_output.data_len, data, len);
+	if (offset)
+		*offset = bif_output.data_len;
+	bif_output.data = new_data;
+	bif_output.data_len = new_size;
+
+	/* Readjust internal pointers */
+	if (bif_output.header)
+		bif_output.header = new_data + header_off;
+	if (bif_output.last_part)
+		bif_output.last_part = new_data + last_part_off;
+	if (bif_output.imgheader)
+		bif_output.imgheader = new_data + imgheader_off;
+
+	return 0;
+}
+
+static int bif_init(void)
+{
+	struct zynqmp_header header = { { 0 } };
+	int r;
+
+	zynqmpimage_default_header(&header);
+
+	r = bif_add_blob(&header, sizeof(header), NULL);
+	if (r)
+		return r;
+
+	bif_output.header = (void *)bif_output.data;
+
+	return 0;
+}
+
+static int bif_add_pmufw(struct bif_entry *bf, const char *data, size_t len)
+{
+	int r;
+
+	if (bif_output.header->image_offset) {
+		printf("PMUFW expected before bootloader in your .bif file!\n");
+		return -1;
+	}
+
+	r = bif_add_blob(data, len, &bf->offset);
+	if (r)
+		return r;
+
+	len = ROUND(len, 64);
+	bif_output.header->pfw_image_length = cpu_to_le32(len);
+	bif_output.header->total_pfw_image_length = cpu_to_le32(len);
+	bif_output.header->image_offset = cpu_to_le32(bf->offset);
+
+	return 0;
+}
+
+static int bif_add_part(struct bif_entry *bf, const char *data, size_t len)
+{
+	size_t parthdr_offset = 0;
+	struct partition_header parthdr = {
+		.len_enc = cpu_to_le32(len / 4),
+		.len_unenc = cpu_to_le32(len / 4),
+		.len = cpu_to_le32(len / 4),
+		.entry_point = cpu_to_le64(bf->entry),
+		.load_address = cpu_to_le64(bf->load),
+	};
+	int r;
+	uint32_t csum;
+
+	if (bf->flags & (1ULL << BIF_FLAG_PMUFW_IMAGE))
+		return bif_add_pmufw(bf, data, len);
+
+	r = bif_add_blob(data, len, &bf->offset);
+	if (r)
+		return r;
+
+	parthdr.offset = cpu_to_le32(bf->offset / 4);
+
+	if (bf->flags & (1ULL << BIF_FLAG_BOOTLOADER)) {
+		if (bif_output.last_part) {
+			printf("ERROR: Bootloader expected before others\n");
+			return -1;
+		}
+
+		parthdr.offset = cpu_to_le32(bif_output.header->image_offset);
+		parthdr.len = cpu_to_le32((bf->offset + len -
+			bif_output.header->image_offset) / 4);
+		parthdr.len_enc = parthdr.len;
+		parthdr.len_unenc = parthdr.len;
+	}
+
+	/* Normalize EL */
+	bf->exp_lvl = bf->exp_lvl ? bf->exp_lvl - 1 : 3;
+	parthdr.attributes |= bf->exp_lvl << PART_ATTR_TARGET_EL_SHIFT;
+	parthdr.attributes |= bf->dest_dev;
+	parthdr.attributes |= bf->dest_cpu;
+	if (bf->flags & (1ULL << BIF_FLAG_TZ))
+		parthdr.attributes |= PART_ATTR_TZ_SECURE;
+	if (bf->flags & (1ULL << BIF_FLAG_PART_OWNER_UBOOT))
+		parthdr.attributes |= PART_ATTR_PART_OWNER_UBOOT;
+	switch (bf->dest_cpu) {
+	case PART_ATTR_DEST_CPU_NONE:
+	case PART_ATTR_DEST_CPU_A53_0:
+	case PART_ATTR_DEST_CPU_A53_1:
+	case PART_ATTR_DEST_CPU_A53_2:
+	case PART_ATTR_DEST_CPU_A53_3:
+		if (bf->flags & (1ULL << BIF_FLAG_AARCH32))
+			parthdr.attributes |= PART_ATTR_A53_EXEC_AARCH32;
+	}
+
+	csum = zynqmp_csum(&parthdr, &parthdr.checksum);
+	parthdr.checksum = cpu_to_le32(csum);
+
+	r = bif_add_blob(&parthdr, sizeof(parthdr), &parthdr_offset);
+	if (r)
+		return r;
+
+	/* Add image header table if not there yet */
+	if (!bif_output.imgheader) {
+		size_t imghdr_off = 0;
+		struct image_header_table imghdr = {
+			.version = cpu_to_le32(0x01020000),
+			.nr_parts = 0,
+		};
+
+		r = bif_add_blob(&imghdr, sizeof(imghdr), &imghdr_off);
+		if (r)
+			return r;
+
+		bif_output.header->image_header_table_offset = imghdr_off;
+		bif_output.imgheader = (void *)(bif_output.data + imghdr_off);
+	}
+
+	bif_output.imgheader->nr_parts = cpu_to_le32(le32_to_cpu(
+		bif_output.imgheader->nr_parts) + 1);
+
+	/* Link to this partition header */
+	if (bif_output.last_part) {
+		bif_output.last_part->next_partition_offset =
+			cpu_to_le32(parthdr_offset / 4);
+
+		/* Recalc checksum of last_part */
+		csum = zynqmp_csum(bif_output.last_part,
+				   &bif_output.last_part->checksum);
+		bif_output.last_part->checksum = cpu_to_le32(csum);
+	} else {
+		bif_output.imgheader->partition_header_offset =
+			cpu_to_le32(parthdr_offset / 4);
+	}
+	bif_output.last_part = (void *)(bif_output.data + parthdr_offset);
+
+	if (bf->flags & (1ULL << BIF_FLAG_BOOTLOADER)) {
+		bif_output.header->image_load = cpu_to_le32(bf->load);
+		if (!bif_output.header->image_offset)
+			bif_output.header->image_offset =
+				cpu_to_le32(bf->offset);
+		bif_output.header->image_size = cpu_to_le32(len);
+		bif_output.header->image_stored_size = cpu_to_le32(len);
+
+		bif_output.header->image_attributes &= ~HEADER_CPU_SELECT_MASK;
+		switch (bf->dest_cpu) {
+		default:
+		case PART_ATTR_DEST_CPU_A53_0:
+			if (bf->flags & BIF_FLAG_AARCH32)
+				bif_output.header->image_attributes |=
+					HEADER_CPU_SELECT_A53_32BIT;
+			else
+				bif_output.header->image_attributes |=
+					HEADER_CPU_SELECT_A53_64BIT;
+			break;
+		case PART_ATTR_DEST_CPU_R5_0:
+			bif_output.header->image_attributes |=
+				HEADER_CPU_SELECT_R5_SINGLE;
+			break;
+		case PART_ATTR_DEST_CPU_R5_L:
+			bif_output.header->image_attributes |=
+				HEADER_CPU_SELECT_R5_DUAL;
+			break;
+		}
+	}
+
+	return 0;
+}
+
+/* Add .bit bitstream */
+static int bif_add_bit(struct bif_entry *bf)
+{
+	char *bit = read_full_file(bf->filename, NULL);
+	char *bitbin;
+	uint8_t initial_header[] = { 0x00, 0x09, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f,
+				     0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x01, 0x61 };
+	uint16_t len;
+	uint32_t bitlen;
+	int i;
+
+	if (!bit)
+		return -1;
+
+	/* Skip initial header */
+	if (memcmp(bit, initial_header, sizeof(initial_header)))
+		return -1;
+
+	bit += sizeof(initial_header);
+
+	/* Design name */
+	len = be16_to_cpu(*(uint16_t *)bit);
+	bit += sizeof(uint16_t);
+	debug("Design: %s\n", bit);
+	bit += len;
+
+	/* Device identifier */
+	if (*bit != 'b')
+		return -1;
+	bit++;
+	len = be16_to_cpu(*(uint16_t *)bit);
+	bit += sizeof(uint16_t);
+	debug("Device: %s\n", bit);
+	bit += len;
+
+	/* Date */
+	if (*bit != 'c')
+		return -1;
+	bit++;
+	len = be16_to_cpu(*(uint16_t *)bit);
+	bit += sizeof(uint16_t);
+	debug("Date: %s\n", bit);
+	bit += len;
+
+	/* Time */
+	if (*bit != 'd')
+		return -1;
+	bit++;
+	len = be16_to_cpu(*(uint16_t *)bit);
+	bit += sizeof(uint16_t);
+	debug("Time: %s\n", bit);
+	bit += len;
+
+	/* Bitstream length */
+	if (*bit != 'e')
+		return -1;
+	bit++;
+	bitlen = be32_to_cpu(*(uint32_t *)bit);
+	bit += sizeof(uint32_t);
+	bitbin = bit;
+
+	debug("Bitstream Length: 0x%x\n", bitlen);
+	for (i = 0; i < bitlen; i += sizeof(uint32_t)) {
+		uint32_t *bitbin32 = (uint32_t *)&bitbin[i];
+		*bitbin32 = __swab32(*bitbin32);
+	}
+
+	if (!bf->dest_dev)
+		bf->dest_dev = PART_ATTR_DEST_DEVICE_PL;
+
+	bf->load = 0xffffffff;
+	bf->entry = 0;
+
+	bf->flags |= 1ULL << BIF_FLAG_BIT_FILE;
+	return bif_add_part(bf, bit, bitlen);
+}
+
+/* Add .bin bitstream */
+static int bif_add_bin(struct bif_entry *bf)
+{
+	size_t size;
+	char *bin = read_full_file(bf->filename, &size);
+
+	if (!bf->dest_dev)
+		bf->dest_dev = PART_ATTR_DEST_DEVICE_PS;
+
+	bf->flags |= 1ULL << BIF_FLAG_BIN_FILE;
+	return bif_add_part(bf, bin, size);
+}
+
+/* Add elf file */
+static char *elf2flat64(char *elf, size_t *flat_size, size_t *load_addr)
+{
+	Elf64_Ehdr *ehdr;
+	Elf64_Shdr *shdr;
+	size_t min_addr = -1, max_addr = 0;
+	char *flat;
+	int i;
+
+	ehdr = (void *)elf;
+	shdr = (void *)(elf + le64_to_cpu(ehdr->e_shoff));
+
+	/* Look for smallest / biggest address */
+	for (i = 0; i < le64_to_cpu(ehdr->e_shnum); i++, shdr++) {
+		if (!shdr->sh_size || !shdr->sh_addr ||
+		    !(shdr->sh_flags & SHF_ALLOC) ||
+		    (shdr->sh_type == SHT_NOBITS))
+			continue;
+
+		if (le64_to_cpu(shdr->sh_addr) < min_addr)
+			min_addr = le64_to_cpu(shdr->sh_addr);
+		if ((le64_to_cpu(shdr->sh_addr) + le64_to_cpu(shdr->sh_size)) >
+			max_addr)
+			max_addr = le64_to_cpu(shdr->sh_addr) +
+				   le64_to_cpu(shdr->sh_size);
+	}
+
+	*load_addr = min_addr;
+	*flat_size = max_addr - min_addr;
+	flat = calloc(1, *flat_size);
+	if (!flat)
+		return NULL;
+
+	shdr = (void *)(elf + le64_to_cpu(ehdr->e_shoff));
+	for (i = 0; i < le64_to_cpu(ehdr->e_shnum); i++, shdr++) {
+		char *dst = flat + le64_to_cpu(shdr->sh_addr) - min_addr;
+		char *src = elf + le64_to_cpu(shdr->sh_offset);
+
+		if (!shdr->sh_size || !shdr->sh_addr ||
+		    !(shdr->sh_flags & SHF_ALLOC))
+			continue;
+
+		if (shdr->sh_type != SHT_NOBITS)
+			memcpy(dst, src, le64_to_cpu(shdr->sh_size));
+	}
+
+	return flat;
+}
+
+static char *elf2flat32(char *elf, size_t *flat_size, size_t *load_addr)
+{
+	Elf32_Ehdr *ehdr;
+	Elf32_Shdr *shdr;
+	size_t min_addr = -1, max_addr = 0;
+	char *flat;
+	int i;
+
+	ehdr = (void *)elf;
+	shdr = (void *)(elf + le32_to_cpu(ehdr->e_shoff));
+
+	/* Look for smallest / biggest address */
+	for (i = 0; i < le32_to_cpu(ehdr->e_shnum); i++, shdr++) {
+		if (!shdr->sh_size || !shdr->sh_addr ||
+		    !(shdr->sh_flags & SHF_ALLOC) ||
+		    (shdr->sh_type == SHT_NOBITS))
+			continue;
+
+		if (le32_to_cpu(shdr->sh_addr) < min_addr)
+			min_addr = le32_to_cpu(shdr->sh_addr);
+		if ((le32_to_cpu(shdr->sh_addr) + le32_to_cpu(shdr->sh_size)) >
+			max_addr)
+			max_addr = le32_to_cpu(shdr->sh_addr) +
+				   le32_to_cpu(shdr->sh_size);
+	}
+
+	*load_addr = min_addr;
+	*flat_size = max_addr - min_addr;
+	flat = calloc(1, *flat_size);
+	if (!flat)
+		return NULL;
+
+	shdr = (void *)(elf + le32_to_cpu(ehdr->e_shoff));
+	for (i = 0; i < le32_to_cpu(ehdr->e_shnum); i++, shdr++) {
+		char *dst = flat + le32_to_cpu(shdr->sh_addr) - min_addr;
+		char *src = elf + le32_to_cpu(shdr->sh_offset);
+
+		if (!shdr->sh_size || !shdr->sh_addr ||
+		    !(shdr->sh_flags & SHF_ALLOC))
+			continue;
+
+		if (shdr->sh_type != SHT_NOBITS)
+			memcpy(dst, src, le32_to_cpu(shdr->sh_size));
+	}
+
+	return flat;
+}
+
+static int bif_add_elf(struct bif_entry *bf)
+{
+	size_t size;
+	size_t elf_size;
+	char *elf;
+	char *flat;
+	size_t load_addr;
+	Elf32_Ehdr *ehdr32;
+	Elf64_Ehdr *ehdr64;
+
+	elf = read_full_file(bf->filename, &elf_size);
+	if (!elf)
+		return -1;
+
+	ehdr32 = (void *)elf;
+	ehdr64 = (void *)elf;
+
+	switch (ehdr32->e_ident[EI_CLASS]) {
+	case ELFCLASS32:
+		flat = elf2flat32(elf, &size, &load_addr);
+		bf->entry = le32_to_cpu(ehdr32->e_entry);
+		bf->flags |= 1ULL << BIF_FLAG_AARCH32;
+		break;
+	case ELFCLASS64:
+		flat = elf2flat64(elf, &size, &load_addr);
+		bf->entry = le64_to_cpu(ehdr64->e_entry);
+		break;
+	default:
+		printf("Unknown ELF class: %d\n", ehdr32->e_ident[EI_CLASS]);
+		return -1;
+	}
+
+	if (!flat)
+		return -1;
+
+	bf->load = load_addr;
+	if (!bf->dest_dev)
+		bf->dest_dev = PART_ATTR_DEST_DEVICE_PS;
+
+	bf->flags |= 1ULL << BIF_FLAG_ELF_FILE;
+	return bif_add_part(bf, flat, size);
+}
+
+static const struct bif_file_type bif_file_types[] = {
+	{
+		.name = "bitstream (.bit)",
+		.header = 0x00090ff0,
+		.add = bif_add_bit,
+	},
+
+	{
+		.name = "ELF",
+		.header = 0x7f454c46,
+		.add = bif_add_elf,
+	},
+
+	/* Anything else is a .bin file */
+	{
+		.name = ".bin",
+		.add = bif_add_bin,
+	},
+};
+
+static int bif_fsbl_config(struct bif_entry *fsbl_config,
+			   struct bif_entry *entries, int nr_entries)
+{
+	int i;
+	int config_set = 0;
+	struct {
+		const char *name;
+		uint64_t flags;
+		uint64_t dest_cpu;
+	} configs[] = {
+		{ .name = "a5x_x64", .dest_cpu = PART_ATTR_DEST_CPU_A53_0 },
+		{ .name = "a53_x64", .dest_cpu = PART_ATTR_DEST_CPU_A53_0 },
+		{ .name = "a5x_x32", .dest_cpu = PART_ATTR_DEST_CPU_A53_0,
+				     .flags = 1ULL << BIF_FLAG_AARCH32 },
+		{ .name = "a53_x32", .dest_cpu = PART_ATTR_DEST_CPU_A53_0,
+				     .flags = 1ULL << BIF_FLAG_AARCH32 },
+		{ .name = "r5_single", .dest_cpu = PART_ATTR_DEST_CPU_R5_0 },
+		{ .name = "r5_dual", .dest_cpu = PART_ATTR_DEST_CPU_R5_L },
+	};
+
+	/* Set target CPU of bootloader entry */
+	for (i = 0; i < nr_entries; i++) {
+		struct bif_entry *b = &entries[i];
+		const char *config_attr = fsbl_config->filename;
+		int j;
+
+		if (!(b->flags & (1ULL << BIF_FLAG_BOOTLOADER)))
+			continue;
+
+		for (j = 0; j < ARRAY_SIZE(configs); j++) {
+			if (!strncmp(config_attr, configs[j].name,
+				     strlen(configs[j].name))) {
+				b->dest_cpu = configs[j].dest_cpu;
+				b->flags |= configs[j].flags;
+				config_set = 1;
+			}
+		}
+
+		if (!config_set) {
+			printf("ERROR: Unsupported fsbl_config: %s\n",
+			       config_attr);
+			return -1;
+		}
+	}
+
+	if (!config_set) {
+		printf("ERROR: fsbl_config w/o bootloader\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static const struct bif_flags *find_flag(char *str)
+{
+	const struct bif_flags *bf;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(bif_flags); i++) {
+		bf = &bif_flags[i];
+		if (!strncmp(bf->name, str, strlen(bf->name)))
+			return bf;
+	}
+
+	printf("ERROR: Flag '%s' not found\n", str);
+
+	return NULL;
+}
+
+static int bif_open_file(struct bif_entry *entry)
+{
+	int fd = open(entry->filename, O_RDONLY);
+
+	if (fd < 0)
+		printf("Error opening file %s\n", entry->filename);
+
+	return fd;
+}
+
+static const struct bif_file_type *get_file_type(struct bif_entry *entry)
+{
+	int fd = bif_open_file(entry);
+	uint32_t header;
+	int i;
+
+	if (fd < 0)
+		return NULL;
+
+	if (read(fd, &header, sizeof(header)) != sizeof(header)) {
+		printf("Error reading file %s", entry->filename);
+		return NULL;
+	}
+
+	close(fd);
+
+	for (i = 0; i < ARRAY_SIZE(bif_file_types); i++) {
+		const struct bif_file_type *type = &bif_file_types[i];
+
+		if (!type->header)
+			return type;
+		if (type->header == be32_to_cpu(header))
+			return type;
+	}
+
+	return NULL;
+}
+
+#define NEXT_CHAR(str, chr) ({		\
+	char *_n = strchr(str, chr);	\
+	if (!_n)			\
+		goto err;		\
+	_n;				\
+})
+
+static char *skip_whitespace(char *str)
+{
+	while (*str == ' ' || *str == '\t')
+		str++;
+
+	return str;
+}
+
+int zynqmpbif_copy_image(int outfd, struct image_tool_params *mparams)
+{
+	char *bif, *bifp, *bifpn;
+	char *line;
+	struct bif_entry entries[32] = { { 0 } };
+	int nr_entries = 0;
+	struct bif_entry *entry = entries;
+	size_t len;
+	int i;
+	uint32_t csum;
+	int bldr = -1;
+
+	bif_init();
+
+	/* Read .bif input file */
+	bif = read_full_file(mparams->datafile, NULL);
+	if (!bif)
+		goto err;
+
+	/* Interpret .bif file */
+	bifp = bif;
+
+	/* A bif description starts with a { section */
+	bifp = NEXT_CHAR(bifp, '{') + 1;
+
+	/* Read every line */
+	while (1) {
+		bifpn = NEXT_CHAR(bifp, '\n');
+
+		if (bifpn[-1] == '\r')
+			bifpn[-1] = '\0';
+
+		*bifpn = '\0';
+		bifpn++;
+		line = bifp;
+
+		line = skip_whitespace(line);
+
+		/* Attributes? */
+		if (*line == '[') {
+			line++;
+			while (1) {
+				const struct bif_flags *bf;
+
+				line = skip_whitespace(line);
+				bf = find_flag(line);
+				if (!bf)
+					goto err;
+
+				line += strlen(bf->name);
+				if (bf->parse)
+					line = bf->parse(line, entry);
+				else
+					entry->flags |= 1ULL << bf->flag;
+
+				if (!line)
+					goto err;
+
+				/* Go to next attribute or quit */
+				if (*line == ']') {
+					line++;
+					break;
+				}
+				if (*line == ',')
+					line++;
+			}
+		}
+
+		/* End of image description */
+		if (*line == '}')
+			break;
+
+		if (*line) {
+			line = skip_whitespace(line);
+			entry->filename = line;
+			nr_entries++;
+			entry++;
+		}
+
+		/* Use next line */
+		bifp = bifpn;
+	}
+
+	for (i = 0; i < nr_entries; i++) {
+		debug("Entry flags=%#lx name=%s\n", entries[i].flags,
+		      entries[i].filename);
+	}
+
+	/*
+	 * Some entries are actually configuration option for other ones,
+	 * let's apply them in an intermediate step.
+	 */
+	for (i = 0; i < nr_entries; i++) {
+		struct bif_entry *entry = &entries[i];
+
+		if (entry->flags & (1ULL << BIF_FLAG_FSBL_CONFIG))
+			if (bif_fsbl_config(entry, entries, nr_entries))
+				goto err;
+	}
+
+	/* Make sure PMUFW comes before bootloader */
+	for (i = 0; i < nr_entries; i++) {
+		struct bif_entry *entry = &entries[i];
+
+		if (entry->flags & (1ULL << BIF_FLAG_BOOTLOADER))
+			bldr = i;
+		if (entry->flags & (1ULL << BIF_FLAG_PMUFW_IMAGE)) {
+			if (bldr >= 0) {
+				struct bif_entry tmp = *entry;
+
+				*entry = entries[bldr];
+				entries[bldr] = tmp;
+			}
+		}
+	}
+
+	for (i = 0; i < nr_entries; i++) {
+		struct bif_entry *entry = &entries[i];
+		const struct bif_file_type *type;
+		int r;
+
+		if (entry->flags & (1ULL << BIF_FLAG_FSBL_CONFIG))
+			continue;
+
+		type = get_file_type(entry);
+		if (!type)
+			goto err;
+
+		debug("type=%s file=%s\n", type->name, entry->filename);
+		r = type->add(entry);
+		if (r)
+			goto err;
+	}
+
+	/* Calculate checksums */
+	csum = zynqmp_csum(&bif_output.header->width_detection,
+			   &bif_output.header->checksum);
+	bif_output.header->checksum = cpu_to_le32(csum);
+
+	if (bif_output.imgheader) {
+		csum = zynqmp_csum(bif_output.imgheader,
+				   &bif_output.imgheader->checksum);
+		bif_output.imgheader->checksum = cpu_to_le32(csum);
+	}
+
+	/* Write headers and components */
+	if (lseek(outfd, 0, SEEK_SET) != 0)
+		goto err;
+
+	len = bif_output.data_len;
+	bifp = bif_output.data;
+	while (len) {
+		int r;
+
+		r = write(outfd, bifp, len);
+		if (r < 0)
+			goto err;
+		len -= r;
+		bifp += r;
+	}
+
+	return 0;
+
+err:
+	fprintf(stderr, "Error: Failed to create image.\n");
+	return -1;
+}
+
+/* Needs to be stubbed out so we can print after creation */
+static void zynqmpbif_set_header(void *ptr, struct stat *sbuf, int ifd,
+				 struct image_tool_params *params)
+{
+}
+
+static struct zynqmp_header zynqmpimage_header;
+
+U_BOOT_IMAGE_TYPE(
+	zynqmpbif,
+	"Xilinx ZynqMP Boot Image support (bif)",
+	sizeof(struct zynqmp_header),
+	(void *)&zynqmpimage_header,
+	zynqmpbif_check_params,
+	NULL,
+	zynqmpimage_print_header,
+	zynqmpbif_set_header,
+	NULL,
+	zynqmpbif_check_image_types,
+	NULL,
+	NULL
+);

+ 100 - 42
tools/zynqmpimage.c

@@ -6,6 +6,7 @@
  * The following Boot Header format/structures and values are defined in the
  * The following Boot Header format/structures and values are defined in the
  * following documents:
  * following documents:
  *   * ug1085 ZynqMP TRM doc v1.4 (Chapter 11, Table 11-4)
  *   * ug1085 ZynqMP TRM doc v1.4 (Chapter 11, Table 11-4)
+ *   * ug1137 ZynqMP Software Developer Guide v6.0 (Chapter 16)
  *
  *
  * Expected Header Size = 0x9C0
  * Expected Header Size = 0x9C0
  * Forced as 'little' endian, 32-bit words
  * Forced as 'little' endian, 32-bit words
@@ -56,47 +57,9 @@
 
 
 #include "imagetool.h"
 #include "imagetool.h"
 #include "mkimage.h"
 #include "mkimage.h"
+#include "zynqmpimage.h"
 #include <image.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 struct zynqmp_header zynqmpimage_header;
 static void *dynamic_header;
 static void *dynamic_header;
 static FILE *fpmu;
 static FILE *fpmu;
@@ -123,7 +86,7 @@ static uint32_t zynqmpimage_checksum(struct zynqmp_header *ptr)
 	return cpu_to_le32(checksum);
 	return cpu_to_le32(checksum);
 }
 }
 
 
-static void zynqmpimage_default_header(struct zynqmp_header *ptr)
+void zynqmpimage_default_header(struct zynqmp_header *ptr)
 {
 {
 	int i;
 	int i;
 
 
@@ -131,7 +94,7 @@ static void zynqmpimage_default_header(struct zynqmp_header *ptr)
 		return;
 		return;
 
 
 	ptr->width_detection = HEADER_WIDTHDETECTION;
 	ptr->width_detection = HEADER_WIDTHDETECTION;
-	ptr->image_attributes = 0x800;
+	ptr->image_attributes = HEADER_CPU_SELECT_A53_64BIT;
 	ptr->image_identifier = HEADER_IMAGEIDENTIFIER;
 	ptr->image_identifier = HEADER_IMAGEIDENTIFIER;
 	ptr->encryption = cpu_to_le32(ENCRYPTION_NONE);
 	ptr->encryption = cpu_to_le32(ENCRYPTION_NONE);
 
 
@@ -172,7 +135,81 @@ static int zynqmpimage_verify_header(unsigned char *ptr, int image_size,
 	return 0;
 	return 0;
 }
 }
 
 
-static void zynqmpimage_print_header(const void *ptr)
+static void print_partition(const void *ptr, const struct partition_header *ph)
+{
+	uint32_t attr = le32_to_cpu(ph->attributes);
+	unsigned long len = le32_to_cpu(ph->len) * 4;
+	const char *part_owner;
+	const char *dest_devs[0x8] = {
+		"none", "PS", "PL", "PMU", "unknown", "unknown", "unknown",
+		"unknown"
+	};
+
+	switch (attr & PART_ATTR_PART_OWNER_MASK) {
+	case PART_ATTR_PART_OWNER_FSBL:
+		part_owner = "FSBL";
+		break;
+	case PART_ATTR_PART_OWNER_UBOOT:
+		part_owner = "U-Boot";
+		break;
+	default:
+		part_owner = "Unknown";
+		break;
+	}
+
+	printf("%s payload on CPU %s (%s):\n", part_owner,
+	       dest_cpus[(attr & PART_ATTR_DEST_CPU_MASK) >> 8],
+	       dest_devs[(attr & PART_ATTR_DEST_DEVICE_MASK) >> 4]);
+
+	printf("    Offset     : 0x%08x\n", le32_to_cpu(ph->offset) * 4);
+	printf("    Size       : %lu (0x%lx) bytes\n", len, len);
+	printf("    Load       : 0x%08llx",
+	       (unsigned long long)le64_to_cpu(ph->load_address));
+	if (ph->load_address != ph->entry_point)
+		printf(" (entry=0x%08llx)\n",
+		       (unsigned long long)le64_to_cpu(ph->entry_point));
+	else
+		printf("\n");
+	printf("    Attributes : ");
+
+	if (attr & PART_ATTR_VEC_LOCATION)
+		printf("vec ");
+
+	if (attr & PART_ATTR_ENCRYPTED)
+		printf("encrypted ");
+
+	switch (attr & PART_ATTR_CHECKSUM_MASK) {
+	case PART_ATTR_CHECKSUM_MD5:
+		printf("md5 ");
+		break;
+	case PART_ATTR_CHECKSUM_SHA2:
+		printf("sha2 ");
+		break;
+	case PART_ATTR_CHECKSUM_SHA3:
+		printf("sha3 ");
+		break;
+	}
+
+	if (attr & PART_ATTR_BIG_ENDIAN)
+		printf("BigEndian ");
+
+	if (attr & PART_ATTR_RSA_SIG)
+		printf("RSA ");
+
+	if (attr & PART_ATTR_A53_EXEC_AARCH32)
+		printf("AArch32 ");
+
+	if (attr & PART_ATTR_TARGET_EL_MASK)
+		printf("EL%d ", (attr & PART_ATTR_TARGET_EL_MASK) >> 1);
+
+	if (attr & PART_ATTR_TZ_SECURE)
+		printf("secure ");
+	printf("\n");
+
+	printf("    Checksum   : 0x%08x\n", le32_to_cpu(ph->checksum));
+}
+
+void zynqmpimage_print_header(const void *ptr)
 {
 {
 	struct zynqmp_header *zynqhdr = (struct zynqmp_header *)ptr;
 	struct zynqmp_header *zynqhdr = (struct zynqmp_header *)ptr;
 	int i;
 	int i;
@@ -212,6 +249,27 @@ static void zynqmpimage_print_header(const void *ptr)
 		       le32_to_cpu(zynqhdr->register_init[i].data));
 		       le32_to_cpu(zynqhdr->register_init[i].data));
 	}
 	}
 
 
+	if (zynqhdr->image_header_table_offset) {
+		struct image_header_table *iht = (void *)ptr +
+			zynqhdr->image_header_table_offset;
+		struct partition_header *ph;
+		uint32_t ph_offset;
+		uint32_t next;
+		int i;
+
+		ph_offset = le32_to_cpu(iht->partition_header_offset) * 4;
+		ph = (void *)ptr + ph_offset;
+		for (i = 0; i < le32_to_cpu(iht->nr_parts); i++) {
+			next = le32_to_cpu(ph->next_partition_offset) * 4;
+
+			/* Partition 0 is the base image itself */
+			if (i)
+				print_partition(ptr, ph);
+
+			ph = (void *)ptr + next;
+		}
+	}
+
 	free(dynamic_header);
 	free(dynamic_header);
 }
 }
 
 

+ 139 - 0
tools/zynqmpimage.h

@@ -0,0 +1,139 @@
+/*
+ * 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 doc v1.4 (Chapter 11, Table 11-4)
+ *   * ug1137 ZynqMP Software Developer Guide v6.0 (Chapter 16)
+ */
+
+#ifndef _ZYNQMPIMAGE_H_
+#define _ZYNQMPIMAGE_H_
+
+#include <stdint.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))
+#define HEADER_CPU_SELECT_MASK		(0x3 << 10)
+#define HEADER_CPU_SELECT_R5_SINGLE	(0x0 << 10)
+#define HEADER_CPU_SELECT_A53_32BIT	(0x1 << 10)
+#define HEADER_CPU_SELECT_A53_64BIT	(0x2 << 10)
+#define HEADER_CPU_SELECT_R5_DUAL	(0x3 << 10)
+
+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 image_header_table {
+	uint32_t version;		  /* 0x00 */
+	uint32_t nr_parts;		  /* 0x04 */
+	uint32_t partition_header_offset; /* 0x08, divided by 4 */
+	uint32_t image_header_offset;	  /* 0x0c, divided by 4 */
+	uint32_t auth_certificate_offset; /* 0x10 */
+	uint32_t boot_device;		  /* 0x14 */
+	uint32_t __reserved1[9];	  /* 0x18 - 0x38 */
+	uint32_t checksum;		  /* 0x3c */
+};
+
+#define PART_ATTR_VEC_LOCATION		0x800000
+#define PART_ATTR_BS_BLOCK_SIZE_MASK	0x700000
+#define     PART_ATTR_BS_BLOCK_SIZE_DEFAULT	0x000000
+#define     PART_ATTR_BS_BLOCK_SIZE_8MB		0x400000
+#define PART_ATTR_BIG_ENDIAN		0x040000
+#define PART_ATTR_PART_OWNER_MASK	0x030000
+#define     PART_ATTR_PART_OWNER_FSBL		0x000000
+#define     PART_ATTR_PART_OWNER_UBOOT		0x010000
+#define PART_ATTR_RSA_SIG		0x008000
+#define PART_ATTR_CHECKSUM_MASK		0x007000
+#define    PART_ATTR_CHECKSUM_NONE		0x000000
+#define    PART_ATTR_CHECKSUM_MD5		0x001000
+#define    PART_ATTR_CHECKSUM_SHA2		0x002000
+#define    PART_ATTR_CHECKSUM_SHA3		0x003000
+#define PART_ATTR_DEST_CPU_SHIFT	8
+#define PART_ATTR_DEST_CPU_MASK		0x000f00
+#define    PART_ATTR_DEST_CPU_NONE		0x000000
+#define    PART_ATTR_DEST_CPU_A53_0		0x000100
+#define    PART_ATTR_DEST_CPU_A53_1		0x000200
+#define    PART_ATTR_DEST_CPU_A53_2		0x000300
+#define    PART_ATTR_DEST_CPU_A53_3		0x000400
+#define    PART_ATTR_DEST_CPU_R5_0		0x000500
+#define    PART_ATTR_DEST_CPU_R5_1		0x000600
+#define    PART_ATTR_DEST_CPU_R5_L		0x000700
+#define    PART_ATTR_DEST_CPU_PMU		0x000800
+#define PART_ATTR_ENCRYPTED		0x000080
+#define PART_ATTR_DEST_DEVICE_SHIFT	4
+#define PART_ATTR_DEST_DEVICE_MASK	0x000070
+#define    PART_ATTR_DEST_DEVICE_NONE		0x000000
+#define    PART_ATTR_DEST_DEVICE_PS		0x000010
+#define    PART_ATTR_DEST_DEVICE_PL		0x000020
+#define    PART_ATTR_DEST_DEVICE_PMU		0x000030
+#define    PART_ATTR_DEST_DEVICE_XIP		0x000040
+#define PART_ATTR_A53_EXEC_AARCH32	0x000008
+#define PART_ATTR_TARGET_EL_SHIFT	1
+#define PART_ATTR_TARGET_EL_MASK	0x000006
+#define PART_ATTR_TZ_SECURE		0x000001
+
+static const char *dest_cpus[0x10] = {
+	"none", "a5x-0", "a5x-1", "a5x-2", "a5x-3", "r5-0", "r5-1",
+	"r5-lockstep", "pmu", "unknown", "unknown", "unknown", "unknown",
+	"unknown", "unknown", "unknown"
+};
+
+struct partition_header {
+	uint32_t len_enc;		  /* 0x00, divided by 4 */
+	uint32_t len_unenc;		  /* 0x04, divided by 4 */
+	uint32_t len;			  /* 0x08, divided by 4 */
+	uint32_t next_partition_offset;   /* 0x0c */
+	uint64_t entry_point;		  /* 0x10 */
+	uint64_t load_address;		  /* 0x18 */
+	uint32_t offset;		  /* 0x20, divided by 4 */
+	uint32_t attributes;		  /* 0x24 */
+	uint32_t __reserved1;		  /* 0x28 */
+	uint32_t checksum_offset;	  /* 0x2c, divided by 4 */
+	uint32_t __reserved2;		  /* 0x30 */
+	uint32_t auth_certificate_offset; /* 0x34 */
+	uint32_t __reserved3;		  /* 0x38 */
+	uint32_t checksum;		  /* 0x3c */
+};
+
+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[19]; /* 0x4c */
+	uint32_t image_header_table_offset; /* 0x98 */
+	uint32_t __reserved2[7]; /* 0x9c */
+	struct zynqmp_reginit register_init[HEADER_REGINITS]; /* 0xb8 */
+	uint32_t __reserved4[66]; /* 0x9c0 */
+};
+
+void zynqmpimage_default_header(struct zynqmp_header *ptr);
+void zynqmpimage_print_header(const void *ptr);
+
+#endif /* _ZYNQMPIMAGE_H_ */