[U-Boot] [RFC 2/2] arm64: zynqmp: install a PMU firmware config object at runtime

Luca Ceresoli luca at lucaceresoli.net
Thu Feb 28 22:28:25 UTC 2019


Optionally allow U-Boot to load at the PMU firmware configuration
object into the Power Management Unit (PMU) on Xilinx ZynqMP.

The configuration object is required by the PMU FW to use the SoC. 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 proper.

Requires the PM_SET_CONFIGURATION command to be implemented by ARM
Trusted Firmware.

Signed-off-by: Luca Ceresoli <luca at lucaceresoli.net>
---
 arch/arm/mach-zynqmp/include/mach/sys_proto.h |  1 +
 board/xilinx/zynqmp/Kconfig                   | 27 +++++++++++++++++++
 board/xilinx/zynqmp/Makefile                  |  4 +++
 board/xilinx/zynqmp/zynqmp.c                  | 23 ++++++++++++++++
 4 files changed, 55 insertions(+)

diff --git a/arch/arm/mach-zynqmp/include/mach/sys_proto.h b/arch/arm/mach-zynqmp/include/mach/sys_proto.h
index 385c8825f2f6..1f2c0476ce96 100644
--- a/arch/arm/mach-zynqmp/include/mach/sys_proto.h
+++ b/arch/arm/mach-zynqmp/include/mach/sys_proto.h
@@ -22,6 +22,7 @@
 #define ZYNQMP_FPGA_AUTH_DDR	1
 
 #define ZYNQMP_SIP_SVC_GET_API_VERSION		0xC2000001
+#define ZYNQMP_SIP_SVC_SET_CONFIGURATION	0xC2000002
 
 #define ZYNQMP_PM_VERSION_MAJOR		1
 #define ZYNQMP_PM_VERSION_MINOR		0
diff --git a/board/xilinx/zynqmp/Kconfig b/board/xilinx/zynqmp/Kconfig
index 7d1f7398c3e9..e9cec5c95470 100644
--- a/board/xilinx/zynqmp/Kconfig
+++ b/board/xilinx/zynqmp/Kconfig
@@ -15,4 +15,31 @@ config CMD_ZYNQMP
 	  and authentication feature enabled while generating
 	  BOOT.BIN using Xilinx bootgen tool.
 
+config ZYNQMP_LOAD_PM_CFG_OBJ_FILE
+	string "PMU firmware configuration object to load at runtime"
+	help
+	  Path to a PMU firmware configuration object to be built into
+	  U-Boot and loaded at runtime into the PMU firmware.
+
+	  The ZynqMP Power Management Unit (PMU) needs a configuration
+	  object for most SoC peripherals to work. It can be either
+	  hard-coded in the PMUFW or passed at runtime.
+
+	  U-Boot can load the configuration object loaded at
+	  runtime. To enable this feature set here the file name
+	  (absolute path or relative to board/xilinx/zynqmp/). It will
+	  be loaded into the PMU firmware at the beginning of U-Boot
+	  proper.
+
+	  Note: if your pm_cfg_obj.c is generated by the Xilinx tools,
+	  you must remove any linking directives from the
+	  XPm_ConfigObject declaration! E.g.:
+
+	    -const u32 XPm_ConfigObject[] __attribute__((used, section(".sys_cfg_data"))) = {
+	    +const u32 XPm_ConfigObject[] = {
+
+	  Leave this option empty if your PMU firmware has a built-in
+	  configuration object or you are loading it by any other
+	  means.
+
 endif
diff --git a/board/xilinx/zynqmp/Makefile b/board/xilinx/zynqmp/Makefile
index 80f8ca7e1e4b..5965e3333ff3 100644
--- a/board/xilinx/zynqmp/Makefile
+++ b/board/xilinx/zynqmp/Makefile
@@ -33,6 +33,10 @@ ifneq ($(call ifdef_any_of, CONFIG_ZYNQMP_PSU_INIT_ENABLED CONFIG_SPL_BUILD),)
 obj-y += $(init-objs)
 endif
 
+ifneq ($(CONFIG_ZYNQMP_LOAD_PM_CFG_OBJ_FILE),"")
+CFLAGS_zynqmp.o += -DZYNQMP_LOAD_PM_CFG_OBJ -I$(srctree)/$(src)
+endif
+
 obj-$(CONFIG_MMC_SDHCI_ZYNQ) += tap_delays.o
 
 ifndef CONFIG_SPL_BUILD
diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index 5e1d2116bc32..84fecf5a347f 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -302,6 +302,25 @@ static char *zynqmp_get_silicon_idcode_name(void)
 }
 #endif
 
+#ifdef ZYNQMP_LOAD_PM_CFG_OBJ
+#include CONFIG_ZYNQMP_LOAD_PM_CFG_OBJ_FILE
+
+void zynqmp_pmufw_load_config_object(void)
+{
+	u32 *ocm = (u32*) CONFIG_SPL_TEXT_BASE;
+	int err;
+
+	printf("Loading PMUFW cfg obj using OCM @ %p (size %ld)\n",
+	       ocm, sizeof(XPm_ConfigObject));
+
+	memcpy(ocm, XPm_ConfigObject, sizeof(XPm_ConfigObject));
+	err = invoke_smc(ZYNQMP_SIP_SVC_SET_CONFIGURATION,
+			 CONFIG_SPL_TEXT_BASE, 0, 0, 0, NULL);
+	if (err)
+		panic("Cannot load PMUFW configuration object (%d)\n", err);
+}
+#endif // ZYNQMP_LOAD_PM_CFG_OBJ
+
 int board_early_init_f(void)
 {
 	int ret = 0;
@@ -316,6 +335,10 @@ int board_early_init_f(void)
 	if (pm_api_version < ZYNQMP_PM_VERSION)
 		panic("PMUFW version error. Expected: v%d.%d\n",
 		      ZYNQMP_PM_VERSION_MAJOR, ZYNQMP_PM_VERSION_MINOR);
+
+	#ifdef ZYNQMP_LOAD_PM_CFG_OBJ
+	zynqmp_pmufw_load_config_object();
+	#endif
 #endif
 
 #if defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED)
-- 
2.17.1



More information about the U-Boot mailing list