summaryrefslogtreecommitdiff
path: root/arch/arm/mach-zynqmp
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-zynqmp')
-rw-r--r--arch/arm/mach-zynqmp/Kconfig11
-rw-r--r--arch/arm/mach-zynqmp/handoff.c17
-rw-r--r--arch/arm/mach-zynqmp/include/mach/hardware.h2
-rw-r--r--arch/arm/mach-zynqmp/include/mach/psu_init_gpl.h1
-rw-r--r--arch/arm/mach-zynqmp/include/mach/sys_proto.h2
-rwxr-xr-xarch/arm/mach-zynqmp/mkimage_fit_atf.sh123
-rw-r--r--arch/arm/mach-zynqmp/psu_spl_init.c9
-rw-r--r--arch/arm/mach-zynqmp/spl.c27
8 files changed, 158 insertions, 34 deletions
diff --git a/arch/arm/mach-zynqmp/Kconfig b/arch/arm/mach-zynqmp/Kconfig
index 6cf17eb94e1..d82a737a699 100644
--- a/arch/arm/mach-zynqmp/Kconfig
+++ b/arch/arm/mach-zynqmp/Kconfig
@@ -117,17 +117,6 @@ config SPL_ZYNQMP_ALT_BOOTMODE_ENABLED
config ZYNQ_SDHCI_MAX_FREQ
default 200000000
-config SPL_ZYNQMP_TWO_SDHCI
- bool "Enable booting from both SDHCIs"
- depends on SPL
- help
- This option reflects that board has two SDHCI controllers which
- platform can use as boot device. This option ensures that SPL will
- setup BOOT_DEVICE_MMC2 for SDHCI1 controller and BOOT_DEVICE_MMC1 for
- SDHCI0 controller. Platforms which have only one SDHCI controller
- shouldn't enable this option because it for software SDHCI0 or SDHCI1
- are both covered by BOOT_DEVICE_MMC1.
-
config SPL_ZYNQMP_ALT_BOOTMODE
hex
default 0x0 if JTAG_MODE
diff --git a/arch/arm/mach-zynqmp/handoff.c b/arch/arm/mach-zynqmp/handoff.c
index f71ff7b3d25..64e5320acc6 100644
--- a/arch/arm/mach-zynqmp/handoff.c
+++ b/arch/arm/mach-zynqmp/handoff.c
@@ -66,7 +66,9 @@ struct xfsbl_atf_handoff_params {
};
#ifdef CONFIG_SPL_OS_BOOT
-void handoff_setup(void)
+struct bl31_params *bl2_plat_get_bl31_params(uintptr_t bl32_entry,
+ uintptr_t bl33_entry,
+ uintptr_t fdt_addr)
{
struct xfsbl_atf_handoff_params *atfhandoffparams;
@@ -76,11 +78,16 @@ void handoff_setup(void)
atfhandoffparams->magic[2] = 'N';
atfhandoffparams->magic[3] = 'X';
- atfhandoffparams->num_entries = 1;
- atfhandoffparams->partition[0].entry_point = CONFIG_SYS_TEXT_BASE;
- atfhandoffparams->partition[0].flags = FSBL_FLAGS_EL2 <<
- FSBL_FLAGS_EL_SHIFT;
+ atfhandoffparams->num_entries = 0;
+ if (bl33_entry) {
+ atfhandoffparams->partition[0].entry_point = bl33_entry;
+ atfhandoffparams->partition[0].flags = FSBL_FLAGS_EL2 <<
+ FSBL_FLAGS_EL_SHIFT;
+ atfhandoffparams->num_entries++;
+ }
writel(CONFIG_SPL_TEXT_BASE, &pmu_base->gen_storage6);
+
+ return NULL;
}
#endif
diff --git a/arch/arm/mach-zynqmp/include/mach/hardware.h b/arch/arm/mach-zynqmp/include/mach/hardware.h
index a0d776166d0..fd361c5ce8a 100644
--- a/arch/arm/mach-zynqmp/include/mach/hardware.h
+++ b/arch/arm/mach-zynqmp/include/mach/hardware.h
@@ -7,8 +7,6 @@
#ifndef _ASM_ARCH_HARDWARE_H
#define _ASM_ARCH_HARDWARE_H
-#define ARASAN_NAND_BASEADDR 0xFF100000
-
#define ZYNQMP_TCM_BASE_ADDR 0xFFE00000
#define ZYNQMP_TCM_SIZE 0x40000
diff --git a/arch/arm/mach-zynqmp/include/mach/psu_init_gpl.h b/arch/arm/mach-zynqmp/include/mach/psu_init_gpl.h
index 15e54c04938..e37acda2f89 100644
--- a/arch/arm/mach-zynqmp/include/mach/psu_init_gpl.h
+++ b/arch/arm/mach-zynqmp/include/mach/psu_init_gpl.h
@@ -21,5 +21,6 @@ void prog_reg(unsigned long addr, unsigned long mask,
unsigned long shift, unsigned long value);
int psu_init(void);
+unsigned long psu_post_config_data(void);
#endif /* _PSU_INIT_GPL_H_ */
diff --git a/arch/arm/mach-zynqmp/include/mach/sys_proto.h b/arch/arm/mach-zynqmp/include/mach/sys_proto.h
index 10b70761de4..2974ffbc2f5 100644
--- a/arch/arm/mach-zynqmp/include/mach/sys_proto.h
+++ b/arch/arm/mach-zynqmp/include/mach/sys_proto.h
@@ -46,8 +46,6 @@ struct zynqmp_ipi_msg {
int zynq_board_read_rom_ethaddr(unsigned char *ethaddr);
unsigned int zynqmp_get_silicon_version(void);
-void handoff_setup(void);
-
int zynqmp_mmio_write(const u32 address, const u32 mask, const u32 value);
int zynqmp_mmio_read(const u32 address, u32 *value);
diff --git a/arch/arm/mach-zynqmp/mkimage_fit_atf.sh b/arch/arm/mach-zynqmp/mkimage_fit_atf.sh
new file mode 100755
index 00000000000..1e770ba111d
--- /dev/null
+++ b/arch/arm/mach-zynqmp/mkimage_fit_atf.sh
@@ -0,0 +1,123 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0+
+#
+# script to generate FIT image source for Xilinx ZynqMP boards with
+# ARM Trusted Firmware and multiple device trees (given on the command line)
+#
+# usage: $0 <dt_name> [<dt_name> [<dt_name] ...]
+
+BL33="u-boot-nodtb.bin"
+[ -z "$BL31" ] && BL31="bl31.bin"
+# Can be also done as ${CROSS_COMPILE}readelf -l bl31.elf | awk '/Entry point/ { print $3 }'
+[ -z "$ATF_LOAD_ADDR" ] && ATF_LOAD_ADDR="0xfffea000"
+
+if [ -z "$BL33_LOAD_ADDR" ];then
+ BL33_LOAD_ADDR=`awk '/CONFIG_SYS_TEXT_BASE/ { print $3 }' include/generated/autoconf.h`
+fi
+
+DTB_LOAD_ADDR=`awk '/CONFIG_XILINX_OF_BOARD_DTB_ADDR/ { print $3 }' include/generated/autoconf.h`
+if [ ! -z "$DTB_LOAD_ADDR" ]; then
+ DTB_LOAD="load = <$DTB_LOAD_ADDR>;"
+else
+ DTB_LOAD=""
+fi
+
+if [ -z "$*" ]; then
+ DT=arch/arm/dts/${DEVICE_TREE}.dtb
+else
+ DT=$*
+fi
+
+if [ ! -f $BL31 ]; then
+ echo "WARNING: BL31 file $BL31 NOT found, resulting binary is non-functional" >&2
+ BL31=/dev/null
+ # But U-Boot proper could be loaded in EL3 by specifying
+ # firmware = "uboot";
+ # instead of "atf" in config node
+fi
+
+cat << __HEADER_EOF
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+/dts-v1/;
+
+/ {
+ description = "Configuration to load ATF before U-Boot";
+
+ images {
+ uboot {
+ description = "U-Boot (64-bit)";
+ data = /incbin/("$BL33");
+ type = "firmware";
+ os = "u-boot";
+ arch = "arm64";
+ compression = "none";
+ load = <$BL33_LOAD_ADDR>;
+ entry = <$BL33_LOAD_ADDR>;
+ hash {
+ algo = "md5";
+ };
+ };
+ atf {
+ description = "ARM Trusted Firmware";
+ data = /incbin/("$BL31");
+ type = "firmware";
+ os = "arm-trusted-firmware";
+ arch = "arm64";
+ compression = "none";
+ load = <$ATF_LOAD_ADDR>;
+ entry = <$ATF_LOAD_ADDR>;
+ hash {
+ algo = "md5";
+ };
+ };
+__HEADER_EOF
+
+DEFAULT=1
+cnt=1
+for dtname in $DT
+do
+ cat << __FDT_IMAGE_EOF
+ fdt_$cnt {
+ description = "$(basename $dtname .dtb)";
+ data = /incbin/("$dtname");
+ type = "flat_dt";
+ arch = "arm64";
+ compression = "none";
+ $DTB_LOAD
+ hash {
+ algo = "md5";
+ };
+ };
+__FDT_IMAGE_EOF
+
+[ "x$(basename $dtname .dtb)" = "x${DEVICE_TREE}" ] && DEFAULT=$cnt
+
+cnt=$((cnt+1))
+done
+
+cat << __CONF_HEADER_EOF
+ };
+ configurations {
+ default = "config_$DEFAULT";
+
+__CONF_HEADER_EOF
+
+cnt=1
+for dtname in $DT
+do
+cat << __CONF_SECTION1_EOF
+ config_$cnt {
+ description = "$(basename $dtname .dtb)";
+ firmware = "atf";
+ loadables = "uboot";
+ fdt = "fdt_$cnt";
+ };
+__CONF_SECTION1_EOF
+cnt=$((cnt+1))
+done
+
+cat << __ITS_EOF
+ };
+};
+__ITS_EOF
diff --git a/arch/arm/mach-zynqmp/psu_spl_init.c b/arch/arm/mach-zynqmp/psu_spl_init.c
index b357de32358..b6abdfd608e 100644
--- a/arch/arm/mach-zynqmp/psu_spl_init.c
+++ b/arch/arm/mach-zynqmp/psu_spl_init.c
@@ -77,3 +77,12 @@ __weak int psu_init(void)
*/
return -1;
}
+
+__weak unsigned long psu_post_config_data(void)
+{
+ /*
+ * This function is overridden by the one in
+ * board/xilinx/zynqmp/(platform)/psu_init_gpl.c, if it exists.
+ */
+ return 0;
+}
diff --git a/arch/arm/mach-zynqmp/spl.c b/arch/arm/mach-zynqmp/spl.c
index 6ba42bb42f6..896657f51c3 100644
--- a/arch/arm/mach-zynqmp/spl.c
+++ b/arch/arm/mach-zynqmp/spl.c
@@ -13,6 +13,7 @@
#include <asm/io.h>
#include <asm/spl.h>
#include <asm/arch/hardware.h>
+#include <asm/arch/psu_init_gpl.h>
#include <asm/arch/sys_proto.h>
void board_init_f(ulong dummy)
@@ -27,13 +28,6 @@ void board_init_f(ulong dummy)
#endif
/* Delay is required for clocks to be propagated */
udelay(1000000);
-
- debug("Clearing BSS 0x%p - 0x%p\n", __bss_start, __bss_end);
- /* Clear the BSS */
- memset(__bss_start, 0, __bss_end - __bss_start);
-
- /* No need to call timer init - it is empty for ZynqMP */
- board_init_r(NULL, 0);
}
static void ps_mode_reset(ulong mode)
@@ -60,9 +54,20 @@ void spl_board_init(void)
preloader_console_init();
ps_mode_reset(MODE_RESET);
board_init();
+ psu_post_config_data();
}
#endif
+void board_boot_order(u32 *spl_boot_list)
+{
+ spl_boot_list[0] = spl_boot_device();
+
+ if (spl_boot_list[0] == BOOT_DEVICE_MMC1)
+ spl_boot_list[1] = BOOT_DEVICE_MMC2;
+ if (spl_boot_list[0] == BOOT_DEVICE_MMC2)
+ spl_boot_list[1] = BOOT_DEVICE_MMC1;
+}
+
u32 spl_boot_device(void)
{
u32 reg = 0;
@@ -86,11 +91,7 @@ u32 spl_boot_device(void)
#ifdef CONFIG_SPL_MMC_SUPPORT
case SD_MODE1:
case SD1_LSHFT_MODE: /* not working on silicon v1 */
-/* if both controllers enabled, then these two are the second controller */
-#ifdef CONFIG_SPL_ZYNQMP_TWO_SDHCI
return BOOT_DEVICE_MMC2;
-/* else, fall through, the one SDHCI controller that is enabled is number 1 */
-#endif
case SD_MODE:
case EMMC_MODE:
return BOOT_DEVICE_MMC1;
@@ -119,8 +120,6 @@ u32 spl_boot_device(void)
#ifdef CONFIG_SPL_OS_BOOT
int spl_start_uboot(void)
{
- handoff_setup();
-
return 0;
}
#endif
@@ -131,6 +130,6 @@ int board_fit_config_name_match(const char *name)
/* Just empty function now - can't decide what to choose */
debug("%s: %s\n", __func__, name);
- return 0;
+ return -1;
}
#endif