On 28. 02. 19 23:28, Luca Ceresoli wrote:
> 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
> ---
> 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 0xC201
> +#define ZYNQMP_SIP_SVC_SET_CONFIGURATION 0xC202
>
> #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..5965eff3 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)
>