aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS11
-rw-r--r--arch/arm/Kconfig11
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/cpu/armv8/zynqmp/cpu.c84
-rw-r--r--arch/arm/dts/Makefile3
-rw-r--r--arch/arm/dts/zynqmp-clk.dtsi2
-rw-r--r--arch/arm/dts/zynqmp-r5.dts73
-rw-r--r--arch/arm/dts/zynqmp-zc1275-revB.dts79
-rw-r--r--arch/arm/dts/zynqmp-zcu100-revC.dts1
-rw-r--r--arch/arm/include/asm/arch-zynqmp/sys_proto.h2
-rw-r--r--arch/arm/mach-zynq/cpu.c85
-rw-r--r--arch/arm/mach-zynq/spl.c11
-rw-r--r--arch/arm/mach-zynqmp-r5/Kconfig27
-rw-r--r--arch/arm/mach-zynqmp-r5/Makefile3
-rw-r--r--arch/arm/mach-zynqmp-r5/cpu.c37
-rw-r--r--board/xilinx/zynq/board.c80
-rw-r--r--board/xilinx/zynqmp/Makefile2
-rw-r--r--board/xilinx/zynqmp/tap_delays.c229
-rw-r--r--board/xilinx/zynqmp/zynqmp-zc1275-revB/psu_init_gpl.c523
-rw-r--r--board/xilinx/zynqmp/zynqmp-zcu100-revC/psu_init_gpl.c2
-rw-r--r--board/xilinx/zynqmp/zynqmp.c80
-rw-r--r--board/xilinx/zynqmp_r5/MAINTAINERS7
-rw-r--r--board/xilinx/zynqmp_r5/Makefile6
-rw-r--r--board/xilinx/zynqmp_r5/board.c25
-rw-r--r--common/image.c1
-rw-r--r--configs/microblaze-generic_defconfig4
-rw-r--r--configs/syzygy_hub_defconfig1
-rw-r--r--configs/topic_miami_defconfig1
-rw-r--r--configs/topic_miamilite_defconfig1
-rw-r--r--configs/topic_miamiplus_defconfig1
-rw-r--r--configs/xilinx_zynqmp_r5_defconfig16
-rw-r--r--configs/xilinx_zynqmp_zc1232_revA_defconfig2
-rw-r--r--configs/xilinx_zynqmp_zc1254_revA_defconfig2
-rw-r--r--configs/xilinx_zynqmp_zc1275_revA_defconfig2
-rw-r--r--configs/xilinx_zynqmp_zc1275_revB_defconfig53
-rw-r--r--configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig2
-rw-r--r--configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig2
-rw-r--r--configs/xilinx_zynqmp_zc1751_xm017_dc3_defconfig2
-rw-r--r--configs/xilinx_zynqmp_zc1751_xm018_dc4_defconfig2
-rw-r--r--configs/xilinx_zynqmp_zc1751_xm019_dc5_defconfig2
-rw-r--r--configs/xilinx_zynqmp_zcu100_revC_defconfig4
-rw-r--r--configs/xilinx_zynqmp_zcu102_rev1_0_defconfig4
-rw-r--r--configs/xilinx_zynqmp_zcu102_revA_defconfig2
-rw-r--r--configs/xilinx_zynqmp_zcu102_revB_defconfig2
-rw-r--r--configs/xilinx_zynqmp_zcu104_revA_defconfig2
-rw-r--r--configs/xilinx_zynqmp_zcu104_revC_defconfig2
-rw-r--r--configs/xilinx_zynqmp_zcu106_revA_defconfig2
-rw-r--r--configs/xilinx_zynqmp_zcu111_revA_defconfig2
-rw-r--r--configs/zynq_cc108_defconfig1
-rw-r--r--configs/zynq_cse_qspi_defconfig1
-rw-r--r--configs/zynq_microzed_defconfig1
-rw-r--r--configs/zynq_picozed_defconfig1
-rw-r--r--configs/zynq_z_turn_defconfig1
-rw-r--r--configs/zynq_zc702_defconfig1
-rw-r--r--configs/zynq_zc706_defconfig1
-rw-r--r--configs/zynq_zc770_xm010_defconfig1
-rw-r--r--configs/zynq_zc770_xm011_defconfig1
-rw-r--r--configs/zynq_zc770_xm011_x16_defconfig1
-rw-r--r--configs/zynq_zc770_xm012_defconfig1
-rw-r--r--configs/zynq_zc770_xm013_defconfig1
-rw-r--r--configs/zynq_zed_defconfig1
-rw-r--r--configs/zynq_zybo_defconfig1
-rw-r--r--drivers/ata/sata_ceva.c36
-rw-r--r--drivers/mmc/mmc.c4
-rw-r--r--drivers/mmc/sdhci.c65
-rw-r--r--drivers/mmc/zynq_sdhci.c231
-rw-r--r--drivers/mtd/nand/zynq_nand.c54
-rw-r--r--drivers/serial/Kconfig2
-rw-r--r--drivers/serial/serial_zynq.c1
-rw-r--r--drivers/timer/Kconfig7
-rw-r--r--drivers/timer/Makefile1
-rw-r--r--drivers/timer/cadence-ttc.c91
-rw-r--r--drivers/watchdog/cdns_wdt.c4
-rw-r--r--include/configs/xilinx_zynqmp_r5.h51
-rw-r--r--include/configs/xilinx_zynqmp_zc1275_revB.h16
-rw-r--r--include/image.h1
-rw-r--r--include/sdhci.h8
-rw-r--r--include/zynqmp_tap_delay.h19
-rw-r--r--include/zynqpl.h89
-rw-r--r--tools/Makefile1
-rw-r--r--tools/imagetool.h1
-rw-r--r--tools/mkimage.c7
-rw-r--r--tools/zynqmpbif.c1008
-rw-r--r--tools/zynqmpimage.c142
-rw-r--r--tools/zynqmpimage.h139
85 files changed, 3176 insertions, 314 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 60d4adf..5670917 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -274,7 +274,7 @@ ARM ZYNQMP
M: Michal Simek <michal.simek@xilinx.com>
S: Maintained
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/fpga/zynqpl.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/spi/zynq_qspi.c
F: drivers/spi/zynq_spi.c
+F: drivers/timer/cadence-ttc.c
F: drivers/usb/host/ehci-zynq.c
F: drivers/watchdog/cdns_wdt.c
F: include/zynqmppl.h
-F: tools/zynqimage.c
+F: tools/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
M: Simon Glass <sjg@chromium.org>
S: Maintained
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 2bbb86c..c9d6e0a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -821,6 +821,15 @@ config ARCH_ZYNQ
imply CMD_CLK
imply FAT_WRITE
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
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-zynqmp-r5/Kconfig"
+
source "arch/arm/cpu/armv7/Kconfig"
source "arch/arm/cpu/armv8/zynqmp/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 3b1dd85..4d6d276 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -76,6 +76,7 @@ machine-$(CONFIG_ARCH_STM32MP) += stm32mp
machine-$(CONFIG_TEGRA) += tegra
machine-$(CONFIG_ARCH_UNIPHIER) += uniphier
machine-$(CONFIG_ARCH_ZYNQ) += zynq
+machine-$(CONFIG_ARCH_ZYNQMP_R5) += zynqmp-r5
machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
diff --git a/arch/arm/cpu/armv8/zynqmp/cpu.c b/arch/arm/cpu/armv8/zynqmp/cpu.c
index eb0db46..2748d65 100644
--- a/arch/arm/cpu/armv8/zynqmp/cpu.c
+++ b/arch/arm/cpu/armv8/zynqmp/cpu.c
@@ -15,16 +15,28 @@
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)
- {
- .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
+
+#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,
.phys = 0x80000000UL,
@@ -32,8 +44,7 @@ static struct mm_region zynqmp_mem_map[] = {
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
- },
- {
+ }, {
.virt = 0xf8000000UL,
.phys = 0xf8000000UL,
.size = 0x07e00000UL,
@@ -41,42 +52,51 @@ static struct mm_region zynqmp_mem_map[] = {
PTE_BLOCK_NON_SHARE |
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,
.phys = 0x400000000UL,
.size = 0x400000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
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,
.phys = 0x1000000000UL,
.size = 0xf000000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
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;
u64 get_page_table_size(void)
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 3426a98..f94940a 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -157,11 +157,14 @@ dtb-$(CONFIG_ARCH_ZYNQMP) += \
zynqmp-zc1232-revA.dtb \
zynqmp-zc1254-revA.dtb \
zynqmp-zc1275-revA.dtb \
+ zynqmp-zc1275-revB.dtb \
zynqmp-zc1751-xm015-dc1.dtb \
zynqmp-zc1751-xm016-dc2.dtb \
zynqmp-zc1751-xm017-dc3.dtb \
zynqmp-zc1751-xm018-dc4.dtb \
zynqmp-zc1751-xm019-dc5.dtb
+dtb-$(CONFIG_ARCH_ZYNQMP_R5) += \
+ zynqmp-r5.dtb
dtb-$(CONFIG_AM33XX) += am335x-boneblack.dtb am335x-bone.dtb \
am335x-draco.dtb \
am335x-evm.dtb \
diff --git a/arch/arm/dts/zynqmp-clk.dtsi b/arch/arm/dts/zynqmp-clk.dtsi
index a8664e8..a795efd 100644
--- a/arch/arm/dts/zynqmp-clk.dtsi
+++ b/arch/arm/dts/zynqmp-clk.dtsi
@@ -219,7 +219,7 @@
};
&watchdog0 {
- clocks = <&clk250>;
+ clocks = <&clk100>;
};
&xilinx_drm {
diff --git a/arch/arm/dts/zynqmp-r5.dts b/arch/arm/dts/zynqmp-r5.dts
new file mode 100644
index 0000000..a72172e
--- /dev/null
+++ b/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>;
+ };
+ };
+};
diff --git a/arch/arm/dts/zynqmp-zc1275-revB.dts b/arch/arm/dts/zynqmp-zc1275-revB.dts
new file mode 100644
index 0000000..f694fae
--- /dev/null
+++ b/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>;
+};
diff --git a/arch/arm/dts/zynqmp-zcu100-revC.dts b/arch/arm/dts/zynqmp-zcu100-revC.dts
index 9114f98..bcd9c39 100644
--- a/arch/arm/dts/zynqmp-zcu100-revC.dts
+++ b/arch/arm/dts/zynqmp-zcu100-revC.dts
@@ -332,6 +332,7 @@
&watchdog0 {
status = "okay";
+ reset-on-timeout;
};
&xilinx_ams {
diff --git a/arch/arm/include/asm/arch-zynqmp/sys_proto.h b/arch/arm/include/asm/arch-zynqmp/sys_proto.h
index d1db4c3..6056bc6 100644
--- a/arch/arm/include/asm/arch-zynqmp/sys_proto.h
+++ b/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);
void initialize_tcm(bool mode);
-
+void mem_map_fill(void);
int chip_id(unsigned char id);
#endif /* _ASM_ARCH_SYS_PROTO_H */
diff --git a/arch/arm/mach-zynq/cpu.c b/arch/arm/mach-zynq/cpu.c
index df4eec8..a3422cd 100644
--- a/arch/arm/mach-zynq/cpu.c
+++ b/arch/arm/mach-zynq/cpu.c
@@ -4,14 +4,45 @@
* Copyright (C) 2012 Xilinx, Inc. All rights reserved.
*/
#include <common.h>
+#include <zynqpl.h>
#include <asm/io.h>
#include <asm/arch/clk.h>
-#include <asm/arch/sys_proto.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_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)
{
zynq_slcr_unlock();
@@ -59,3 +90,55 @@ void enable_caches(void)
dcache_enable();
}
#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
diff --git a/arch/arm/mach-zynq/spl.c b/arch/arm/mach-zynq/spl.c
index 48e3d8d..83297d6 100644
--- a/arch/arm/mach-zynq/spl.c
+++ b/arch/arm/mach-zynq/spl.c
@@ -17,11 +17,12 @@ void board_init_f(ulong dummy)
ps7_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
diff --git a/arch/arm/mach-zynqmp-r5/Kconfig b/arch/arm/mach-zynqmp-r5/Kconfig
new file mode 100644
index 0000000..5e01754
--- /dev/null
+++ b/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
diff --git a/arch/arm/mach-zynqmp-r5/Makefile b/arch/arm/mach-zynqmp-r5/Makefile
new file mode 100644
index 0000000..0d39e97
--- /dev/null
+++ b/arch/arm/mach-zynqmp-r5/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += cpu.o
diff --git a/arch/arm/mach-zynqmp-r5/cpu.c b/arch/arm/mach-zynqmp-r5/cpu.c
new file mode 100644
index 0000000..98f63e3
--- /dev/null
+++ b/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)
+ ;
+}
diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c
index fe36cf7..e4f86d1 100644
--- a/board/xilinx/zynq/board.c
+++ b/board/xilinx/zynq/board.c
@@ -13,27 +13,9 @@
#include <zynqpl.h>
#include <asm/arch/hardware.h>
#include <asm/arch/sys_proto.h>
-#include <asm/arch/ps7_init_gpl.h>
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)
static struct udevice *watchdog_dev;
#endif
@@ -52,46 +34,6 @@ int board_early_init_f(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 (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) {
puts("Watchdog: Not found!\n");
@@ -101,12 +43,6 @@ int board_init(void)
}
# 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;
}
@@ -136,22 +72,6 @@ int board_late_init(void)
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)
{
#if defined(CONFIG_ZYNQ_GEM_EEPROM_ADDR) && \
diff --git a/board/xilinx/zynqmp/Makefile b/board/xilinx/zynqmp/Makefile
index 65bcb59..05ccd25 100644
--- a/board/xilinx/zynqmp/Makefile
+++ b/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)
endif
+obj-$(CONFIG_MMC_SDHCI_ZYNQ) += tap_delays.o
+
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_CMD_ZYNQMP) += cmds.o
endif
diff --git a/board/xilinx/zynqmp/tap_delays.c b/board/xilinx/zynqmp/tap_delays.c
new file mode 100644
index 0000000..c3ae357
--- /dev/null
+++ b/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);
+}
diff --git a/board/xilinx/zynqmp/zynqmp-zc1275-revB/psu_init_gpl.c b/board/xilinx/zynqmp/zynqmp-zc1275-revB/psu_init_gpl.c
new file mode 100644
index 0000000..54cc828
--- /dev/null
+++ b/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;
+}
diff --git a/board/xilinx/zynqmp/zynqmp-zcu100-revC/psu_init_gpl.c b/board/xilinx/zynqmp/zynqmp-zcu100-revC/psu_init_gpl.c
index d83dcd1..e1fdaba 100644
--- a/board/xilinx/zynqmp/zynqmp-zcu100-revC/psu_init_gpl.c
+++ b/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)
{
- psu_mask_write(0xFD1A0100, 0x0001007CU, 0x00000000U);
+ psu_mask_write(0xFD1A0100, 0x0001807CU, 0x00000000U);
psu_mask_write(0xFF5E0238, 0x001A0000U, 0x00000000U);
psu_mask_write(0xFF5E023C, 0x0093C018U, 0x00000000U);
psu_mask_write(0xFF5E023C, 0x00000FC0U, 0x00000000U);
diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index ce7c050..57c0d93 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -9,11 +9,13 @@
#include <ahci.h>
#include <scsi.h>
#include <malloc.h>
+#include <wdt.h>
#include <asm/arch/clk.h>
#include <asm/arch/hardware.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/psu_init_gpl.h>
#include <asm/io.h>
+#include <dm/uclass.h>
#include <usb.h>
#include <dwc3-uboot.h>
#include <zynqmppl.h>
@@ -22,6 +24,10 @@
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) && \
!defined(CONFIG_SPL_BUILD)
static xilinx_desc zynqmppl = XILINX_ZYNQMP_DESC;
@@ -281,6 +287,11 @@ int board_early_init_f(void)
ret = psu_init();
#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;
}
@@ -299,9 +310,40 @@ int board_init(void)
}
#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;
}
+#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)
{
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)
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)
@@ -374,6 +424,18 @@ int dram_init(void)
return 0;
}
#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)
{
gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
@@ -391,6 +453,7 @@ int board_late_init(void)
{
u32 reg = 0;
u8 bootmode;
+ int env_targets_len = 0;
const char *mode;
char *new_targets;
char *env_targets;
@@ -467,14 +530,13 @@ int board_late_init(void)
* and default 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);
diff --git a/board/xilinx/zynqmp_r5/MAINTAINERS b/board/xilinx/zynqmp_r5/MAINTAINERS
new file mode 100644
index 0000000..ac26764
--- /dev/null
+++ b/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_*
diff --git a/board/xilinx/zynqmp_r5/Makefile b/board/xilinx/zynqmp_r5/Makefile
new file mode 100644
index 0000000..c5a3e3d
--- /dev/null
+++ b/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
diff --git a/board/xilinx/zynqmp_r5/board.c b/board/xilinx/zynqmp_r5/board.c
new file mode 100644
index 0000000..70fb202
--- /dev/null
+++ b/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;
+}
diff --git a/common/image.c b/common/image.c
index 1493c3a..214ac33 100644
--- a/common/image.c
+++ b/common/image.c
@@ -159,6 +159,7 @@ static const table_entry_t uimage_type[] = {
{ IH_TYPE_VYBRIDIMAGE, "vybridimage", "Vybrid Boot Image", },
{ IH_TYPE_ZYNQIMAGE, "zynqimage", "Xilinx Zynq 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_TEE, "tee", "Trusted Execution Environment Image",},
{ IH_TYPE_FIRMWARE_IVT, "firmware_ivt", "Firmware with HABv4 IVT" },
diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig
index 2cbabf6..6ba7022 100644
--- a/configs/microblaze-generic_defconfig
+++ b/configs/microblaze-generic_defconfig
@@ -35,10 +35,6 @@ CONFIG_CMD_TFTPPUT=y
CONFIG_CMD_MII=y
CONFIG_CMD_PING=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_OF_EMBED=y
CONFIG_NETCONSOLE=y
diff --git a/configs/syzygy_hub_defconfig b/configs/syzygy_hub_defconfig
index aef21a8..4ceff11 100644
--- a/configs/syzygy_hub_defconfig
+++ b/configs/syzygy_hub_defconfig
@@ -13,7 +13,6 @@ CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_IMAGE_FORMAT_LEGACY=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="Zynq> "
diff --git a/configs/topic_miami_defconfig b/configs/topic_miami_defconfig
index 1619df3..7ea09ac 100644
--- a/configs/topic_miami_defconfig
+++ b/configs/topic_miami_defconfig
@@ -11,7 +11,6 @@ CONFIG_DEBUG_UART=y
CONFIG_DISTRO_DEFAULTS=y
CONFIG_BOOTDELAY=0
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_STACK_R=y
CONFIG_SPL_SPI_LOAD=y
CONFIG_SYS_PROMPT="zynq-uboot> "
diff --git a/configs/topic_miamilite_defconfig b/configs/topic_miamilite_defconfig
index 5e55ebd..d30843c 100644
--- a/configs/topic_miamilite_defconfig
+++ b/configs/topic_miamilite_defconfig
@@ -11,7 +11,6 @@ CONFIG_DEBUG_UART=y
CONFIG_DISTRO_DEFAULTS=y
CONFIG_BOOTDELAY=0
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_STACK_R=y
CONFIG_SPL_SPI_LOAD=y
CONFIG_SYS_PROMPT="zynq-uboot> "
diff --git a/configs/topic_miamiplus_defconfig b/configs/topic_miamiplus_defconfig
index 39cdb22..9710d95 100644
--- a/configs/topic_miamiplus_defconfig
+++ b/configs/topic_miamiplus_defconfig
@@ -11,7 +11,6 @@ CONFIG_DEBUG_UART=y
CONFIG_DISTRO_DEFAULTS=y
CONFIG_BOOTDELAY=0
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_STACK_R=y
CONFIG_SPL_SPI_LOAD=y
CONFIG_SYS_PROMPT="zynq-uboot> "
diff --git a/configs/xilinx_zynqmp_r5_defconfig b/configs/xilinx_zynqmp_r5_defconfig
new file mode 100644
index 0000000..4671524
--- /dev/null
+++ b/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
diff --git a/configs/xilinx_zynqmp_zc1232_revA_defconfig b/configs/xilinx_zynqmp_zc1232_revA_defconfig
index f4e680d..70dc870 100644
--- a/configs/xilinx_zynqmp_zc1232_revA_defconfig
+++ b/configs/xilinx_zynqmp_zc1232_revA_defconfig
@@ -4,7 +4,6 @@ CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
# CONFIG_SPL_LIBDISK_SUPPORT is not set
CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZC1232 revA"
# CONFIG_SPL_FAT_SUPPORT is not set
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1232-revA"
CONFIG_DEBUG_UART=y
@@ -13,7 +12,6 @@ CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_RAM_SUPPORT=y
CONFIG_SPL_RAM_DEVICE=y
diff --git a/configs/xilinx_zynqmp_zc1254_revA_defconfig b/configs/xilinx_zynqmp_zc1254_revA_defconfig
index 77b4ada..09de18d 100644
--- a/configs/xilinx_zynqmp_zc1254_revA_defconfig
+++ b/configs/xilinx_zynqmp_zc1254_revA_defconfig
@@ -4,7 +4,6 @@ CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
# CONFIG_SPL_LIBDISK_SUPPORT is not set
CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZC1254 revA"
# CONFIG_SPL_FAT_SUPPORT is not set
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1254-revA"
CONFIG_DEBUG_UART=y
@@ -13,7 +12,6 @@ CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_RAM_SUPPORT=y
CONFIG_SPL_RAM_DEVICE=y
diff --git a/configs/xilinx_zynqmp_zc1275_revA_defconfig b/configs/xilinx_zynqmp_zc1275_revA_defconfig
index 17c1be8..a7e79f5 100644
--- a/configs/xilinx_zynqmp_zc1275_revA_defconfig
+++ b/configs/xilinx_zynqmp_zc1275_revA_defconfig
@@ -4,7 +4,6 @@ CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
# CONFIG_SPL_LIBDISK_SUPPORT is not set
CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZC1275 revA"
# CONFIG_SPL_FAT_SUPPORT is not set
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1275-revA"
CONFIG_DEBUG_UART=y
@@ -13,7 +12,6 @@ CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_RAM_SUPPORT=y
CONFIG_SPL_RAM_DEVICE=y
diff --git a/configs/xilinx_zynqmp_zc1275_revB_defconfig b/configs/xilinx_zynqmp_zc1275_revB_defconfig
new file mode 100644
index 0000000..823b503
--- /dev/null
+++ b/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
diff --git a/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig b/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig
index 0272eea..3aa3930 100644
--- a/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig
+++ b/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig
@@ -4,7 +4,6 @@ CONFIG_ARCH_ZYNQMP=y
CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZC1751 xm015 dc1"
CONFIG_ZYNQMP_USB=y
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm015-dc1"
CONFIG_DEBUG_UART=y
@@ -14,7 +13,6 @@ CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_RAM_SUPPORT=y
diff --git a/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig b/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig
index 2758bfb..1bd52ab 100644
--- a/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig
+++ b/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig
@@ -5,7 +5,6 @@ CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
# CONFIG_SPL_LIBDISK_SUPPORT is not set
CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZC1751 xm016 dc2"
# CONFIG_SPL_FAT_SUPPORT is not set
CONFIG_ZYNQMP_USB=y
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm016-dc2"
@@ -15,7 +14,6 @@ CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_RAM_SUPPORT=y
diff --git a/configs/xilinx_zynqmp_zc1751_xm017_dc3_defconfig b/configs/xilinx_zynqmp_zc1751_xm017_dc3_defconfig
index a92361e..e1e7d22 100644
--- a/configs/xilinx_zynqmp_zc1751_xm017_dc3_defconfig
+++ b/configs/xilinx_zynqmp_zc1751_xm017_dc3_defconfig
@@ -4,7 +4,6 @@ CONFIG_ARCH_ZYNQMP=y
CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZC1751 xm017 dc3"
CONFIG_ZYNQMP_USB=y
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm017-dc3"
CONFIG_DEBUG_UART=y
@@ -14,7 +13,6 @@ CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_RAM_SUPPORT=y
CONFIG_SPL_RAM_DEVICE=y
diff --git a/configs/xilinx_zynqmp_zc1751_xm018_dc4_defconfig b/configs/xilinx_zynqmp_zc1751_xm018_dc4_defconfig
index 9a6a1e5..7e3f2c2 100644
--- a/configs/xilinx_zynqmp_zc1751_xm018_dc4_defconfig
+++ b/configs/xilinx_zynqmp_zc1751_xm018_dc4_defconfig
@@ -3,7 +3,6 @@ CONFIG_ARCH_ZYNQMP=y
CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZC1751 xm018 dc4"
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm018-dc4"
CONFIG_DEBUG_UART=y
CONFIG_DISTRO_DEFAULTS=y
@@ -11,7 +10,6 @@ CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_RAM_SUPPORT=y
diff --git a/configs/xilinx_zynqmp_zc1751_xm019_dc5_defconfig b/configs/xilinx_zynqmp_zc1751_xm019_dc5_defconfig
index 8d6b353..dad2105 100644
--- a/configs/xilinx_zynqmp_zc1751_xm019_dc5_defconfig
+++ b/configs/xilinx_zynqmp_zc1751_xm019_dc5_defconfig
@@ -4,7 +4,6 @@ CONFIG_ARCH_ZYNQMP=y
CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZC1751 xm019 dc5"
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm019-dc5"
CONFIG_DEBUG_UART=y
CONFIG_DISTRO_DEFAULTS=y
@@ -12,7 +11,6 @@ CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_RAM_SUPPORT=y
diff --git a/configs/xilinx_zynqmp_zcu100_revC_defconfig b/configs/xilinx_zynqmp_zcu100_revC_defconfig
index 87b7941..3dd6ae9 100644
--- a/configs/xilinx_zynqmp_zcu100_revC_defconfig
+++ b/configs/xilinx_zynqmp_zcu100_revC_defconfig
@@ -4,7 +4,6 @@ CONFIG_ARCH_ZYNQMP=y
CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZCU100 RevC"
CONFIG_ZYNQ_SDHCI_MAX_FREQ=15000000
CONFIG_ZYNQMP_USB=y
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu100-revC"
@@ -14,7 +13,6 @@ CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_RAM_SUPPORT=y
CONFIG_SPL_RAM_DEVICE=y
@@ -80,5 +78,7 @@ CONFIG_USB_ULPI=y
CONFIG_USB_STORAGE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_WDT=y
+CONFIG_WDT_CDNS=y
CONFIG_OF_LIBFDT_OVERLAY=y
CONFIG_EFI_LOADER_BOUNCE_BUFFER=y
diff --git a/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig b/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig
index 68da9dc..0ddec99 100644
--- a/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig
+++ b/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig
@@ -4,7 +4,6 @@ CONFIG_ARCH_ZYNQMP=y
CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZCU102 rev1.0"
CONFIG_ZYNQMP_USB=y
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102-rev1.0"
CONFIG_DEBUG_UART=y
@@ -14,7 +13,6 @@ CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_RAM_SUPPORT=y
@@ -62,6 +60,8 @@ CONFIG_ZYNQ_I2C1=y
CONFIG_MISC=y
CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0x20
CONFIG_DM_MMC=y
+CONFIG_MMC_IO_VOLTAGE=y
+CONFIG_MMC_UHS_SUPPORT=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_ZYNQ=y
CONFIG_SPI_FLASH=y
diff --git a/configs/xilinx_zynqmp_zcu102_revA_defconfig b/configs/xilinx_zynqmp_zcu102_revA_defconfig
index 2adba61..94dc62a 100644
--- a/configs/xilinx_zynqmp_zcu102_revA_defconfig
+++ b/configs/xilinx_zynqmp_zcu102_revA_defconfig
@@ -4,7 +4,6 @@ CONFIG_ARCH_ZYNQMP=y
CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZCU102 revA"
CONFIG_ZYNQMP_USB=y
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102-revA"
CONFIG_DEBUG_UART=y
@@ -14,7 +13,6 @@ CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_RAM_SUPPORT=y
diff --git a/configs/xilinx_zynqmp_zcu102_revB_defconfig b/configs/xilinx_zynqmp_zcu102_revB_defconfig
index 2310fa8..8889f19 100644
--- a/configs/xilinx_zynqmp_zcu102_revB_defconfig
+++ b/configs/xilinx_zynqmp_zcu102_revB_defconfig
@@ -4,7 +4,6 @@ CONFIG_ARCH_ZYNQMP=y
CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZCU102 revB"
CONFIG_ZYNQMP_USB=y
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102-revB"
CONFIG_DEBUG_UART=y
@@ -14,7 +13,6 @@ CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_RAM_SUPPORT=y
diff --git a/configs/xilinx_zynqmp_zcu104_revA_defconfig b/configs/xilinx_zynqmp_zcu104_revA_defconfig
index 817f789..3d3d941 100644
--- a/configs/xilinx_zynqmp_zcu104_revA_defconfig
+++ b/configs/xilinx_zynqmp_zcu104_revA_defconfig
@@ -4,7 +4,6 @@ CONFIG_ARCH_ZYNQMP=y
CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZCU104 revA"
CONFIG_ZYNQMP_USB=y
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu104-revA"
CONFIG_DEBUG_UART=y
@@ -14,7 +13,6 @@ CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_RAM_SUPPORT=y
CONFIG_SPL_RAM_DEVICE=y
diff --git a/configs/xilinx_zynqmp_zcu104_revC_defconfig b/configs/xilinx_zynqmp_zcu104_revC_defconfig
index 4be3d83..7c22d7f 100644
--- a/configs/xilinx_zynqmp_zcu104_revC_defconfig
+++ b/configs/xilinx_zynqmp_zcu104_revC_defconfig
@@ -4,7 +4,6 @@ CONFIG_ARCH_ZYNQMP=y
CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZCU104 revC"
CONFIG_ZYNQMP_USB=y
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu104-revC"
CONFIG_DEBUG_UART=y
@@ -14,7 +13,6 @@ CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_RAM_SUPPORT=y
CONFIG_SPL_RAM_DEVICE=y
diff --git a/configs/xilinx_zynqmp_zcu106_revA_defconfig b/configs/xilinx_zynqmp_zcu106_revA_defconfig
index 8c9a60d..017940e 100644
--- a/configs/xilinx_zynqmp_zcu106_revA_defconfig
+++ b/configs/xilinx_zynqmp_zcu106_revA_defconfig
@@ -4,7 +4,6 @@ CONFIG_ARCH_ZYNQMP=y
CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZCU106 revA"
CONFIG_ZYNQMP_USB=y
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu106-revA"
CONFIG_DEBUG_UART=y
@@ -14,7 +13,6 @@ CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_RAM_SUPPORT=y
CONFIG_SPL_RAM_DEVICE=y
diff --git a/configs/xilinx_zynqmp_zcu111_revA_defconfig b/configs/xilinx_zynqmp_zcu111_revA_defconfig
index cb4542c..028a7b5 100644
--- a/configs/xilinx_zynqmp_zcu111_revA_defconfig
+++ b/configs/xilinx_zynqmp_zcu111_revA_defconfig
@@ -4,7 +4,6 @@ CONFIG_ARCH_ZYNQMP=y
CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_SPL=y
-CONFIG_IDENT_STRING=" Xilinx ZynqMP ZCU111"
CONFIG_ZYNQMP_USB=y
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu111-revA"
CONFIG_DEBUG_UART=y
@@ -14,7 +13,6 @@ CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_RAM_SUPPORT=y
CONFIG_SPL_RAM_DEVICE=y
diff --git a/configs/zynq_cc108_defconfig b/configs/zynq_cc108_defconfig
index f161cf8..7689a21 100644
--- a/configs/zynq_cc108_defconfig
+++ b/configs/zynq_cc108_defconfig
@@ -11,7 +11,6 @@ CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_IMAGE_FORMAT_LEGACY=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_STACK_R=y
CONFIG_SPL_SPI_LOAD=y
CONFIG_SYS_PROMPT="Zynq> "
diff --git a/configs/zynq_cse_qspi_defconfig b/configs/zynq_cse_qspi_defconfig
index 9d4c79f..88049d2 100644
--- a/configs/zynq_cse_qspi_defconfig
+++ b/configs/zynq_cse_qspi_defconfig
@@ -12,6 +12,7 @@ CONFIG_DISTRO_DEFAULTS=y
CONFIG_BOOTDELAY=-1
# CONFIG_USE_BOOTCOMMAND is not set
# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_ARCH_EARLY_INIT_R is not set
CONFIG_SPL_STACK_R=y
CONFIG_SPL_SPI_LOAD=y
CONFIG_SYS_PROMPT="Zynq> "
diff --git a/configs/zynq_microzed_defconfig b/configs/zynq_microzed_defconfig
index 34939fa..48f223b 100644
--- a/configs/zynq_microzed_defconfig
+++ b/configs/zynq_microzed_defconfig
@@ -10,7 +10,6 @@ CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_IMAGE_FORMAT_LEGACY=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_SPI_LOAD=y
diff --git a/configs/zynq_picozed_defconfig b/configs/zynq_picozed_defconfig
index 6a841f8..0136502 100644
--- a/configs/zynq_picozed_defconfig
+++ b/configs/zynq_picozed_defconfig
@@ -6,7 +6,6 @@ CONFIG_SPL_STACK_R_ADDR=0x200000
CONFIG_DEFAULT_DEVICE_TREE="zynq-picozed"
CONFIG_DISTRO_DEFAULTS=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="Zynq> "
diff --git a/configs/zynq_z_turn_defconfig b/configs/zynq_z_turn_defconfig
index c2c478d..c5301d4 100644
--- a/configs/zynq_z_turn_defconfig
+++ b/configs/zynq_z_turn_defconfig
@@ -11,7 +11,6 @@ CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_IMAGE_FORMAT_LEGACY=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_SPI_LOAD=y
diff --git a/configs/zynq_zc702_defconfig b/configs/zynq_zc702_defconfig
index c23dd8f..58b9c30 100644
--- a/configs/zynq_zc702_defconfig
+++ b/configs/zynq_zc702_defconfig
@@ -13,7 +13,6 @@ CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_IMAGE_FORMAT_LEGACY=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_SPI_LOAD=y
diff --git a/configs/zynq_zc706_defconfig b/configs/zynq_zc706_defconfig
index 00042c1..8257614 100644
--- a/configs/zynq_zc706_defconfig
+++ b/configs/zynq_zc706_defconfig
@@ -13,7 +13,6 @@ CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_IMAGE_FORMAT_LEGACY=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_SPI_LOAD=y
diff --git a/configs/zynq_zc770_xm010_defconfig b/configs/zynq_zc770_xm010_defconfig
index 7713e5a..d6811bb 100644
--- a/configs/zynq_zc770_xm010_defconfig
+++ b/configs/zynq_zc770_xm010_defconfig
@@ -12,7 +12,6 @@ CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_IMAGE_FORMAT_LEGACY=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_SPI_LOAD=y
diff --git a/configs/zynq_zc770_xm011_defconfig b/configs/zynq_zc770_xm011_defconfig
index 3c394bf..1602bce 100644
--- a/configs/zynq_zc770_xm011_defconfig
+++ b/configs/zynq_zc770_xm011_defconfig
@@ -13,7 +13,6 @@ CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_IMAGE_FORMAT_LEGACY=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="Zynq> "
diff --git a/configs/zynq_zc770_xm011_x16_defconfig b/configs/zynq_zc770_xm011_x16_defconfig
index 447cc62..37b4c42 100644
--- a/configs/zynq_zc770_xm011_x16_defconfig
+++ b/configs/zynq_zc770_xm011_x16_defconfig
@@ -13,7 +13,6 @@ CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_IMAGE_FORMAT_LEGACY=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="Zynq> "
diff --git a/configs/zynq_zc770_xm012_defconfig b/configs/zynq_zc770_xm012_defconfig
index 0a78830..275bb33 100644
--- a/configs/zynq_zc770_xm012_defconfig
+++ b/configs/zynq_zc770_xm012_defconfig
@@ -12,7 +12,6 @@ CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_IMAGE_FORMAT_LEGACY=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="Zynq> "
diff --git a/configs/zynq_zc770_xm013_defconfig b/configs/zynq_zc770_xm013_defconfig
index 6659218..e83222d 100644
--- a/configs/zynq_zc770_xm013_defconfig
+++ b/configs/zynq_zc770_xm013_defconfig
@@ -12,7 +12,6 @@ CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_IMAGE_FORMAT_LEGACY=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_SPI_LOAD=y
diff --git a/configs/zynq_zed_defconfig b/configs/zynq_zed_defconfig
index 13898b3..9ab54ec 100644
--- a/configs/zynq_zed_defconfig
+++ b/configs/zynq_zed_defconfig
@@ -11,7 +11,6 @@ CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_IMAGE_FORMAT_LEGACY=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_SPI_LOAD=y
diff --git a/configs/zynq_zybo_defconfig b/configs/zynq_zybo_defconfig
index 771d8ca..efb99b5 100644
--- a/configs/zynq_zybo_defconfig
+++ b/configs/zynq_zybo_defconfig
@@ -12,7 +12,6 @@ CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_IMAGE_FORMAT_LEGACY=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
-# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_SPI_LOAD=y
diff --git a/drivers/ata/sata_ceva.c b/drivers/ata/sata_ceva.c
index 1544097..a7d45e8 100644
--- a/drivers/ata/sata_ceva.c
+++ b/drivers/ata/sata_ceva.c
@@ -72,6 +72,10 @@
#define DRV_NAME "ahci-ceva"
#define CEVA_FLAG_BROKEN_GEN2 1
+struct ceva_sata_priv {
+ ulong base;
+};
+
static int ceva_init_sata(ulong mmio)
{
ulong tmp;
@@ -110,18 +114,20 @@ static int ceva_init_sata(ulong mmio)
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[] = {
@@ -131,24 +137,22 @@ static const struct udevice_id sata_ceva_ids[] = {
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;
- /* Hardcode number for ceva sata controller */
- plat->max_lun = 1; /* Actually two but untested */
- plat->max_id = 2;
-
return 0;
}
U_BOOT_DRIVER(ceva_host_blk) = {
.name = "ceva_sata",
- .id = UCLASS_SCSI,
+ .id = UCLASS_AHCI,
.of_match = sata_ceva_ids,
+ .bind = sata_ceva_bind,
.ops = &scsi_ops,
+ .priv_auto_alloc_size = sizeof(struct ceva_sata_priv),
.probe = sata_ceva_probe,
.ofdata_to_platdata = sata_ceva_ofdata_to_platdata,
};
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index a08c6947..3cfe6bf 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -679,7 +679,7 @@ static int mmc_complete_op_cond(struct mmc *mmc)
{
struct mmc_cmd cmd;
int timeout = 1000;
- uint start;
+ ulong start;
int err;
mmc->op_cond_pending = 0;
@@ -2611,7 +2611,7 @@ static int mmc_complete_init(struct mmc *mmc)
int mmc_init(struct mmc *mmc)
{
int err = 0;
- __maybe_unused unsigned start;
+ __maybe_unused ulong start;
#if CONFIG_IS_ENABLED(DM_MMC)
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 758850f..8971a11 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -151,7 +151,7 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
u32 mask, flags, mode;
unsigned int time = 0, start_addr = 0;
int mmc_dev = mmc_get_blk_desc(mmc)->devnum;
- unsigned start = get_timer(0);
+ ulong start = get_timer(0);
/* Timeout unit - ms */
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
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;
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);
mask = SDHCI_INT_RESPONSE;
+ if (cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK)
+ mask = SDHCI_INT_DATA_AVAIL;
+
if (!(cmd->resp_type & MMC_RSP_PRESENT))
flags = SDHCI_CMD_RESP_NONE;
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;
if (cmd->resp_type & MMC_RSP_OPCODE)
flags |= SDHCI_CMD_INDEX;
- if (data)
+ if (data || cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK)
flags |= SDHCI_CMD_DATA;
/* 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;
}
+#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)
{
struct sdhci_host *host = mmc->priv;
@@ -325,6 +347,9 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
if (clock == 0)
return 0;
+ if (host->ops->set_delay)
+ host->ops->set_delay(host);
+
if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
/*
* 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)
sdhci_set_clock(mmc, mmc->clock);
+ if (mmc->clk_disable)
+ sdhci_set_clock(mmc, 0);
+
/* Set bus width */
ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
if (mmc->bus_width == 8) {
@@ -514,6 +542,9 @@ int sdhci_probe(struct udevice *dev)
const struct dm_mmc_ops sdhci_ops = {
.send_cmd = sdhci_send_command,
.set_ios = sdhci_set_ios,
+#ifdef MMC_SUPPORTS_TUNING
+ .execute_tuning = sdhci_execute_tuning,
+#endif
};
#else
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,
u32 f_max, u32 f_min)
{
- u32 caps, caps_1;
+ u32 caps, caps_1 = 0;
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;
}
+ 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)
cfg->host_caps |= host->host_caps;
diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
index b53308a..f99731f 100644
--- a/drivers/mmc/zynq_sdhci.c
+++ b/drivers/mmc/zynq_sdhci.c
@@ -9,9 +9,11 @@
#include <common.h>
#include <dm.h>
#include <fdtdec.h>
+#include "mmc_private.h"
#include <linux/libfdt.h>
#include <malloc.h>
#include <sdhci.h>
+#include <zynqmp_tap_delay.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -21,15 +23,212 @@ struct arasan_sdhci_plat {
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)
{
struct arasan_sdhci_plat *plat = dev_get_platdata(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;
unsigned long clock;
int ret;
+ host = priv->host;
+
ret = clk_get_by_index(dev, 0, &clk);
if (ret < 0) {
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");
return clock;
}
+
debug("%s: CLK %ld\n", __func__, clock);
ret = clk_enable(&clk);
@@ -56,6 +256,9 @@ static int arasan_sdhci_probe(struct udevice *dev)
host->quirks |= SDHCI_QUIRK_BROKEN_HISPD_MODE;
#endif
+ if (priv->no_1p8)
+ host->quirks |= SDHCI_QUIRK_NO_1_8_V;
+
host->max_clk = clock;
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)
{
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),
"max-frequency", CONFIG_ZYNQ_SDHCI_MAX_FREQ);
@@ -104,6 +325,6 @@ U_BOOT_DRIVER(arasan_sdhci_drv) = {
.ops = &sdhci_ops,
.bind = arasan_sdhci_bind,
.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),
};
diff --git a/drivers/mtd/nand/zynq_nand.c b/drivers/mtd/nand/zynq_nand.c
index efd3c9b..e932a58 100644
--- a/drivers/mtd/nand/zynq_nand.c
+++ b/drivers/mtd/nand/zynq_nand.c
@@ -16,6 +16,7 @@
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand_ecc.h>
#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
/* The NAND flash driver defines */
#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_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
#define NAND_CMD_LOCK_TIGHT 0x2c
#endif
@@ -768,6 +781,7 @@ static void zynq_nand_cmd_function(struct mtd_info *mtd, unsigned int command,
{
struct nand_chip *chip = mtd->priv;
const struct zynq_nand_command_format *curr_cmd = NULL;
+ u8 addr_cycles = 0;
struct zynq_nand_info *xnand = (struct zynq_nand_info *)chip->priv;
void *cmd_addr;
unsigned long cmd_data = 0;
@@ -818,8 +832,18 @@ static void zynq_nand_cmd_function(struct mtd_info *mtd, unsigned int command,
else
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 |
- (curr_cmd->addr_cycles << ADDR_CYCLES_SHIFT) |
+ (addr_cycles << ADDR_CYCLES_SHIFT) |
(end_cmd_valid << END_CMD_VALID_SHIFT) |
(COMMAND_PHASE) |
(end_cmd << END_CMD_SHIFT) |
@@ -1005,6 +1029,23 @@ static int zynq_nand_device_ready(struct mtd_info *mtd)
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)
{
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;
int ondie_ecc_enabled = 0;
int err = -1;
+ int is_16bit_bw;
xnand = calloc(1, sizeof(struct zynq_nand_info));
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->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;
/* Initialize the NAND flash interface on NAND controller */
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 4be8868..5937910 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -624,7 +624,7 @@ config STM32_SERIAL
config ZYNQ_SERIAL
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
This driver supports the Cadence UART. It is found e.g. in Xilinx
Zynq/ZynqMP.
diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c
index af9790d..06f0a48 100644
--- a/drivers/serial/serial_zynq.c
+++ b/drivers/serial/serial_zynq.c
@@ -14,7 +14,6 @@
#include <asm/io.h>
#include <linux/compiler.h>
#include <serial.h>
-#include <asm/arch/hardware.h>
#define ZYNQ_UART_SR_TXEMPTY (1 << 3) /* TX FIFO empty */
#define ZYNQ_UART_SR_TXACTIVE (1 << 11) /* TX active */
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index 2c96896..8a31397 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -52,6 +52,13 @@ config ATMEL_PIT_TIMER
it is designed to offer maximum accuracy and efficient management,
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
bool "Sandbox timer support"
depends on SANDBOX && TIMER
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index a8b531a..ee2fcb1 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -4,6 +4,7 @@
obj-y += timer-uclass.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_X86_TSC_TIMER) += tsc_timer.o
obj-$(CONFIG_OMAP_TIMER) += omap-timer.o
diff --git a/drivers/timer/cadence-ttc.c b/drivers/timer/cadence-ttc.c
new file mode 100644
index 0000000..5b91c8a
--- /dev/null
+++ b/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,
+};
diff --git a/drivers/watchdog/cdns_wdt.c b/drivers/watchdog/cdns_wdt.c
index fb045fc..9a07fa1 100644
--- a/drivers/watchdog/cdns_wdt.c
+++ b/drivers/watchdog/cdns_wdt.c
@@ -142,13 +142,13 @@ static int cdns_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
return -1;
}
- debug("%s: CLK_FREQ %ld, timeout %lld\n", __func__, clk_f, timeout);
-
if ((timeout < CDNS_WDT_MIN_TIMEOUT) ||
(timeout > CDNS_WDT_MAX_TIMEOUT)) {
timeout = priv->timeout;
}
+ debug("%s: CLK_FREQ %ld, timeout %lld\n", __func__, clk_f, timeout);
+
if (clk_f <= CDNS_WDT_CLK_75MHZ) {
prescaler = CDNS_WDT_PRESCALE_512;
ctrl_clksel = CDNS_WDT_PRESCALE_SELECT_512;
diff --git a/include/configs/xilinx_zynqmp_r5.h b/include/configs/xilinx_zynqmp_r5.h
new file mode 100644
index 0000000..05105e5
--- /dev/null
+++ b/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 */
diff --git a/include/configs/xilinx_zynqmp_zc1275_revB.h b/include/configs/xilinx_zynqmp_zc1275_revB.h
new file mode 100644
index 0000000..4cebe21
--- /dev/null
+++ b/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 */
diff --git a/include/image.h b/include/image.h
index cd13cd2..df701e3 100644
--- a/include/image.h
+++ b/include/image.h
@@ -268,6 +268,7 @@ enum {
IH_TYPE_RKSPI, /* Rockchip SPI image */
IH_TYPE_ZYNQIMAGE, /* Xilinx Zynq Boot Image */
IH_TYPE_ZYNQMPIMAGE, /* Xilinx ZynqMP Boot Image */
+ IH_TYPE_ZYNQMPBIF, /* Xilinx ZynqMP Boot Image (bif) */
IH_TYPE_FPGA, /* FPGA Image */
IH_TYPE_VYBRIDIMAGE, /* VYBRID .vyb Image */
IH_TYPE_TEE, /* Trusted Execution Environment OS Image */
diff --git a/include/sdhci.h b/include/sdhci.h
index 1e0c92c..bef37df 100644
--- a/include/sdhci.h
+++ b/include/sdhci.h
@@ -166,6 +166,11 @@
#define SDHCI_CAN_64BIT BIT(28)
#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_SHIFT 16
@@ -220,6 +225,7 @@
#define SDHCI_QUIRK_BROKEN_HISPD_MODE BIT(5)
#define SDHCI_QUIRK_WAIT_SEND_CMD (1 << 6)
#define SDHCI_QUIRK_USE_WIDE8 (1 << 8)
+#define SDHCI_QUIRK_NO_1_8_V (1 << 9)
/* to make gcc happy */
struct sdhci_host;
@@ -242,6 +248,8 @@ struct sdhci_ops {
void (*set_control_reg)(struct sdhci_host *host);
void (*set_ios_post)(struct sdhci_host *host);
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 {
diff --git a/include/zynqmp_tap_delay.h b/include/zynqmp_tap_delay.h
new file mode 100644
index 0000000..b07e3e0
--- /dev/null
+++ b/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
diff --git a/include/zynqpl.h b/include/zynqpl.h
index 9c63c01..cdfd8a2 100644
--- a/include/zynqpl.h
+++ b/include/zynqpl.h
@@ -11,23 +11,18 @@
#include <xilinx.h>
-#if defined(CONFIG_FPGA_ZYNQPL)
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 */
#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_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_ */
diff --git a/tools/Makefile b/tools/Makefile
index 1185bf5..5dd33ed 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -111,6 +111,7 @@ dumpimage-mkimage-objs := aisimage.o \
ublimage.o \
zynqimage.o \
zynqmpimage.o \
+ zynqmpbif.o \
$(LIBFDT_OBJS) \
gpimage.o \
gpimage-common.o \
diff --git a/tools/imagetool.h b/tools/imagetool.h
index ef2429e..d191b9c 100644
--- a/tools/imagetool.h
+++ b/tools/imagetool.h
@@ -231,6 +231,7 @@ time_t imagetool_get_source_date(
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) ___cat(a, b)
diff --git a/tools/mkimage.c b/tools/mkimage.c
index 64ad131..e0d4d20 100644
--- a/tools/mkimage.c
+++ b/tools/mkimage.c
@@ -515,6 +515,13 @@ int main(int argc, char **argv)
} else if (params.type == IH_TYPE_PBLIMAGE) {
/* PBL has special Image format, implements its' own */
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 {
copy_file(ifd, params.datafile, pad_len);
}
diff --git a/tools/zynqmpbif.c b/tools/zynqmpbif.c
new file mode 100644
index 0000000..6c8f660
--- /dev/null
+++ b/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
+);
diff --git a/tools/zynqmpimage.c b/tools/zynqmpimage.c
index 421558d..19b2f02 100644
--- a/tools/zynqmpimage.c
+++ b/tools/zynqmpimage.c
@@ -6,6 +6,7 @@
* 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)
*
* Expected Header Size = 0x9C0
* Forced as 'little' endian, 32-bit words
@@ -56,47 +57,9 @@
#include "imagetool.h"
#include "mkimage.h"
+#include "zynqmpimage.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 void *dynamic_header;
static FILE *fpmu;
@@ -123,7 +86,7 @@ static uint32_t zynqmpimage_checksum(struct zynqmp_header *ptr)
return cpu_to_le32(checksum);
}
-static void zynqmpimage_default_header(struct zynqmp_header *ptr)
+void zynqmpimage_default_header(struct zynqmp_header *ptr)
{
int i;
@@ -131,7 +94,7 @@ static void zynqmpimage_default_header(struct zynqmp_header *ptr)
return;
ptr->width_detection = HEADER_WIDTHDETECTION;
- ptr->image_attributes = 0x800;
+ ptr->image_attributes = HEADER_CPU_SELECT_A53_64BIT;
ptr->image_identifier = HEADER_IMAGEIDENTIFIER;
ptr->encryption = cpu_to_le32(ENCRYPTION_NONE);
@@ -172,7 +135,81 @@ static int zynqmpimage_verify_header(unsigned char *ptr, int image_size,
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;
int i;
@@ -212,6 +249,27 @@ static void zynqmpimage_print_header(const void *ptr)
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);
}
diff --git a/tools/zynqmpimage.h b/tools/zynqmpimage.h
new file mode 100644
index 0000000..7a57681
--- /dev/null
+++ b/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_ */