summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Kconfig1
-rw-r--r--Makefile11
-rw-r--r--arch/arm/config.mk7
-rw-r--r--arch/arm/cpu/armv8/Kconfig5
-rw-r--r--arch/arm/cpu/armv8/config.mk4
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/cpu.c33
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/fdt.c6
-rw-r--r--arch/arm/cpu/armv8/zynqmp/Kconfig7
-rw-r--r--arch/arm/cpu/armv8/zynqmp/spl.c6
-rw-r--r--arch/arm/dts/Makefile2
-rw-r--r--arch/arm/dts/zynq-7000.dtsi7
-rw-r--r--arch/arm/dts/zynq-microzed.dts2
-rw-r--r--arch/arm/dts/zynq-picozed.dts2
-rw-r--r--arch/arm/dts/zynq-topic-miami.dts97
-rw-r--r--arch/arm/dts/zynq-topic-miamiplus.dts17
-rw-r--r--arch/arm/dts/zynq-zc702.dts2
-rw-r--r--arch/arm/dts/zynq-zc706.dts2
-rw-r--r--arch/arm/dts/zynq-zc770-xm010.dts2
-rw-r--r--arch/arm/dts/zynq-zc770-xm011.dts2
-rw-r--r--arch/arm/dts/zynq-zc770-xm012.dts2
-rw-r--r--arch/arm/dts/zynq-zc770-xm013.dts2
-rw-r--r--arch/arm/dts/zynq-zed.dts2
-rw-r--r--arch/arm/dts/zynq-zybo.dts2
-rw-r--r--arch/arm/dts/zynqmp-clk.dtsi32
-rw-r--r--arch/arm/dts/zynqmp-ep108-clk.dtsi48
-rw-r--r--arch/arm/dts/zynqmp-ep108.dts8
-rw-r--r--arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts4
-rw-r--r--arch/arm/dts/zynqmp-zc1751-xm016-dc2.dts2
-rw-r--r--arch/arm/dts/zynqmp-zc1751-xm018-dc4.dts2
-rw-r--r--arch/arm/dts/zynqmp-zc1751-xm019-dc5.dts2
-rw-r--r--arch/arm/dts/zynqmp-zcu102.dts34
-rw-r--r--arch/arm/dts/zynqmp.dtsi341
-rw-r--r--arch/arm/include/asm/arch-zynqmp/hardware.h1
-rw-r--r--arch/arm/include/asm/u-boot-arm.h1
-rw-r--r--arch/arm/lib/Makefile10
-rw-r--r--arch/arm/lib/bootm.c7
-rw-r--r--arch/arm/lib/crt0_aarch64_efi.S135
-rw-r--r--arch/arm/lib/crt0_arm_efi.S138
-rw-r--r--arch/arm/lib/elf_aarch64_efi.lds70
-rw-r--r--arch/arm/lib/elf_arm_efi.lds70
-rw-r--r--arch/arm/lib/reloc_aarch64_efi.c87
-rw-r--r--arch/arm/lib/reloc_arm_efi.c66
-rw-r--r--arch/arm/lib/relocate.S3
-rw-r--r--arch/arm/lib/relocate_64.S3
-rw-r--r--arch/arm/mach-zynq/Kconfig8
-rw-r--r--arch/arm/mach-zynq/slcr.c25
-rw-r--r--arch/x86/config.mk20
-rw-r--r--arch/x86/include/asm/u-boot-x86.h1
-rw-r--r--arch/x86/lib/Makefile23
-rw-r--r--arch/x86/lib/bootm.c4
-rw-r--r--arch/x86/lib/crt0_ia32_efi.S (renamed from arch/x86/lib/efi/crt0-efi-ia32.S)0
-rw-r--r--arch/x86/lib/crt0_x86_64_efi.S (renamed from arch/x86/lib/efi/crt0-efi-x86_64.S)0
-rw-r--r--arch/x86/lib/efi/Makefile18
-rw-r--r--arch/x86/lib/elf_ia32_efi.lds (renamed from arch/x86/cpu/efi/elf_ia32_efi.lds)2
-rw-r--r--arch/x86/lib/elf_x86_64_efi.lds (renamed from arch/x86/cpu/efi/elf_x86_64_efi.lds)2
-rw-r--r--arch/x86/lib/reloc_ia32_efi.c (renamed from arch/x86/lib/efi/reloc_ia32.c)0
-rw-r--r--arch/x86/lib/reloc_x86_64_efi.c (renamed from arch/x86/lib/efi/reloc_x86_64.c)0
-rw-r--r--arch/x86/lib/tables.c2
-rw-r--r--board/freescale/ls2080a/ls2080a.c6
-rw-r--r--board/freescale/ls2080aqds/ls2080aqds.c11
-rw-r--r--board/freescale/ls2080ardb/ls2080ardb.c20
-rw-r--r--board/topic/zynq/MAINTAINERS6
-rw-r--r--board/topic/zynq/Makefile10
-rw-r--r--board/topic/zynq/board.c1
-rw-r--r--board/topic/zynq/ps7_init_common.c117
-rw-r--r--board/topic/zynq/ps7_init_gpl.h34
-rw-r--r--board/topic/zynq/zynq-topic-miami/ps7_init_gpl.c227
-rw-r--r--board/topic/zynq/zynq-topic-miami/ps7_regs.txt61
-rw-r--r--board/topic/zynq/zynq-topic-miamiplus/ps7_init_gpl.c233
-rw-r--r--board/topic/zynq/zynq-topic-miamiplus/ps7_regs.txt61
-rw-r--r--board/xilinx/zynq/board.c12
-rw-r--r--board/xilinx/zynqmp/Makefile3
-rw-r--r--board/xilinx/zynqmp/xil_io.h9
-rw-r--r--board/xilinx/zynqmp/zynqmp.c21
-rw-r--r--cmd/Kconfig9
-rw-r--r--cmd/bootefi.c40
-rw-r--r--configs/efi-x86_defconfig1
-rw-r--r--configs/topic_miami_defconfig49
-rw-r--r--configs/topic_miamiplus_defconfig49
-rw-r--r--configs/zynq_zc770_xm011_defconfig2
-rw-r--r--doc/README.efi14
-rw-r--r--doc/README.x861
-rw-r--r--drivers/mtd/nand/Kconfig7
-rw-r--r--drivers/mtd/nand/Makefile1
-rw-r--r--drivers/mtd/nand/arasan_nfc.c2
-rw-r--r--drivers/mtd/nand/zynq_nand.c1186
-rw-r--r--drivers/net/fsl-mc/mc.c24
-rw-r--r--drivers/net/zynq_gem.c16
-rw-r--r--include/asm-generic/sections.h2
-rw-r--r--include/configs/ls2080ardb.h26
-rw-r--r--include/configs/topic_miami.h149
-rw-r--r--include/configs/topic_miamiplus.h2
-rw-r--r--include/configs/xilinx_zynqmp_ep.h2
-rw-r--r--include/configs/zynq-common.h7
-rw-r--r--include/efi.h7
-rw-r--r--include/efi_api.h13
-rw-r--r--include/efi_loader.h2
-rw-r--r--include/elf.h13
-rw-r--r--include/zynqmppl.h6
-rw-r--r--include/zynqpl.h18
-rw-r--r--lib/efi/Makefile4
-rw-r--r--lib/efi_loader/Kconfig2
-rw-r--r--lib/efi_loader/Makefile4
-rw-r--r--lib/efi_loader/efi_boottime.c2
-rw-r--r--lib/efi_loader/efi_console.c100
-rw-r--r--lib/efi_loader/efi_image_loader.c3
-rw-r--r--lib/efi_loader/efi_net.c17
-rw-r--r--lib/efi_loader/helloworld.c24
-rw-r--r--scripts/Makefile.lib33
-rw-r--r--scripts/Makefile.spl4
-rw-r--r--tools/zynqimage.c28
-rw-r--r--tools/zynqmpimage.c34
112 files changed, 3886 insertions, 241 deletions
diff --git a/Kconfig b/Kconfig
index 1263d0b612..f3a9f73dd0 100644
--- a/Kconfig
+++ b/Kconfig
@@ -56,6 +56,7 @@ config CC_OPTIMIZE_FOR_SIZE
config DISTRO_DEFAULTS
bool "Select defaults suitable for booting general purpose Linux distributions"
default y if ARCH_SUNXI
+ default y if ARCH_LS2080A
default n
select CMD_BOOTZ if ARM && !ARM64
select CMD_BOOTI if ARM64
diff --git a/Makefile b/Makefile
index 8ca1db57d4..96ddc59ca6 100644
--- a/Makefile
+++ b/Makefile
@@ -527,6 +527,15 @@ endif
endif
endif
+# These are set by the arch-specific config.mk. Make sure they are exported
+# so they can be used when building an EFI application.
+export EFI_LDS # Filename of EFI link script in arch/$(ARCH)/lib
+export EFI_CRT0 # Filename of EFI CRT0 in arch/$(ARCH)/lib
+export EFI_RELOC # Filename of EFU relocation code in arch/$(ARCH)/lib
+export CFLAGS_EFI # Compiler flags to add when building EFI app
+export CFLAGS_NON_EFI # Compiler flags to remove when building EFI app
+export EFI_TARGET # binutils target if EFI is natively supported
+
# If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use
# that (or fail if absent). Otherwise, search for a linker script in a
# standard location.
@@ -1131,7 +1140,7 @@ quiet_cmd_u-boot_payload ?= LD $@
cmd_u-boot_payload ?= $(LD) $(LDFLAGS_EFI_PAYLOAD) -o $@ \
-T u-boot-payload.lds arch/x86/cpu/call32.o \
lib/efi/efi.o lib/efi/efi_stub.o u-boot.bin.o \
- $(addprefix arch/$(ARCH)/lib/efi/,$(EFISTUB))
+ $(addprefix arch/$(ARCH)/lib/,$(EFISTUB))
u-boot-payload: u-boot.bin.o u-boot-payload.lds FORCE
$(call if_changed,u-boot_payload)
diff --git a/arch/arm/config.mk b/arch/arm/config.mk
index 542b897c31..27914a95b9 100644
--- a/arch/arm/config.mk
+++ b/arch/arm/config.mk
@@ -13,6 +13,9 @@ CONFIG_STANDALONE_LOAD_ADDR = 0xc100000
endif
endif
+CFLAGS_NON_EFI := -fno-pic -ffixed-r9 -ffunction-sections -fdata-sections
+CFLAGS_EFI := -fpic -fshort-wchar
+
LDFLAGS_FINAL += --gc-sections
PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections \
-fno-common -ffixed-r9
@@ -148,3 +151,7 @@ ifneq ($(CONFIG_VF610),)
ALL-y += u-boot.vyb
endif
endif
+
+EFI_LDS := elf_arm_efi.lds
+EFI_CRT0 := crt0_arm_efi.o
+EFI_RELOC := reloc_arm_efi.o
diff --git a/arch/arm/cpu/armv8/Kconfig b/arch/arm/cpu/armv8/Kconfig
index cd2d9bb917..965a8d129c 100644
--- a/arch/arm/cpu/armv8/Kconfig
+++ b/arch/arm/cpu/armv8/Kconfig
@@ -28,8 +28,9 @@ config PSCI_RESET
!TARGET_LS2080A_SIMU && !TARGET_LS2080AQDS && \
!TARGET_LS2080ARDB && !TARGET_LS1012AQDS && \
!TARGET_LS1012ARDB && !TARGET_LS1012AFRDM && \
- !TARGET_LS1043ARDB && !ARCH_UNIPHIER && !ARCH_SNAPDRAGON && \
- !TARGET_S32V234EVB
+ !TARGET_LS1043ARDB && !TARGET_LS1043AQDS && \
+ !TARGET_LS1046ARDB && !TARGET_LS1046AQDS && \
+ !ARCH_UNIPHIER && !ARCH_SNAPDRAGON && !TARGET_S32V234EVB
help
Most armv8 systems have PSCI support enabled in EL3, either through
ARM Trusted Firmware or other firmware.
diff --git a/arch/arm/cpu/armv8/config.mk b/arch/arm/cpu/armv8/config.mk
index 685025881c..27b66d41b1 100644
--- a/arch/arm/cpu/armv8/config.mk
+++ b/arch/arm/cpu/armv8/config.mk
@@ -8,3 +8,7 @@ PLATFORM_RELFLAGS += -fno-common -ffixed-x18
PF_NO_UNALIGNED := $(call cc-option, -mstrict-align)
PLATFORM_CPPFLAGS += $(PF_NO_UNALIGNED)
+
+EFI_LDS := elf_aarch64_efi.lds
+EFI_CRT0 := crt0_aarch64_efi.o
+EFI_RELOC := reloc_aarch64_efi.o
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
index b7a2e0c946..0b516e37d7 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
@@ -17,6 +17,7 @@
#ifdef CONFIG_MP
#include <asm/arch/mp.h>
#endif
+#include <efi_loader.h>
#include <fm_eth.h>
#include <fsl-mc/fsl_mc.h>
#ifdef CONFIG_FSL_ESDHC
@@ -462,9 +463,10 @@ int timer_init(void)
return 0;
}
-void reset_cpu(ulong addr)
+__efi_runtime_data u32 __iomem *rstcr = (u32 *)CONFIG_SYS_FSL_RST_ADDR;
+
+void __efi_runtime reset_cpu(ulong addr)
{
- u32 __iomem *rstcr = (u32 *)CONFIG_SYS_FSL_RST_ADDR;
u32 val;
/* Raise RESET_REQ_B */
@@ -473,6 +475,33 @@ void reset_cpu(ulong addr)
scfg_out32(rstcr, val);
}
+#ifdef CONFIG_EFI_LOADER
+
+void __efi_runtime EFIAPI efi_reset_system(
+ enum efi_reset_type reset_type,
+ efi_status_t reset_status,
+ unsigned long data_size, void *reset_data)
+{
+ switch (reset_type) {
+ case EFI_RESET_COLD:
+ case EFI_RESET_WARM:
+ reset_cpu(0);
+ break;
+ case EFI_RESET_SHUTDOWN:
+ /* Nothing we can do */
+ break;
+ }
+
+ while (1) { }
+}
+
+void efi_reset_system_init(void)
+{
+ efi_add_runtime_mmio(&rstcr, sizeof(*rstcr));
+}
+
+#endif
+
phys_size_t board_reserve_ram_top(phys_size_t ram_size)
{
phys_size_t ram_top = ram_size;
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
index 1a8321b0e4..0dae5faad8 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c
@@ -5,6 +5,7 @@
*/
#include <common.h>
+#include <efi_loader.h>
#include <libfdt.h>
#include <fdt_support.h>
#include <phy.h>
@@ -105,6 +106,11 @@ remove_psci_node:
fdt_add_mem_rsv(blob, (uintptr_t)&secondary_boot_code,
*boot_code_size);
+#if defined(CONFIG_EFI_LOADER) && !defined(CONFIG_SPL_BUILD)
+ efi_add_memory_map((uintptr_t)&secondary_boot_code,
+ ALIGN(*boot_code_size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT,
+ EFI_RESERVED_MEMORY_TYPE, false);
+#endif
}
#endif
diff --git a/arch/arm/cpu/armv8/zynqmp/Kconfig b/arch/arm/cpu/armv8/zynqmp/Kconfig
index 1eedb39aa5..a3baae4f74 100644
--- a/arch/arm/cpu/armv8/zynqmp/Kconfig
+++ b/arch/arm/cpu/armv8/zynqmp/Kconfig
@@ -41,6 +41,13 @@ config SYS_CONFIG_NAME
Based on this option include/configs/<CONFIG_SYS_CONFIG_NAME>.h header
will be used for board configuration.
+config BOOT_INIT_FILE
+ string "boot.bin init register filename"
+ default ""
+ help
+ Add register writes to boot.bin format (max 256 pairs).
+ Expect a table of register-value pairs, e.g. "0x12345678 0x4321"
+
config ZYNQMP_USB
bool "Configure ZynqMP USB"
diff --git a/arch/arm/cpu/armv8/zynqmp/spl.c b/arch/arm/cpu/armv8/zynqmp/spl.c
index 04e190537d..bdbd61380a 100644
--- a/arch/arm/cpu/armv8/zynqmp/spl.c
+++ b/arch/arm/cpu/armv8/zynqmp/spl.c
@@ -69,12 +69,14 @@ u32 spl_boot_device(void)
#if defined(CONFIG_SPL_ZYNQMP_ALT_BOOTMODE_ENABLED)
/* Change default boot mode at run-time */
- writel(BOOT_MODE_USE_ALT |
- CONFIG_SPL_ZYNQMP_ALT_BOOTMODE << BOOT_MODE_ALT_SHIFT,
+ writel(CONFIG_SPL_ZYNQMP_ALT_BOOTMODE << BOOT_MODE_ALT_SHIFT,
&crlapb_base->boot_mode);
#endif
reg = readl(&crlapb_base->boot_mode);
+ if (reg >> BOOT_MODE_ALT_SHIFT)
+ reg >>= BOOT_MODE_ALT_SHIFT;
+
bootmode = reg & BOOT_MODES_MASK;
switch (bootmode) {
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 836a8c4d1e..2c5b2f22c6 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -97,6 +97,8 @@ dtb-$(CONFIG_ARCH_ZYNQ) += zynq-zc702.dtb \
zynq-zybo.dtb \
zynq-microzed.dtb \
zynq-picozed.dtb \
+ zynq-topic-miami.dtb \
+ zynq-topic-miamiplus.dtb \
zynq-zc770-xm010.dtb \
zynq-zc770-xm011.dtb \
zynq-zc770-xm012.dtb \
diff --git a/arch/arm/dts/zynq-7000.dtsi b/arch/arm/dts/zynq-7000.dtsi
index b618a3f484..6df0329cfc 100644
--- a/arch/arm/dts/zynq-7000.dtsi
+++ b/arch/arm/dts/zynq-7000.dtsi
@@ -6,9 +6,10 @@
*
* SPDX-License-Identifier: GPL-2.0+
*/
-/include/ "skeleton.dtsi"
/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
compatible = "xlnx,zynq-7000";
cpus {
@@ -37,14 +38,14 @@
};
};
- pmu {
+ pmu@f8891000 {
compatible = "arm,cortex-a9-pmu";
interrupts = <0 5 4>, <0 6 4>;
interrupt-parent = <&intc>;
reg = < 0xf8891000 0x1000 0xf8893000 0x1000 >;
};
- regulator_vccpint: fixedregulator@0 {
+ regulator_vccpint: fixedregulator {
compatible = "regulator-fixed";
regulator-name = "VCCPINT";
regulator-min-microvolt = <1000000>;
diff --git a/arch/arm/dts/zynq-microzed.dts b/arch/arm/dts/zynq-microzed.dts
index cb238cd5e7..2d07b92e9c 100644
--- a/arch/arm/dts/zynq-microzed.dts
+++ b/arch/arm/dts/zynq-microzed.dts
@@ -18,7 +18,7 @@
mmc0 = &sdhci0;
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0 0x40000000>;
};
diff --git a/arch/arm/dts/zynq-picozed.dts b/arch/arm/dts/zynq-picozed.dts
index 3408df8b8b..fea04ab45a 100644
--- a/arch/arm/dts/zynq-picozed.dts
+++ b/arch/arm/dts/zynq-picozed.dts
@@ -16,7 +16,7 @@
serial0 = &uart1;
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0 0x40000000>;
};
diff --git a/arch/arm/dts/zynq-topic-miami.dts b/arch/arm/dts/zynq-topic-miami.dts
new file mode 100644
index 0000000000..aa05c4d368
--- /dev/null
+++ b/arch/arm/dts/zynq-topic-miami.dts
@@ -0,0 +1,97 @@
+/*
+ * Topic Miami board DTS
+ *
+ * Copyright (C) 2014-2016 Topic Embedded Products
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+/dts-v1/;
+#include "zynq-7000.dtsi"
+
+/ {
+ model = "Topic Miami Zynq Board";
+ compatible = "topic,miami", "xlnx,zynq-7000";
+
+ aliases {
+ ethernet0 = &gem0;
+ serial0 = &uart0;
+ spi0 = &qspi;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ mmc0 = &sdhci0;
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x40000000>;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+};
+
+&qspi {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+ is-dual = <0>;
+ num-cs = <1>;
+ flash@0 {
+ compatible = "st,m25p80", "n25q256a";
+ m25p,fast-read;
+ reg = <0x0>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <4>;
+ spi-max-frequency = <100000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@qspi-u-boot-spl {
+ label = "qspi-u-boot-spl";
+ reg = <0x00000 0x10000>;
+ };
+ partition@qspi-u-boot-img {
+ label = "qspi-u-boot-img";
+ reg = <0x10000 0x60000>;
+ };
+ partition@qspi-device-tree {
+ label = "qspi-device-tree";
+ reg = <0x70000 0x10000>;
+ };
+ partition@qspi-linux {
+ label = "qspi-linux";
+ reg = <0x80000 0x400000>;
+ };
+ partition@qspi-rootfs {
+ label = "qspi-rootfs";
+ reg = <0x480000 0x1b80000>;
+ };
+ };
+};
+
+&i2c0 {
+ status = "okay";
+ clock-frequency = <400000>;
+};
+
+&i2c1 {
+ status = "okay";
+ clock-frequency = <400000>;
+};
+
+&clkc {
+ ps-clk-frequency = <33333333>;
+};
+
+&sdhci0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+};
diff --git a/arch/arm/dts/zynq-topic-miamiplus.dts b/arch/arm/dts/zynq-topic-miamiplus.dts
new file mode 100644
index 0000000000..3036f6ea9c
--- /dev/null
+++ b/arch/arm/dts/zynq-topic-miamiplus.dts
@@ -0,0 +1,17 @@
+/*
+ * Topic Miami Plus board DTS
+ *
+ * Copyright (C) 2016 Topic Embedded Products
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include "zynq-topic-miami.dts"
+
+/ {
+ model = "Topic Miami+ Zynq Board";
+ compatible = "topic,miamiplus", "xlnx,zynq-7000";
+};
+
+&qspi {
+ is-dual = <1>;
+};
diff --git a/arch/arm/dts/zynq-zc702.dts b/arch/arm/dts/zynq-zc702.dts
index 6585010f4b..478e9fd4ef 100644
--- a/arch/arm/dts/zynq-zc702.dts
+++ b/arch/arm/dts/zynq-zc702.dts
@@ -21,7 +21,7 @@
mmc0 = &sdhci0;
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x40000000>;
};
diff --git a/arch/arm/dts/zynq-zc706.dts b/arch/arm/dts/zynq-zc706.dts
index d04880a2cd..8b0177bc51 100644
--- a/arch/arm/dts/zynq-zc706.dts
+++ b/arch/arm/dts/zynq-zc706.dts
@@ -21,7 +21,7 @@
mmc0 = &sdhci0;
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x40000000>;
};
diff --git a/arch/arm/dts/zynq-zc770-xm010.dts b/arch/arm/dts/zynq-zc770-xm010.dts
index 33524cb6de..42af313c13 100644
--- a/arch/arm/dts/zynq-zc770-xm010.dts
+++ b/arch/arm/dts/zynq-zc770-xm010.dts
@@ -25,7 +25,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x40000000>;
};
diff --git a/arch/arm/dts/zynq-zc770-xm011.dts b/arch/arm/dts/zynq-zc770-xm011.dts
index 463b14b5ea..7f08961491 100644
--- a/arch/arm/dts/zynq-zc770-xm011.dts
+++ b/arch/arm/dts/zynq-zc770-xm011.dts
@@ -23,7 +23,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x40000000>;
};
diff --git a/arch/arm/dts/zynq-zc770-xm012.dts b/arch/arm/dts/zynq-zc770-xm012.dts
index 6cab832667..699cd2c0fb 100644
--- a/arch/arm/dts/zynq-zc770-xm012.dts
+++ b/arch/arm/dts/zynq-zc770-xm012.dts
@@ -24,7 +24,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x40000000>;
};
diff --git a/arch/arm/dts/zynq-zc770-xm013.dts b/arch/arm/dts/zynq-zc770-xm013.dts
index d5bb4efcc5..07e92b88fb 100644
--- a/arch/arm/dts/zynq-zc770-xm013.dts
+++ b/arch/arm/dts/zynq-zc770-xm013.dts
@@ -25,7 +25,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x40000000>;
};
diff --git a/arch/arm/dts/zynq-zed.dts b/arch/arm/dts/zynq-zed.dts
index 4363a4fcac..0ac7532300 100644
--- a/arch/arm/dts/zynq-zed.dts
+++ b/arch/arm/dts/zynq-zed.dts
@@ -20,7 +20,7 @@
mmc0 = &sdhci0;
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x20000000>;
};
diff --git a/arch/arm/dts/zynq-zybo.dts b/arch/arm/dts/zynq-zybo.dts
index f8dcf1d699..d59a383135 100644
--- a/arch/arm/dts/zynq-zybo.dts
+++ b/arch/arm/dts/zynq-zybo.dts
@@ -20,7 +20,7 @@
mmc0 = &sdhci0;
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x20000000>;
};
diff --git a/arch/arm/dts/zynqmp-clk.dtsi b/arch/arm/dts/zynqmp-clk.dtsi
index 0918c686d7..aa848c8646 100644
--- a/arch/arm/dts/zynqmp-clk.dtsi
+++ b/arch/arm/dts/zynqmp-clk.dtsi
@@ -114,6 +114,38 @@
clocks = <&clk600>, <&clk100>;
};
+&lpd_dma_chan1 {
+ clocks = <&clk600>, <&clk100>;
+};
+
+&lpd_dma_chan2 {
+ clocks = <&clk600>, <&clk100>;
+};
+
+&lpd_dma_chan3 {
+ clocks = <&clk600>, <&clk100>;
+};
+
+&lpd_dma_chan4 {
+ clocks = <&clk600>, <&clk100>;
+};
+
+&lpd_dma_chan5 {
+ clocks = <&clk600>, <&clk100>;
+};
+
+&lpd_dma_chan6 {
+ clocks = <&clk600>, <&clk100>;
+};
+
+&lpd_dma_chan7 {
+ clocks = <&clk600>, <&clk100>;
+};
+
+&lpd_dma_chan8 {
+ clocks = <&clk600>, <&clk100>;
+};
+
&nand0 {
clocks = <&clk100 &clk100>;
};
diff --git a/arch/arm/dts/zynqmp-ep108-clk.dtsi b/arch/arm/dts/zynqmp-ep108-clk.dtsi
index b3ce0de549..1c2efe459d 100644
--- a/arch/arm/dts/zynqmp-ep108-clk.dtsi
+++ b/arch/arm/dts/zynqmp-ep108-clk.dtsi
@@ -35,6 +35,18 @@
clock-accuracy = <100>;
};
+ clk100: clk100 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ };
+
+ clk600: clk600 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <600000000>;
+ };
+
dp_aud_clk: clock1 {
compatible = "fixed-clock";
#clock-cells = <0>;
@@ -47,6 +59,42 @@
clocks = <&misc_clk &misc_clk>;
};
+&can1 {
+ clocks = <&misc_clk &misc_clk>;
+};
+
+&fpd_dma_chan1 {
+ clocks = <&clk600>, <&clk100>;
+};
+
+&fpd_dma_chan2 {
+ clocks = <&clk600>, <&clk100>;
+};
+
+&fpd_dma_chan3 {
+ clocks = <&clk600>, <&clk100>;
+};
+
+&fpd_dma_chan4 {
+ clocks = <&clk600>, <&clk100>;
+};
+
+&fpd_dma_chan5 {
+ clocks = <&clk600>, <&clk100>;
+};
+
+&fpd_dma_chan6 {
+ clocks = <&clk600>, <&clk100>;
+};
+
+&fpd_dma_chan7 {
+ clocks = <&clk600>, <&clk100>;
+};
+
+&fpd_dma_chan8 {
+ clocks = <&clk600>, <&clk100>;
+};
+
&gem0 {
clocks = <&misc_clk>, <&misc_clk>, <&misc_clk>;
};
diff --git a/arch/arm/dts/zynqmp-ep108.dts b/arch/arm/dts/zynqmp-ep108.dts
index 0bbf9a7597..2483180d38 100644
--- a/arch/arm/dts/zynqmp-ep108.dts
+++ b/arch/arm/dts/zynqmp-ep108.dts
@@ -31,7 +31,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x0 0x0 0x40000000>;
};
@@ -41,6 +41,10 @@
status = "okay";
};
+&can1 {
+ status = "okay";
+};
+
&gem0 {
status = "okay";
phy-handle = <&phy0>;
@@ -150,10 +154,12 @@
&sdhci0 {
status = "okay";
bus-width = <8>;
+ xlnx,mio_bank = <2>;
};
&sdhci1 {
status = "okay";
+ xlnx,mio_bank = <1>;
};
&spi0 {
diff --git a/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts b/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts
index c68a41bea7..b3f42977ab 100644
--- a/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts
+++ b/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts
@@ -34,7 +34,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x0 0x0 0x80000000>, <0x8 0x00000000 0x0 0x80000000>;
};
@@ -159,12 +159,14 @@
&sdhci0 {
status = "okay";
bus-width = <8>;
+ xlnx,mio_bank = <0>;
};
/* SD1 with level shifter */
&sdhci1 {
status = "okay";
no-1-8-v; /* for 1.0 silicon */
+ xlnx,mio_bank = <1>;
};
&uart0 {
diff --git a/arch/arm/dts/zynqmp-zc1751-xm016-dc2.dts b/arch/arm/dts/zynqmp-zc1751-xm016-dc2.dts
index 3fdfcc8a11..09a114be16 100644
--- a/arch/arm/dts/zynqmp-zc1751-xm016-dc2.dts
+++ b/arch/arm/dts/zynqmp-zc1751-xm016-dc2.dts
@@ -36,7 +36,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x0 0x0 0x80000000>, <0x8 0x00000000 0x0 0x80000000>;
};
diff --git a/arch/arm/dts/zynqmp-zc1751-xm018-dc4.dts b/arch/arm/dts/zynqmp-zc1751-xm018-dc4.dts
index 03f1ad7934..1f03a94820 100644
--- a/arch/arm/dts/zynqmp-zc1751-xm018-dc4.dts
+++ b/arch/arm/dts/zynqmp-zc1751-xm018-dc4.dts
@@ -41,7 +41,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x0 0x0 0x80000000>, <0x8 0x00000000 0x0 0x80000000>;
};
diff --git a/arch/arm/dts/zynqmp-zc1751-xm019-dc5.dts b/arch/arm/dts/zynqmp-zc1751-xm019-dc5.dts
index d754f9f904..698e72e0c5 100644
--- a/arch/arm/dts/zynqmp-zc1751-xm019-dc5.dts
+++ b/arch/arm/dts/zynqmp-zc1751-xm019-dc5.dts
@@ -32,7 +32,7 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x0 0x0 0x80000000>, <0x8 0x00000000 0x0 0x80000000>;
};
diff --git a/arch/arm/dts/zynqmp-zcu102.dts b/arch/arm/dts/zynqmp-zcu102.dts
index de99602456..0e9150e6b1 100644
--- a/arch/arm/dts/zynqmp-zcu102.dts
+++ b/arch/arm/dts/zynqmp-zcu102.dts
@@ -12,6 +12,7 @@
#include "zynqmp.dtsi"
#include "zynqmp-clk.dtsi"
+#include <dt-bindings/gpio/gpio.h>
/ {
model = "ZynqMP ZCU102 RevA";
@@ -26,6 +27,7 @@
rtc0 = &rtc;
serial0 = &uart0;
serial1 = &uart1;
+ serial2 = &dcc;
spi0 = &qspi;
usb0 = &usb0;
};
@@ -35,16 +37,43 @@
stdout-path = "serial0:115200n8";
};
- memory {
+ memory@0 {
device_type = "memory";
reg = <0x0 0x0 0x0 0x80000000>, <0x8 0x00000000 0x0 0x80000000>;
};
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ autorepeat;
+ sw19 {
+ label = "sw19";
+ gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
+ linux,code = <108>; /* down */
+ gpio-key,wakeup;
+ autorepeat;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ heartbeat_led {
+ label = "heartbeat";
+ gpios = <&gpio 23 0>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
};
&can1 {
status = "okay";
};
+&dcc {
+ status = "okay";
+};
+
/* fpd_dma clk 667MHz, lpd_dma 500MHz */
&fpd_dma_chan1 {
status = "okay";
@@ -365,7 +394,7 @@ drivers/hwmon/pmbus/Makefile:11:obj-$(CONFIG_SENSORS_MAX20751) += max20751.o
/* Bus 3 is not connected */
};
- /* FIXME PL connection - u55 , PMOD - j160 */
+ /* FIXME PMOD - j160 */
/* FIXME MSP430F - u41 - not detected */
};
@@ -576,6 +605,7 @@ drivers/hwmon/pmbus/Makefile:11:obj-$(CONFIG_SENSORS_MAX20751) += max20751.o
&sdhci1 {
status = "okay";
no-1-8-v; /* for 1.0 silicon */
+ xlnx,mio_bank = <1>;
};
&uart0 {
diff --git a/arch/arm/dts/zynqmp.dtsi b/arch/arm/dts/zynqmp.dtsi
index 619450e1ba..ab5c243c61 100644
--- a/arch/arm/dts/zynqmp.dtsi
+++ b/arch/arm/dts/zynqmp.dtsi
@@ -45,6 +45,12 @@
};
};
+ dcc: dcc {
+ compatible = "arm,dcc";
+ status = "disabled";
+ u-boot,dm-pre-reloc;
+ };
+
power-domains {
compatible = "xlnx,zynqmp-genpd";
@@ -184,34 +190,14 @@
pd-id = <0x30>;
};
- pd_ddr: pd-ddr {
- #power-domain-cells = <0x0>;
- pd-id = <0x37>;
- };
-
- pd_apll: pd-apll {
- #power-domain-cells = <0x0>;
- pd-id = <0x32>;
- };
-
- pd_vpll: pd-vpll {
+ pd_pcie: pd-pcie {
#power-domain-cells = <0x0>;
- pd-id = <0x33>;
+ pd-id = <0x3b>;
};
- pd_dpll: pd-dpll {
+ pd_gpu: pd-gpu {
#power-domain-cells = <0x0>;
- pd-id = <0x34>;
- };
-
- pd_rpll: pd-rpll {
- #power-domain-cells = <0x0>;
- pd-id = <0x35>;
- };
-
- pd_iopll: pd-iopll {
- #power-domain-cells = <0x0>;
- pd-id = <0x36>;
+ pd-id = <0x3a 0x14 0x15>;
};
};
@@ -243,7 +229,15 @@
<1 10 0xf01>;
};
- amba_apu: amba_apu {
+ edac {
+ compatible = "arm,cortex-a53-edac";
+ };
+
+ pcap {
+ compatible = "xlnx,zynqmp-pcap-fpga";
+ };
+
+ amba_apu: amba_apu@0 {
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <1>;
@@ -266,14 +260,14 @@
compatible = "simple-bus";
u-boot,dm-pre-reloc;
#address-cells = <2>;
- #size-cells = <1>;
- ranges = <0 0 0 0 0xffffffff>;
+ #size-cells = <2>;
+ ranges;
can0: can@ff060000 {
compatible = "xlnx,zynq-can-1.0";
status = "disabled";
clock-names = "can_clk", "pclk";
- reg = <0x0 0xff060000 0x1000>;
+ reg = <0x0 0xff060000 0x0 0x1000>;
interrupts = <0 23 4>;
interrupt-parent = <&gic>;
tx-fifo-depth = <0x40>;
@@ -285,7 +279,7 @@
compatible = "xlnx,zynq-can-1.0";
status = "disabled";
clock-names = "can_clk", "pclk";
- reg = <0x0 0xff070000 0x1000>;
+ reg = <0x0 0xff070000 0x0 0x1000>;
interrupts = <0 24 4>;
interrupt-parent = <&gic>;
tx-fifo-depth = <0x40>;
@@ -295,7 +289,7 @@
cci: cci@fd6e0000 {
compatible = "arm,cci-400";
- reg = <0x0 0xfd6e0000 0x9000>;
+ reg = <0x0 0xfd6e0000 0x0 0x9000>;
ranges = <0x0 0x0 0xfd6e0000 0x10000>;
#address-cells = <1>;
#size-cells = <1>;
@@ -316,200 +310,228 @@
fpd_dma_chan1: dma@fd500000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
- reg = <0x0 0xfd500000 0x1000>;
+ reg = <0x0 0xfd500000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 124 4>;
clock-names = "clk_main", "clk_apb";
- xlnx,id = <0>;
xlnx,bus-width = <128>;
+ #stream-id-cells = <1>;
+ iommus = <&smmu 0x14e8>;
power-domains = <&pd_gdma>;
};
fpd_dma_chan2: dma@fd510000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
- reg = <0x0 0xfd510000 0x1000>;
+ reg = <0x0 0xfd510000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 125 4>;
clock-names = "clk_main", "clk_apb";
- xlnx,id = <1>;
xlnx,bus-width = <128>;
+ #stream-id-cells = <1>;
+ iommus = <&smmu 0x14e9>;
power-domains = <&pd_gdma>;
};
fpd_dma_chan3: dma@fd520000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
- reg = <0x0 0xfd520000 0x1000>;
+ reg = <0x0 0xfd520000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 126 4>;
clock-names = "clk_main", "clk_apb";
- xlnx,id = <2>;
xlnx,bus-width = <128>;
+ #stream-id-cells = <1>;
+ iommus = <&smmu 0x14ea>;
power-domains = <&pd_gdma>;
};
fpd_dma_chan4: dma@fd530000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
- reg = <0x0 0xfd530000 0x1000>;
+ reg = <0x0 0xfd530000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 127 4>;
clock-names = "clk_main", "clk_apb";
- xlnx,id = <3>;
xlnx,bus-width = <128>;
+ #stream-id-cells = <1>;
+ iommus = <&smmu 0x14eb>;
power-domains = <&pd_gdma>;
};
fpd_dma_chan5: dma@fd540000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
- reg = <0x0 0xfd540000 0x1000>;
+ reg = <0x0 0xfd540000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 128 4>;
clock-names = "clk_main", "clk_apb";
- xlnx,id = <4>;
xlnx,bus-width = <128>;
+ #stream-id-cells = <1>;
+ iommus = <&smmu 0x14ec>;
power-domains = <&pd_gdma>;
};
fpd_dma_chan6: dma@fd550000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
- reg = <0x0 0xfd550000 0x1000>;
+ reg = <0x0 0xfd550000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 129 4>;
clock-names = "clk_main", "clk_apb";
- xlnx,id = <5>;
xlnx,bus-width = <128>;
+ #stream-id-cells = <1>;
+ iommus = <&smmu 0x14ed>;
power-domains = <&pd_gdma>;
};
fpd_dma_chan7: dma@fd560000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
- reg = <0x0 0xfd560000 0x1000>;
+ reg = <0x0 0xfd560000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 130 4>;
clock-names = "clk_main", "clk_apb";
- xlnx,id = <6>;
xlnx,bus-width = <128>;
+ #stream-id-cells = <1>;
+ iommus = <&smmu 0x14ee>;
power-domains = <&pd_gdma>;
};
fpd_dma_chan8: dma@fd570000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
- reg = <0x0 0xfd570000 0x1000>;
+ reg = <0x0 0xfd570000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 131 4>;
clock-names = "clk_main", "clk_apb";
- xlnx,id = <7>;
xlnx,bus-width = <128>;
+ #stream-id-cells = <1>;
+ iommus = <&smmu 0x14ef>;
power-domains = <&pd_gdma>;
};
gpu: gpu@fd4b0000 {
status = "disabled";
compatible = "arm,mali-400", "arm,mali-utgard";
- reg = <0x0 0xfd4b0000 0x30000>;
+ reg = <0x0 0xfd4b0000 0x0 0x30000>;
interrupt-parent = <&gic>;
interrupts = <0 132 4>, <0 132 4>, <0 132 4>, <0 132 4>, <0 132 4>, <0 132 4>;
interrupt-names = "IRQGP", "IRQGPMMU", "IRQPP0", "IRQPPMMU0", "IRQPP1", "IRQPPMMU1";
+ power-domains = <&pd_gpu>;
};
- /* ADMA */
+ /* LPDDMA default allows only secured access. inorder to enable
+ * These dma channels, Users should ensure that these dma
+ * Channels are allowed for non secure access.
+ */
lpd_dma_chan1: dma@ffa80000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
- reg = <0x0 0xffa80000 0x1000>;
+ clock-names = "clk_main", "clk_apb";
+ reg = <0x0 0xffa80000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 77 4>;
- xlnx,id = <0>;
xlnx,bus-width = <64>;
+ #stream-id-cells = <1>;
+ iommus = <&smmu 0x868>;
power-domains = <&pd_adma>;
};
lpd_dma_chan2: dma@ffa90000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
- reg = <0x0 0xffa90000 0x1000>;
+ clock-names = "clk_main", "clk_apb";
+ reg = <0x0 0xffa90000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 78 4>;
- xlnx,id = <1>;
xlnx,bus-width = <64>;
+ #stream-id-cells = <1>;
+ iommus = <&smmu 0x869>;
power-domains = <&pd_adma>;
};
lpd_dma_chan3: dma@ffaa0000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
- reg = <0x0 0xffaa0000 0x1000>;
+ clock-names = "clk_main", "clk_apb";
+ reg = <0x0 0xffaa0000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 79 4>;
- xlnx,id = <2>;
xlnx,bus-width = <64>;
+ #stream-id-cells = <1>;
+ iommus = <&smmu 0x86a>;
power-domains = <&pd_adma>;
};
lpd_dma_chan4: dma@ffab0000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
- reg = <0x0 0xffab0000 0x1000>;
+ clock-names = "clk_main", "clk_apb";
+ reg = <0x0 0xffab0000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 80 4>;
- xlnx,id = <3>;
xlnx,bus-width = <64>;
+ #stream-id-cells = <1>;
+ iommus = <&smmu 0x86b>;
power-domains = <&pd_adma>;
};
lpd_dma_chan5: dma@ffac0000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
- reg = <0x0 0xffac0000 0x1000>;
+ clock-names = "clk_main", "clk_apb";
+ reg = <0x0 0xffac0000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 81 4>;
- xlnx,id = <4>;
xlnx,bus-width = <64>;
+ #stream-id-cells = <1>;
+ iommus = <&smmu 0x86c>;
power-domains = <&pd_adma>;
};
lpd_dma_chan6: dma@ffad0000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
- reg = <0x0 0xffad0000 0x1000>;
+ clock-names = "clk_main", "clk_apb";
+ reg = <0x0 0xffad0000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 82 4>;
- xlnx,id = <5>;
xlnx,bus-width = <64>;
+ #stream-id-cells = <1>;
+ iommus = <&smmu 0x86d>;
power-domains = <&pd_adma>;
};
lpd_dma_chan7: dma@ffae0000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
- reg = <0x0 0xffae0000 0x1000>;
+ clock-names = "clk_main", "clk_apb";
+ reg = <0x0 0xffae0000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 83 4>;
- xlnx,id = <6>;
xlnx,bus-width = <64>;
+ #stream-id-cells = <1>;
+ iommus = <&smmu 0x86e>;
power-domains = <&pd_adma>;
};
lpd_dma_chan8: dma@ffaf0000 {
status = "disabled";
compatible = "xlnx,zynqmp-dma-1.0";
- reg = <0x0 0xffaf0000 0x1000>;
+ clock-names = "clk_main", "clk_apb";
+ reg = <0x0 0xffaf0000 0x0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 84 4>;
- xlnx,id = <7>;
xlnx,bus-width = <64>;
+ #stream-id-cells = <1>;
+ iommus = <&smmu 0x86f>;
power-domains = <&pd_adma>;
};
mc: memory-controller@fd070000 {
compatible = "xlnx,zynqmp-ddrc-2.40a";
- reg = <0x0 0xfd070000 0x30000>;
+ reg = <0x0 0xfd070000 0x0 0x30000>;
interrupt-parent = <&gic>;
interrupts = <0 112 4>;
};
@@ -517,12 +539,14 @@
nand0: nand@ff100000 {
compatible = "arasan,nfc-v3p10";
status = "disabled";
- reg = <0x0 0xff100000 0x1000>;
+ reg = <0x0 0xff100000 0x0 0x1000>;
clock-names = "clk_sys", "clk_flash";
interrupt-parent = <&gic>;
interrupts = <0 14 4>;
#address-cells = <2>;
#size-cells = <1>;
+ #stream-id-cells = <1>;
+ iommus = <&smmu 0x872>;
power-domains = <&pd_nand>;
};
@@ -531,11 +555,12 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 57 4>, <0 57 4>;
- reg = <0x0 0xff0b0000 0x1000>;
+ reg = <0x0 0xff0b0000 0x0 0x1000>;
clock-names = "pclk", "hclk", "tx_clk";
#address-cells = <1>;
#size-cells = <0>;
#stream-id-cells = <1>;
+ iommus = <&smmu 0x874>;
power-domains = <&pd_eth0>;
};
@@ -544,11 +569,12 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 59 4>, <0 59 4>;
- reg = <0x0 0xff0c0000 0x1000>;
+ reg = <0x0 0xff0c0000 0x0 0x1000>;
clock-names = "pclk", "hclk", "tx_clk";
#address-cells = <1>;
#size-cells = <0>;
#stream-id-cells = <1>;
+ iommus = <&smmu 0x875>;
power-domains = <&pd_eth1>;
};
@@ -557,11 +583,12 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 61 4>, <0 61 4>;
- reg = <0x0 0xff0d0000 0x1000>;
+ reg = <0x0 0xff0d0000 0x0 0x1000>;
clock-names = "pclk", "hclk", "tx_clk";
#address-cells = <1>;
#size-cells = <0>;
#stream-id-cells = <1>;
+ iommus = <&smmu 0x876>;
power-domains = <&pd_eth2>;
};
@@ -570,11 +597,12 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 63 4>, <0 63 4>;
- reg = <0x0 0xff0e0000 0x1000>;
+ reg = <0x0 0xff0e0000 0x0 0x1000>;
clock-names = "pclk", "hclk", "tx_clk";
#address-cells = <1>;
#size-cells = <0>;
#stream-id-cells = <1>;
+ iommus = <&smmu 0x877>;
power-domains = <&pd_eth3>;
};
@@ -582,11 +610,11 @@
compatible = "xlnx,zynqmp-gpio-1.0";
status = "disabled";
#gpio-cells = <0x2>;
- #interrupt-cells = <2>;
- interrupt-controller;
interrupt-parent = <&gic>;
interrupts = <0 16 4>;
- reg = <0x0 0xff0a0000 0x1000>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x0 0xff0a0000 0x0 0x1000>;
power-domains = <&pd_gpio>;
};
@@ -595,7 +623,7 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 17 4>;
- reg = <0x0 0xff020000 0x1000>;
+ reg = <0x0 0xff020000 0x0 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
power-domains = <&pd_i2c0>;
@@ -606,35 +634,47 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 18 4>;
- reg = <0x0 0xff030000 0x1000>;
+ reg = <0x0 0xff030000 0x0 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
power-domains = <&pd_i2c1>;
};
+ ocm: memory-controller@ff960000 {
+ compatible = "xlnx,zynqmp-ocmc-1.0";
+ reg = <0x0 0xff960000 0x0 0x1000>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 10 4>;
+ };
+
pcie: pcie@fd0e0000 {
compatible = "xlnx,nwl-pcie-2.11";
status = "disabled";
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
+ msi-controller;
device_type = "pci";
interrupt-parent = <&gic>;
interrupts = <0 118 4>,
+ <0 117 4>,
<0 116 4>,
<0 115 4>, /* MSI_1 [63...32] */
<0 114 4>; /* MSI_0 [31...0] */
- interrupt-names = "misc", "intx", "msi_1", "msi_0";
- reg = <0x0 0xfd0e0000 0x1000>,
- <0x0 0xfd480000 0x1000>,
- <0x0 0xe0000000 0x1000000>;
+ interrupt-names = "misc","dummy","intx", "msi1", "msi0";
+ msi-parent = <&pcie>;
+ reg = <0x0 0xfd0e0000 0x0 0x1000>,
+ <0x0 0xfd480000 0x0 0x1000>,
+ <0x80 0x00000000 0x0 0x1000000>;
reg-names = "breg", "pcireg", "cfg";
- ranges = <0x02000000 0x00000000 0xe1000000 0x00000000 0xe1000000 0 0x0f000000>;
+ ranges = <0x02000000 0x00000000 0xe0000000 0x00000000 0xe0000000 0x00000000 0x10000000 /* non-prefetchable memory */
+ 0x43000000 0x00000006 0x00000000 0x00000006 0x00000000 0x00000002 0x00000000>;/* prefetchable memory */
interrupt-map-mask = <0x0 0x0 0x0 0x7>;
interrupt-map = <0x0 0x0 0x0 0x1 &pcie_intc 0x1>,
<0x0 0x0 0x0 0x2 &pcie_intc 0x2>,
<0x0 0x0 0x0 0x3 &pcie_intc 0x3>,
<0x0 0x0 0x0 0x4 &pcie_intc 0x4>;
+ power-domains = <&pd_pcie>;
pcie_intc: legacy-interrupt-controller {
interrupt-controller;
#address-cells = <0>;
@@ -649,26 +689,51 @@
interrupts = <0 15 4>;
interrupt-parent = <&gic>;
num-cs = <1>;
- reg = <0x0 0xff0f0000 0x1000>,
- <0x0 0xc0000000 0x8000000>;
+ reg = <0x0 0xff0f0000 0x0 0x1000>,
+ <0x0 0xc0000000 0x0 0x8000000>;
#address-cells = <1>;
#size-cells = <0>;
+ #stream-id-cells = <1>;
+ iommus = <&smmu 0x873>;
power-domains = <&pd_qspi>;
};
rtc: rtc@ffa60000 {
compatible = "xlnx,zynqmp-rtc";
status = "disabled";
- reg = <0x0 0xffa60000 0x100>;
+ reg = <0x0 0xffa60000 0x0 0x100>;
interrupt-parent = <&gic>;
interrupts = <0 26 4>, <0 27 4>;
interrupt-names = "alarm", "sec";
};
+ serdes: zynqmp_phy@fd400000 {
+ compatible = "xlnx,zynqmp-psgtr";
+ status = "disabled";
+ reg = <0x0 0xfd400000 0x0 0x40000>,
+ <0x0 0xfd3d0000 0x0 0x1000>,
+ <0x0 0xfd1a0000 0x0 0x1000>,
+ <0x0 0xff5e0000 0x0 0x1000>;
+ reg-names = "serdes", "siou", "fpd", "lpd";
+ xlnx,tx_termination_fix;
+ lane0: lane0 {
+ #phy-cells = <4>;
+ };
+ lane1: lane1 {
+ #phy-cells = <4>;
+ };
+ lane2: lane2 {
+ #phy-cells = <4>;
+ };
+ lane3: lane3 {
+ #phy-cells = <4>;
+ };
+ };
+
sata: ahci@fd0c0000 {
compatible = "ceva,ahci-1v84";
status = "disabled";
- reg = <0x0 0xfd0c0000 0x2000>;
+ reg = <0x0 0xfd0c0000 0x0 0x2000>;
interrupt-parent = <&gic>;
interrupts = <0 133 4>;
power-domains = <&pd_sata>;
@@ -676,31 +741,36 @@
sdhci0: sdhci@ff160000 {
u-boot,dm-pre-reloc;
- compatible = "arasan,sdhci-8.9a";
+ compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a";
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 48 4>;
- reg = <0x0 0xff160000 0x1000>;
+ reg = <0x0 0xff160000 0x0 0x1000>;
clock-names = "clk_xin", "clk_ahb";
- broken-tuning;
+ xlnx,device_id = <0>;
+ #stream-id-cells = <1>;
+ iommus = <&smmu 0x870>;
power-domains = <&pd_sd0>;
};
sdhci1: sdhci@ff170000 {
u-boot,dm-pre-reloc;
- compatible = "arasan,sdhci-8.9a";
+ compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a";
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 49 4>;
- reg = <0x0 0xff170000 0x1000>;
+ reg = <0x0 0xff170000 0x0 0x1000>;
clock-names = "clk_xin", "clk_ahb";
- broken-tuning;
+ xlnx,device_id = <1>;
+ #stream-id-cells = <1>;
+ iommus = <&smmu 0x871>;
power-domains = <&pd_sd1>;
};
smmu: smmu@fd800000 {
compatible = "arm,mmu-500";
- reg = <0x0 0xfd800000 0x20000>;
+ reg = <0x0 0xfd800000 0x0 0x20000>;
+ #iommu-cells = <1>;
#global-interrupts = <1>;
interrupt-parent = <&gic>;
interrupts = <0 155 4>,
@@ -711,7 +781,29 @@
mmu-masters = < &gem0 0x874
&gem1 0x875
&gem2 0x876
- &gem3 0x877 >;
+ &gem3 0x877
+ &usb0 0x860
+ &usb1 0x861
+ &qspi 0x873
+ &lpd_dma_chan1 0x868
+ &lpd_dma_chan2 0x869
+ &lpd_dma_chan3 0x86a
+ &lpd_dma_chan4 0x86b
+ &lpd_dma_chan5 0x86c
+ &lpd_dma_chan6 0x86d
+ &lpd_dma_chan7 0x86e
+ &lpd_dma_chan8 0x86f
+ &fpd_dma_chan1 0x14e8
+ &fpd_dma_chan2 0x14e9
+ &fpd_dma_chan3 0x14ea
+ &fpd_dma_chan4 0x14eb
+ &fpd_dma_chan5 0x14ec
+ &fpd_dma_chan6 0x14ed
+ &fpd_dma_chan7 0x14ee
+ &fpd_dma_chan8 0x14ef
+ &sdhci0 0x870
+ &sdhci1 0x871
+ &nand0 0x872>;
};
spi0: spi@ff040000 {
@@ -719,7 +811,7 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 19 4>;
- reg = <0x0 0xff040000 0x1000>;
+ reg = <0x0 0xff040000 0x0 0x1000>;
clock-names = "ref_clk", "pclk";
#address-cells = <1>;
#size-cells = <0>;
@@ -731,7 +823,7 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 20 4>;
- reg = <0x0 0xff050000 0x1000>;
+ reg = <0x0 0xff050000 0x0 0x1000>;
clock-names = "ref_clk", "pclk";
#address-cells = <1>;
#size-cells = <0>;
@@ -743,7 +835,7 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 36 4>, <0 37 4>, <0 38 4>;
- reg = <0x0 0xff110000 0x1000>;
+ reg = <0x0 0xff110000 0x0 0x1000>;
timer-width = <32>;
power-domains = <&pd_ttc0>;
};
@@ -753,7 +845,7 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 39 4>, <0 40 4>, <0 41 4>;
- reg = <0x0 0xff120000 0x1000>;
+ reg = <0x0 0xff120000 0x0 0x1000>;
timer-width = <32>;
power-domains = <&pd_ttc1>;
};
@@ -763,7 +855,7 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 42 4>, <0 43 4>, <0 44 4>;
- reg = <0x0 0xff130000 0x1000>;
+ reg = <0x0 0xff130000 0x0 0x1000>;
timer-width = <32>;
power-domains = <&pd_ttc2>;
};
@@ -773,7 +865,7 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 45 4>, <0 46 4>, <0 47 4>;
- reg = <0x0 0xff140000 0x1000>;
+ reg = <0x0 0xff140000 0x0 0x1000>;
timer-width = <32>;
power-domains = <&pd_ttc3>;
};
@@ -784,7 +876,7 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 21 4>;
- reg = <0x0 0xff000000 0x1000>;
+ reg = <0x0 0xff000000 0x0 0x1000>;
clock-names = "uart_clk", "pclk";
power-domains = <&pd_uart0>;
};
@@ -795,25 +887,27 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 22 4>;
- reg = <0x0 0xff010000 0x1000>;
+ reg = <0x0 0xff010000 0x0 0x1000>;
clock-names = "uart_clk", "pclk";
power-domains = <&pd_uart1>;
};
- usb0: usb@fe200000 {
+ usb0: usb0 {
#address-cells = <2>;
- #size-cells = <1>;
+ #size-cells = <2>;
status = "disabled";
compatible = "xlnx,zynqmp-dwc3";
clock-names = "bus_clk", "ref_clk";
clocks = <&clk125>, <&clk125>;
+ #stream-id-cells = <1>;
+ iommus = <&smmu 0x860>;
power-domains = <&pd_usb0>;
ranges;
dwc3_0: dwc3@fe200000 {
compatible = "snps,dwc3";
status = "disabled";
- reg = <0x0 0xfe200000 0x40000>;
+ reg = <0x0 0xfe200000 0x0 0x40000>;
interrupt-parent = <&gic>;
interrupts = <0 65 4>;
/* snps,quirk-frame-length-adjustment = <0x20>; */
@@ -821,20 +915,22 @@
};
};
- usb1: usb@fe300000 {
+ usb1: usb1 {
#address-cells = <2>;
- #size-cells = <1>;
+ #size-cells = <2>;
status = "disabled";
compatible = "xlnx,zynqmp-dwc3";
clock-names = "bus_clk", "ref_clk";
clocks = <&clk125>, <&clk125>;
+ #stream-id-cells = <1>;
+ iommus = <&smmu 0x861>;
power-domains = <&pd_usb1>;
ranges;
dwc3_1: dwc3@fe300000 {
compatible = "snps,dwc3";
status = "disabled";
- reg = <0x0 0xfe300000 0x40000>;
+ reg = <0x0 0xfe300000 0x0 0x40000>;
interrupt-parent = <&gic>;
interrupts = <0 70 4>;
/* snps,quirk-frame-length-adjustment = <0x20>; */
@@ -847,7 +943,7 @@
status = "disabled";
interrupt-parent = <&gic>;
interrupts = <0 113 1>;
- reg = <0x0 0xfd4d0000 0x1000>;
+ reg = <0x0 0xfd4d0000 0x0 0x1000>;
timeout-sec = <10>;
};
@@ -861,11 +957,13 @@
xlnx,pixel-format = "rgb565";
plane0 {
dmas = <&xlnx_dpdma 3>;
- dma-names = "dma";
+ dma-names = "dma0";
};
plane1 {
- dmas = <&xlnx_dpdma 0>;
- dma-names = "dma";
+ dmas = <&xlnx_dpdma 0>,
+ <&xlnx_dpdma 1>,
+ <&xlnx_dpdma 2>;
+ dma-names = "dma0", "dma1", "dma2";
};
};
};
@@ -873,8 +971,7 @@
xlnx_dp: dp@fd4a0000 {
compatible = "xlnx,v-dp";
status = "disabled";
- reg = <0x0 0xfd4a0000 0x1000>,
- <0x0 0xfd400000 0x20000>;
+ reg = <0x0 0xfd4a0000 0x0 0x1000>;
interrupts = <0 119 4>;
interrupt-parent = <&gic>;
clock-names = "aclk", "aud_clk";
@@ -920,9 +1017,9 @@
xlnx_dp_sub: dp_sub@fd4aa000 {
compatible = "xlnx,dp-sub";
status = "disabled";
- reg = <0x0 0xfd4aa000 0x1000>,
- <0x0 0xfd4ab000 0x1000>,
- <0x0 0xfd4ac000 0x1000>;
+ reg = <0x0 0xfd4aa000 0x0 0x1000>,
+ <0x0 0xfd4ab000 0x0 0x1000>,
+ <0x0 0xfd4ac000 0x0 0x1000>;
reg-names = "blend", "av_buf", "aud";
xlnx,output-fmt = "rgb";
xlnx,vid-fmt = "yuyv";
@@ -932,28 +1029,28 @@
xlnx_dpdma: dma@fd4c0000 {
compatible = "xlnx,dpdma";
status = "disabled";
- reg = <0x0 0xfd4c0000 0x1000>;
+ reg = <0x0 0xfd4c0000 0x0 0x1000>;
interrupts = <0 122 4>;
interrupt-parent = <&gic>;
clock-names = "axi_clk";
dma-channels = <6>;
#dma-cells = <1>;
- dma-video0channel@fd4c0000 {
+ dma-video0channel {
compatible = "xlnx,video0";
};
- dma-video1channel@fd4c0000 {
+ dma-video1channel {
compatible = "xlnx,video1";
};
- dma-video2channel@fd4c0000 {
+ dma-video2channel {
compatible = "xlnx,video2";
};
- dma-graphicschannel@fd4c0000 {
+ dma-graphicschannel {
compatible = "xlnx,graphics";
};
- dma-audio0channel@fd4c0000 {
+ dma-audio0channel {
compatible = "xlnx,audio0";
};
- dma-audio1channel@fd4c0000 {
+ dma-audio1channel {
compatible = "xlnx,audio1";
};
};
diff --git a/arch/arm/include/asm/arch-zynqmp/hardware.h b/arch/arm/include/asm/arch-zynqmp/hardware.h
index 456c1b0902..e7738faaf8 100644
--- a/arch/arm/include/asm/arch-zynqmp/hardware.h
+++ b/arch/arm/include/asm/arch-zynqmp/hardware.h
@@ -79,6 +79,7 @@ struct iou_scntr_secure {
#define NAND_MODE 0x00000004
#define EMMC_MODE 0x00000006
#define USB_MODE 0x00000007
+#define SD1_LSHFT_MODE 0x0000000E /* SD1 Level shifter */
#define JTAG_MODE 0x00000000
#define BOOT_MODE_USE_ALT 0x100
#define BOOT_MODE_ALT_SHIFT 12
diff --git a/arch/arm/include/asm/u-boot-arm.h b/arch/arm/include/asm/u-boot-arm.h
index 414042d403..305a302dfc 100644
--- a/arch/arm/include/asm/u-boot-arm.h
+++ b/arch/arm/include/asm/u-boot-arm.h
@@ -37,6 +37,7 @@ int arch_early_init_r(void);
/* board/.../... */
int board_init(void);
void dram_init_banksize (void);
+void board_quiesce_devices(void);
/* cpu/.../interrupt.c */
int arch_interrupt_init (void);
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index caa62c6355..a812306c25 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -92,3 +92,13 @@ AFLAGS_memset.o := -DMEMSET_NO_THUMB_BUILD
AFLAGS_memcpy.o := -DMEMCPY_NO_THUMB_BUILD
endif
endif
+
+# For building EFI apps
+CFLAGS_$(EFI_CRT0) := $(CFLAGS_EFI)
+CFLAGS_REMOVE_$(EFI_CRT0) := $(CFLAGS_NON_EFI)
+
+CFLAGS_$(EFI_RELOC) := $(CFLAGS_EFI)
+CFLAGS_REMOVE_$(EFI_RELOC) := $(CFLAGS_NON_EFI)
+
+extra-$(CONFIG_CMD_BOOTEFI_HELLO) += $(EFI_CRT0) $(EFI_RELOC)
+extra-$(CONFIG_EFI) += $(EFI_CRT0) $(EFI_RELOC)
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
index 53c3141322..dedcd1e9a4 100644
--- a/arch/arm/lib/bootm.c
+++ b/arch/arm/lib/bootm.c
@@ -64,6 +64,10 @@ void arch_lmb_reserve(struct lmb *lmb)
gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size - sp);
}
+__weak void board_quiesce_devices(void)
+{
+}
+
/**
* announce_and_cleanup() - Print message and prepare for kernel boot
*
@@ -84,6 +88,9 @@ static void announce_and_cleanup(int fake)
#ifdef CONFIG_USB_DEVICE
udc_disconnect();
#endif
+
+ board_quiesce_devices();
+
cleanup_before_linux();
}
diff --git a/arch/arm/lib/crt0_aarch64_efi.S b/arch/arm/lib/crt0_aarch64_efi.S
new file mode 100644
index 0000000000..52056469be
--- /dev/null
+++ b/arch/arm/lib/crt0_aarch64_efi.S
@@ -0,0 +1,135 @@
+/*
+ * crt0-efi-aarch64.S - PE/COFF header for aarch64 EFI applications
+ *
+ * Copright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+ BSD-2-Clause
+ *
+ * This file is taken and modified from the gnu-efi project.
+ */
+
+ .section .text.head
+
+ /*
+ * Magic "MZ" signature for PE/COFF
+ */
+ .globl ImageBase
+ImageBase:
+ .ascii "MZ"
+ .skip 58 /* 'MZ' + pad + offset == 64 */
+ .long pe_header - ImageBase /* Offset to the PE header */
+pe_header:
+ .ascii "PE"
+ .short 0
+coff_header:
+ .short 0xaa64 /* AArch64 */
+ .short 2 /* nr_sections */
+ .long 0 /* TimeDateStamp */
+ .long 0 /* PointerToSymbolTable */
+ .long 1 /* NumberOfSymbols */
+ .short section_table - optional_header /* SizeOfOptionalHeader */
+ /*
+ * Characteristics: IMAGE_FILE_DEBUG_STRIPPED |
+ * IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_LINE_NUMS_STRIPPED
+ */
+ .short 0x206
+optional_header:
+ .short 0x20b /* PE32+ format */
+ .byte 0x02 /* MajorLinkerVersion */
+ .byte 0x14 /* MinorLinkerVersion */
+ .long _edata - _start /* SizeOfCode */
+ .long 0 /* SizeOfInitializedData */
+ .long 0 /* SizeOfUninitializedData */
+ .long _start - ImageBase /* AddressOfEntryPoint */
+ .long _start - ImageBase /* BaseOfCode */
+
+extra_header_fields:
+ .quad 0 /* ImageBase */
+ .long 0x20 /* SectionAlignment */
+ .long 0x8 /* FileAlignment */
+ .short 0 /* MajorOperatingSystemVersion */
+ .short 0 /* MinorOperatingSystemVersion */
+ .short 0 /* MajorImageVersion */
+ .short 0 /* MinorImageVersion */
+ .short 0 /* MajorSubsystemVersion */
+ .short 0 /* MinorSubsystemVersion */
+ .long 0 /* Win32VersionValue */
+
+ .long _edata - ImageBase /* SizeOfImage */
+
+ /*
+ * Everything before the kernel image is considered part of the header
+ */
+ .long _start - ImageBase /* SizeOfHeaders */
+ .long 0 /* CheckSum */
+ .short EFI_SUBSYSTEM /* Subsystem */
+ .short 0 /* DllCharacteristics */
+ .quad 0 /* SizeOfStackReserve */
+ .quad 0 /* SizeOfStackCommit */
+ .quad 0 /* SizeOfHeapReserve */
+ .quad 0 /* SizeOfHeapCommit */
+ .long 0 /* LoaderFlags */
+ .long 0x6 /* NumberOfRvaAndSizes */
+
+ .quad 0 /* ExportTable */
+ .quad 0 /* ImportTable */
+ .quad 0 /* ResourceTable */
+ .quad 0 /* ExceptionTable */
+ .quad 0 /* CertificationTable */
+ .quad 0 /* BaseRelocationTable */
+
+ /* Section table */
+section_table:
+
+ /*
+ * The EFI application loader requires a relocation section
+ * because EFI applications must be relocatable. This is a
+ * dummy section as far as we are concerned.
+ */
+ .ascii ".reloc"
+ .byte 0
+ .byte 0 /* end of 0 padding of section name */
+ .long 0
+ .long 0
+ .long 0 /* SizeOfRawData */
+ .long 0 /* PointerToRawData */
+ .long 0 /* PointerToRelocations */
+ .long 0 /* PointerToLineNumbers */
+ .short 0 /* NumberOfRelocations */
+ .short 0 /* NumberOfLineNumbers */
+ .long 0x42100040 /* Characteristics (section flags) */
+
+
+ .ascii ".text"
+ .byte 0
+ .byte 0
+ .byte 0 /* end of 0 padding of section name */
+ .long _edata - _start /* VirtualSize */
+ .long _start - ImageBase /* VirtualAddress */
+ .long _edata - _start /* SizeOfRawData */
+ .long _start - ImageBase /* PointerToRawData */
+
+ .long 0 /* PointerToRelocations (0 for executables) */
+ .long 0 /* PointerToLineNumbers (0 for executables) */
+ .short 0 /* NumberOfRelocations (0 for executables) */
+ .short 0 /* NumberOfLineNumbers (0 for executables) */
+ .long 0xe0500020 /* Characteristics (section flags) */
+
+_start:
+ stp x29, x30, [sp, #-32]!
+ mov x29, sp
+
+ stp x0, x1, [sp, #16]
+ mov x2, x0
+ mov x3, x1
+ adr x0, ImageBase
+ adrp x1, _DYNAMIC
+ add x1, x1, #:lo12:_DYNAMIC
+ bl _relocate
+ cbnz x0, 0f
+
+ ldp x0, x1, [sp, #16]
+ bl efi_main
+
+0: ldp x29, x30, [sp], #32
+ ret
diff --git a/arch/arm/lib/crt0_arm_efi.S b/arch/arm/lib/crt0_arm_efi.S
new file mode 100644
index 0000000000..967c885982
--- /dev/null
+++ b/arch/arm/lib/crt0_arm_efi.S
@@ -0,0 +1,138 @@
+/*
+ * crt0-efi-arm.S - PE/COFF header for ARM EFI applications
+ *
+ * Copright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+ BSD-2-Clause
+ *
+ * This file is taken and modified from the gnu-efi project.
+ */
+
+ .section .text.head
+
+ /*
+ * Magic "MZ" signature for PE/COFF
+ */
+ .globl image_base
+image_base:
+ .ascii "MZ"
+ .skip 58 /* 'MZ' + pad + offset == 64 */
+ .long pe_header - image_base /* Offset to the PE header */
+pe_header:
+ .ascii "PE"
+ .short 0
+coff_header:
+ .short 0x1c2 /* Mixed ARM/Thumb */
+ .short 2 /* nr_sections */
+ .long 0 /* TimeDateStamp */
+ .long 0 /* PointerToSymbolTable */
+ .long 1 /* NumberOfSymbols */
+ .short section_table - optional_header /* SizeOfOptionalHeader */
+ /*
+ * Characteristics: IMAGE_FILE_32BIT_MACHINE |
+ * IMAGE_FILE_DEBUG_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE |
+ * IMAGE_FILE_LINE_NUMS_STRIPPED
+ */
+ .short 0x306
+optional_header:
+ .short 0x10b /* PE32+ format */
+ .byte 0x02 /* MajorLinkerVersion */
+ .byte 0x14 /* MinorLinkerVersion */
+ .long _edata - _start /* SizeOfCode */
+ .long 0 /* SizeOfInitializedData */
+ .long 0 /* SizeOfUninitializedData */
+ .long _start - image_base /* AddressOfEntryPoint */
+ .long _start - image_base /* BaseOfCode */
+ .long 0 /* BaseOfData */
+
+extra_header_fields:
+ .long 0 /* image_base */
+ .long 0x20 /* SectionAlignment */
+ .long 0x8 /* FileAlignment */
+ .short 0 /* MajorOperatingSystemVersion */
+ .short 0 /* MinorOperatingSystemVersion */
+ .short 0 /* MajorImageVersion */
+ .short 0 /* MinorImageVersion */
+ .short 0 /* MajorSubsystemVersion */
+ .short 0 /* MinorSubsystemVersion */
+ .long 0 /* Win32VersionValue */
+
+ .long _edata - image_base /* SizeOfImage */
+
+ /*
+ * Everything before the kernel image is considered part of the header
+ */
+ .long _start - image_base /* SizeOfHeaders */
+ .long 0 /* CheckSum */
+ .short EFI_SUBSYSTEM /* Subsystem */
+ .short 0 /* DllCharacteristics */
+ .long 0 /* SizeOfStackReserve */
+ .long 0 /* SizeOfStackCommit */
+ .long 0 /* SizeOfHeapReserve */
+ .long 0 /* SizeOfHeapCommit */
+ .long 0 /* LoaderFlags */
+ .long 0x6 /* NumberOfRvaAndSizes */
+
+ .quad 0 /* ExportTable */
+ .quad 0 /* ImportTable */
+ .quad 0 /* ResourceTable */
+ .quad 0 /* ExceptionTable */
+ .quad 0 /* CertificationTable */
+ .quad 0 /* BaseRelocationTable */
+
+section_table:
+
+ /*
+ * The EFI application loader requires a relocation section
+ * because EFI applications must be relocatable. This is a
+ * dummy section as far as we are concerned.
+ */
+ .ascii ".reloc"
+ .byte 0
+ .byte 0 /* end of 0 padding of section name */
+ .long 0
+ .long 0
+ .long 0 /* SizeOfRawData */
+ .long 0 /* PointerToRawData */
+ .long 0 /* PointerToRelocations */
+ .long 0 /* PointerToLineNumbers */
+ .short 0 /* NumberOfRelocations */
+ .short 0 /* NumberOfLineNumbers */
+ .long 0x42100040 /* Characteristics (section flags) */
+
+ .ascii ".text"
+ .byte 0
+ .byte 0
+ .byte 0 /* end of 0 padding of section name */
+ .long _edata - _start /* VirtualSize */
+ .long _start - image_base /* VirtualAddress */
+ .long _edata - _start /* SizeOfRawData */
+ .long _start - image_base /* PointerToRawData */
+
+ .long 0 /* PointerToRelocations (0 for executables) */
+ .long 0 /* PointerToLineNumbers (0 for executables) */
+ .short 0 /* NumberOfRelocations (0 for executables) */
+ .short 0 /* NumberOfLineNumbers (0 for executables) */
+ .long 0xe0500020 /* Characteristics (section flags) */
+
+_start:
+ stmfd sp!, {r0-r2, lr}
+
+ mov r2, r0
+ mov r3, r1
+ adr r1, .L_DYNAMIC
+ ldr r0, [r1]
+ add r1, r0, r1
+ adr r0, image_base
+ bl _relocate
+ teq r0, #0
+ bne 0f
+
+ ldmfd sp, {r0-r1}
+ bl efi_main
+
+0: add sp, sp, #12
+ ldr pc, [sp], #4
+
+.L_DYNAMIC:
+ .word _DYNAMIC - .
diff --git a/arch/arm/lib/elf_aarch64_efi.lds b/arch/arm/lib/elf_aarch64_efi.lds
new file mode 100644
index 0000000000..47cce1db97
--- /dev/null
+++ b/arch/arm/lib/elf_aarch64_efi.lds
@@ -0,0 +1,70 @@
+/*
+ * U-Boot aarch64 EFI linker script
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Modified from elf_aarch64_efi.lds in gnu-efi
+ */
+
+OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
+OUTPUT_ARCH(aarch64)
+ENTRY(_start)
+SECTIONS
+{
+ .text 0x0 : {
+ _text = .;
+ *(.text.head)
+ *(.text)
+ *(.text.*)
+ *(.gnu.linkonce.t.*)
+ *(.srodata)
+ *(.rodata*)
+ . = ALIGN(16);
+ }
+ _etext = .;
+ _text_size = . - _text;
+ .dynamic : { *(.dynamic) }
+ .data : {
+ _data = .;
+ *(.sdata)
+ *(.data)
+ *(.data1)
+ *(.data.*)
+ *(.got.plt)
+ *(.got)
+
+ /*
+ * The EFI loader doesn't seem to like a .bss section, so we
+ * stick it all into .data:
+ */
+ . = ALIGN(16);
+ _bss = .;
+ *(.sbss)
+ *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(.bss.*)
+ *(COMMON)
+ . = ALIGN(16);
+ _bss_end = .;
+ _edata = .;
+ }
+ .rela.dyn : { *(.rela.dyn) }
+ .rela.plt : { *(.rela.plt) }
+ .rela.got : { *(.rela.got) }
+ .rela.data : { *(.rela.data) *(.rela.data*) }
+ _data_size = . - _etext;
+
+ . = ALIGN(4096);
+ .dynsym : { *(.dynsym) }
+ . = ALIGN(4096);
+ .dynstr : { *(.dynstr) }
+ . = ALIGN(4096);
+ .note.gnu.build-id : { *(.note.gnu.build-id) }
+ /DISCARD/ : {
+ *(.rel.reloc)
+ *(.eh_frame)
+ *(.note.GNU-stack)
+ }
+ .comment 0 : { *(.comment) }
+}
diff --git a/arch/arm/lib/elf_arm_efi.lds b/arch/arm/lib/elf_arm_efi.lds
new file mode 100644
index 0000000000..59f66a1d4a
--- /dev/null
+++ b/arch/arm/lib/elf_arm_efi.lds
@@ -0,0 +1,70 @@
+/*
+ * U-Boot ARM EFI linker script
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Modified from elf_arm_efi.lds in gnu-efi
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ .text 0x0 : {
+ _text = .;
+ *(.text.head)
+ *(.text)
+ *(.text.*)
+ *(.gnu.linkonce.t.*)
+ *(.srodata)
+ *(.rodata*)
+ . = ALIGN(16);
+ }
+ _etext = .;
+ _text_size = . - _text;
+ .dynamic : { *(.dynamic) }
+ .data : {
+ _data = .;
+ *(.sdata)
+ *(.data)
+ *(.data1)
+ *(.data.*)
+ *(.got.plt)
+ *(.got)
+
+ /*
+ * The EFI loader doesn't seem to like a .bss section, so we
+ * stick it all into .data:
+ */
+ . = ALIGN(16);
+ _bss = .;
+ *(.sbss)
+ *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(.bss.*)
+ *(COMMON)
+ . = ALIGN(16);
+ _bss_end = .;
+ _edata = .;
+ }
+ .rel.dyn : { *(.rel.dyn) }
+ .rel.plt : { *(.rel.plt) }
+ .rel.got : { *(.rel.got) }
+ .rel.data : { *(.rel.data) *(.rel.data*) }
+ _data_size = . - _etext;
+
+ . = ALIGN(4096);
+ .dynsym : { *(.dynsym) }
+ . = ALIGN(4096);
+ .dynstr : { *(.dynstr) }
+ . = ALIGN(4096);
+ .note.gnu.build-id : { *(.note.gnu.build-id) }
+ /DISCARD/ : {
+ *(.rel.reloc)
+ *(.eh_frame)
+ *(.note.GNU-stack)
+ }
+ .comment 0 : { *(.comment) }
+}
diff --git a/arch/arm/lib/reloc_aarch64_efi.c b/arch/arm/lib/reloc_aarch64_efi.c
new file mode 100644
index 0000000000..38c13d3689
--- /dev/null
+++ b/arch/arm/lib/reloc_aarch64_efi.c
@@ -0,0 +1,87 @@
+/* reloc_aarch64.c - position independent x86 ELF shared object relocator
+ Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
+ Copyright (C) 1999 Hewlett-Packard Co.
+ Contributed by David Mosberger <davidm@hpl.hp.com>.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+ * Neither the name of Hewlett-Packard Co. nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+*/
+
+#include <efi.h>
+
+#include <elf.h>
+
+efi_status_t _relocate(long ldbase, Elf64_Dyn *dyn, efi_handle_t image,
+ struct efi_system_table *systab)
+{
+ long relsz = 0, relent = 0;
+ Elf64_Rela *rel = 0;
+ unsigned long *addr;
+ int i;
+
+ for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
+ switch (dyn[i].d_tag) {
+ case DT_RELA:
+ rel = (Elf64_Rela *)((ulong)dyn[i].d_un.d_ptr + ldbase);
+ break;
+ case DT_RELASZ:
+ relsz = dyn[i].d_un.d_val;
+ break;
+ case DT_RELAENT:
+ relent = dyn[i].d_un.d_val;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!rel && relent == 0)
+ return EFI_SUCCESS;
+
+ if (!rel || relent == 0)
+ return EFI_LOAD_ERROR;
+
+ while (relsz > 0) {
+ /* apply the relocs */
+ switch (ELF64_R_TYPE(rel->r_info)) {
+ case R_AARCH64_NONE:
+ break;
+ case R_AARCH64_RELATIVE:
+ addr = (ulong *)(ldbase + rel->r_offset);
+ *addr = ldbase + rel->r_addend;
+ break;
+ default:
+ break;
+ }
+ rel = (Elf64_Rela *)((char *)rel + relent);
+ relsz -= relent;
+ }
+ return EFI_SUCCESS;
+}
diff --git a/arch/arm/lib/reloc_arm_efi.c b/arch/arm/lib/reloc_arm_efi.c
new file mode 100644
index 0000000000..d2f96eeb98
--- /dev/null
+++ b/arch/arm/lib/reloc_arm_efi.c
@@ -0,0 +1,66 @@
+/*
+ * reloc_arm.c - position-independent ARM ELF shared object relocator
+ *
+ * Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
+ * Copyright (C) 1999 Hewlett-Packard Co.
+ * Contributed by David Mosberger <davidm@hpl.hp.com>.
+ *
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is taken and modified from the gnu-efi project.
+ */
+
+#include <efi.h>
+#include <elf.h>
+
+efi_status_t _relocate(long ldbase, Elf32_Dyn *dyn, efi_handle_t image,
+ struct efi_system_table *systab)
+{
+ long relsz = 0, relent = 0;
+ Elf32_Rel *rel = 0;
+ ulong *addr;
+ int i;
+
+ for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
+ switch (dyn[i].d_tag) {
+ case DT_REL:
+ rel = (Elf32_Rel *)((ulong)dyn[i].d_un.d_ptr
+ + ldbase);
+ break;
+ case DT_RELSZ:
+ relsz = dyn[i].d_un.d_val;
+ break;
+ case DT_RELENT:
+ relent = dyn[i].d_un.d_val;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!rel && relent == 0)
+ return EFI_SUCCESS;
+
+ if (!rel || relent == 0)
+ return EFI_LOAD_ERROR;
+
+ while (relsz > 0) {
+ /* apply the relocs */
+ switch (ELF32_R_TYPE(rel->r_info)) {
+ case R_ARM_NONE:
+ break;
+ case R_ARM_RELATIVE:
+ addr = (ulong *)(ldbase + rel->r_offset);
+ *addr += ldbase;
+ break;
+ default:
+ break;
+ }
+ rel = (Elf32_Rel *)((char *)rel + relent);
+ relsz -= relent;
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/arch/arm/lib/relocate.S b/arch/arm/lib/relocate.S
index 475d503dd9..a6fb07c401 100644
--- a/arch/arm/lib/relocate.S
+++ b/arch/arm/lib/relocate.S
@@ -8,6 +8,7 @@
#include <asm-offsets.h>
#include <config.h>
+#include <elf.h>
#include <linux/linkage.h>
#ifdef CONFIG_CPU_V7M
#include <asm/armv7m.h>
@@ -96,7 +97,7 @@ copy_loop:
fixloop:
ldmia r2!, {r0-r1} /* (r0,r1) <- (SRC location,fixup) */
and r1, r1, #0xff
- cmp r1, #23 /* relative fixup? */
+ cmp r1, #R_ARM_RELATIVE
bne fixnext
/* relative fix: increase location by offset */
diff --git a/arch/arm/lib/relocate_64.S b/arch/arm/lib/relocate_64.S
index 5c51cae8ab..242e56e960 100644
--- a/arch/arm/lib/relocate_64.S
+++ b/arch/arm/lib/relocate_64.S
@@ -10,6 +10,7 @@
#include <asm-offsets.h>
#include <config.h>
+#include <elf.h>
#include <linux/linkage.h>
#include <asm/macro.h>
@@ -47,7 +48,7 @@ fixloop:
ldp x0, x1, [x2], #16 /* (x0,x1) <- (SRC location, fixup) */
ldr x4, [x2], #8 /* x4 <- addend */
and x1, x1, #0xffffffff
- cmp x1, #1027 /* relative fixup? */
+ cmp x1, #R_AARCH64_RELATIVE
bne fixnext
/* relative fix: store addend plus offset at dest location */
diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig
index a1175eea6e..c46591846a 100644
--- a/arch/arm/mach-zynq/Kconfig
+++ b/arch/arm/mach-zynq/Kconfig
@@ -28,6 +28,7 @@ config SYS_BOARD
default "zynq"
config SYS_VENDOR
+ string "Vendor name"
default "xilinx"
config SYS_SOC
@@ -44,4 +45,11 @@ config SYS_CONFIG_NAME
config SYS_MALLOC_F_LEN
default 0x600
+config BOOT_INIT_FILE
+ string "boot.bin init register filename"
+ default ""
+ help
+ Add register writes to boot.bin format (max 256 pairs).
+ Expect a table of register-value pairs, e.g. "0x12345678 0x4321"
+
endif
diff --git a/arch/arm/mach-zynq/slcr.c b/arch/arm/mach-zynq/slcr.c
index 05f4099aae..2d3bf2acef 100644
--- a/arch/arm/mach-zynq/slcr.c
+++ b/arch/arm/mach-zynq/slcr.c
@@ -14,6 +14,9 @@
#define SLCR_LOCK_MAGIC 0x767B
#define SLCR_UNLOCK_MAGIC 0xDF0D
+#define SLCR_NAND_L2_SEL 0x10
+#define SLCR_NAND_L2_SEL_MASK 0x1F
+
#define SLCR_USB_L1_SEL 0x04
#define SLCR_IDCODE_MASK 0x1F000
@@ -36,6 +39,14 @@ struct zynq_slcr_mio_get_status {
u32 check_val;
};
+static const int nand8_pins[] = {
+ 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13
+};
+
+static const int nand16_pins[] = {
+ 16, 17, 18, 19, 20, 21, 22, 23
+};
+
static const int usb0_pins[] = {
28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39
};
@@ -46,6 +57,20 @@ static const int usb1_pins[] = {
static const struct zynq_slcr_mio_get_status mio_periphs[] = {
{
+ "nand8",
+ nand8_pins,
+ ARRAY_SIZE(nand8_pins),
+ SLCR_NAND_L2_SEL_MASK,
+ SLCR_NAND_L2_SEL,
+ },
+ {
+ "nand16",
+ nand16_pins,
+ ARRAY_SIZE(nand16_pins),
+ SLCR_NAND_L2_SEL_MASK,
+ SLCR_NAND_L2_SEL,
+ },
+ {
"usb0",
usb0_pins,
ARRAY_SIZE(usb0_pins),
diff --git a/arch/x86/config.mk b/arch/x86/config.mk
index d7addd8728..03c71f7bae 100644
--- a/arch/x86/config.mk
+++ b/arch/x86/config.mk
@@ -45,8 +45,8 @@ endif
EFIPAYLOAD_BFDARCH = i386
-LDSCRIPT_EFI := $(srctree)/$(CPUDIR)/efi/elf_$(EFIARCH)_efi.lds
-EFISTUB := crt0-efi-$(EFIARCH).o reloc_$(EFIARCH).o
+LDSCRIPT_EFI := $(srctree)/arch/x86/lib/elf_$(EFIARCH)_efi.lds
+EFISTUB := crt0_$(EFIARCH)_efi.o reloc_$(EFIARCH)_efi.o
OBJCOPYFLAGS_EFI += --target=efi-app-$(EFIARCH)
CPPFLAGS_REMOVE_crt0-efi-$(EFIARCH).o += $(CFLAGS_NON_EFI)
@@ -65,3 +65,19 @@ PLATFORM_LDFLAGS += --emit-relocs
LDFLAGS_FINAL += --gc-sections -pie
endif
+
+ifneq ($(CONFIG_EFI_STUB)$(CONFIG_CMD_BOOTEFI_HELLO),)
+
+ifneq ($(CONFIG_EFI_STUB_64BIT),)
+EFI_LDS := elf_x86_64_efi.lds
+EFI_CRT0 := crt0_x86_64_efi.o
+EFI_RELOC := reloc_x86_64_efi.o
+EFI_TARGET := --target=efi-app-ia32
+else
+EFI_LDS := elf_ia32_efi.lds
+EFI_CRT0 := crt0_ia32_efi.o
+EFI_RELOC := reloc_ia32_efi.o
+EFI_TARGET := --target=efi-app-x86_64
+endif
+
+endif
diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h
index 031740b708..4f901f9392 100644
--- a/arch/x86/include/asm/u-boot-x86.h
+++ b/arch/x86/include/asm/u-boot-x86.h
@@ -74,6 +74,7 @@ static inline __attribute__((no_instrument_function)) uint64_t rdtsc(void)
/* board/... */
void timer_set_tsc_base(uint64_t new_base);
uint64_t timer_get_tsc(void);
+void board_quiesce_devices(void);
void quick_ram_check(void);
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index b9c29226bd..ff402dc578 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -44,3 +44,26 @@ NORMAL_LIBGCC = $(shell $(CC) $(PLATFORM_CPPFLAGS) -print-libgcc-file-name)
OBJCOPYFLAGS := --prefix-symbols=__normal_
$(obj)/lib.a: $(NORMAL_LIBGCC) FORCE
$(call if_changed,objcopy)
+
+obj-$(CONFIG_EFI_APP) += crt0_ia32_efi.o reloc_ia32_efi.o
+
+ifneq ($(CONFIG_EFI_STUB),)
+
+CFLAGS_REMOVE_reloc_ia32_efi.o += -mregparm=3
+CFLAGS_reloc_ia32_efi.o += -fpic -fshort-wchar
+
+# When building for 64-bit we must remove the i386-specific flags
+CFLAGS_REMOVE_reloc_x86_64_efi.o += -mregparm=3 -march=i386 -m32
+CFLAGS_reloc_x86_64_efi.o += -fpic -fshort-wchar
+
+AFLAGS_REMOVE_crt0_x86_64_efi.o += -mregparm=3 -march=i386 -m32
+AFLAGS_crt0_x86_64_efi.o += -fpic -fshort-wchar
+
+extra-$(CONFIG_EFI_STUB_32BIT) += crt0_ia32_efi.o reloc_ia32_efi.o
+extra-$(CONFIG_EFI_STUB_64BIT) += crt0_x86_64_efi.o reloc_x86_64_efi.o
+
+endif
+
+ifneq ($(CONFIG_EFI_STUB)$(CONFIG_CMD_BOOTEFI_HELLO),)
+extra-y += $(EFI_CRT0) $(EFI_RELOC)
+endif
diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c
index 7cf9de4d7b..80fadef34e 100644
--- a/arch/x86/lib/bootm.c
+++ b/arch/x86/lib/bootm.c
@@ -26,6 +26,10 @@ DECLARE_GLOBAL_DATA_PTR;
#define COMMAND_LINE_OFFSET 0x9000
+__weak void board_quiesce_devices(void)
+{
+}
+
void bootm_announce_and_cleanup(void)
{
printf("\nStarting kernel ...\n\n");
diff --git a/arch/x86/lib/efi/crt0-efi-ia32.S b/arch/x86/lib/crt0_ia32_efi.S
index 30e5eb0c1a..30e5eb0c1a 100644
--- a/arch/x86/lib/efi/crt0-efi-ia32.S
+++ b/arch/x86/lib/crt0_ia32_efi.S
diff --git a/arch/x86/lib/efi/crt0-efi-x86_64.S b/arch/x86/lib/crt0_x86_64_efi.S
index c5cbf4108b..c5cbf4108b 100644
--- a/arch/x86/lib/efi/crt0-efi-x86_64.S
+++ b/arch/x86/lib/crt0_x86_64_efi.S
diff --git a/arch/x86/lib/efi/Makefile b/arch/x86/lib/efi/Makefile
index af4503e1c2..43aadfc996 100644
--- a/arch/x86/lib/efi/Makefile
+++ b/arch/x86/lib/efi/Makefile
@@ -7,21 +7,3 @@
obj-$(CONFIG_EFI_STUB) += car.o
obj-$(CONFIG_EFI_STUB) += efi.o
-
-obj-$(CONFIG_EFI_APP) += crt0-efi-ia32.o reloc_ia32.o
-
-ifneq ($(CONFIG_EFI_STUB),)
-
-CFLAGS_REMOVE_reloc_ia32.o += -mregparm=3
-CFLAGS_reloc_ia32.o += -fpic -fshort-wchar
-
-# When building for 64-bit we must remove the i386-specific flags
-CFLAGS_REMOVE_reloc_x86_64.o += -mregparm=3 -march=i386 -m32
-CFLAGS_reloc_x86_64.o += -fpic -fshort-wchar
-
-AFLAGS_REMOVE_crt0-efi-x86_64.o += -mregparm=3 -march=i386 -m32
-AFLAGS_crt0-efi-x86_64.o += -fpic -fshort-wchar
-
-extra-$(CONFIG_EFI_STUB_32BIT) += crt0-efi-ia32.o reloc_ia32.o
-extra-$(CONFIG_EFI_STUB_64BIT) += crt0-efi-x86_64.o reloc_x86_64.o
-endif
diff --git a/arch/x86/cpu/efi/elf_ia32_efi.lds b/arch/x86/lib/elf_ia32_efi.lds
index cd3b0a982d..174d36f758 100644
--- a/arch/x86/cpu/efi/elf_ia32_efi.lds
+++ b/arch/x86/lib/elf_ia32_efi.lds
@@ -6,8 +6,6 @@
* Modified from usr/lib32/elf_ia32_efi.lds in gnu-efi
*/
-#include <config.h>
-
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_start)
diff --git a/arch/x86/cpu/efi/elf_x86_64_efi.lds b/arch/x86/lib/elf_x86_64_efi.lds
index 9d9f05774a..70c7c52332 100644
--- a/arch/x86/cpu/efi/elf_x86_64_efi.lds
+++ b/arch/x86/lib/elf_x86_64_efi.lds
@@ -6,8 +6,6 @@
* Modified from usr/lib32/elf_x86_64_efi.lds in gnu-efi
*/
-#include <config.h>
-
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
diff --git a/arch/x86/lib/efi/reloc_ia32.c b/arch/x86/lib/reloc_ia32_efi.c
index 4d6825515d..4d6825515d 100644
--- a/arch/x86/lib/efi/reloc_ia32.c
+++ b/arch/x86/lib/reloc_ia32_efi.c
diff --git a/arch/x86/lib/efi/reloc_x86_64.c b/arch/x86/lib/reloc_x86_64_efi.c
index 5f71f2ac8a..5f71f2ac8a 100644
--- a/arch/x86/lib/efi/reloc_x86_64.c
+++ b/arch/x86/lib/reloc_x86_64_efi.c
diff --git a/arch/x86/lib/tables.c b/arch/x86/lib/tables.c
index 025b183d6b..5966e5862a 100644
--- a/arch/x86/lib/tables.c
+++ b/arch/x86/lib/tables.c
@@ -12,10 +12,12 @@
#include <asm/acpi_table.h>
#include <asm/coreboot_tables.h>
+#ifdef CONFIG_GENERATE_SMBIOS_TABLE
static u32 write_smbios_table_wrapper(u32 addr)
{
return write_smbios_table(addr);
}
+#endif
/**
* Function prototype to write a specific configuration table
diff --git a/board/freescale/ls2080a/ls2080a.c b/board/freescale/ls2080a/ls2080a.c
index d0a88d4ef9..4f9b9c8a77 100644
--- a/board/freescale/ls2080a/ls2080a.c
+++ b/board/freescale/ls2080a/ls2080a.c
@@ -102,6 +102,11 @@ void fdt_fixup_board_enet(void *fdt)
else
fdt_status_fail(fdt, offset);
}
+
+void board_quiesce_devices(void)
+{
+ fsl_mc_ldpaa_exit(gd->bd);
+}
#endif
#ifdef CONFIG_OF_BOARD_SETUP
@@ -122,7 +127,6 @@ int ft_board_setup(void *blob, bd_t *bd)
#ifdef CONFIG_FSL_MC_ENET
fdt_fixup_board_enet(blob);
- fsl_mc_ldpaa_exit(bd);
#endif
return 0;
diff --git a/board/freescale/ls2080aqds/ls2080aqds.c b/board/freescale/ls2080aqds/ls2080aqds.c
index d07ca18af9..73a61fd75a 100644
--- a/board/freescale/ls2080aqds/ls2080aqds.c
+++ b/board/freescale/ls2080aqds/ls2080aqds.c
@@ -292,14 +292,16 @@ void fdt_fixup_board_enet(void *fdt)
else
fdt_status_fail(fdt, offset);
}
+
+void board_quiesce_devices(void)
+{
+ fsl_mc_ldpaa_exit(gd->bd);
+}
#endif
#ifdef CONFIG_OF_BOARD_SETUP
int ft_board_setup(void *blob, bd_t *bd)
{
-#ifdef CONFIG_FSL_MC_ENET
- int err;
-#endif
u64 base[CONFIG_NR_DRAM_BANKS];
u64 size[CONFIG_NR_DRAM_BANKS];
@@ -317,9 +319,6 @@ int ft_board_setup(void *blob, bd_t *bd)
#ifdef CONFIG_FSL_MC_ENET
fdt_fixup_board_enet(blob);
- err = fsl_mc_ldpaa_exit(bd);
- if (err)
- return err;
#endif
return 0;
diff --git a/board/freescale/ls2080ardb/ls2080ardb.c b/board/freescale/ls2080ardb/ls2080ardb.c
index 83d9e7ec12..02954ef6d7 100644
--- a/board/freescale/ls2080ardb/ls2080ardb.c
+++ b/board/freescale/ls2080ardb/ls2080ardb.c
@@ -15,6 +15,7 @@
#include <libfdt.h>
#include <fsl-mc/fsl_mc.h>
#include <environment.h>
+#include <efi_loader.h>
#include <i2c.h>
#include <asm/arch/soc.h>
#include <fsl_sec.h>
@@ -201,6 +202,14 @@ int misc_init_r(void)
if (adjust_vdd(0))
printf("Warning: Adjusting core voltage failed.\n");
+#if defined(CONFIG_EFI_LOADER) && !defined(CONFIG_SPL_BUILD)
+ if (soc_has_dp_ddr() && gd->bd->bi_dram[2].size) {
+ efi_add_memory_map(gd->bd->bi_dram[2].start,
+ gd->bd->bi_dram[2].size >> EFI_PAGE_SHIFT,
+ EFI_RESERVED_MEMORY_TYPE, false);
+ }
+#endif
+
return 0;
}
@@ -256,14 +265,16 @@ void fdt_fixup_board_enet(void *fdt)
else
fdt_status_fail(fdt, offset);
}
+
+void board_quiesce_devices(void)
+{
+ fsl_mc_ldpaa_exit(gd->bd);
+}
#endif
#ifdef CONFIG_OF_BOARD_SETUP
int ft_board_setup(void *blob, bd_t *bd)
{
-#ifdef CONFIG_FSL_MC_ENET
- int err;
-#endif
u64 base[CONFIG_NR_DRAM_BANKS];
u64 size[CONFIG_NR_DRAM_BANKS];
@@ -281,9 +292,6 @@ int ft_board_setup(void *blob, bd_t *bd)
#ifdef CONFIG_FSL_MC_ENET
fdt_fixup_board_enet(blob);
- err = fsl_mc_ldpaa_exit(bd);
- if (err)
- return err;
#endif
return 0;
diff --git a/board/topic/zynq/MAINTAINERS b/board/topic/zynq/MAINTAINERS
new file mode 100644
index 0000000000..d795b304e5
--- /dev/null
+++ b/board/topic/zynq/MAINTAINERS
@@ -0,0 +1,6 @@
+TOPIC BOARD
+M: Mike Looijmans <mike.looijmans@topic.nl>
+S: Maintained
+F: board/topic/zynq/
+F: include/configs/topic*.h
+F: configs/topic_*_defconfig
diff --git a/board/topic/zynq/Makefile b/board/topic/zynq/Makefile
new file mode 100644
index 0000000000..eaf59cd55c
--- /dev/null
+++ b/board/topic/zynq/Makefile
@@ -0,0 +1,10 @@
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y := board.o
+
+# Remove quotes
+hw-platform-y :=$(shell echo $(CONFIG_DEFAULT_DEVICE_TREE))
+
+obj-$(CONFIG_SPL_BUILD) += $(hw-platform-y)/ps7_init_gpl.o ps7_init_common.o
diff --git a/board/topic/zynq/board.c b/board/topic/zynq/board.c
new file mode 100644
index 0000000000..a95c9d1eff
--- /dev/null
+++ b/board/topic/zynq/board.c
@@ -0,0 +1 @@
+#include "../../xilinx/zynq/board.c"
diff --git a/board/topic/zynq/ps7_init_common.c b/board/topic/zynq/ps7_init_common.c
new file mode 100644
index 0000000000..b1d45c242f
--- /dev/null
+++ b/board/topic/zynq/ps7_init_common.c
@@ -0,0 +1,117 @@
+/*
+ * (c) Copyright 2010-2014 Xilinx, Inc. All rights reserved.
+ * (c) Copyright 2016 Topic Embedded Products.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "ps7_init_gpl.h"
+#include <asm/io.h>
+
+/* For delay calculation using global registers*/
+#define SCU_GLOBAL_TIMER_COUNT_L32 0xF8F00200
+#define SCU_GLOBAL_TIMER_COUNT_U32 0xF8F00204
+#define SCU_GLOBAL_TIMER_CONTROL 0xF8F00208
+#define SCU_GLOBAL_TIMER_AUTO_INC 0xF8F00218
+#define APU_FREQ 666666666
+
+#define PS7_MASK_POLL_TIME 100000000
+
+/* IO accessors. No memory barriers desired. */
+static inline void iowrite(unsigned long val, unsigned long addr)
+{
+ __raw_writel(val, addr);
+}
+
+static inline unsigned long ioread(unsigned long addr)
+{
+ return __raw_readl(addr);
+}
+
+/* start timer */
+static void perf_start_clock(void)
+{
+ iowrite((1 << 0) | /* Timer Enable */
+ (1 << 3) | /* Auto-increment */
+ (0 << 8), /* Pre-scale */
+ SCU_GLOBAL_TIMER_CONTROL);
+}
+
+/* Compute mask for given delay in miliseconds*/
+static int get_number_of_cycles_for_delay(unsigned int delay)
+{
+ return (APU_FREQ / (2 * 1000)) * delay;
+}
+
+/* stop timer */
+static void perf_disable_clock(void)
+{
+ iowrite(0, SCU_GLOBAL_TIMER_CONTROL);
+}
+
+/* stop timer and reset timer count regs */
+static void perf_reset_clock(void)
+{
+ perf_disable_clock();
+ iowrite(0, SCU_GLOBAL_TIMER_COUNT_L32);
+ iowrite(0, SCU_GLOBAL_TIMER_COUNT_U32);
+}
+
+static void perf_reset_and_start_timer(void)
+{
+ perf_reset_clock();
+ perf_start_clock();
+}
+
+int ps7_config(unsigned long *ps7_config_init)
+{
+ unsigned long *ptr = ps7_config_init;
+ unsigned long opcode;
+ unsigned long addr;
+ unsigned long val;
+ unsigned long mask;
+ unsigned int numargs;
+ int i;
+ int delay;
+
+ for (;;) {
+ opcode = ptr[0];
+ if (opcode == OPCODE_EXIT)
+ return PS7_INIT_SUCCESS;
+ addr = (opcode & OPCODE_ADDRESS_MASK);
+
+ switch (opcode & ~OPCODE_ADDRESS_MASK) {
+ case OPCODE_MASKWRITE:
+ numargs = 3;
+ mask = ptr[1];
+ val = ptr[2];
+ iowrite((ioread(addr) & ~mask) | (val & mask), addr);
+ break;
+
+ case OPCODE_MASKPOLL:
+ numargs = 2;
+ mask = ptr[1];
+ i = 0;
+ while (!(ioread(addr) & mask)) {
+ if (i == PS7_MASK_POLL_TIME)
+ return PS7_INIT_TIMEOUT;
+ i++;
+ }
+ break;
+
+ case OPCODE_MASKDELAY:
+ numargs = 2;
+ mask = ptr[1];
+ delay = get_number_of_cycles_for_delay(mask);
+ perf_reset_and_start_timer();
+ while (ioread(addr) < delay)
+ ;
+ break;
+
+ default:
+ return PS7_INIT_CORRUPT;
+ }
+
+ ptr += numargs;
+ }
+}
diff --git a/board/topic/zynq/ps7_init_gpl.h b/board/topic/zynq/ps7_init_gpl.h
new file mode 100644
index 0000000000..ef719acaba
--- /dev/null
+++ b/board/topic/zynq/ps7_init_gpl.h
@@ -0,0 +1,34 @@
+/*
+ * (c) Copyright 2010-2014 Xilinx, Inc. All rights reserved.
+ * (c) Copyright 2016 Topic Embedded Products.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#define OPCODE_EXIT 0U
+#define OPCODE_MASKWRITE 0U
+#define OPCODE_MASKPOLL 1U
+#define OPCODE_MASKDELAY 2U
+#define OPCODE_ADDRESS_MASK (~3U)
+
+/* Sentinel */
+#define EMIT_EXIT() OPCODE_EXIT
+/* Opcode is in lower 2 bits of address, address is always 4-byte aligned */
+#define EMIT_MASKWRITE(addr, mask, val) OPCODE_MASKWRITE | addr, mask, val
+#define EMIT_MASKPOLL(addr, mask) OPCODE_MASKPOLL | addr, mask
+#define EMIT_MASKDELAY(addr, mask) OPCODE_MASKDELAY | addr, mask
+
+/* Returns codes of ps7_init* */
+#define PS7_INIT_SUCCESS (0)
+#define PS7_INIT_CORRUPT (1)
+#define PS7_INIT_TIMEOUT (2)
+#define PS7_POLL_FAILED_DDR_INIT (3)
+#define PS7_POLL_FAILED_DMA (4)
+#define PS7_POLL_FAILED_PLL (5)
+
+/* Called by spl.c */
+int ps7_init(void);
+int ps7_post_config(void);
+
+/* Defined in ps7_init_common.c */
+int ps7_config(unsigned long *ps7_config_init);
diff --git a/board/topic/zynq/zynq-topic-miami/ps7_init_gpl.c b/board/topic/zynq/zynq-topic-miami/ps7_init_gpl.c
new file mode 100644
index 0000000000..b195d7a25b
--- /dev/null
+++ b/board/topic/zynq/zynq-topic-miami/ps7_init_gpl.c
@@ -0,0 +1,227 @@
+/*
+ * (c) Copyright 2010-2014 Xilinx, Inc. All rights reserved.
+ * (c) Copyright 2016 Topic Embedded Products.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "../ps7_init_gpl.h"
+
+static unsigned long ps7_pll_init_data_3_0[] = {
+ EMIT_MASKWRITE(0XF8000008, 0x0000FFFFU, 0x0000DF0DU),
+ EMIT_MASKWRITE(0XF8000110, 0x003FFFF0U, 0x000FA220U),
+ EMIT_MASKWRITE(0XF8000100, 0x0007F000U, 0x00028000U),
+ EMIT_MASKWRITE(0XF8000100, 0x00000010U, 0x00000010U),
+ EMIT_MASKWRITE(0XF8000100, 0x00000001U, 0x00000001U),
+ EMIT_MASKWRITE(0XF8000100, 0x00000001U, 0x00000000U),
+ EMIT_MASKPOLL(0XF800010C, 0x00000001U),
+ EMIT_MASKWRITE(0XF8000100, 0x00000010U, 0x00000000U),
+ EMIT_MASKWRITE(0XF8000120, 0x1F003F30U, 0x1F000200U),
+ EMIT_MASKWRITE(0XF8000114, 0x003FFFF0U, 0x0012C220U),
+ EMIT_MASKWRITE(0XF8000104, 0x0007F000U, 0x00020000U),
+ EMIT_MASKWRITE(0XF8000104, 0x00000010U, 0x00000010U),
+ EMIT_MASKWRITE(0XF8000104, 0x00000001U, 0x00000001U),
+ EMIT_MASKWRITE(0XF8000104, 0x00000001U, 0x00000000U),
+ EMIT_MASKPOLL(0XF800010C, 0x00000002U),
+ EMIT_MASKWRITE(0XF8000104, 0x00000010U, 0x00000000U),
+ EMIT_MASKWRITE(0XF8000124, 0xFFF00003U, 0x0C200003U),
+ EMIT_MASKWRITE(0XF8000118, 0x003FFFF0U, 0x00113220U),
+ EMIT_MASKWRITE(0XF8000108, 0x0007F000U, 0x00024000U),
+ EMIT_MASKWRITE(0XF8000108, 0x00000010U, 0x00000010U),
+ EMIT_MASKWRITE(0XF8000108, 0x00000001U, 0x00000001U),
+ EMIT_MASKWRITE(0XF8000108, 0x00000001U, 0x00000000U),
+ EMIT_MASKPOLL(0XF800010C, 0x00000004U),
+ EMIT_MASKWRITE(0XF8000108, 0x00000010U, 0x00000000U),
+ EMIT_MASKWRITE(0XF8000004, 0x0000FFFFU, 0x0000767BU),
+ EMIT_EXIT(),
+};
+
+static unsigned long ps7_clock_init_data_3_0[] = {
+ EMIT_MASKWRITE(0XF8000008, 0x0000FFFFU, 0x0000DF0DU),
+ EMIT_MASKWRITE(0XF8000128, 0x03F03F01U, 0x00302301U),
+ EMIT_MASKWRITE(0XF8000138, 0x00000011U, 0x00000011U),
+ EMIT_MASKWRITE(0XF800013C, 0x00000011U, 0x00000011U),
+ EMIT_MASKWRITE(0XF8000140, 0x03F03F71U, 0x00100141U),
+ EMIT_MASKWRITE(0XF8000144, 0x03F03F71U, 0x00100141U),
+ EMIT_MASKWRITE(0XF8000148, 0x00003F31U, 0x00000C01U),
+ EMIT_MASKWRITE(0XF800014C, 0x00003F31U, 0x00000601U),
+ EMIT_MASKWRITE(0XF8000150, 0x00003F33U, 0x00001803U),
+ EMIT_MASKWRITE(0XF8000154, 0x00003F33U, 0x00000C03U),
+ EMIT_MASKWRITE(0XF8000158, 0x00003F33U, 0x00000601U),
+ EMIT_MASKWRITE(0XF8000168, 0x00003F31U, 0x00000601U),
+ EMIT_MASKWRITE(0XF8000170, 0x03F03F30U, 0x00100C00U),
+ EMIT_MASKWRITE(0XF8000180, 0x03F03F30U, 0x00100C00U),
+ EMIT_MASKWRITE(0XF8000190, 0x03F03F30U, 0x00100600U),
+ EMIT_MASKWRITE(0XF80001A0, 0x03F03F30U, 0x00101800U),
+ EMIT_MASKWRITE(0XF80001C4, 0x00000001U, 0x00000001U),
+ EMIT_MASKWRITE(0XF800012C, 0x01FFCCCDU, 0x01FC4C4DU),
+ EMIT_MASKWRITE(0XF8000004, 0x0000FFFFU, 0x0000767BU),
+ EMIT_EXIT(),
+};
+
+static unsigned long ps7_ddr_init_data_3_0[] = {
+ EMIT_MASKWRITE(0XF8006000, 0x0001FFFFU, 0x00000080U),
+ EMIT_MASKWRITE(0XF8006004, 0x0007FFFFU, 0x00001081U),
+ EMIT_MASKWRITE(0XF8006008, 0x03FFFFFFU, 0x03C0780FU),
+ EMIT_MASKWRITE(0XF800600C, 0x03FFFFFFU, 0x02001001U),
+ EMIT_MASKWRITE(0XF8006010, 0x03FFFFFFU, 0x00014001U),
+ EMIT_MASKWRITE(0XF8006014, 0x001FFFFFU, 0x0004281AU),
+ EMIT_MASKWRITE(0XF8006018, 0xF7FFFFFFU, 0x44E458D2U),
+ EMIT_MASKWRITE(0XF800601C, 0xFFFFFFFFU, 0x720238E5U),
+ EMIT_MASKWRITE(0XF8006020, 0x7FDFFFFCU, 0x270872D0U),
+ EMIT_MASKWRITE(0XF8006024, 0x0FFFFFC3U, 0x00000000U),
+ EMIT_MASKWRITE(0XF8006028, 0x00003FFFU, 0x00002007U),
+ EMIT_MASKWRITE(0XF800602C, 0xFFFFFFFFU, 0x00000008U),
+ EMIT_MASKWRITE(0XF8006030, 0xFFFFFFFFU, 0x00040930U),
+ EMIT_MASKWRITE(0XF8006034, 0x13FF3FFFU, 0x000116D4U),
+ EMIT_MASKWRITE(0XF8006038, 0x00000003U, 0x00000000U),
+ EMIT_MASKWRITE(0XF800603C, 0x000FFFFFU, 0x00000777U),
+ EMIT_MASKWRITE(0XF8006040, 0xFFFFFFFFU, 0xFFF00000U),
+ EMIT_MASKWRITE(0XF8006044, 0x0FFFFFFFU, 0x0F666666U),
+ EMIT_MASKWRITE(0XF8006048, 0x0003F03FU, 0x0003C008U),
+ EMIT_MASKWRITE(0XF8006050, 0xFF0F8FFFU, 0x77010800U),
+ EMIT_MASKWRITE(0XF8006058, 0x00010000U, 0x00000000U),
+ EMIT_MASKWRITE(0XF800605C, 0x0000FFFFU, 0x00005003U),
+ EMIT_MASKWRITE(0XF8006060, 0x000017FFU, 0x0000003EU),
+ EMIT_MASKWRITE(0XF8006064, 0x00021FE0U, 0x00020000U),
+ EMIT_MASKWRITE(0XF8006068, 0x03FFFFFFU, 0x00284141U),
+ EMIT_MASKWRITE(0XF800606C, 0x0000FFFFU, 0x00001610U),
+ EMIT_MASKWRITE(0XF8006078, 0x03FFFFFFU, 0x00466111U),
+ EMIT_MASKWRITE(0XF800607C, 0x000FFFFFU, 0x00032222U),
+ EMIT_MASKWRITE(0XF80060A4, 0xFFFFFFFFU, 0x10200802U),
+ EMIT_MASKWRITE(0XF80060A8, 0x0FFFFFFFU, 0x0690CB73U),
+ EMIT_MASKWRITE(0XF80060AC, 0x000001FFU, 0x000001FEU),
+ EMIT_MASKWRITE(0XF80060B0, 0x1FFFFFFFU, 0x1CFFFFFFU),
+ EMIT_MASKWRITE(0XF80060B4, 0x00000200U, 0x00000200U),
+ EMIT_MASKWRITE(0XF80060B8, 0x01FFFFFFU, 0x00200066U),
+ EMIT_MASKWRITE(0XF80060C4, 0x00000003U, 0x00000003U),
+ EMIT_MASKWRITE(0XF80060C4, 0x00000003U, 0x00000000U),
+ EMIT_MASKWRITE(0XF80060C8, 0x000000FFU, 0x00000000U),
+ EMIT_MASKWRITE(0XF80060DC, 0x00000001U, 0x00000000U),
+ EMIT_MASKWRITE(0XF80060F0, 0x0000FFFFU, 0x00000000U),
+ EMIT_MASKWRITE(0XF80060F4, 0x0000000FU, 0x00000008U),
+ EMIT_MASKWRITE(0XF8006114, 0x000000FFU, 0x00000000U),
+ EMIT_MASKWRITE(0XF8006118, 0x7FFFFFCFU, 0x40000001U),
+ EMIT_MASKWRITE(0XF800611C, 0x7FFFFFCFU, 0x40000001U),
+ EMIT_MASKWRITE(0XF8006120, 0x7FFFFFCFU, 0x40000001U),
+ EMIT_MASKWRITE(0XF8006124, 0x7FFFFFCFU, 0x40000001U),
+ EMIT_MASKWRITE(0XF800612C, 0x000FFFFFU, 0x00025010U),
+ EMIT_MASKWRITE(0XF8006130, 0x000FFFFFU, 0x00026400U),
+ EMIT_MASKWRITE(0XF8006134, 0x000FFFFFU, 0x00029418U),
+ EMIT_MASKWRITE(0XF8006138, 0x000FFFFFU, 0x00027820U),
+ EMIT_MASKWRITE(0XF8006140, 0x000FFFFFU, 0x00000035U),
+ EMIT_MASKWRITE(0XF8006144, 0x000FFFFFU, 0x00000035U),
+ EMIT_MASKWRITE(0XF8006148, 0x000FFFFFU, 0x00000035U),
+ EMIT_MASKWRITE(0XF800614C, 0x000FFFFFU, 0x00000035U),
+ EMIT_MASKWRITE(0XF8006154, 0x000FFFFFU, 0x00000090U),
+ EMIT_MASKWRITE(0XF8006158, 0x000FFFFFU, 0x00000080U),
+ EMIT_MASKWRITE(0XF800615C, 0x000FFFFFU, 0x00000098U),
+ EMIT_MASKWRITE(0XF8006160, 0x000FFFFFU, 0x000000A0U),
+ EMIT_MASKWRITE(0XF8006168, 0x001FFFFFU, 0x000000E9U),
+ EMIT_MASKWRITE(0XF800616C, 0x001FFFFFU, 0x000000EEU),
+ EMIT_MASKWRITE(0XF8006170, 0x001FFFFFU, 0x000000FAU),
+ EMIT_MASKWRITE(0XF8006174, 0x001FFFFFU, 0x000000F3U),
+ EMIT_MASKWRITE(0XF800617C, 0x000FFFFFU, 0x000000D0U),
+ EMIT_MASKWRITE(0XF8006180, 0x000FFFFFU, 0x000000C0U),
+ EMIT_MASKWRITE(0XF8006184, 0x000FFFFFU, 0x000000D8U),
+ EMIT_MASKWRITE(0XF8006188, 0x000FFFFFU, 0x000000E0U),
+ EMIT_MASKWRITE(0XF8006190, 0x6FFFFEFEU, 0x00040080U),
+ EMIT_MASKWRITE(0XF8006194, 0x000FFFFFU, 0x0001FC82U),
+ EMIT_MASKWRITE(0XF8006204, 0xFFFFFFFFU, 0x00000000U),
+ EMIT_MASKWRITE(0XF8006208, 0x000703FFU, 0x000003FFU),
+ EMIT_MASKWRITE(0XF800620C, 0x000703FFU, 0x000003FFU),
+ EMIT_MASKWRITE(0XF8006210, 0x000703FFU, 0x000003FFU),
+ EMIT_MASKWRITE(0XF8006214, 0x000703FFU, 0x000003FFU),
+ EMIT_MASKWRITE(0XF8006218, 0x000F03FFU, 0x000003FFU),
+ EMIT_MASKWRITE(0XF800621C, 0x000F03FFU, 0x000003FFU),
+ EMIT_MASKWRITE(0XF8006220, 0x000F03FFU, 0x000003FFU),
+ EMIT_MASKWRITE(0XF8006224, 0x000F03FFU, 0x000003FFU),
+ EMIT_MASKWRITE(0XF80062A8, 0x00000FF5U, 0x00000000U),
+ EMIT_MASKWRITE(0XF80062AC, 0xFFFFFFFFU, 0x00000000U),
+ EMIT_MASKWRITE(0XF80062B0, 0x003FFFFFU, 0x00005125U),
+ EMIT_MASKWRITE(0XF80062B4, 0x0003FFFFU, 0x000012A8U),
+ EMIT_MASKPOLL(0XF8000B74, 0x00002000U),
+ EMIT_MASKWRITE(0XF8006000, 0x0001FFFFU, 0x00000081U),
+ EMIT_MASKPOLL(0XF8006054, 0x00000007U),
+ EMIT_EXIT(),
+};
+
+static unsigned long ps7_mio_init_data_3_0[] = {
+ EMIT_MASKWRITE(0XF8000008, 0x0000FFFFU, 0x0000DF0DU),
+ EMIT_MASKWRITE(0XF8000B40, 0x00000FFFU, 0x00000600U),
+ EMIT_MASKWRITE(0XF8000B44, 0x00000FFFU, 0x00000600U),
+ EMIT_MASKWRITE(0XF8000B48, 0x00000FFFU, 0x00000672U),
+ EMIT_MASKWRITE(0XF8000B4C, 0x00000FFFU, 0x00000672U),
+ EMIT_MASKWRITE(0XF8000B50, 0x00000FFFU, 0x00000674U),
+ EMIT_MASKWRITE(0XF8000B54, 0x00000FFFU, 0x00000674U),
+ EMIT_MASKWRITE(0XF8000B58, 0x00000FFFU, 0x00000600U),
+ EMIT_MASKWRITE(0XF8000B5C, 0xFFFFFFFFU, 0x0018C61CU),
+ EMIT_MASKWRITE(0XF8000B60, 0xFFFFFFFFU, 0x00F9861CU),
+ EMIT_MASKWRITE(0XF8000B64, 0xFFFFFFFFU, 0x00F9861CU),
+ EMIT_MASKWRITE(0XF8000B68, 0xFFFFFFFFU, 0x00F9861CU),
+ EMIT_MASKWRITE(0XF8000B6C, 0x00007FFFU, 0x00000E60U),
+ EMIT_MASKWRITE(0XF8000B70, 0x00000001U, 0x00000001U),
+ EMIT_MASKWRITE(0XF8000B70, 0x00000021U, 0x00000020U),
+ EMIT_MASKWRITE(0XF8000B70, 0x07FEFFFFU, 0x00000823U),
+ EMIT_MASKWRITE(0XF8000004, 0x0000FFFFU, 0x0000767BU),
+ EMIT_EXIT(),
+};
+
+static unsigned long ps7_peripherals_init_data_3_0[] = {
+ EMIT_MASKWRITE(0XF8000008, 0x0000FFFFU, 0x0000DF0DU),
+ EMIT_MASKWRITE(0XF8000B48, 0x00000180U, 0x00000180U),
+ EMIT_MASKWRITE(0XF8000B4C, 0x00000180U, 0x00000180U),
+ EMIT_MASKWRITE(0XF8000B50, 0x00000180U, 0x00000180U),
+ EMIT_MASKWRITE(0XF8000B54, 0x00000180U, 0x00000180U),
+ EMIT_MASKWRITE(0XF8000004, 0x0000FFFFU, 0x0000767BU),
+ EMIT_MASKWRITE(0XE0001034, 0x000000FFU, 0x00000006U),
+ EMIT_MASKWRITE(0XE0001018, 0x0000FFFFU, 0x0000007CU),
+ EMIT_MASKWRITE(0XE0001000, 0x000001FFU, 0x00000017U),
+ EMIT_MASKWRITE(0XE0001004, 0x000003FFU, 0x00000020U),
+ EMIT_MASKWRITE(0XE0000034, 0x000000FFU, 0x00000006U),
+ EMIT_MASKWRITE(0XE0000018, 0x0000FFFFU, 0x0000007CU),
+ EMIT_MASKWRITE(0XE0000000, 0x000001FFU, 0x00000017U),
+ EMIT_MASKWRITE(0XE0000004, 0x000003FFU, 0x00000020U),
+ EMIT_MASKWRITE(0XE000D000, 0x000800FFU, 0x000800C1U),
+ EMIT_MASKWRITE(0XF8007000, 0x20000000U, 0x00000000U),
+ EMIT_MASKDELAY(0XF8F00200, 1),
+ EMIT_MASKDELAY(0XF8F00200, 1),
+ EMIT_MASKDELAY(0XF8F00200, 1),
+ EMIT_EXIT(),
+};
+
+static unsigned long ps7_post_config_3_0[] = {
+ EMIT_MASKWRITE(0XF8000008, 0x0000FFFFU, 0x0000DF0DU),
+ EMIT_MASKWRITE(0XF8000900, 0x0000000FU, 0x0000000FU),
+ EMIT_MASKWRITE(0XF8000240, 0xFFFFFFFFU, 0x00000000U),
+ EMIT_MASKWRITE(0XF8000004, 0x0000FFFFU, 0x0000767BU),
+ EMIT_EXIT(),
+};
+
+int ps7_init(void)
+{
+ int ret;
+
+ ret = ps7_config(ps7_mio_init_data_3_0);
+ if (ret != PS7_INIT_SUCCESS)
+ return ret;
+ ret = ps7_config(ps7_pll_init_data_3_0);
+ if (ret != PS7_INIT_SUCCESS)
+ return ret;
+ ret = ps7_config(ps7_clock_init_data_3_0);
+ if (ret != PS7_INIT_SUCCESS)
+ return ret;
+ ret = ps7_config(ps7_ddr_init_data_3_0);
+ if (ret != PS7_INIT_SUCCESS)
+ return ret;
+ ret = ps7_config(ps7_peripherals_init_data_3_0);
+ if (ret != PS7_INIT_SUCCESS)
+ return ret;
+
+ return PS7_INIT_SUCCESS;
+}
+
+int ps7_post_config(void)
+{
+ return ps7_config(ps7_post_config_3_0);
+}
diff --git a/board/topic/zynq/zynq-topic-miami/ps7_regs.txt b/board/topic/zynq/zynq-topic-miami/ps7_regs.txt
new file mode 100644
index 0000000000..2ad9da6972
--- /dev/null
+++ b/board/topic/zynq/zynq-topic-miami/ps7_regs.txt
@@ -0,0 +1,61 @@
+0xF8000120 0x1F000200 // ARM_CLK_CTRL - divisor = 2 433 MHz (?)
+0xf8000700 0x1210 // MIO configuration
+0xf8000704 0x202
+0xf8000708 0x202
+0xf800070c 0x202
+0xf8000710 0x202
+0xf8000714 0x202
+0xf8000718 0x202
+0xf800071c 0x210
+0xf8000720 0x202
+0xf8000724 0x1210
+0xf8000728 0x1210
+0xf800072c 0x1210
+0xf8000730 0x1210
+0xf8000734 0x1210
+0xf8000738 0x1211
+0xf800073c 0x1200
+0xf8000740 0x1210
+0xf8000744 0x1210
+0xf8000748 0x1210
+0xf800074c 0x1210
+0xf8000750 0x1210
+0xf8000754 0x1210
+0xf8000758 0x1210
+0xf800075c 0x1210
+0xf8000760 0x1201
+0xf8000764 0x200
+0xf8000768 0x12e1
+0xf800076c 0x2e0
+0xf8000770 0x304
+0xf8000774 0x305
+0xf8000778 0x304
+0xf800077c 0x305
+0xf8000780 0x304
+0xf8000784 0x304
+0xf8000788 0x304
+0xf800078c 0x304
+0xf8000790 0x305
+0xf8000794 0x304
+0xf8000798 0x304
+0xf800079c 0x304
+0xf80007a0 0x380
+0xf80007a4 0x380
+0xf80007a8 0x380
+0xf80007ac 0x380
+0xf80007b0 0x380
+0xf80007b4 0x380
+0xf80007b8 0x1261
+0xf80007bc 0x1260
+0xf80007c0 0x1261
+0xf80007c4 0x1261
+0xf80007c8 0x1240
+0xf80007cc 0x1240
+0xf80007d0 0x1240
+0xf80007d4 0x1240
+0xf8000830 0x180037
+0xf8000834 0x3a0039
+0xF800014C 0x00000621 // LQSPI_CLK_CTRL - ARMPLL/6 (200 MHz)
+0xE000D000 0x800238C1 // QSPI config - divide-by-2
+0xE000D038 0x00000020 // QSPI loopback - internal, 0 delay
+0xE000D0A0 0x82FF04EB // LQSPI_CFG - QIOREAD mode, Numonyx/Micron
diff --git a/board/topic/zynq/zynq-topic-miamiplus/ps7_init_gpl.c b/board/topic/zynq/zynq-topic-miamiplus/ps7_init_gpl.c
new file mode 100644
index 0000000000..5a923366eb
--- /dev/null
+++ b/board/topic/zynq/zynq-topic-miamiplus/ps7_init_gpl.c
@@ -0,0 +1,233 @@
+/*
+ * (c) Copyright 2010-2014 Xilinx, Inc. All rights reserved.
+ * (c) Copyright 2016 Topic Embedded Products.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "../ps7_init_gpl.h"
+
+static unsigned long ps7_pll_init_data_3_0[] = {
+ EMIT_MASKWRITE(0XF8000008, 0x0000FFFFU, 0x0000DF0DU),
+ EMIT_MASKWRITE(0XF8000110, 0x003FFFF0U, 0x000FA220U),
+ EMIT_MASKWRITE(0XF8000100, 0x0007F000U, 0x00028000U),
+ EMIT_MASKWRITE(0XF8000100, 0x00000010U, 0x00000010U),
+ EMIT_MASKWRITE(0XF8000100, 0x00000001U, 0x00000001U),
+ EMIT_MASKWRITE(0XF8000100, 0x00000001U, 0x00000000U),
+ EMIT_MASKPOLL(0XF800010C, 0x00000001U),
+ EMIT_MASKWRITE(0XF8000100, 0x00000010U, 0x00000000U),
+ EMIT_MASKWRITE(0XF8000120, 0x1F003F30U, 0x1F000200U),
+ EMIT_MASKWRITE(0XF8000114, 0x003FFFF0U, 0x0012C220U),
+ EMIT_MASKWRITE(0XF8000104, 0x0007F000U, 0x00020000U),
+ EMIT_MASKWRITE(0XF8000104, 0x00000010U, 0x00000010U),
+ EMIT_MASKWRITE(0XF8000104, 0x00000001U, 0x00000001U),
+ EMIT_MASKWRITE(0XF8000104, 0x00000001U, 0x00000000U),
+ EMIT_MASKPOLL(0XF800010C, 0x00000002U),
+ EMIT_MASKWRITE(0XF8000104, 0x00000010U, 0x00000000U),
+ EMIT_MASKWRITE(0XF8000124, 0xFFF00003U, 0x0C200003U),
+ EMIT_MASKWRITE(0XF8000118, 0x003FFFF0U, 0x00113220U),
+ EMIT_MASKWRITE(0XF8000108, 0x0007F000U, 0x00024000U),
+ EMIT_MASKWRITE(0XF8000108, 0x00000010U, 0x00000010U),
+ EMIT_MASKWRITE(0XF8000108, 0x00000001U, 0x00000001U),
+ EMIT_MASKWRITE(0XF8000108, 0x00000001U, 0x00000000U),
+ EMIT_MASKPOLL(0XF800010C, 0x00000004U),
+ EMIT_MASKWRITE(0XF8000108, 0x00000010U, 0x00000000U),
+ EMIT_MASKWRITE(0XF8000004, 0x0000FFFFU, 0x0000767BU),
+ EMIT_EXIT(),
+};
+
+static unsigned long ps7_clock_init_data_3_0[] = {
+ EMIT_MASKWRITE(0XF8000008, 0x0000FFFFU, 0x0000DF0DU),
+ EMIT_MASKWRITE(0XF8000128, 0x03F03F01U, 0x00302301U),
+ EMIT_MASKWRITE(0XF8000138, 0x00000011U, 0x00000011U),
+ EMIT_MASKWRITE(0XF800013C, 0x00000011U, 0x00000011U),
+ EMIT_MASKWRITE(0XF8000140, 0x03F03F71U, 0x00100141U),
+ EMIT_MASKWRITE(0XF8000144, 0x03F03F71U, 0x00100141U),
+ EMIT_MASKWRITE(0XF8000148, 0x00003F31U, 0x00000C01U),
+ EMIT_MASKWRITE(0XF800014C, 0x00003F31U, 0x00000601U),
+ EMIT_MASKWRITE(0XF8000150, 0x00003F33U, 0x00001803U),
+ EMIT_MASKWRITE(0XF8000154, 0x00003F33U, 0x00000C03U),
+ EMIT_MASKWRITE(0XF8000158, 0x00003F33U, 0x00000601U),
+ EMIT_MASKWRITE(0XF8000168, 0x00003F31U, 0x00000601U),
+ EMIT_MASKWRITE(0XF8000170, 0x03F03F30U, 0x00100C00U),
+ EMIT_MASKWRITE(0XF8000180, 0x03F03F30U, 0x00100C00U),
+ EMIT_MASKWRITE(0XF8000190, 0x03F03F30U, 0x00100600U),
+ EMIT_MASKWRITE(0XF80001A0, 0x03F03F30U, 0x00101800U),
+ EMIT_MASKWRITE(0XF80001C4, 0x00000001U, 0x00000001U),
+ EMIT_MASKWRITE(0XF800012C, 0x01FFCCCDU, 0x01FC4C4DU),
+ EMIT_MASKWRITE(0XF8000004, 0x0000FFFFU, 0x0000767BU),
+ EMIT_EXIT(),
+};
+
+static unsigned long ps7_ddr_init_data_3_0[] = {
+ EMIT_MASKWRITE(0XF8006000, 0x0001FFFFU, 0x00000080U),
+ EMIT_MASKWRITE(0XF8006004, 0x0007FFFFU, 0x00001081U),
+ EMIT_MASKWRITE(0XF8006008, 0x03FFFFFFU, 0x03C0780FU),
+ EMIT_MASKWRITE(0XF800600C, 0x03FFFFFFU, 0x02001001U),
+ EMIT_MASKWRITE(0XF8006010, 0x03FFFFFFU, 0x00014001U),
+ EMIT_MASKWRITE(0XF8006014, 0x001FFFFFU, 0x0004281AU),
+ EMIT_MASKWRITE(0XF8006018, 0xF7FFFFFFU, 0x44E458D2U),
+ EMIT_MASKWRITE(0XF800601C, 0xFFFFFFFFU, 0x720238E5U),
+ EMIT_MASKWRITE(0XF8006020, 0x7FDFFFFCU, 0x270872D0U),
+ EMIT_MASKWRITE(0XF8006024, 0x0FFFFFC3U, 0x00000000U),
+ EMIT_MASKWRITE(0XF8006028, 0x00003FFFU, 0x00002007U),
+ EMIT_MASKWRITE(0XF800602C, 0xFFFFFFFFU, 0x00000008U),
+ EMIT_MASKWRITE(0XF8006030, 0xFFFFFFFFU, 0x00040930U),
+ EMIT_MASKWRITE(0XF8006034, 0x13FF3FFFU, 0x000116D4U),
+ EMIT_MASKWRITE(0XF8006038, 0x00000003U, 0x00000000U),
+ EMIT_MASKWRITE(0XF800603C, 0x000FFFFFU, 0x00000777U),
+ EMIT_MASKWRITE(0XF8006040, 0xFFFFFFFFU, 0xFFF00000U),
+ EMIT_MASKWRITE(0XF8006044, 0x0FFFFFFFU, 0x0F666666U),
+ EMIT_MASKWRITE(0XF8006048, 0x0003F03FU, 0x0003C008U),
+ EMIT_MASKWRITE(0XF8006050, 0xFF0F8FFFU, 0x77010800U),
+ EMIT_MASKWRITE(0XF8006058, 0x00010000U, 0x00000000U),
+ EMIT_MASKWRITE(0XF800605C, 0x0000FFFFU, 0x00005003U),
+ EMIT_MASKWRITE(0XF8006060, 0x000017FFU, 0x0000003EU),
+ EMIT_MASKWRITE(0XF8006064, 0x00021FE0U, 0x00020000U),
+ EMIT_MASKWRITE(0XF8006068, 0x03FFFFFFU, 0x00284141U),
+ EMIT_MASKWRITE(0XF800606C, 0x0000FFFFU, 0x00001610U),
+ EMIT_MASKWRITE(0XF8006078, 0x03FFFFFFU, 0x00466111U),
+ EMIT_MASKWRITE(0XF800607C, 0x000FFFFFU, 0x00032222U),
+ EMIT_MASKWRITE(0XF80060A4, 0xFFFFFFFFU, 0x10200802U),
+ EMIT_MASKWRITE(0XF80060A8, 0x0FFFFFFFU, 0x0690CB73U),
+ EMIT_MASKWRITE(0XF80060AC, 0x000001FFU, 0x000001FEU),
+ EMIT_MASKWRITE(0XF80060B0, 0x1FFFFFFFU, 0x1CFFFFFFU),
+ EMIT_MASKWRITE(0XF80060B4, 0x00000200U, 0x00000200U),
+ EMIT_MASKWRITE(0XF80060B8, 0x01FFFFFFU, 0x00200066U),
+ EMIT_MASKWRITE(0XF80060C4, 0x00000003U, 0x00000003U),
+ EMIT_MASKWRITE(0XF80060C4, 0x00000003U, 0x00000000U),
+ EMIT_MASKWRITE(0XF80060C8, 0x000000FFU, 0x00000000U),
+ EMIT_MASKWRITE(0XF80060DC, 0x00000001U, 0x00000000U),
+ EMIT_MASKWRITE(0XF80060F0, 0x0000FFFFU, 0x00000000U),
+ EMIT_MASKWRITE(0XF80060F4, 0x0000000FU, 0x00000008U),
+ EMIT_MASKWRITE(0XF8006114, 0x000000FFU, 0x00000000U),
+ EMIT_MASKWRITE(0XF8006118, 0x7FFFFFCFU, 0x40000001U),
+ EMIT_MASKWRITE(0XF800611C, 0x7FFFFFCFU, 0x40000001U),
+ EMIT_MASKWRITE(0XF8006120, 0x7FFFFFCFU, 0x40000001U),
+ EMIT_MASKWRITE(0XF8006124, 0x7FFFFFCFU, 0x40000001U),
+ EMIT_MASKWRITE(0XF800612C, 0x000FFFFFU, 0x00025010U),
+ EMIT_MASKWRITE(0XF8006130, 0x000FFFFFU, 0x00026400U),
+ EMIT_MASKWRITE(0XF8006134, 0x000FFFFFU, 0x00029418U),
+ EMIT_MASKWRITE(0XF8006138, 0x000FFFFFU, 0x00027820U),
+ EMIT_MASKWRITE(0XF8006140, 0x000FFFFFU, 0x00000035U),
+ EMIT_MASKWRITE(0XF8006144, 0x000FFFFFU, 0x00000035U),
+ EMIT_MASKWRITE(0XF8006148, 0x000FFFFFU, 0x00000035U),
+ EMIT_MASKWRITE(0XF800614C, 0x000FFFFFU, 0x00000035U),
+ EMIT_MASKWRITE(0XF8006154, 0x000FFFFFU, 0x00000090U),
+ EMIT_MASKWRITE(0XF8006158, 0x000FFFFFU, 0x00000080U),
+ EMIT_MASKWRITE(0XF800615C, 0x000FFFFFU, 0x00000098U),
+ EMIT_MASKWRITE(0XF8006160, 0x000FFFFFU, 0x000000A0U),
+ EMIT_MASKWRITE(0XF8006168, 0x001FFFFFU, 0x000000E9U),
+ EMIT_MASKWRITE(0XF800616C, 0x001FFFFFU, 0x000000EEU),
+ EMIT_MASKWRITE(0XF8006170, 0x001FFFFFU, 0x000000FAU),
+ EMIT_MASKWRITE(0XF8006174, 0x001FFFFFU, 0x000000F3U),
+ EMIT_MASKWRITE(0XF800617C, 0x000FFFFFU, 0x000000D0U),
+ EMIT_MASKWRITE(0XF8006180, 0x000FFFFFU, 0x000000C0U),
+ EMIT_MASKWRITE(0XF8006184, 0x000FFFFFU, 0x000000D8U),
+ EMIT_MASKWRITE(0XF8006188, 0x000FFFFFU, 0x000000E0U),
+ EMIT_MASKWRITE(0XF8006190, 0x6FFFFEFEU, 0x00040080U),
+ EMIT_MASKWRITE(0XF8006194, 0x000FFFFFU, 0x0001FC82U),
+ EMIT_MASKWRITE(0XF8006204, 0xFFFFFFFFU, 0x00000000U),
+ EMIT_MASKWRITE(0XF8006208, 0x000703FFU, 0x000003FFU),
+ EMIT_MASKWRITE(0XF800620C, 0x000703FFU, 0x000003FFU),
+ EMIT_MASKWRITE(0XF8006210, 0x000703FFU, 0x000003FFU),
+ EMIT_MASKWRITE(0XF8006214, 0x000703FFU, 0x000003FFU),
+ EMIT_MASKWRITE(0XF8006218, 0x000F03FFU, 0x000003FFU),
+ EMIT_MASKWRITE(0XF800621C, 0x000F03FFU, 0x000003FFU),
+ EMIT_MASKWRITE(0XF8006220, 0x000F03FFU, 0x000003FFU),
+ EMIT_MASKWRITE(0XF8006224, 0x000F03FFU, 0x000003FFU),
+ EMIT_MASKWRITE(0XF80062A8, 0x00000FF5U, 0x00000000U),
+ EMIT_MASKWRITE(0XF80062AC, 0xFFFFFFFFU, 0x00000000U),
+ EMIT_MASKWRITE(0XF80062B0, 0x003FFFFFU, 0x00005125U),
+ EMIT_MASKWRITE(0XF80062B4, 0x0003FFFFU, 0x000012A8U),
+ EMIT_MASKPOLL(0XF8000B74, 0x00002000U),
+ EMIT_MASKWRITE(0XF8006000, 0x0001FFFFU, 0x00000081U),
+ EMIT_MASKPOLL(0XF8006054, 0x00000007U),
+ EMIT_EXIT(),
+};
+
+static unsigned long ps7_mio_init_data_3_0[] = {
+ EMIT_MASKWRITE(0XF8000008, 0x0000FFFFU, 0x0000DF0DU),
+ EMIT_MASKWRITE(0XF8000B40, 0x00000FFFU, 0x00000600U),
+ EMIT_MASKWRITE(0XF8000B44, 0x00000FFFU, 0x00000600U),
+ EMIT_MASKWRITE(0XF8000B48, 0x00000FFFU, 0x00000672U),
+ EMIT_MASKWRITE(0XF8000B4C, 0x00000FFFU, 0x00000672U),
+ EMIT_MASKWRITE(0XF8000B50, 0x00000FFFU, 0x00000674U),
+ EMIT_MASKWRITE(0XF8000B54, 0x00000FFFU, 0x00000674U),
+ EMIT_MASKWRITE(0XF8000B58, 0x00000FFFU, 0x00000600U),
+ EMIT_MASKWRITE(0XF8000B5C, 0xFFFFFFFFU, 0x0018C61CU),
+ EMIT_MASKWRITE(0XF8000B60, 0xFFFFFFFFU, 0x00F9861CU),
+ EMIT_MASKWRITE(0XF8000B64, 0xFFFFFFFFU, 0x00F9861CU),
+ EMIT_MASKWRITE(0XF8000B68, 0xFFFFFFFFU, 0x00F9861CU),
+ EMIT_MASKWRITE(0XF8000B6C, 0x00007FFFU, 0x00000E60U),
+ EMIT_MASKWRITE(0XF8000B70, 0x00000001U, 0x00000001U),
+ EMIT_MASKWRITE(0XF8000B70, 0x00000021U, 0x00000020U),
+ EMIT_MASKWRITE(0XF8000B70, 0x07FEFFFFU, 0x00000823U),
+ EMIT_MASKWRITE(0XF8000004, 0x0000FFFFU, 0x0000767BU),
+ EMIT_EXIT(),
+};
+
+static unsigned long ps7_peripherals_init_data_3_0[] = {
+ EMIT_MASKWRITE(0XF8000008, 0x0000FFFFU, 0x0000DF0DU),
+ EMIT_MASKWRITE(0XF8000B48, 0x00000180U, 0x00000180U),
+ EMIT_MASKWRITE(0XF8000B4C, 0x00000180U, 0x00000180U),
+ EMIT_MASKWRITE(0XF8000B50, 0x00000180U, 0x00000180U),
+ EMIT_MASKWRITE(0XF8000B54, 0x00000180U, 0x00000180U),
+ EMIT_MASKWRITE(0XF8000004, 0x0000FFFFU, 0x0000767BU),
+ EMIT_MASKWRITE(0XE0001034, 0x000000FFU, 0x00000006U),
+ EMIT_MASKWRITE(0XE0001018, 0x0000FFFFU, 0x0000007CU),
+ EMIT_MASKWRITE(0XE0001000, 0x000001FFU, 0x00000017U),
+ EMIT_MASKWRITE(0XE0001004, 0x000003FFU, 0x00000020U),
+ EMIT_MASKWRITE(0XE0000034, 0x000000FFU, 0x00000006U),
+ EMIT_MASKWRITE(0XE0000018, 0x0000FFFFU, 0x0000007CU),
+ EMIT_MASKWRITE(0XE0000000, 0x000001FFU, 0x00000017U),
+ EMIT_MASKWRITE(0XE0000004, 0x000003FFU, 0x00000020U),
+ EMIT_MASKWRITE(0XE000D000, 0x000800FFU, 0x000800C1U),
+ EMIT_MASKWRITE(0XF8007000, 0x20000000U, 0x00000000U),
+ EMIT_MASKDELAY(0XF8F00200, 1),
+ EMIT_MASKWRITE(0XE000A244, 0x003FFFFFU, 0x00004000U),
+ EMIT_MASKWRITE(0XE000A008, 0xFFFFFFFFU, 0xBFFF4000U),
+ EMIT_MASKWRITE(0XE000A248, 0x003FFFFFU, 0x00004000U),
+ EMIT_MASKWRITE(0XE000A008, 0xFFFFFFFFU, 0xBFFF0000U),
+ EMIT_MASKDELAY(0XF8F00200, 1),
+ EMIT_MASKWRITE(0XE000A008, 0xFFFFFFFFU, 0xBFFF4000U),
+ EMIT_MASKDELAY(0XF8F00200, 1),
+ EMIT_MASKDELAY(0XF8F00200, 1),
+ EMIT_EXIT(),
+};
+
+static unsigned long ps7_post_config_3_0[] = {
+ EMIT_MASKWRITE(0XF8000008, 0x0000FFFFU, 0x0000DF0DU),
+ EMIT_MASKWRITE(0XF8000900, 0x0000000FU, 0x0000000FU),
+ EMIT_MASKWRITE(0XF8000240, 0xFFFFFFFFU, 0x00000000U),
+ EMIT_MASKWRITE(0XF8000004, 0x0000FFFFU, 0x0000767BU),
+ EMIT_EXIT(),
+};
+
+int ps7_init(void)
+{
+ int ret;
+
+ ret = ps7_config(ps7_mio_init_data_3_0);
+ if (ret != PS7_INIT_SUCCESS)
+ return ret;
+ ret = ps7_config(ps7_pll_init_data_3_0);
+ if (ret != PS7_INIT_SUCCESS)
+ return ret;
+ ret = ps7_config(ps7_clock_init_data_3_0);
+ if (ret != PS7_INIT_SUCCESS)
+ return ret;
+ ret = ps7_config(ps7_ddr_init_data_3_0);
+ if (ret != PS7_INIT_SUCCESS)
+ return ret;
+ ret = ps7_config(ps7_peripherals_init_data_3_0);
+ if (ret != PS7_INIT_SUCCESS)
+ return ret;
+
+ return PS7_INIT_SUCCESS;
+}
+
+int ps7_post_config(void)
+{
+ return ps7_config(ps7_post_config_3_0);
+}
diff --git a/board/topic/zynq/zynq-topic-miamiplus/ps7_regs.txt b/board/topic/zynq/zynq-topic-miamiplus/ps7_regs.txt
new file mode 100644
index 0000000000..7b102de378
--- /dev/null
+++ b/board/topic/zynq/zynq-topic-miamiplus/ps7_regs.txt
@@ -0,0 +1,61 @@
+0xF8000120 0x1F000200 // ARM_CLK_CTRL - divisor = 2 (433 MHz)
+0xf8000700 0x1202 // MIO configuration
+0xf8000704 0x1202
+0xf8000708 0x202
+0xf800070c 0x202
+0xf8000710 0x202
+0xf8000714 0x202
+0xf8000718 0x202
+0xf800071c 0x200
+0xf8000720 0x202
+0xf8000724 0x202
+0xf8000728 0x202
+0xf800072c 0x202
+0xf8000730 0x202
+0xf8000734 0x202
+0xf8000738 0x12e1
+0xf800073c 0x12e0
+0xf8000740 0x1202
+0xf8000744 0x1202
+0xf8000748 0x1202
+0xf800074c 0x1202
+0xf8000750 0x1202
+0xf8000754 0x1202
+0xf8000758 0x1203
+0xf800075c 0x1203
+0xf8000760 0x1203
+0xf8000764 0x203
+0xf8000768 0x1203
+0xf800076c 0x203
+0xf8000770 0x304
+0xf8000774 0x305
+0xf8000778 0x304
+0xf800077c 0x305
+0xf8000780 0x304
+0xf8000784 0x304
+0xf8000788 0x304
+0xf800078c 0x304
+0xf8000790 0x305
+0xf8000794 0x304
+0xf8000798 0x304
+0xf800079c 0x304
+0xf80007a0 0x380
+0xf80007a4 0x380
+0xf80007a8 0x380
+0xf80007ac 0x380
+0xf80007b0 0x380
+0xf80007b4 0x380
+0xf80007b8 0x1200
+0xf80007bc 0x1201
+0xf80007c0 0x1240
+0xf80007c4 0x1240
+0xf80007c8 0x1240
+0xf80007cc 0x1240
+0xf80007d0 0x1280
+0xf80007d4 0x1280
+0xf8000830 0x2f0037
+0xf8000834 0x3a0039
+0xF800014C 0x00000621 // LQSPI_CLK_CTRL - ARMPLL/6
+0xE000D000 0x800238C1 // QSPI config - divide-by-2
+0xE000D038 0x00000020 // QSPI loopback - internal, 0 delay
+0xE000D0A0 0xE2FF06EB // LQSPI_CFG - Quad read, dual flash
diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c
index 183f642753..2c86940957 100644
--- a/board/xilinx/zynq/board.c
+++ b/board/xilinx/zynq/board.c
@@ -19,7 +19,10 @@ DECLARE_GLOBAL_DATA_PTR;
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);
@@ -37,9 +40,18 @@ int board_init(void)
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;
diff --git a/board/xilinx/zynqmp/Makefile b/board/xilinx/zynqmp/Makefile
index 90f00c650a..efc8edaaf6 100644
--- a/board/xilinx/zynqmp/Makefile
+++ b/board/xilinx/zynqmp/Makefile
@@ -27,3 +27,6 @@ CFLAGS_REMOVE_psu_init_gpl.o := -Wstrict-prototypes
# To include xil_io.h
CFLAGS_psu_init_gpl.o := -I$(srctree)/$(src)
+
+# To suppress "warning: cast to pointer from integer of different size"
+CFLAGS_psu_init_gpl.o += -Wno-int-to-pointer-cast
diff --git a/board/xilinx/zynqmp/xil_io.h b/board/xilinx/zynqmp/xil_io.h
index 57ca4adf11..6bbc000da8 100644
--- a/board/xilinx/zynqmp/xil_io.h
+++ b/board/xilinx/zynqmp/xil_io.h
@@ -7,6 +7,7 @@
/* FIXME remove this when vivado is fixed */
#include <asm/io.h>
+#include <common.h>
#define xil_printf(...)
@@ -32,4 +33,12 @@ int Xil_In32(unsigned long addr)
return readl(addr);
}
+void mask_delay(u32 delay);
+void usleep(u32 sleep)
+{
+ udelay(sleep);
+}
+int mask_poll(u32 add, u32 mask);
+int mask_pollOnValue(u32 add, u32 mask, u32 value);
+
#endif /* XIL_IO_H */
diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index ba4dfbb476..cef1f6a13a 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -86,6 +86,17 @@ static int chip_id(void)
smc_call(&regs);
+ /*
+ * SMC returns:
+ * regs[0][31:0] = status of the operation
+ * regs[0][63:32] = CSU.IDCODE register
+ * regs[1][31:0] = CSU.version register
+ */
+ regs.regs[0] = upper_32_bits(regs.regs[0]);
+ regs.regs[0] &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
+ ZYNQMP_CSU_IDCODE_SVD_MASK;
+ regs.regs[0] >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
+
return regs.regs[0];
}
@@ -324,6 +335,9 @@ int board_late_init(void)
}
reg = readl(&crlapb_base->boot_mode);
+ if (reg >> BOOT_MODE_ALT_SHIFT)
+ reg >>= BOOT_MODE_ALT_SHIFT;
+
bootmode = reg & BOOT_MODES_MASK;
puts("Bootmode: ");
@@ -349,6 +363,9 @@ int board_late_init(void)
puts("SD_MODE\n");
mode = "mmc0";
break;
+ case SD1_LSHFT_MODE:
+ puts("LVL_SHFT_");
+ /* fall through */
case SD_MODE1:
puts("SD_MODE1\n");
#if defined(CONFIG_ZYNQ_SDHCI0) && defined(CONFIG_ZYNQ_SDHCI1)
@@ -411,6 +428,10 @@ int board_usb_init(int index, enum usb_init_type init)
{
debug("%s: index %x\n", __func__, index);
+#if defined(CONFIG_USB_GADGET_DOWNLOAD)
+ g_dnl_set_serialnumber(CONFIG_SYS_CONFIG_NAME);
+#endif
+
switch (index) {
case 0:
return dwc3_uboot_init(&dwc3_device_data0);
diff --git a/cmd/Kconfig b/cmd/Kconfig
index e339d8638a..2a2f23e251 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -181,6 +181,15 @@ config CMD_BOOTEFI
help
Boot an EFI image from memory.
+config CMD_BOOTEFI_HELLO
+ bool "Allow booting a standard EFI hello world for testing"
+ depends on CMD_BOOTEFI && (ARM || X86)
+ help
+ This adds a standard EFI hello world application to U-Boot so that
+ it can be used with the 'bootefi hello' command. This is useful
+ for testing that EFI is working at a basic level, and for bringing
+ up EFI support on a new architecture.
+
config CMD_ELF
bool "bootelf, bootvx"
default y
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index c8079c4fe8..ca411702ba 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -226,6 +226,17 @@ static unsigned long do_bootefi_exec(void *efi, void *fdt)
return status == EFI_SUCCESS ? 0 : -EINVAL;
}
+#ifdef CONFIG_ARM64
+ /* On AArch64 we need to make sure we call our payload in < EL3 */
+ if (current_el() == 3) {
+ smp_kick_all_cpus();
+ dcache_disable(); /* flush cache before switch to EL2 */
+ armv8_switch_to_el2();
+ /* Enable caches again */
+ dcache_enable();
+ }
+#endif
+
return entry(&loaded_image_info, &systab);
}
@@ -239,16 +250,26 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
if (argc < 2)
return CMD_RET_USAGE;
- saddr = argv[1];
+#ifdef CONFIG_CMD_BOOTEFI_HELLO
+ if (!strcmp(argv[1], "hello")) {
+ ulong size = __efi_hello_world_end - __efi_hello_world_begin;
- addr = simple_strtoul(saddr, NULL, 16);
+ addr = CONFIG_SYS_LOAD_ADDR;
+ memcpy((char *)addr, __efi_hello_world_begin, size);
+ } else
+#endif
+ {
+ saddr = argv[1];
+
+ addr = simple_strtoul(saddr, NULL, 16);
- if (argc > 2) {
- sfdt = argv[2];
- fdt_addr = simple_strtoul(sfdt, NULL, 16);
+ if (argc > 2) {
+ sfdt = argv[2];
+ fdt_addr = simple_strtoul(sfdt, NULL, 16);
+ }
}
- printf("## Starting EFI application at 0x%08lx ...\n", addr);
+ printf("## Starting EFI application at %08lx ...\n", addr);
r = do_bootefi_exec((void *)addr, (void*)fdt_addr);
printf("## Application terminated, r = %d\n", r);
@@ -263,7 +284,12 @@ static char bootefi_help_text[] =
"<image address> [fdt address]\n"
" - boot EFI payload stored at address <image address>.\n"
" If specified, the device tree located at <fdt address> gets\n"
- " exposed as EFI configuration table.\n";
+ " exposed as EFI configuration table.\n"
+#ifdef CONFIG_CMD_BOOTEFI_HELLO
+ "hello\n"
+ " - boot a sample Hello World application stored within U-Boot"
+#endif
+ ;
#endif
U_BOOT_CMD(
diff --git a/configs/efi-x86_defconfig b/configs/efi-x86_defconfig
index b31c73b71e..1fe6142864 100644
--- a/configs/efi-x86_defconfig
+++ b/configs/efi-x86_defconfig
@@ -34,3 +34,4 @@ CONFIG_USB=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
CONFIG_EFI=y
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/topic_miami_defconfig b/configs/topic_miami_defconfig
new file mode 100644
index 0000000000..3d6161e9f9
--- /dev/null
+++ b/configs/topic_miami_defconfig
@@ -0,0 +1,49 @@
+CONFIG_ARM=y
+CONFIG_SYS_VENDOR="topic"
+CONFIG_SYS_CONFIG_NAME="topic_miami"
+CONFIG_ARCH_ZYNQ=y
+CONFIG_BOOT_INIT_FILE="board/topic/zynq/zynq-topic-miami/ps7_regs.txt"
+CONFIG_DEFAULT_DEVICE_TREE="zynq-topic-miami"
+CONFIG_BOOTDELAY=0
+CONFIG_SYS_NO_FLASH=y
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_SPL=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="zynq-uboot> "
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_MMC=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_DFU=y
+CONFIG_CMD_GPIO=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_OF_EMBED=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_ZYNQ_SDHCI=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
+CONFIG_SPI_FLASH_STMICRO=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
+# CONFIG_NETDEVICES is not set
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_ZYNQ=y
+CONFIG_DEBUG_UART_BASE=0xe0000000
+CONFIG_DEBUG_UART_CLOCK=100000000
+CONFIG_ZYNQ_QSPI=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_ULPI_VIEWPORT=y
+CONFIG_USB_ULPI=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_CI_UDC=y
+CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_G_DNL_MANUFACTURER="Xilinx"
+CONFIG_G_DNL_VENDOR_NUM=0x03fd
+CONFIG_G_DNL_PRODUCT_NUM=0x0300
diff --git a/configs/topic_miamiplus_defconfig b/configs/topic_miamiplus_defconfig
new file mode 100644
index 0000000000..3160f00ba6
--- /dev/null
+++ b/configs/topic_miamiplus_defconfig
@@ -0,0 +1,49 @@
+CONFIG_ARM=y
+CONFIG_SYS_VENDOR="topic"
+CONFIG_SYS_CONFIG_NAME="topic_miamiplus"
+CONFIG_ARCH_ZYNQ=y
+CONFIG_BOOT_INIT_FILE="board/topic/zynq/zynq-topic-miamiplus/ps7_regs.txt"
+CONFIG_DEFAULT_DEVICE_TREE="zynq-topic-miamiplus"
+CONFIG_BOOTDELAY=0
+CONFIG_SYS_NO_FLASH=y
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_SPL=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="zynq-uboot> "
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_MMC=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_DFU=y
+CONFIG_CMD_GPIO=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_OF_EMBED=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_ZYNQ_SDHCI=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=y
+CONFIG_SPI_FLASH_STMICRO=y
+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
+# CONFIG_NETDEVICES is not set
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_ZYNQ=y
+CONFIG_DEBUG_UART_BASE=0xe0000000
+CONFIG_DEBUG_UART_CLOCK=100000000
+CONFIG_ZYNQ_QSPI=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_ULPI_VIEWPORT=y
+CONFIG_USB_ULPI=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_CI_UDC=y
+CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_G_DNL_MANUFACTURER="Xilinx"
+CONFIG_G_DNL_VENDOR_NUM=0x03fd
+CONFIG_G_DNL_PRODUCT_NUM=0x0300
diff --git a/configs/zynq_zc770_xm011_defconfig b/configs/zynq_zc770_xm011_defconfig
index 56c2851154..2f4fc1e37d 100644
--- a/configs/zynq_zc770_xm011_defconfig
+++ b/configs/zynq_zc770_xm011_defconfig
@@ -13,6 +13,7 @@ CONFIG_HUSH_PARSER=y
CONFIG_SYS_PROMPT="Zynq> "
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_NAND=y
CONFIG_CMD_GPIO=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_TFTPPUT=y
@@ -22,4 +23,5 @@ CONFIG_CMD_PING=y
CONFIG_CMD_CACHE=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_NAND_ZYNQ=y
CONFIG_ZYNQ_GEM=y
diff --git a/doc/README.efi b/doc/README.efi
index 1fd3f004c3..66259f3e26 100644
--- a/doc/README.efi
+++ b/doc/README.efi
@@ -310,6 +310,20 @@ Removable media booting (search for /efi/boot/boota{a64,arm}.efi) is supported.
Simple use cases like "Plug this SD card into my ARM device and it just
boots into grub which boots into Linux", work very well.
+
+Running HelloWord.efi
+---------------------
+
+You can run a simple 'hello world' EFI program in U-Boot.
+Enable the option CONFIG_CMD_BOOTEFI_HELLO.
+
+Then you can boot into U-Boot and type:
+
+ > bootefi hello
+
+The 'hello world EFI' program will then run, print a message and exit.
+
+
Future work
-----------
diff --git a/doc/README.x86 b/doc/README.x86
index 679955983b..a38cc1bc6c 100644
--- a/doc/README.x86
+++ b/doc/README.x86
@@ -1077,7 +1077,6 @@ TODO List
---------
- Audio
- Chrome OS verified boot
-- Support for CONFIG_EFI_LOADER
- Building U-Boot to run in 64-bit mode
References
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index df154bfd32..65bb040407 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -87,6 +87,13 @@ config NAND_MXS
This enables NAND driver for the NAND flash controller on the
MXS processors.
+config NAND_ZYNQ
+ bool "Support for Zynq Nand controller"
+ select SYS_NAND_SELF_INIT
+ help
+ This enables Nand driver support for Nand flash controller
+ found on Zynq SoC.
+
comment "Generic NAND options"
# Enhance depends when converting drivers to Kconfig which use this config
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 1df9273cdd..fd4bb66f50 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -67,6 +67,7 @@ obj-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
obj-$(CONFIG_NAND_OMAP_ELM) += omap_elm.o
obj-$(CONFIG_NAND_PLAT) += nand_plat.o
obj-$(CONFIG_NAND_SUNXI) += sunxi_nand.o
+obj-$(CONFIG_NAND_ZYNQ) += zynq_nand.o
else # minimal SPL drivers
diff --git a/drivers/mtd/nand/arasan_nfc.c b/drivers/mtd/nand/arasan_nfc.c
index 86f7526a84..a8f795d957 100644
--- a/drivers/mtd/nand/arasan_nfc.c
+++ b/drivers/mtd/nand/arasan_nfc.c
@@ -853,6 +853,8 @@ static int arasan_nand_send_rdcmd(struct arasan_nand_command_format *curr_cmd,
reg_val |= (page_val << ARASAN_NAND_CMD_PG_SIZE_SHIFT);
}
+ reg_val &= ~ARASAN_NAND_CMD_ECC_ON_MASK;
+
reg_val &= ~ARASAN_NAND_CMD_ADDR_CYCL_MASK;
addr_cycles = arasan_nand_get_addrcycle(mtd);
diff --git a/drivers/mtd/nand/zynq_nand.c b/drivers/mtd/nand/zynq_nand.c
new file mode 100644
index 0000000000..cb3340d9b0
--- /dev/null
+++ b/drivers/mtd/nand/zynq_nand.c
@@ -0,0 +1,1186 @@
+/*
+ * (C) Copyright 2016 Xilinx, Inc.
+ *
+ * Xilinx Zynq NAND Flash Controller Driver
+ * This driver is based on plat_nand.c and mxc_nand.c drivers
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <linux/errno.h>
+#include <nand.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand_ecc.h>
+#include <asm/arch/hardware.h>
+
+/* The NAND flash driver defines */
+#define ZYNQ_NAND_CMD_PHASE 1
+#define ZYNQ_NAND_DATA_PHASE 2
+#define ZYNQ_NAND_ECC_SIZE 512
+#define ZYNQ_NAND_SET_OPMODE_8BIT (0 << 0)
+#define ZYNQ_NAND_SET_OPMODE_16BIT (1 << 0)
+#define ZYNQ_NAND_ECC_STATUS (1 << 6)
+#define ZYNQ_MEMC_CLRCR_INT_CLR1 (1 << 4)
+#define ZYNQ_MEMC_SR_RAW_INT_ST1 (1 << 6)
+#define ZYNQ_MEMC_SR_INT_ST1 (1 << 4)
+#define ZYNQ_MEMC_NAND_ECC_MODE_MASK 0xC
+
+/* Flash memory controller operating parameters */
+#define ZYNQ_NAND_CLR_CONFIG ((0x1 << 1) | /* Disable interrupt */ \
+ (0x1 << 4) | /* Clear interrupt */ \
+ (0x1 << 6)) /* Disable ECC interrupt */
+
+/* Assuming 50MHz clock (20ns cycle time) and 3V operation */
+#define ZYNQ_NAND_SET_CYCLES ((0x2 << 20) | /* t_rr from nand_cycles */ \
+ (0x2 << 17) | /* t_ar from nand_cycles */ \
+ (0x1 << 14) | /* t_clr from nand_cycles */ \
+ (0x3 << 11) | /* t_wp from nand_cycles */ \
+ (0x2 << 8) | /* t_rea from nand_cycles */ \
+ (0x5 << 4) | /* t_wc from nand_cycles */ \
+ (0x5 << 0)) /* t_rc from nand_cycles */
+
+
+#define ZYNQ_NAND_DIRECT_CMD ((0x4 << 23) | /* Chip 0 from interface 1 */ \
+ (0x2 << 21)) /* UpdateRegs operation */
+
+#define ZYNQ_NAND_ECC_CONFIG ((0x1 << 2) | /* ECC available on APB */ \
+ (0x1 << 4) | /* ECC read at end of page */ \
+ (0x0 << 5)) /* No Jumping */
+
+#define ZYNQ_NAND_ECC_CMD1 ((0x80) | /* Write command */ \
+ (0x00 << 8) | /* Read command */ \
+ (0x30 << 16) | /* Read End command */ \
+ (0x1 << 24)) /* Read End command calid */
+
+#define ZYNQ_NAND_ECC_CMD2 ((0x85) | /* Write col change cmd */ \
+ (0x05 << 8) | /* Read col change cmd */ \
+ (0xE0 << 16) | /* Read col change end cmd */ \
+ (0x1 << 24)) /* Read col change
+ end cmd valid */
+/* AXI Address definitions */
+#define START_CMD_SHIFT 3
+#define END_CMD_SHIFT 11
+#define END_CMD_VALID_SHIFT 20
+#define ADDR_CYCLES_SHIFT 21
+#define CLEAR_CS_SHIFT 21
+#define ECC_LAST_SHIFT 10
+#define COMMAND_PHASE (0 << 19)
+#define DATA_PHASE (1 << 19)
+#define ONDIE_ECC_FEATURE_ADDR 0x90
+#define ONDIE_ECC_FEATURE_ENABLE 0x08
+
+#define ZYNQ_NAND_ECC_LAST (1 << ECC_LAST_SHIFT) /* Set ECC_Last */
+#define ZYNQ_NAND_CLEAR_CS (1 << CLEAR_CS_SHIFT) /* Clear chip select */
+
+/* ECC block registers bit position and bit mask */
+#define ZYNQ_NAND_ECC_BUSY (1 << 6) /* ECC block is busy */
+#define ZYNQ_NAND_ECC_MASK 0x00FFFFFF /* ECC value mask */
+
+
+/* SMC register set */
+struct zynq_nand_smc_regs {
+ u32 csr; /* 0x00 */
+ u32 reserved0[2];
+ u32 cfr; /* 0x0C */
+ u32 dcr; /* 0x10 */
+ u32 scr; /* 0x14 */
+ u32 sor; /* 0x18 */
+ u32 reserved1[249];
+ u32 esr; /* 0x400 */
+ u32 emcr; /* 0x404 */
+ u32 emcmd1r; /* 0x408 */
+ u32 emcmd2r; /* 0x40C */
+ u32 reserved2[2];
+ u32 eval0r; /* 0x418 */
+};
+#define zynq_nand_smc_base ((struct zynq_nand_smc_regs __iomem *)\
+ ZYNQ_SMC_BASEADDR)
+
+/*
+ * struct zynq_nand_info - Defines the NAND flash driver instance
+ * @parts: Pointer to the mtd_partition structure
+ * @nand_base: Virtual address of the NAND flash device
+ * @end_cmd_pending: End command is pending
+ * @end_cmd: End command
+ */
+struct zynq_nand_info {
+ void __iomem *nand_base;
+ u8 end_cmd_pending;
+ u8 end_cmd;
+};
+
+/*
+ * struct zynq_nand_command_format - Defines NAND flash command format
+ * @start_cmd: First cycle command (Start command)
+ * @end_cmd: Second cycle command (Last command)
+ * @addr_cycles: Number of address cycles required to send the address
+ * @end_cmd_valid: The second cycle command is valid for cmd or data phase
+ */
+struct zynq_nand_command_format {
+ u8 start_cmd;
+ u8 end_cmd;
+ u8 addr_cycles;
+ u8 end_cmd_valid;
+};
+
+/* The NAND flash operations command format */
+static const struct zynq_nand_command_format zynq_nand_commands[] = {
+ {NAND_CMD_READ0, NAND_CMD_READSTART, 5, ZYNQ_NAND_CMD_PHASE},
+ {NAND_CMD_RNDOUT, NAND_CMD_RNDOUTSTART, 2, ZYNQ_NAND_CMD_PHASE},
+ {NAND_CMD_READID, NAND_CMD_NONE, 1, 0},
+ {NAND_CMD_STATUS, NAND_CMD_NONE, 0, 0},
+ {NAND_CMD_SEQIN, NAND_CMD_PAGEPROG, 5, ZYNQ_NAND_DATA_PHASE},
+ {NAND_CMD_RNDIN, NAND_CMD_NONE, 2, 0},
+ {NAND_CMD_ERASE1, NAND_CMD_ERASE2, 3, ZYNQ_NAND_CMD_PHASE},
+ {NAND_CMD_RESET, NAND_CMD_NONE, 0, 0},
+ {NAND_CMD_PARAM, NAND_CMD_NONE, 1, 0},
+ {NAND_CMD_GET_FEATURES, NAND_CMD_NONE, 1, 0},
+ {NAND_CMD_SET_FEATURES, NAND_CMD_NONE, 1, 0},
+ {NAND_CMD_NONE, NAND_CMD_NONE, 0, 0},
+ /* Add all the flash commands supported by the flash device */
+};
+
+/* Define default oob placement schemes for large and small page devices */
+static struct nand_ecclayout nand_oob_16 = {
+ .eccbytes = 3,
+ .eccpos = {0, 1, 2},
+ .oobfree = {
+ { .offset = 8, .length = 8 }
+ }
+};
+
+static struct nand_ecclayout nand_oob_64 = {
+ .eccbytes = 12,
+ .eccpos = {
+ 52, 53, 54, 55, 56, 57,
+ 58, 59, 60, 61, 62, 63},
+ .oobfree = {
+ { .offset = 2, .length = 50 }
+ }
+};
+
+static struct nand_ecclayout ondie_nand_oob_64 = {
+ .eccbytes = 32,
+
+ .eccpos = {
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 24, 25, 26, 27, 28, 29, 30, 31,
+ 40, 41, 42, 43, 44, 45, 46, 47,
+ 56, 57, 58, 59, 60, 61, 62, 63
+ },
+
+ .oobfree = {
+ { .offset = 4, .length = 4 },
+ { .offset = 20, .length = 4 },
+ { .offset = 36, .length = 4 },
+ { .offset = 52, .length = 4 }
+ }
+};
+
+/* bbt decriptors for chips with on-die ECC and
+ chips with 64-byte OOB */
+static u8 bbt_pattern[] = {'B', 'b', 't', '0' };
+static u8 mirror_pattern[] = {'1', 't', 'b', 'B' };
+
+static struct nand_bbt_descr bbt_main_descr = {
+ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
+ NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
+ .offs = 4,
+ .len = 4,
+ .veroffs = 20,
+ .maxblocks = 4,
+ .pattern = bbt_pattern
+};
+
+static struct nand_bbt_descr bbt_mirror_descr = {
+ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
+ NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
+ .offs = 4,
+ .len = 4,
+ .veroffs = 20,
+ .maxblocks = 4,
+ .pattern = mirror_pattern
+};
+
+/*
+ * zynq_nand_waitfor_ecc_completion - Wait for ECC completion
+ *
+ * returns: status for command completion, -1 for Timeout
+ */
+static int zynq_nand_waitfor_ecc_completion(void)
+{
+ unsigned long timeout;
+ u32 status;
+
+ /* Wait max 10us */
+ timeout = 10;
+ status = readl(&zynq_nand_smc_base->esr);
+ while (status & ZYNQ_NAND_ECC_BUSY) {
+ status = readl(&zynq_nand_smc_base->esr);
+ if (timeout == 0)
+ return -1;
+ timeout--;
+ udelay(1);
+ }
+
+ return status;
+}
+
+/*
+ * zynq_nand_init_nand_flash - Initialize NAND controller
+ * @option: Device property flags
+ *
+ * This function initializes the NAND flash interface on the NAND controller.
+ *
+ * returns: 0 on success or error value on failure
+ */
+static int zynq_nand_init_nand_flash(int option)
+{
+ u32 status;
+
+ /* disable interrupts */
+ writel(ZYNQ_NAND_CLR_CONFIG, &zynq_nand_smc_base->cfr);
+ /* Initialize the NAND interface by setting cycles and operation mode */
+ writel(ZYNQ_NAND_SET_CYCLES, &zynq_nand_smc_base->scr);
+ if (option & NAND_BUSWIDTH_16)
+ writel(ZYNQ_NAND_SET_OPMODE_16BIT, &zynq_nand_smc_base->sor);
+ else
+ writel(ZYNQ_NAND_SET_OPMODE_8BIT, &zynq_nand_smc_base->sor);
+
+ writel(ZYNQ_NAND_DIRECT_CMD, &zynq_nand_smc_base->dcr);
+
+ /* Wait till the ECC operation is complete */
+ status = zynq_nand_waitfor_ecc_completion();
+ if (status < 0) {
+ printf("%s: Timeout\n", __func__);
+ return status;
+ }
+
+ /* Set the command1 and command2 register */
+ writel(ZYNQ_NAND_ECC_CMD1, &zynq_nand_smc_base->emcmd1r);
+ writel(ZYNQ_NAND_ECC_CMD2, &zynq_nand_smc_base->emcmd2r);
+
+ return 0;
+}
+
+/*
+ * zynq_nand_calculate_hwecc - Calculate Hardware ECC
+ * @mtd: Pointer to the mtd_info structure
+ * @data: Pointer to the page data
+ * @ecc_code: Pointer to the ECC buffer where ECC data needs to be stored
+ *
+ * This function retrieves the Hardware ECC data from the controller and returns
+ * ECC data back to the MTD subsystem.
+ *
+ * returns: 0 on success or error value on failure
+ */
+static int zynq_nand_calculate_hwecc(struct mtd_info *mtd, const u8 *data,
+ u8 *ecc_code)
+{
+ u32 ecc_value = 0;
+ u8 ecc_reg, ecc_byte;
+ u32 ecc_status;
+
+ /* Wait till the ECC operation is complete */
+ ecc_status = zynq_nand_waitfor_ecc_completion();
+ if (ecc_status < 0) {
+ printf("%s: Timeout\n", __func__);
+ return ecc_status;
+ }
+
+ for (ecc_reg = 0; ecc_reg < 4; ecc_reg++) {
+ /* Read ECC value for each block */
+ ecc_value = readl(&zynq_nand_smc_base->eval0r + ecc_reg);
+
+ /* Get the ecc status from ecc read value */
+ ecc_status = (ecc_value >> 24) & 0xFF;
+
+ /* ECC value valid */
+ if (ecc_status & ZYNQ_NAND_ECC_STATUS) {
+ for (ecc_byte = 0; ecc_byte < 3; ecc_byte++) {
+ /* Copy ECC bytes to MTD buffer */
+ *ecc_code = ecc_value & 0xFF;
+ ecc_value = ecc_value >> 8;
+ ecc_code++;
+ }
+ } else {
+ debug("%s: ecc status failed\n", __func__);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * onehot - onehot function
+ * @value: value to check for onehot
+ *
+ * This function checks whether a value is onehot or not.
+ * onehot is if and only if one bit is set.
+ *
+ * FIXME: Try to move this in common.h
+ */
+static bool onehot(unsigned short value)
+{
+ bool onehot;
+
+ onehot = value && !(value & (value - 1));
+ return onehot;
+}
+
+/*
+ * zynq_nand_correct_data - ECC correction function
+ * @mtd: Pointer to the mtd_info structure
+ * @buf: Pointer to the page data
+ * @read_ecc: Pointer to the ECC value read from spare data area
+ * @calc_ecc: Pointer to the calculated ECC value
+ *
+ * This function corrects the ECC single bit errors & detects 2-bit errors.
+ *
+ * returns: 0 if no ECC errors found
+ * 1 if single bit error found and corrected.
+ * -1 if multiple ECC errors found.
+ */
+static int zynq_nand_correct_data(struct mtd_info *mtd, unsigned char *buf,
+ unsigned char *read_ecc, unsigned char *calc_ecc)
+{
+ unsigned char bit_addr;
+ unsigned int byte_addr;
+ unsigned short ecc_odd, ecc_even;
+ unsigned short read_ecc_lower, read_ecc_upper;
+ unsigned short calc_ecc_lower, calc_ecc_upper;
+
+ read_ecc_lower = (read_ecc[0] | (read_ecc[1] << 8)) & 0xfff;
+ read_ecc_upper = ((read_ecc[1] >> 4) | (read_ecc[2] << 4)) & 0xfff;
+
+ calc_ecc_lower = (calc_ecc[0] | (calc_ecc[1] << 8)) & 0xfff;
+ calc_ecc_upper = ((calc_ecc[1] >> 4) | (calc_ecc[2] << 4)) & 0xfff;
+
+ ecc_odd = read_ecc_lower ^ calc_ecc_lower;
+ ecc_even = read_ecc_upper ^ calc_ecc_upper;
+
+ if ((ecc_odd == 0) && (ecc_even == 0))
+ return 0; /* no error */
+
+ if (ecc_odd == (~ecc_even & 0xfff)) {
+ /* bits [11:3] of error code is byte offset */
+ byte_addr = (ecc_odd >> 3) & 0x1ff;
+ /* bits [2:0] of error code is bit offset */
+ bit_addr = ecc_odd & 0x7;
+ /* Toggling error bit */
+ buf[byte_addr] ^= (1 << bit_addr);
+ return 1;
+ }
+
+ if (onehot(ecc_odd | ecc_even))
+ return 1; /* one error in parity */
+
+ return -1; /* Uncorrectable error */
+}
+
+/*
+ * zynq_nand_read_oob - [REPLACABLE] the most common OOB data read function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @page: page number to read
+ * @sndcmd: flag whether to issue read command or not
+ */
+static int zynq_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
+ int page)
+{
+ unsigned long data_phase_addr = 0;
+ int data_width = 4;
+ u8 *p;
+
+ chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
+
+ p = chip->oob_poi;
+ chip->read_buf(mtd, p, (mtd->oobsize - data_width));
+ p += mtd->oobsize - data_width;
+
+ data_phase_addr = (unsigned long)chip->IO_ADDR_R;
+ data_phase_addr |= ZYNQ_NAND_CLEAR_CS;
+ chip->IO_ADDR_R = (void __iomem *)data_phase_addr;
+ chip->read_buf(mtd, p, data_width);
+
+ return 0;
+}
+
+/*
+ * zynq_nand_write_oob - [REPLACABLE] the most common OOB data write function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @page: page number to write
+ */
+static int zynq_nand_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
+ int page)
+{
+ int status = 0, data_width = 4;
+ const u8 *buf = chip->oob_poi;
+ unsigned long data_phase_addr = 0;
+
+ chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page);
+
+ chip->write_buf(mtd, buf, (mtd->oobsize - data_width));
+ buf += mtd->oobsize - data_width;
+
+ data_phase_addr = (unsigned long)chip->IO_ADDR_W;
+ data_phase_addr |= ZYNQ_NAND_CLEAR_CS;
+ data_phase_addr |= (1 << END_CMD_VALID_SHIFT);
+ chip->IO_ADDR_W = (void __iomem *)data_phase_addr;
+ chip->write_buf(mtd, buf, data_width);
+
+ /* Send command to program the OOB data */
+ chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
+ status = chip->waitfunc(mtd, chip);
+
+ return status & NAND_STATUS_FAIL ? -EIO : 0;
+}
+
+/*
+ * zynq_nand_read_page_raw - [Intern] read raw page data without ecc
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ * @oob_required: must write chip->oob_poi to OOB
+ * @page: page number to read
+ */
+static int zynq_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+ u8 *buf, int oob_required, int page)
+{
+ unsigned long data_width = 4;
+ unsigned long data_phase_addr = 0;
+ u8 *p;
+
+ chip->read_buf(mtd, buf, mtd->writesize);
+
+ p = chip->oob_poi;
+ chip->read_buf(mtd, p, (mtd->oobsize - data_width));
+ p += (mtd->oobsize - data_width);
+
+ data_phase_addr = (unsigned long)chip->IO_ADDR_R;
+ data_phase_addr |= ZYNQ_NAND_CLEAR_CS;
+ chip->IO_ADDR_R = (void __iomem *)data_phase_addr;
+
+ chip->read_buf(mtd, p, data_width);
+ return 0;
+}
+
+static int zynq_nand_read_page_raw_nooob(struct mtd_info *mtd,
+ struct nand_chip *chip, u8 *buf, int oob_required, int page)
+{
+ chip->read_buf(mtd, buf, mtd->writesize);
+ return 0;
+}
+
+static int zynq_nand_read_subpage_raw(struct mtd_info *mtd,
+ struct nand_chip *chip, u32 data_offs,
+ u32 readlen, u8 *buf, int page)
+{
+ if (data_offs != 0) {
+ chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_offs, -1);
+ buf += data_offs;
+ }
+ chip->read_buf(mtd, buf, readlen);
+
+ return 0;
+}
+
+/*
+ * zynq_nand_write_page_raw - [Intern] raw page write function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: data buffer
+ * @oob_required: must write chip->oob_poi to OOB
+ */
+static int zynq_nand_write_page_raw(struct mtd_info *mtd,
+ struct nand_chip *chip, const u8 *buf, int oob_required, int page)
+{
+ unsigned long data_width = 4;
+ unsigned long data_phase_addr = 0;
+ u8 *p;
+
+ chip->write_buf(mtd, buf, mtd->writesize);
+
+ p = chip->oob_poi;
+ chip->write_buf(mtd, p, (mtd->oobsize - data_width));
+ p += (mtd->oobsize - data_width);
+
+ data_phase_addr = (unsigned long)chip->IO_ADDR_W;
+ data_phase_addr |= ZYNQ_NAND_CLEAR_CS;
+ data_phase_addr |= (1 << END_CMD_VALID_SHIFT);
+ chip->IO_ADDR_W = (void __iomem *)data_phase_addr;
+
+ chip->write_buf(mtd, p, data_width);
+
+ return 0;
+}
+
+/*
+ * nand_write_page_hwecc - Hardware ECC based page write function
+ * @mtd: Pointer to the mtd info structure
+ * @chip: Pointer to the NAND chip info structure
+ * @buf: Pointer to the data buffer
+ * @oob_required: must write chip->oob_poi to OOB
+ *
+ * This functions writes data and hardware generated ECC values in to the page.
+ */
+static int zynq_nand_write_page_hwecc(struct mtd_info *mtd,
+ struct nand_chip *chip, const u8 *buf, int oob_required, int page)
+{
+ int i, eccsteps, eccsize = chip->ecc.size;
+ u8 *ecc_calc = chip->buffers->ecccalc;
+ const u8 *p = buf;
+ u32 *eccpos = chip->ecc.layout->eccpos;
+ unsigned long data_phase_addr = 0;
+ unsigned long data_width = 4;
+ u8 *oob_ptr;
+
+ for (eccsteps = chip->ecc.steps; (eccsteps - 1); eccsteps--) {
+ chip->write_buf(mtd, p, eccsize);
+ p += eccsize;
+ }
+ chip->write_buf(mtd, p, (eccsize - data_width));
+ p += eccsize - data_width;
+
+ /* Set ECC Last bit to 1 */
+ data_phase_addr = (unsigned long) chip->IO_ADDR_W;
+ data_phase_addr |= ZYNQ_NAND_ECC_LAST;
+ chip->IO_ADDR_W = (void __iomem *)data_phase_addr;
+ chip->write_buf(mtd, p, data_width);
+
+ /* Wait for ECC to be calculated and read the error values */
+ p = buf;
+ chip->ecc.calculate(mtd, p, &ecc_calc[0]);
+
+ for (i = 0; i < chip->ecc.total; i++)
+ chip->oob_poi[eccpos[i]] = ~(ecc_calc[i]);
+
+ /* Clear ECC last bit */
+ data_phase_addr = (unsigned long)chip->IO_ADDR_W;
+ data_phase_addr &= ~ZYNQ_NAND_ECC_LAST;
+ chip->IO_ADDR_W = (void __iomem *)data_phase_addr;
+
+ /* Write the spare area with ECC bytes */
+ oob_ptr = chip->oob_poi;
+ chip->write_buf(mtd, oob_ptr, (mtd->oobsize - data_width));
+
+ data_phase_addr = (unsigned long)chip->IO_ADDR_W;
+ data_phase_addr |= ZYNQ_NAND_CLEAR_CS;
+ data_phase_addr |= (1 << END_CMD_VALID_SHIFT);
+ chip->IO_ADDR_W = (void __iomem *)data_phase_addr;
+ oob_ptr += (mtd->oobsize - data_width);
+ chip->write_buf(mtd, oob_ptr, data_width);
+
+ return 0;
+}
+
+/*
+ * zynq_nand_write_page_swecc - [REPLACABLE] software ecc based page
+ * write function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: data buffer
+ * @oob_required: must write chip->oob_poi to OOB
+ */
+static int zynq_nand_write_page_swecc(struct mtd_info *mtd,
+ struct nand_chip *chip, const u8 *buf, int oob_required, int page)
+{
+ int i, eccsize = chip->ecc.size;
+ int eccbytes = chip->ecc.bytes;
+ int eccsteps = chip->ecc.steps;
+ u8 *ecc_calc = chip->buffers->ecccalc;
+ const u8 *p = buf;
+ u32 *eccpos = chip->ecc.layout->eccpos;
+
+ /* Software ecc calculation */
+ for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
+ chip->ecc.calculate(mtd, p, &ecc_calc[i]);
+
+ for (i = 0; i < chip->ecc.total; i++)
+ chip->oob_poi[eccpos[i]] = ecc_calc[i];
+
+ return chip->ecc.write_page_raw(mtd, chip, buf, 1, page);
+}
+
+/*
+ * nand_read_page_hwecc - Hardware ECC based page read function
+ * @mtd: Pointer to the mtd info structure
+ * @chip: Pointer to the NAND chip info structure
+ * @buf: Pointer to the buffer to store read data
+ * @oob_required: must write chip->oob_poi to OOB
+ * @page: page number to read
+ *
+ * This functions reads data and checks the data integrity by comparing hardware
+ * generated ECC values and read ECC values from spare area.
+ *
+ * returns: 0 always and updates ECC operation status in to MTD structure
+ */
+static int zynq_nand_read_page_hwecc(struct mtd_info *mtd,
+ struct nand_chip *chip, u8 *buf, int oob_required, int page)
+{
+ int i, stat, eccsteps, eccsize = chip->ecc.size;
+ int eccbytes = chip->ecc.bytes;
+ u8 *p = buf;
+ u8 *ecc_calc = chip->buffers->ecccalc;
+ u8 *ecc_code = chip->buffers->ecccode;
+ u32 *eccpos = chip->ecc.layout->eccpos;
+ unsigned long data_phase_addr = 0;
+ unsigned long data_width = 4;
+ u8 *oob_ptr;
+
+ for (eccsteps = chip->ecc.steps; (eccsteps - 1); eccsteps--) {
+ chip->read_buf(mtd, p, eccsize);
+ p += eccsize;
+ }
+ chip->read_buf(mtd, p, (eccsize - data_width));
+ p += eccsize - data_width;
+
+ /* Set ECC Last bit to 1 */
+ data_phase_addr = (unsigned long)chip->IO_ADDR_R;
+ data_phase_addr |= ZYNQ_NAND_ECC_LAST;
+ chip->IO_ADDR_R = (void __iomem *)data_phase_addr;
+ chip->read_buf(mtd, p, data_width);
+
+ /* Read the calculated ECC value */
+ p = buf;
+ chip->ecc.calculate(mtd, p, &ecc_calc[0]);
+
+ /* Clear ECC last bit */
+ data_phase_addr = (unsigned long)chip->IO_ADDR_R;
+ data_phase_addr &= ~ZYNQ_NAND_ECC_LAST;
+ chip->IO_ADDR_R = (void __iomem *)data_phase_addr;
+
+ /* Read the stored ECC value */
+ oob_ptr = chip->oob_poi;
+ chip->read_buf(mtd, oob_ptr, (mtd->oobsize - data_width));
+
+ /* de-assert chip select */
+ data_phase_addr = (unsigned long)chip->IO_ADDR_R;
+ data_phase_addr |= ZYNQ_NAND_CLEAR_CS;
+ chip->IO_ADDR_R = (void __iomem *)data_phase_addr;
+
+ oob_ptr += (mtd->oobsize - data_width);
+ chip->read_buf(mtd, oob_ptr, data_width);
+
+ for (i = 0; i < chip->ecc.total; i++)
+ ecc_code[i] = ~(chip->oob_poi[eccpos[i]]);
+
+ eccsteps = chip->ecc.steps;
+ p = buf;
+
+ /* Check ECC error for all blocks and correct if it is correctable */
+ for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+ stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
+ if (stat < 0)
+ mtd->ecc_stats.failed++;
+ else
+ mtd->ecc_stats.corrected += stat;
+ }
+ return 0;
+}
+
+/*
+ * zynq_nand_read_page_swecc - [REPLACABLE] software ecc based page
+ * read function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ * @page: page number to read
+ */
+static int zynq_nand_read_page_swecc(struct mtd_info *mtd,
+ struct nand_chip *chip, u8 *buf, int oob_required, int page)
+{
+ int i, eccsize = chip->ecc.size;
+ int eccbytes = chip->ecc.bytes;
+ int eccsteps = chip->ecc.steps;
+ u8 *p = buf;
+ u8 *ecc_calc = chip->buffers->ecccalc;
+ u8 *ecc_code = chip->buffers->ecccode;
+ u32 *eccpos = chip->ecc.layout->eccpos;
+
+ chip->ecc.read_page_raw(mtd, chip, buf, 1, page);
+
+ for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
+ chip->ecc.calculate(mtd, p, &ecc_calc[i]);
+
+ for (i = 0; i < chip->ecc.total; i++)
+ ecc_code[i] = chip->oob_poi[eccpos[i]];
+
+ eccsteps = chip->ecc.steps;
+ p = buf;
+
+ for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+ int stat;
+
+ stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
+ if (stat < 0)
+ mtd->ecc_stats.failed++;
+ else
+ mtd->ecc_stats.corrected += stat;
+ }
+ return 0;
+}
+
+/*
+ * zynq_nand_select_chip - Select the flash device
+ * @mtd: Pointer to the mtd_info structure
+ * @chip: Chip number to be selected
+ *
+ * This function is empty as the NAND controller handles chip select line
+ * internally based on the chip address passed in command and data phase.
+ */
+static void zynq_nand_select_chip(struct mtd_info *mtd, int chip)
+{
+ /* Not support multiple chips yet */
+}
+
+/*
+ * zynq_nand_cmd_function - Send command to NAND device
+ * @mtd: Pointer to the mtd_info structure
+ * @command: The command to be sent to the flash device
+ * @column: The column address for this command, -1 if none
+ * @page_addr: The page address for this command, -1 if none
+ */
+static void zynq_nand_cmd_function(struct mtd_info *mtd, unsigned int command,
+ int column, int page_addr)
+{
+ struct nand_chip *chip = mtd->priv;
+ const struct zynq_nand_command_format *curr_cmd = NULL;
+ struct zynq_nand_info *xnand = (struct zynq_nand_info *)chip->priv;
+ void *cmd_addr;
+ unsigned long cmd_data = 0;
+ unsigned long cmd_phase_addr = 0;
+ unsigned long data_phase_addr = 0;
+ u8 end_cmd = 0;
+ u8 end_cmd_valid = 0;
+ u32 index;
+
+ if (xnand->end_cmd_pending) {
+ /* Check for end command if this command request is same as the
+ * pending command then return
+ */
+ if (xnand->end_cmd == command) {
+ xnand->end_cmd = 0;
+ xnand->end_cmd_pending = 0;
+ return;
+ }
+ }
+
+ /* Emulate NAND_CMD_READOOB for large page device */
+ if ((mtd->writesize > ZYNQ_NAND_ECC_SIZE) &&
+ (command == NAND_CMD_READOOB)) {
+ column += mtd->writesize;
+ command = NAND_CMD_READ0;
+ }
+
+ /* Get the command format */
+ for (index = 0; index < ARRAY_SIZE(zynq_nand_commands); index++)
+ if (command == zynq_nand_commands[index].start_cmd)
+ break;
+
+ if (index == ARRAY_SIZE(zynq_nand_commands)) {
+ printf("%s: Unsupported start cmd %02x\n", __func__, command);
+ return;
+ }
+ curr_cmd = &zynq_nand_commands[index];
+
+ /* Clear interrupt */
+ writel(ZYNQ_MEMC_CLRCR_INT_CLR1, &zynq_nand_smc_base->cfr);
+
+ /* Get the command phase address */
+ if (curr_cmd->end_cmd_valid == ZYNQ_NAND_CMD_PHASE)
+ end_cmd_valid = 1;
+
+ if (curr_cmd->end_cmd == NAND_CMD_NONE)
+ end_cmd = 0x0;
+ else
+ end_cmd = curr_cmd->end_cmd;
+
+ cmd_phase_addr = (unsigned long)xnand->nand_base |
+ (curr_cmd->addr_cycles << ADDR_CYCLES_SHIFT) |
+ (end_cmd_valid << END_CMD_VALID_SHIFT) |
+ (COMMAND_PHASE) |
+ (end_cmd << END_CMD_SHIFT) |
+ (curr_cmd->start_cmd << START_CMD_SHIFT);
+
+ cmd_addr = (void __iomem *)cmd_phase_addr;
+
+ /* Get the data phase address */
+ end_cmd_valid = 0;
+
+ data_phase_addr = (unsigned long)xnand->nand_base |
+ (0x0 << CLEAR_CS_SHIFT) |
+ (end_cmd_valid << END_CMD_VALID_SHIFT) |
+ (DATA_PHASE) |
+ (end_cmd << END_CMD_SHIFT) |
+ (0x0 << ECC_LAST_SHIFT);
+
+ chip->IO_ADDR_R = (void __iomem *)data_phase_addr;
+ chip->IO_ADDR_W = chip->IO_ADDR_R;
+
+ /* Command phase AXI Read & Write */
+ if (column != -1 && page_addr != -1) {
+ /* Adjust columns for 16 bit bus width */
+ if (chip->options & NAND_BUSWIDTH_16)
+ column >>= 1;
+ cmd_data = column;
+ if (mtd->writesize > ZYNQ_NAND_ECC_SIZE) {
+ cmd_data |= page_addr << 16;
+ /* Another address cycle for devices > 128MiB */
+ if (chip->chipsize > (128 << 20)) {
+ writel(cmd_data, cmd_addr);
+ cmd_data = (page_addr >> 16);
+ }
+ } else {
+ cmd_data |= page_addr << 8;
+ }
+ } else if (page_addr != -1) { /* Erase */
+ cmd_data = page_addr;
+ } else if (column != -1) { /* Change read/write column, read id etc */
+ /* Adjust columns for 16 bit bus width */
+ if ((chip->options & NAND_BUSWIDTH_16) &&
+ ((command == NAND_CMD_READ0) ||
+ (command == NAND_CMD_SEQIN) ||
+ (command == NAND_CMD_RNDOUT) ||
+ (command == NAND_CMD_RNDIN)))
+ column >>= 1;
+ cmd_data = column;
+ }
+
+ writel(cmd_data, cmd_addr);
+
+ if (curr_cmd->end_cmd_valid) {
+ xnand->end_cmd = curr_cmd->end_cmd;
+ xnand->end_cmd_pending = 1;
+ }
+
+ ndelay(100);
+
+ if ((command == NAND_CMD_READ0) ||
+ (command == NAND_CMD_RESET) ||
+ (command == NAND_CMD_PARAM) ||
+ (command == NAND_CMD_GET_FEATURES))
+ /* wait until command is processed */
+ nand_wait_ready(mtd);
+}
+
+/*
+ * zynq_nand_read_buf - read chip data into buffer
+ * @mtd: MTD device structure
+ * @buf: buffer to store date
+ * @len: number of bytes to read
+ */
+static void zynq_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len)
+{
+ struct nand_chip *chip = mtd->priv;
+
+ /* Make sure that buf is 32 bit aligned */
+ if (((unsigned long)buf & 0x3) != 0) {
+ if (((unsigned long)buf & 0x1) != 0) {
+ if (len) {
+ *buf = readb(chip->IO_ADDR_R);
+ buf += 1;
+ len--;
+ }
+ }
+
+ if (((unsigned long)buf & 0x3) != 0) {
+ if (len >= 2) {
+ *(u16 *)buf = readw(chip->IO_ADDR_R);
+ buf += 2;
+ len -= 2;
+ }
+ }
+ }
+
+ /* copy aligned data */
+ while (len >= 4) {
+ *(u32 *)buf = readl(chip->IO_ADDR_R);
+ buf += 4;
+ len -= 4;
+ }
+
+ /* mop up any remaining bytes */
+ if (len) {
+ if (len >= 2) {
+ *(u16 *)buf = readw(chip->IO_ADDR_R);
+ buf += 2;
+ len -= 2;
+ }
+ if (len)
+ *buf = readb(chip->IO_ADDR_R);
+ }
+}
+
+/*
+ * zynq_nand_write_buf - write buffer to chip
+ * @mtd: MTD device structure
+ * @buf: data buffer
+ * @len: number of bytes to write
+ */
+static void zynq_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
+{
+ struct nand_chip *chip = mtd->priv;
+ const u32 *nand = chip->IO_ADDR_W;
+
+ /* Make sure that buf is 32 bit aligned */
+ if (((unsigned long)buf & 0x3) != 0) {
+ if (((unsigned long)buf & 0x1) != 0) {
+ if (len) {
+ writeb(*buf, nand);
+ buf += 1;
+ len--;
+ }
+ }
+
+ if (((unsigned long)buf & 0x3) != 0) {
+ if (len >= 2) {
+ writew(*(u16 *)buf, nand);
+ buf += 2;
+ len -= 2;
+ }
+ }
+ }
+
+ /* copy aligned data */
+ while (len >= 4) {
+ writel(*(u32 *)buf, nand);
+ buf += 4;
+ len -= 4;
+ }
+
+ /* mop up any remaining bytes */
+ if (len) {
+ if (len >= 2) {
+ writew(*(u16 *)buf, nand);
+ buf += 2;
+ len -= 2;
+ }
+
+ if (len)
+ writeb(*buf, nand);
+ }
+}
+
+/*
+ * zynq_nand_device_ready - Check device ready/busy line
+ * @mtd: Pointer to the mtd_info structure
+ *
+ * returns: 0 on busy or 1 on ready state
+ */
+static int zynq_nand_device_ready(struct mtd_info *mtd)
+{
+ u32 csr_val;
+
+ csr_val = readl(&zynq_nand_smc_base->csr);
+ /* Check the raw_int_status1 bit */
+ if (csr_val & ZYNQ_MEMC_SR_RAW_INT_ST1) {
+ /* Clear the interrupt condition */
+ writel(ZYNQ_MEMC_SR_INT_ST1, &zynq_nand_smc_base->cfr);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int zynq_nand_init(struct nand_chip *nand_chip, int devnum)
+{
+ struct zynq_nand_info *xnand;
+ struct mtd_info *mtd;
+ unsigned long ecc_page_size;
+ u8 maf_id, dev_id, i;
+ u8 get_feature[4];
+ u8 set_feature[4] = {ONDIE_ECC_FEATURE_ENABLE, 0x00, 0x00, 0x00};
+ unsigned long ecc_cfg;
+ int ondie_ecc_enabled = 0;
+ int err = -1;
+
+ xnand = calloc(1, sizeof(struct zynq_nand_info));
+ if (!xnand) {
+ printf("%s: failed to allocate\n", __func__);
+ goto fail;
+ }
+
+ xnand->nand_base = (void __iomem *)ZYNQ_NAND_BASEADDR;
+ mtd = (struct mtd_info *)&nand_info[0];
+
+ nand_chip->priv = xnand;
+ mtd->priv = nand_chip;
+
+ /* Set address of NAND IO lines */
+ nand_chip->IO_ADDR_R = xnand->nand_base;
+ nand_chip->IO_ADDR_W = xnand->nand_base;
+
+ /* Set the driver entry points for MTD */
+ nand_chip->cmdfunc = zynq_nand_cmd_function;
+ nand_chip->dev_ready = zynq_nand_device_ready;
+ nand_chip->select_chip = zynq_nand_select_chip;
+
+ /* If we don't set this delay driver sets 20us by default */
+ nand_chip->chip_delay = 30;
+
+ /* Buffer read/write routines */
+ nand_chip->read_buf = zynq_nand_read_buf;
+ nand_chip->write_buf = zynq_nand_write_buf;
+
+ nand_chip->bbt_options = NAND_BBT_USE_FLASH;
+
+ /* Initialize the NAND flash interface on NAND controller */
+ if (zynq_nand_init_nand_flash(nand_chip->options) < 0) {
+ printf("%s: nand flash init failed\n", __func__);
+ goto fail;
+ }
+
+ /* first scan to find the device and get the page size */
+ if (nand_scan_ident(mtd, 1, NULL)) {
+ printf("%s: nand_scan_ident failed\n", __func__);
+ goto fail;
+ }
+ /* Send the command for reading device ID */
+ nand_chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
+ nand_chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
+
+ /* Read manufacturer and device IDs */
+ maf_id = nand_chip->read_byte(mtd);
+ dev_id = nand_chip->read_byte(mtd);
+
+ if ((maf_id == 0x2c) && ((dev_id == 0xf1) ||
+ (dev_id == 0xa1) || (dev_id == 0xb1) ||
+ (dev_id == 0xaa) || (dev_id == 0xba) ||
+ (dev_id == 0xda) || (dev_id == 0xca) ||
+ (dev_id == 0xac) || (dev_id == 0xbc) ||
+ (dev_id == 0xdc) || (dev_id == 0xcc) ||
+ (dev_id == 0xa3) || (dev_id == 0xb3) ||
+ (dev_id == 0xd3) || (dev_id == 0xc3))) {
+ nand_chip->cmdfunc(mtd, NAND_CMD_SET_FEATURES,
+ ONDIE_ECC_FEATURE_ADDR, -1);
+ for (i = 0; i < 4; i++)
+ writeb(set_feature[i], nand_chip->IO_ADDR_W);
+
+ /* Wait for 1us after writing data with SET_FEATURES command */
+ ndelay(1000);
+
+ nand_chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES,
+ ONDIE_ECC_FEATURE_ADDR, -1);
+ nand_chip->read_buf(mtd, get_feature, 4);
+
+ if (get_feature[0] & ONDIE_ECC_FEATURE_ENABLE) {
+ debug("%s: OnDie ECC flash\n", __func__);
+ ondie_ecc_enabled = 1;
+ } else {
+ printf("%s: Unable to detect OnDie ECC\n", __func__);
+ }
+ }
+
+ if (ondie_ecc_enabled) {
+ /* Bypass the controller ECC block */
+ ecc_cfg = readl(&zynq_nand_smc_base->emcr);
+ ecc_cfg &= ~ZYNQ_MEMC_NAND_ECC_MODE_MASK;
+ writel(ecc_cfg, &zynq_nand_smc_base->emcr);
+
+ /* The software ECC routines won't work
+ * with the SMC controller
+ */
+ nand_chip->ecc.mode = NAND_ECC_HW;
+ nand_chip->ecc.strength = 1;
+ nand_chip->ecc.read_page = zynq_nand_read_page_raw_nooob;
+ nand_chip->ecc.read_subpage = zynq_nand_read_subpage_raw;
+ nand_chip->ecc.write_page = zynq_nand_write_page_raw;
+ nand_chip->ecc.read_page_raw = zynq_nand_read_page_raw;
+ nand_chip->ecc.write_page_raw = zynq_nand_write_page_raw;
+ nand_chip->ecc.read_oob = zynq_nand_read_oob;
+ nand_chip->ecc.write_oob = zynq_nand_write_oob;
+ nand_chip->ecc.size = mtd->writesize;
+ nand_chip->ecc.bytes = 0;
+
+ /* NAND with on-die ECC supports subpage reads */
+ nand_chip->options |= NAND_SUBPAGE_READ;
+
+ /* On-Die ECC spare bytes offset 8 is used for ECC codes */
+ if (ondie_ecc_enabled) {
+ nand_chip->ecc.layout = &ondie_nand_oob_64;
+ /* Use the BBT pattern descriptors */
+ nand_chip->bbt_td = &bbt_main_descr;
+ nand_chip->bbt_md = &bbt_mirror_descr;
+ }
+ } else {
+ /* Hardware ECC generates 3 bytes ECC code for each 512 bytes */
+ nand_chip->ecc.mode = NAND_ECC_HW;
+ nand_chip->ecc.strength = 1;
+ nand_chip->ecc.size = ZYNQ_NAND_ECC_SIZE;
+ nand_chip->ecc.bytes = 3;
+ nand_chip->ecc.calculate = zynq_nand_calculate_hwecc;
+ nand_chip->ecc.correct = zynq_nand_correct_data;
+ nand_chip->ecc.hwctl = NULL;
+ nand_chip->ecc.read_page = zynq_nand_read_page_hwecc;
+ nand_chip->ecc.write_page = zynq_nand_write_page_hwecc;
+ nand_chip->ecc.read_page_raw = zynq_nand_read_page_raw;
+ nand_chip->ecc.write_page_raw = zynq_nand_write_page_raw;
+ nand_chip->ecc.read_oob = zynq_nand_read_oob;
+ nand_chip->ecc.write_oob = zynq_nand_write_oob;
+
+ switch (mtd->writesize) {
+ case 512:
+ ecc_page_size = 0x1;
+ /* Set the ECC memory config register */
+ writel((ZYNQ_NAND_ECC_CONFIG | ecc_page_size),
+ &zynq_nand_smc_base->emcr);
+ break;
+ case 1024:
+ ecc_page_size = 0x2;
+ /* Set the ECC memory config register */
+ writel((ZYNQ_NAND_ECC_CONFIG | ecc_page_size),
+ &zynq_nand_smc_base->emcr);
+ break;
+ case 2048:
+ ecc_page_size = 0x3;
+ /* Set the ECC memory config register */
+ writel((ZYNQ_NAND_ECC_CONFIG | ecc_page_size),
+ &zynq_nand_smc_base->emcr);
+ break;
+ default:
+ nand_chip->ecc.mode = NAND_ECC_SOFT;
+ nand_chip->ecc.calculate = nand_calculate_ecc;
+ nand_chip->ecc.correct = nand_correct_data;
+ nand_chip->ecc.read_page = zynq_nand_read_page_swecc;
+ nand_chip->ecc.write_page = zynq_nand_write_page_swecc;
+ nand_chip->ecc.size = 256;
+ break;
+ }
+
+ if (mtd->oobsize == 16)
+ nand_chip->ecc.layout = &nand_oob_16;
+ else if (mtd->oobsize == 64)
+ nand_chip->ecc.layout = &nand_oob_64;
+ else
+ printf("%s: No oob layout found\n", __func__);
+ }
+
+ /* Second phase scan */
+ if (nand_scan_tail(mtd)) {
+ printf("%s: nand_scan_tail failed\n", __func__);
+ goto fail;
+ }
+ if (nand_register(devnum, mtd))
+ goto fail;
+ return 0;
+fail:
+ free(xnand);
+ return err;
+}
+
+static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE];
+
+void board_nand_init(void)
+{
+ struct nand_chip *nand = &nand_chip[0];
+
+ if (zynq_nand_init(nand, 0))
+ puts("ZYNQ NAND init failed\n");
+}
diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c
index 1811b0fe1a..46b8a6bc69 100644
--- a/drivers/net/fsl-mc/mc.c
+++ b/drivers/net/fsl-mc/mc.c
@@ -40,6 +40,7 @@ int child_dprc_id;
struct fsl_dpbp_obj *dflt_dpbp = NULL;
struct fsl_dpio_obj *dflt_dpio = NULL;
struct fsl_dpni_obj *dflt_dpni = NULL;
+static u64 mc_lazy_dpl_addr;
#ifdef DEBUG
void dump_ram_words(const char *title, void *addr)
@@ -572,6 +573,9 @@ int mc_apply_dpl(u64 mc_dpl_addr)
u64 mc_ram_addr = mc_get_dram_addr();
size_t mc_ram_size = mc_get_dram_block_size();
+ if (!mc_dpl_addr)
+ return -1;
+
error = load_mc_dpl(mc_ram_addr, mc_ram_size, mc_dpl_addr);
if (error != 0)
return error;
@@ -1156,6 +1160,11 @@ int fsl_mc_ldpaa_exit(bd_t *bd)
{
int err = 0;
+ if (bd && mc_lazy_dpl_addr && !fsl_mc_ldpaa_exit(NULL)) {
+ mc_apply_dpl(mc_lazy_dpl_addr);
+ mc_lazy_dpl_addr = 0;
+ }
+
/* MC is not loaded intentionally, So return success. */
if (bd && get_mc_boot_status() != 0)
return 0;
@@ -1259,6 +1268,7 @@ static int do_fsl_mc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
break;
+ case 'l':
case 'a': {
u64 mc_dpl_addr;
@@ -1279,8 +1289,17 @@ static int do_fsl_mc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
return -ENODEV;
}
- if (!fsl_mc_ldpaa_exit(NULL))
- err = mc_apply_dpl(mc_dpl_addr);
+ if (argv[1][0] == 'l') {
+ /*
+ * We will do the actual dpaa exit and dpl apply
+ * later from announce_and_cleanup().
+ */
+ mc_lazy_dpl_addr = mc_dpl_addr;
+ } else {
+ /* The user wants it applied now */
+ if (!fsl_mc_ldpaa_exit(NULL))
+ err = mc_apply_dpl(mc_dpl_addr);
+ }
break;
}
default:
@@ -1298,5 +1317,6 @@ U_BOOT_CMD(
"DPAA2 command to manage Management Complex (MC)",
"start mc [FW_addr] [DPC_addr] - Start Management Complex\n"
"fsl_mc apply DPL [DPL_addr] - Apply DPL file\n"
+ "fsl_mc lazyapply DPL [DPL_addr] - Apply DPL file on exit\n"
"fsl_mc start aiop [FW_addr] - Start AIOP\n"
);
diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
index 8b7c1be5d9..3319e10467 100644
--- a/drivers/net/zynq_gem.c
+++ b/drivers/net/zynq_gem.c
@@ -53,16 +53,16 @@ DECLARE_GLOBAL_DATA_PTR;
#define ZYNQ_GEM_NWCTRL_MDEN_MASK 0x00000010 /* Enable MDIO port */
#define ZYNQ_GEM_NWCTRL_STARTTX_MASK 0x00000200 /* Start tx (tx_go) */
-#define ZYNQ_GEM_NWCFG_SPEED100 0x000000001 /* 100 Mbps operation */
-#define ZYNQ_GEM_NWCFG_SPEED1000 0x000000400 /* 1Gbps operation */
-#define ZYNQ_GEM_NWCFG_FDEN 0x000000002 /* Full Duplex mode */
-#define ZYNQ_GEM_NWCFG_FSREM 0x000020000 /* FCS removal */
-#define ZYNQ_GEM_NWCFG_SGMII_ENBL 0x080000000 /* SGMII Enable */
-#define ZYNQ_GEM_NWCFG_PCS_SEL 0x000000800 /* PCS select */
+#define ZYNQ_GEM_NWCFG_SPEED100 0x00000001 /* 100 Mbps operation */
+#define ZYNQ_GEM_NWCFG_SPEED1000 0x00000400 /* 1Gbps operation */
+#define ZYNQ_GEM_NWCFG_FDEN 0x00000002 /* Full Duplex mode */
+#define ZYNQ_GEM_NWCFG_FSREM 0x00020000 /* FCS removal */
+#define ZYNQ_GEM_NWCFG_SGMII_ENBL 0x08000000 /* SGMII Enable */
+#define ZYNQ_GEM_NWCFG_PCS_SEL 0x00000800 /* PCS select */
#ifdef CONFIG_ARM64
-#define ZYNQ_GEM_NWCFG_MDCCLKDIV 0x000100000 /* Div pclk by 64, max 160MHz */
+#define ZYNQ_GEM_NWCFG_MDCCLKDIV 0x00100000 /* Div pclk by 64, max 160MHz */
#else
-#define ZYNQ_GEM_NWCFG_MDCCLKDIV 0x0000c0000 /* Div pclk by 48, max 120MHz */
+#define ZYNQ_GEM_NWCFG_MDCCLKDIV 0x000c0000 /* Div pclk by 48, max 120MHz */
#endif
#ifdef CONFIG_ARM64
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index d69bc6035b..daf021b647 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -22,6 +22,8 @@ extern char __kprobes_text_start[], __kprobes_text_end[];
extern char __entry_text_start[], __entry_text_end[];
extern char __initdata_begin[], __initdata_end[];
extern char __start_rodata[], __end_rodata[];
+extern char __efi_hello_world_begin[];
+extern char __efi_hello_world_end[];
/* Start and end of .ctors section - used for constructor calls. */
extern char __ctors_start[], __ctors_end[];
diff --git a/include/configs/ls2080ardb.h b/include/configs/ls2080ardb.h
index b9cb6d3879..32fa0eb3ee 100644
--- a/include/configs/ls2080ardb.h
+++ b/include/configs/ls2080ardb.h
@@ -316,10 +316,25 @@ unsigned long get_board_sys_clk(void);
#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2
+#undef CONFIG_CMDLINE_EDITING
+#include <config_distro_defaults.h>
+
+#define BOOT_TARGET_DEVICES(func) \
+ func(USB, usb, 0) \
+ func(MMC, mmc, 0) \
+ func(SCSI, scsi, 0) \
+ func(DHCP, dhcp, na)
+#include <config_distro_bootcmd.h>
+
/* Initial environment variables */
#undef CONFIG_EXTRA_ENV_SETTINGS
#define CONFIG_EXTRA_ENV_SETTINGS \
"hwconfig=fsl_ddr:bank_intlv=auto\0" \
+ "scriptaddr=0x80800000\0" \
+ "kernel_addr_r=0x81000000\0" \
+ "pxefile_addr_r=0x81000000\0" \
+ "fdt_addr_r=0x88000000\0" \
+ "ramdisk_addr_r=0x89000000\0" \
"loadaddr=0x80100000\0" \
"kernel_addr=0x100000\0" \
"ramdisk_addr=0x800000\0" \
@@ -329,8 +344,10 @@ unsigned long get_board_sys_clk(void);
"kernel_start=0x581100000\0" \
"kernel_load=0xa0000000\0" \
"kernel_size=0x2800000\0" \
+ "fdtfile=fsl-ls2080a-rdb.dtb\0" \
"mcinitcmd=fsl_mc start mc 0x580300000" \
- " 0x580800000 \0"
+ " 0x580800000 \0" \
+ BOOTENV
#undef CONFIG_BOOTARGS
#define CONFIG_BOOTARGS "console=ttyS1,115200 root=/dev/ram0 " \
@@ -338,6 +355,13 @@ unsigned long get_board_sys_clk(void);
"ramdisk_size=0x2000000 default_hugepagesz=2m" \
" hugepagesz=2m hugepages=256"
+#undef CONFIG_BOOTCOMMAND
+/* Try to boot an on-NOR kernel first, then do normal distro boot */
+#define CONFIG_BOOTCOMMAND "run mcinitcmd && fsl_mc lazyapply dpl 0x580700000" \
+ " && cp.b $kernel_start $kernel_load $kernel_size" \
+ " && bootm $kernel_load" \
+ " || run distro_bootcmd"
+
/* MAC/PHY configuration */
#ifdef CONFIG_FSL_MC_ENET
#define CONFIG_PHYLIB_10G
diff --git a/include/configs/topic_miami.h b/include/configs/topic_miami.h
new file mode 100644
index 0000000000..3b0fa29890
--- /dev/null
+++ b/include/configs/topic_miami.h
@@ -0,0 +1,149 @@
+/*
+ * (C) Copyright 2014 Topic Embedded Products
+ *
+ * Configuration for Zynq Evaluation and Development Board - Miami
+ * See zynq-common.h for Zynq common configs
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __CONFIG_TOPIC_MIAMI_H
+#define __CONFIG_TOPIC_MIAMI_H
+
+#define CONFIG_ZYNQ_PS_CLK_FREQ 33333333UL
+
+#define CONFIG_ZYNQ_I2C0
+#define CONFIG_ZYNQ_I2C1
+
+/* Speed up boot time by ignoring the environment which we never used */
+#define CONFIG_ENV_IS_NOWHERE
+
+#include "zynq-common.h"
+
+/* Fixup settings */
+#undef CONFIG_ENV_SIZE
+#define CONFIG_ENV_SIZE 0x8000
+#undef CONFIG_ENV_OFFSET
+#define CONFIG_ENV_OFFSET 0x80000
+
+/* SPL settings */
+#undef CONFIG_SPL_ETH_SUPPORT
+#undef CONFIG_SYS_SPI_U_BOOT_OFFS
+#define CONFIG_SYS_SPI_U_BOOT_OFFS 0x20000
+#undef CONFIG_SPL_MAX_FOOTPRINT
+#define CONFIG_SPL_MAX_FOOTPRINT CONFIG_SYS_SPI_U_BOOT_OFFS
+#define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.img"
+
+/* sspi command isn't useful */
+#undef CONFIG_CMD_SPI
+
+/* No useful gpio */
+#undef CONFIG_ZYNQ_GPIO
+#undef CONFIG_CMD_GPIO
+
+/* No falcon support */
+#undef CONFIG_SPL_OS_BOOT
+#undef CONFIG_SPL_FPGA_SUPPORT
+
+/* FPGA commands that we don't use */
+#undef CONFIG_CMD_FPGA_LOADMK
+#undef CONFIG_CMD_FPGA_LOADP
+#undef CONFIG_CMD_FPGA_LOADBP
+#undef CONFIG_CMD_FPGA_LOADFS
+
+/* Extras */
+#define CONFIG_CMD_MEMTEST
+#undef CONFIG_SYS_MEMTEST_START
+#define CONFIG_SYS_MEMTEST_START 0
+#undef CONFIG_SYS_MEMTEST_END
+#define CONFIG_SYS_MEMTEST_END 0x18000000
+
+/* Faster flash, ours may run at 108 MHz */
+#undef CONFIG_SF_DEFAULT_SPEED
+#define CONFIG_SF_DEFAULT_SPEED 108000000
+#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0
+#undef CONFIG_SF_DUAL_FLASH
+#define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED
+#undef CONFIG_SPI_FLASH_WINBOND
+#undef CONFIG_SPI_FLASH_ISSI
+
+/* Setup proper boot sequences for Miami boards */
+
+#if defined(CONFIG_USB)
+# define EXTRA_ENV_USB \
+ "usbreset=i2c dev 1 && i2c mw 41 1 ff && i2c mw 41 3 fe && "\
+ "i2c mw 41 1 fe && i2c mw 41 1 ff\0" \
+ "usbboot=run usbreset && if usb start; then " \
+ "echo Booting from USB... && " \
+ "if load usb 0 0x1900000 ${bootscript}; then "\
+ "source 0x1900000; fi; " \
+ "load usb 0 ${kernel_addr} ${kernel_image} && " \
+ "load usb 0 ${devicetree_addr} ${devicetree_image} && " \
+ "load usb 0 ${ramdisk_load_address} ${ramdisk_image} && " \
+ "bootm ${kernel_addr} ${ramdisk_load_address} "\
+ "${devicetree_addr}; " \
+ "fi\0"
+ /* Note that addresses here should match the addresses in the env */
+# undef DFU_ALT_INFO
+# define DFU_ALT_INFO \
+ "dfu_alt_info=" \
+ "uImage ram 0x2080000 0x500000;" \
+ "devicetree.dtb ram 0x2000000 0x20000;" \
+ "uramdisk.image.gz ram 0x4000000 0x10000000\0" \
+ "dfu_ram=run usbreset && dfu 0 ram 0\0" \
+ "thor_ram=run usbreset && thordown 0 ram 0\0"
+#else
+# define EXTRA_ENV_USB
+#endif
+
+#undef CONFIG_PREBOOT
+
+#undef CONFIG_EXTRA_ENV_SETTINGS
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "kernel_image=uImage\0" \
+ "kernel_addr=0x2080000\0" \
+ "ramdisk_image=uramdisk.image.gz\0" \
+ "ramdisk_load_address=0x4000000\0" \
+ "devicetree_image=devicetree.dtb\0" \
+ "devicetree_addr=0x2000000\0" \
+ "bitstream_image=fpga.bin\0" \
+ "bootscript=autorun.scr\0" \
+ "loadbit_addr=0x100000\0" \
+ "loadbootenv_addr=0x2000000\0" \
+ "kernel_size=0x400000\0" \
+ "devicetree_size=0x10000\0" \
+ "boot_size=0xF00000\0" \
+ "fdt_high=0x20000000\0" \
+ "initrd_high=0x20000000\0" \
+ "mmc_loadbit=echo Loading bitstream from SD/MMC/eMMC to RAM.. && " \
+ "mmcinfo && " \
+ "load mmc 0 ${loadbit_addr} ${bitstream_image} && " \
+ "fpga load 0 ${loadbit_addr} ${filesize}\0" \
+ "qspiboot=echo Booting from QSPI flash... && " \
+ "sf probe && " \
+ "sf read ${devicetree_addr} 0xA0000 ${devicetree_size} && " \
+ "sf read ${kernel_addr} 0xC0000 ${kernel_size} && " \
+ "bootm ${kernel_addr} - ${devicetree_addr}\0" \
+ "sdboot=if mmcinfo; then " \
+ "setenv bootargs console=ttyPS0,115200 " \
+ "root=/dev/mmcblk0p2 rw rootfstype=ext4 " \
+ "rootwait quiet ; " \
+ "load mmc 0 ${kernel_addr} ${kernel_image}&& " \
+ "load mmc 0 ${devicetree_addr} ${devicetree_image}&& " \
+ "bootm ${kernel_addr} - ${devicetree_addr}; " \
+ "fi\0" \
+ EXTRA_ENV_USB \
+ DFU_ALT_INFO
+
+#undef CONFIG_BOOTCOMMAND
+#define CONFIG_BOOTCOMMAND "if mmcinfo; then " \
+ "if fatload mmc 0 0x1900000 ${bootscript}; then source 0x1900000; " \
+ "fi; fi; run $modeboot"
+#undef CONFIG_DISPLAY_BOARDINFO
+
+/* Further tweaks to reduce image size */
+#undef CONFIG_CMD_BOOTZ
+#undef CONFIG_CMD_NET
+#undef CONFIG_CMD_AES
+
+#endif /* __CONFIG_TOPIC_MIAMI_H */
diff --git a/include/configs/topic_miamiplus.h b/include/configs/topic_miamiplus.h
new file mode 100644
index 0000000000..46ca6bda04
--- /dev/null
+++ b/include/configs/topic_miamiplus.h
@@ -0,0 +1,2 @@
+#include "topic_miami.h"
+#define CONFIG_SF_DUAL_FLASH
diff --git a/include/configs/xilinx_zynqmp_ep.h b/include/configs/xilinx_zynqmp_ep.h
index 8e4b96033b..d0ce768e6e 100644
--- a/include/configs/xilinx_zynqmp_ep.h
+++ b/include/configs/xilinx_zynqmp_ep.h
@@ -14,7 +14,7 @@
#define __CONFIG_ZYNQMP_EP_H
#define CONFIG_ZYNQ_SDHCI_MAX_FREQ 52000000
-#define CONFIG_ZYNQ_SDHCI_MIN_FREQ (CONFIG_ZYNQ_SDHCI_MAX_FREQ << 9)
+#define CONFIG_ZYNQ_SDHCI_MIN_FREQ (CONFIG_ZYNQ_SDHCI_MAX_FREQ >> 9)
#define CONFIG_ZYNQ_EEPROM
#define CONFIG_SATA_CEVA
#define CONFIG_ZYNQMP_XHCI_LIST {ZYNQMP_USB0_XHCI_BASEADDR, \
diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h
index 4f0253cd7d..3a2080f9e5 100644
--- a/include/configs/zynq-common.h
+++ b/include/configs/zynq-common.h
@@ -76,6 +76,13 @@
# define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
#endif
+#ifdef CONFIG_NAND_ZYNQ
+#define CONFIG_CMD_NAND_LOCK_UNLOCK
+#define CONFIG_SYS_MAX_NAND_DEVICE 1
+#define CONFIG_SYS_NAND_ONFI_DETECTION
+#define CONFIG_MTD_DEVICE
+#endif
+
/* MMC */
#if defined(CONFIG_ZYNQ_SDHCI)
# define CONFIG_MMC
diff --git a/include/efi.h b/include/efi.h
index d07187c7dd..3d587807e8 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -30,8 +30,11 @@ struct efi_device_path;
#define EFI_BITS_PER_LONG BITS_PER_LONG
-/* With 64-bit EFI stub, EFI_BITS_PER_LONG has to be 64 */
-#ifdef CONFIG_EFI_STUB_64BIT
+/*
+ * With 64-bit EFI stub, EFI_BITS_PER_LONG has to be 64. EFI_STUB is set
+ * in lib/efi/Makefile, when building the stub.
+ */
+#if defined(CONFIG_EFI_STUB_64BIT) && defined(EFI_STUB)
#undef EFI_BITS_PER_LONG
#define EFI_BITS_PER_LONG 64
#endif
diff --git a/include/efi_api.h b/include/efi_api.h
index bdb600e08d..5c3836a51b 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -268,6 +268,19 @@ struct efi_device_path {
u16 length;
};
+struct efi_mac_addr {
+ u8 addr[32];
+};
+
+#define DEVICE_PATH_TYPE_MESSAGING_DEVICE 0x03
+# define DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR 0x0b
+
+struct efi_device_path_mac_addr {
+ struct efi_device_path dp;
+ struct efi_mac_addr mac;
+ u8 if_type;
+};
+
#define DEVICE_PATH_TYPE_MEDIA_DEVICE 0x04
# define DEVICE_PATH_SUB_TYPE_FILE_PATH 0x04
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 35b3fe2d39..99619f53a9 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -181,7 +181,7 @@ void efi_get_time_init(void);
/* Without CONFIG_EFI_LOADER we don't have a runtime section, stub it out */
#define __efi_runtime_data
#define __efi_runtime
-static inline void efi_add_runtime_mmio(void **mmio_ptr, u64 len) { }
+static inline void efi_add_runtime_mmio(void *mmio_ptr, u64 len) { }
/* No loader configured, stub out EFI_ENTRY */
static inline void efi_restore_gd(void) { }
diff --git a/include/elf.h b/include/elf.h
index bcc5eb7b07..aaecac799e 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -13,6 +13,7 @@
#ifndef _ELF_H
#define _ELF_H
+#ifndef __ASSEMBLER__
#include "compiler.h"
/*
@@ -517,6 +518,8 @@ unsigned long elf_hash(const unsigned char *name);
#define ELF_TARG_VER 1 /* The ver for which this code is intended */
+#endif /* __ASSEMBLER */
+
/*
* XXX - PowerPC defines really don't belong in here,
* but we'll put them in for simplicity.
@@ -602,6 +605,16 @@ unsigned long elf_hash(const unsigned char *name);
that may still be in object files. */
#define R_PPC_TOC16 255
+ /* ARM relocs */
+#define R_ARM_NONE 0 /* No reloc */
+#define R_ARM_RELATIVE 23 /* Adjust by program base */
+
+/* AArch64 relocs */
+#define R_AARCH64_NONE 0 /* No relocation. */
+#define R_AARCH64_RELATIVE 1027 /* Adjust by program base. */
+
+#ifndef __ASSEMBLER__
int valid_elf_image(unsigned long addr);
+#endif
#endif /* _ELF_H */
diff --git a/include/zynqmppl.h b/include/zynqmppl.h
index 542ace9a03..fb5200ec84 100644
--- a/include/zynqmppl.h
+++ b/include/zynqmppl.h
@@ -16,6 +16,12 @@
#define ZYNQMP_FPGA_OP_LOAD (1 << 1)
#define ZYNQMP_FPGA_OP_DONE (1 << 2)
+#define ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT 15
+#define ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK (0xf << \
+ ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT)
+#define ZYNQMP_CSU_IDCODE_SVD_SHIFT 12
+#define ZYNQMP_CSU_IDCODE_SVD_MASK (0xe << ZYNQMP_CSU_IDCODE_SVD_SHIFT)
+
extern struct xilinx_fpga_op zynqmp_op;
#define XILINX_ZYNQMP_DESC \
diff --git a/include/zynqpl.h b/include/zynqpl.h
index 1d37a51a04..5a34a17dae 100644
--- a/include/zynqpl.h
+++ b/include/zynqpl.h
@@ -19,7 +19,10 @@ extern struct xilinx_fpga_op zynq_op;
# 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
@@ -28,7 +31,10 @@ extern struct xilinx_fpga_op zynq_op;
#define XILINX_ZYNQ_7100 0x16
/* Device Image Sizes */
+#define XILINX_XC7Z007S_SIZE 16669920/8
#define XILINX_XC7Z010_SIZE 16669920/8
+#define XILINX_XC7Z012S_SIZE 28085344/8
+#define XILINX_XC7Z014S_SIZE 32364512/8
#define XILINX_XC7Z015_SIZE 28085344/8
#define XILINX_XC7Z020_SIZE 32364512/8
#define XILINX_XC7Z030_SIZE 47839328/8
@@ -37,10 +43,22 @@ extern struct xilinx_fpga_op zynq_op;
#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" }
diff --git a/lib/efi/Makefile b/lib/efi/Makefile
index e32dc14f3d..9449600b5b 100644
--- a/lib/efi/Makefile
+++ b/lib/efi/Makefile
@@ -9,9 +9,9 @@ obj-$(CONFIG_EFI_STUB) += efi_info.o
CFLAGS_REMOVE_efi_stub.o := -mregparm=3 \
$(if $(CONFIG_EFI_STUB_64BIT),-march=i386 -m32)
-CFLAGS_efi_stub.o := -fpic -fshort-wchar
+CFLAGS_efi_stub.o := -fpic -fshort-wchar -DEFI_STUB
CFLAGS_REMOVE_efi.o := -mregparm=3 \
$(if $(CONFIG_EFI_STUB_64BIT),-march=i386 -m32)
-CFLAGS_efi.o := -fpic -fshort-wchar
+CFLAGS_efi.o := -fpic -fshort-wchar -DEFI_STUB
extra-$(CONFIG_EFI_STUB) += efi_stub.o efi.o
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index 37a0dd60a5..d2b6327119 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -1,6 +1,6 @@
config EFI_LOADER
bool "Support running EFI Applications in U-Boot"
- depends on (ARM64 || ARM) && OF_LIBFDT
+ depends on (ARM || X86) && OF_LIBFDT
default y
help
Select this option if you want to run EFI applications (like grub2)
diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
index 12159dd5ce..f4664085e5 100644
--- a/lib/efi_loader/Makefile
+++ b/lib/efi_loader/Makefile
@@ -7,6 +7,10 @@
# This file only gets included with CONFIG_EFI_LOADER set, so all
# object inclusion implicitly depends on it
+CFLAGS_helloworld.o := $(CFLAGS_EFI)
+CFLAGS_REMOVE_helloworld.o := $(CFLAGS_NON_EFI)
+
+obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o
obj-y += efi_image_loader.o efi_boottime.o efi_runtime.o efi_console.o
obj-y += efi_memory.o
obj-$(CONFIG_LCD) += efi_gop.o
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 1fdddf4591..51080cbeed 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -538,6 +538,8 @@ static efi_status_t EFIAPI efi_exit_boot_services(void *image_handle,
{
EFI_ENTRY("%p, %ld", image_handle, map_key);
+ board_quiesce_devices();
+
/* Fix up caches for EFI payloads if necessary */
efi_exit_caches();
diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
index 2e0228c3e0..8ef7326fef 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -9,11 +9,38 @@
#include <common.h>
#include <efi_loader.h>
-/* If we can't determine the console size, default to 80x24 */
-static int console_columns = 80;
-static int console_rows = 24;
static bool console_size_queried;
+#define EFI_COUT_MODE_2 2
+#define EFI_MAX_COUT_MODE 3
+
+struct cout_mode {
+ unsigned long columns;
+ unsigned long rows;
+ int present;
+};
+
+static struct cout_mode efi_cout_modes[] = {
+ /* EFI Mode 0 is 80x25 and always present */
+ {
+ .columns = 80,
+ .rows = 25,
+ .present = 1,
+ },
+ /* EFI Mode 1 is always 80x50 */
+ {
+ .columns = 80,
+ .rows = 50,
+ .present = 0,
+ },
+ /* Value are unknown until we query the console */
+ {
+ .columns = 0,
+ .rows = 0,
+ .present = 0,
+ },
+};
+
const efi_guid_t efi_guid_console_control = CONSOLE_CONTROL_GUID;
#define cESC '\x1b'
@@ -56,8 +83,9 @@ const struct efi_console_control_protocol efi_console_control = {
.lock_std_in = efi_cin_lock_std_in,
};
+/* Default to mode 0 */
static struct simple_text_output_mode efi_con_mode = {
- .max_mode = 0,
+ .max_mode = 1,
.mode = 0,
.attribute = 0,
.cursor_column = 0,
@@ -131,8 +159,10 @@ static efi_status_t EFIAPI efi_cout_output_string(
struct efi_simple_text_output_protocol *this,
const unsigned short *string)
{
+ struct cout_mode *mode;
u16 ch;
+ mode = &efi_cout_modes[efi_con_mode.mode];
EFI_ENTRY("%p, %p", this, string);
for (;(ch = *string); string++) {
print_unicode_in_utf8(ch);
@@ -140,13 +170,12 @@ static efi_status_t EFIAPI efi_cout_output_string(
if (ch == '\n') {
efi_con_mode.cursor_column = 1;
efi_con_mode.cursor_row++;
- } else if (efi_con_mode.cursor_column > console_columns) {
+ } else if (efi_con_mode.cursor_column > mode->columns) {
efi_con_mode.cursor_column = 1;
efi_con_mode.cursor_row++;
}
- if (efi_con_mode.cursor_row > console_rows) {
- efi_con_mode.cursor_row = console_rows;
- }
+ if (efi_con_mode.cursor_row > mode->rows)
+ efi_con_mode.cursor_row = mode->rows;
}
return EFI_EXIT(EFI_SUCCESS);
@@ -160,6 +189,14 @@ static efi_status_t EFIAPI efi_cout_test_string(
return EFI_EXIT(EFI_SUCCESS);
}
+static bool cout_mode_matches(struct cout_mode *mode, int rows, int cols)
+{
+ if (!mode->present)
+ return false;
+
+ return (mode->rows == rows) && (mode->columns == cols);
+}
+
static efi_status_t EFIAPI efi_cout_query_mode(
struct efi_simple_text_output_protocol *this,
unsigned long mode_number, unsigned long *columns,
@@ -170,6 +207,8 @@ static efi_status_t EFIAPI efi_cout_query_mode(
if (!console_size_queried) {
/* Ask the terminal about its size */
int n[3];
+ int cols;
+ int rows;
u64 timeout;
console_size_queried = true;
@@ -191,15 +230,40 @@ static efi_status_t EFIAPI efi_cout_query_mode(
goto out;
}
- console_columns = n[2];
- console_rows = n[1];
+ cols = n[2];
+ rows = n[1];
+
+ /* Test if we can have Mode 1 */
+ if (cols >= 80 && rows >= 50) {
+ efi_cout_modes[1].present = 1;
+ efi_con_mode.max_mode = 2;
+ }
+
+ /*
+ * Install our mode as mode 2 if it is different
+ * than mode 0 or 1 and set it as the currently selected mode
+ */
+ if (!cout_mode_matches(&efi_cout_modes[0], rows, cols) &&
+ !cout_mode_matches(&efi_cout_modes[1], rows, cols)) {
+ efi_cout_modes[EFI_COUT_MODE_2].columns = cols;
+ efi_cout_modes[EFI_COUT_MODE_2].rows = rows;
+ efi_cout_modes[EFI_COUT_MODE_2].present = 1;
+ efi_con_mode.max_mode = EFI_MAX_COUT_MODE;
+ efi_con_mode.mode = EFI_COUT_MODE_2;
+ }
}
+ if (mode_number >= efi_con_mode.max_mode)
+ return EFI_EXIT(EFI_UNSUPPORTED);
+
+ if (efi_cout_modes[mode_number].present != 1)
+ return EFI_EXIT(EFI_UNSUPPORTED);
+
out:
if (columns)
- *columns = console_columns;
+ *columns = efi_cout_modes[mode_number].columns;
if (rows)
- *rows = console_rows;
+ *rows = efi_cout_modes[mode_number].rows;
return EFI_EXIT(EFI_SUCCESS);
}
@@ -210,11 +274,15 @@ static efi_status_t EFIAPI efi_cout_set_mode(
{
EFI_ENTRY("%p, %ld", this, mode_number);
- /* We only support text output for now */
- if (mode_number == EFI_CONSOLE_MODE_TEXT)
- return EFI_EXIT(EFI_SUCCESS);
- return EFI_EXIT(EFI_UNSUPPORTED);
+ if (mode_number > efi_con_mode.max_mode)
+ return EFI_EXIT(EFI_UNSUPPORTED);
+
+ efi_con_mode.mode = mode_number;
+ efi_con_mode.cursor_column = 0;
+ efi_con_mode.cursor_row = 0;
+
+ return EFI_EXIT(EFI_SUCCESS);
}
static efi_status_t EFIAPI efi_cout_set_attribute(
diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c
index 5165377eee..3262d76bca 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -174,7 +174,8 @@ void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info)
efi_loader_relocate(rel, rel_size, efi_reloc);
/* Flush cache */
- flush_cache((ulong)efi_reloc, virt_size);
+ flush_cache((ulong)efi_reloc,
+ ALIGN(virt_size, CONFIG_SYS_CACHELINE_SIZE));
invalidate_icache_all();
/* Populate the loaded image interface bits */
diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c
index 3796496caa..604ac6e040 100644
--- a/lib/efi_loader/efi_net.c
+++ b/lib/efi_loader/efi_net.c
@@ -27,7 +27,8 @@ struct efi_net_obj {
struct efi_simple_network net;
struct efi_simple_network_mode net_mode;
/* Device path to the network adapter */
- struct efi_device_path_file_path dp[2];
+ struct efi_device_path_mac_addr dp_mac;
+ struct efi_device_path_file_path dp_end;
/* PXE struct to transmit dhcp data */
struct efi_pxe pxe;
struct efi_pxe_mode pxe_mode;
@@ -205,7 +206,7 @@ static efi_status_t EFIAPI efi_net_open_dp(void *handle, efi_guid_t *protocol,
struct efi_simple_network *net = handle;
struct efi_net_obj *netobj = container_of(net, struct efi_net_obj, net);
- *protocol_interface = netobj->dp;
+ *protocol_interface = &netobj->dp_mac;
return EFI_SUCCESS;
}
@@ -236,11 +237,10 @@ void efi_net_set_dhcp_ack(void *pkt, int len)
int efi_net_register(void **handle)
{
struct efi_net_obj *netobj;
- struct efi_device_path_file_path dp_net = {
- .dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE,
- .dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH,
+ struct efi_device_path_mac_addr dp_net = {
+ .dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE,
+ .dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR,
.dp.length = sizeof(dp_net),
- .str = { 'N', 'e', 't' },
};
struct efi_device_path_file_path dp_end = {
.dp.type = DEVICE_PATH_TYPE_END,
@@ -279,8 +279,9 @@ int efi_net_register(void **handle)
netobj->net.receive = efi_net_receive;
netobj->net.mode = &netobj->net_mode;
netobj->net_mode.state = EFI_NETWORK_STARTED;
- netobj->dp[0] = dp_net;
- netobj->dp[1] = dp_end;
+ netobj->dp_mac = dp_net;
+ netobj->dp_end = dp_end;
+ memcpy(netobj->dp_mac.mac.addr, eth_get_ethaddr(), 6);
memcpy(netobj->net_mode.current_address.mac_addr, eth_get_ethaddr(), 6);
netobj->net_mode.max_packet_size = PKTSIZE;
diff --git a/lib/efi_loader/helloworld.c b/lib/efi_loader/helloworld.c
new file mode 100644
index 0000000000..03e65ab133
--- /dev/null
+++ b/lib/efi_loader/helloworld.c
@@ -0,0 +1,24 @@
+/*
+ * EFI hello world
+ *
+ * Copyright (c) 2016 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <part_efi.h>
+#include <efi_api.h>
+
+efi_status_t EFIAPI efi_main(efi_handle_t handle,
+ struct efi_system_table *systable)
+{
+ struct efi_simple_text_output_protocol *con_out = systable->con_out;
+ struct efi_boot_services *boottime = systable->boottime;
+
+ con_out->output_string(con_out, L"Hello, world!\n");
+ boottime->exit(handle, 0, 0, NULL);
+
+ return EFI_SUCCESS;
+}
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 45a0e1d486..956a8a9b04 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -321,6 +321,39 @@ cmd_S_ttf= \
$(obj)/%.S: $(src)/%.ttf
$(call cmd,S_ttf)
+# EFI Hello World application
+# ---------------------------------------------------------------------------
+
+# Generate an assembly file to wrap the EFI app
+cmd_S_efi= \
+( \
+ echo '.section .rodata.efi.init,"a"'; \
+ echo '.balign 16'; \
+ echo '.global __efi_hello_world_begin'; \
+ echo '__efi_hello_world_begin:'; \
+ echo '.incbin "$<" '; \
+ echo '__efi_hello_world_end:'; \
+ echo '.global __efi_hello_world_end'; \
+ echo '.balign 16'; \
+) > $@
+
+$(obj)/%_efi.S: $(obj)/%.efi
+ $(call cmd,S_efi)
+
+$(obj)/%.efi: $(obj)/%.so
+ $(OBJCOPY) -j .header -j .text -j .sdata -j .data -j .dynamic \
+ -j .dynsym -j .rel* -j .rela* -j .reloc \
+ $(if $(EFI_TARGET),$(EFI_TARGET),-O binary) $^ $@
+
+EFI_LDS_PATH = $(srctree)/arch/$(ARCH)/lib/$(EFI_LDS)
+
+$(obj)/helloworld.so: $(EFI_LDS_PATH)
+
+$(obj)/helloworld.so: $(obj)/helloworld.o arch/$(ARCH)/lib/$(EFI_CRT0) \
+ arch/$(ARCH)/lib/$(EFI_RELOC)
+ $(LD) -nostdlib -znocombreloc -T $(EFI_LDS_PATH) -shared -Bsymbolic \
+ $^ -o $@
+
# ACPI
# ---------------------------------------------------------------------------
quiet_cmd_acpi_c_asl= ASL $<
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
index e0b0117dc9..03a2f061a4 100644
--- a/scripts/Makefile.spl
+++ b/scripts/Makefile.spl
@@ -146,10 +146,10 @@ boot.bin: $(obj)/u-boot-spl.bin FORCE
$(call if_changed,mkimage)
else
ifdef CONFIG_ARCH_ZYNQ
-MKIMAGEFLAGS_boot.bin = -T zynqimage
+MKIMAGEFLAGS_boot.bin = -T zynqimage -R $(srctree)/$(CONFIG_BOOT_INIT_FILE)
endif
ifdef CONFIG_ARCH_ZYNQMP
-MKIMAGEFLAGS_boot.bin = -T zynqmpimage
+MKIMAGEFLAGS_boot.bin = -T zynqmpimage -R $(srctree)/$(CONFIG_BOOT_INIT_FILE)
endif
spl/boot.bin: $(obj)/u-boot-spl.bin FORCE
diff --git a/tools/zynqimage.c b/tools/zynqimage.c
index c43bd5d488..43876e7a30 100644
--- a/tools/zynqimage.c
+++ b/tools/zynqimage.c
@@ -222,6 +222,30 @@ static int zynqimage_check_image_types(uint8_t type)
return EXIT_FAILURE;
}
+static void zynqimage_parse_initparams(struct zynq_header *zynqhdr,
+ const char *filename)
+{
+ /* Expect a table of register-value pairs, e.g. "0x12345678 0x4321" */
+ FILE *fp = fopen(filename, "r");
+ struct zynq_reginit reginit;
+ unsigned int reg_count = 0;
+ int r;
+
+ if (!fp) {
+ fprintf(stderr, "Cannot open initparams file: %s\n", filename);
+ exit(1);
+ }
+ do {
+ r = fscanf(fp, "%x %x", &reginit.address, &reginit.data);
+ if (r == 2) {
+ zynqhdr->register_init[reg_count] = reginit;
+ ++reg_count;
+ }
+ r = fscanf(fp, "%*[^\n]\n"); /* Skip to next line */
+ } while ((r != EOF) && (reg_count < HEADER_REGINITS));
+ fclose(fp);
+}
+
static void zynqimage_set_header(void *ptr, struct stat *sbuf, int ifd,
struct image_tool_params *params)
{
@@ -237,6 +261,10 @@ static void zynqimage_set_header(void *ptr, struct stat *sbuf, int ifd,
if (params->eflag)
zynqhdr->image_load = cpu_to_le32((uint32_t)params->ep);
+ /* User can pass in text file with init list */
+ if (strlen(params->imagename2))
+ zynqimage_parse_initparams(zynqhdr, params->imagename2);
+
zynqhdr->checksum = zynqimage_checksum(zynqhdr);
}
diff --git a/tools/zynqmpimage.c b/tools/zynqmpimage.c
index 3f28eb401d..202faea072 100644
--- a/tools/zynqmpimage.c
+++ b/tools/zynqmpimage.c
@@ -234,6 +234,36 @@ static int zynqmpimage_check_image_types(uint8_t type)
return EXIT_FAILURE;
}
+static void zynqmpimage_parse_initparams(struct zynqmp_header *zynqhdr,
+ const char *filename)
+{
+ FILE *fp;
+ struct zynqmp_reginit reginit;
+ unsigned int reg_count = 0;
+ int r;
+ struct stat path_stat;
+
+ stat(filename, &path_stat);
+ if (!S_ISREG(path_stat.st_mode))
+ return;
+
+ /* Expect a table of register-value pairs, e.g. "0x12345678 0x4321" */
+ fp = fopen(filename, "r");
+ if (!fp) {
+ fprintf(stderr, "Cannot open initparams file: %s\n", filename);
+ exit(1);
+ }
+ do {
+ r = fscanf(fp, "%x %x", &reginit.address, &reginit.data);
+ if (r == 2) {
+ zynqhdr->register_init[reg_count] = reginit;
+ ++reg_count;
+ }
+ r = fscanf(fp, "%*[^\n]\n"); /* Skip to next line */
+ } while ((r != EOF) && (reg_count < HEADER_REGINITS));
+ fclose(fp);
+}
+
static void zynqmpimage_set_header(void *ptr, struct stat *sbuf, int ifd,
struct image_tool_params *params)
{
@@ -250,6 +280,10 @@ static void zynqmpimage_set_header(void *ptr, struct stat *sbuf, int ifd,
if (params->eflag)
zynqhdr->image_load = cpu_to_le32((uint32_t)params->ep);
+ /* User can pass in text file with init list */
+ if (strlen(params->imagename2))
+ zynqmpimage_parse_initparams(zynqhdr, params->imagename2);
+
zynqhdr->checksum = zynqmpimage_checksum(zynqhdr);
}