diff options
author | Luca Ceresoli <luca@lucaceresoli.net> | 2019-05-21 18:06:43 +0200 |
---|---|---|
committer | Michal Simek <michal.simek@xilinx.com> | 2019-07-30 10:20:06 +0200 |
commit | c28a9cfa4079031edd511746770096a131414642 (patch) | |
tree | cc60c3832d062604109d4c123dfc412e5fbde2db /board | |
parent | 420d44678119a5df1fcc154d1c33d35fd9722285 (diff) |
arm64: zynqmp: spl: install a PMU firmware config object at runtime
Optionally allow U-Boot to load a configuration object into the Power
Management Unit (PMU) firmware on Xilinx ZynqMP.
The configuration object is required by the PMU FW to enable most SoC
peripherals. So far the only way to boot using U-Boot SPL was to hard-code
the configuration object in the PMU firmware. Allow a different boot
process, where the PMU FW is equal for any ZynqMP chip and its
configuration is passed at runtime by U-Boot SPL.
All the code for Inter-processor communication with the PMU is isolated in
a new file (pmu_ipc.c). The code is inspired by the same feature as
implemented in the Xilinx First Stage Bootloader (FSBL) and Arm Trusted
Firmware:
* https://github.com/Xilinx/embeddedsw/blob/fb647e6b4c00f5154eba52a88b948195b6f1dc2b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_misc_drivers.c#L295
* https://github.com/ARM-software/arm-trusted-firmware/blob/c48d02bade88b07fa7f43aa44e5217f68e5d047f/plat/xilinx/zynqmp/pm_service/pm_api_sys.c#L357
SPL logs on the console before loading the configuration object:
U-Boot SPL 2019.07-rc1-00511-gaec224515c87 (May 15 2019 - 08:43:41 +0200)
Loading PMUFW cfg obj (2008 bytes)
EL Level: EL3
...
Signed-off-by: Luca Ceresoli <luca@lucaceresoli.net>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Diffstat (limited to 'board')
-rw-r--r-- | board/xilinx/zynqmp/Makefile | 5 | ||||
-rw-r--r-- | board/xilinx/zynqmp/pm_cfg_obj.S | 17 | ||||
-rw-r--r-- | board/xilinx/zynqmp/pm_cfg_obj.h | 9 | ||||
-rw-r--r-- | board/xilinx/zynqmp/zynqmp.c | 9 |
4 files changed, 40 insertions, 0 deletions
diff --git a/board/xilinx/zynqmp/Makefile b/board/xilinx/zynqmp/Makefile index 80f8ca7e1e4..b4d39edc118 100644 --- a/board/xilinx/zynqmp/Makefile +++ b/board/xilinx/zynqmp/Makefile @@ -33,6 +33,11 @@ ifneq ($(call ifdef_any_of, CONFIG_ZYNQMP_PSU_INIT_ENABLED CONFIG_SPL_BUILD),) obj-y += $(init-objs) endif +ifneq ($(CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE),"") +obj-$(CONFIG_SPL_BUILD) += pm_cfg_obj.o +$(obj)/pm_cfg_obj.o: $(shell cd $(srctree); readlink -f $(CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE)) FORCE +endif + obj-$(CONFIG_MMC_SDHCI_ZYNQ) += tap_delays.o ifndef CONFIG_SPL_BUILD diff --git a/board/xilinx/zynqmp/pm_cfg_obj.S b/board/xilinx/zynqmp/pm_cfg_obj.S new file mode 100644 index 00000000000..c4ca77e396c --- /dev/null +++ b/board/xilinx/zynqmp/pm_cfg_obj.S @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +.section .rodata + +.global zynqmp_pm_cfg_obj +.type zynqmp_pm_cfg_obj, @object +.global zynqmp_pm_cfg_obj_size +.type zynqmp_pm_cfg_obj_size, @object + +zynqmp_pm_cfg_obj: +.align 4 +.incbin CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE + +zynqmp_pm_cfg_obj_end: + +zynqmp_pm_cfg_obj_size: +.int zynqmp_pm_cfg_obj_end - zynqmp_pm_cfg_obj diff --git a/board/xilinx/zynqmp/pm_cfg_obj.h b/board/xilinx/zynqmp/pm_cfg_obj.h new file mode 100644 index 00000000000..86e785490ce --- /dev/null +++ b/board/xilinx/zynqmp/pm_cfg_obj.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2019 Luca Ceresoli <luca@lucaceresoli.net> + * + * Declaration of PMU config object binary blob linked in at build time. + */ + +extern const u32 zynqmp_pm_cfg_obj[]; +extern const int zynqmp_pm_cfg_obj_size; diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index c840e92d9c4..057ca1fbf7a 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/board/xilinx/zynqmp/zynqmp.c @@ -22,6 +22,8 @@ #include <zynqmppl.h> #include <g_dnl.h> +#include "pm_cfg_obj.h" + DECLARE_GLOBAL_DATA_PTR; #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \ @@ -327,6 +329,13 @@ int board_early_init_f(void) int board_init(void) { +#if defined(CONFIG_SPL_BUILD) + /* Check *at build time* if the filename is an non-empty string */ + if (sizeof(CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE) > 1) + zynqmp_pmufw_load_config_object(zynqmp_pm_cfg_obj, + zynqmp_pm_cfg_obj_size); +#endif + printf("EL Level:\tEL%d\n", current_el()); #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \ |