[U-Boot] [RFC 0/2] arm64: zynqmp: pass a PMUFW config object

Hi,
a long-standing issue in the ZynqMP users community is the management on the PMU firmware configuration object.
The Platform Management Unit (PMU) needs a configuration object (cfg obj) to know how to operate the SoC. When using the "Xilinx workflow", the Xilinx FSBL (First Stage Bootloader) has te SPL role. FSBL has a built-in cfg obj and passes it to the PMUFW at runtime before jumping to U-Boot proper.
This is just not implemented in the U-Boot code. The best workaround for U-Boot SPL users is to patch [0] the PMUFW itself to have the cfg obj built-in and self-load it. This approach has some drawbacks: among others, it forces to use a different PMUFW binary for each hardware and hardware configuation. It also makes it impossible to change the configuration after boot.
This patchset is a first attempt at filling the gap by allowing U-Boot to load the cfg obj firmware at runtime. It adds a Kconfig string option to point to the cfg obj in the form of a C file as produced by Xilinx tools (usually called pm_cfg_obj.c). If the option is non-empty, code is enabled to compile that file in U-Boot proper and to send the configuration to PMUFW early after SPL.
This mechanism relies on the underlying EL3 (ARM Trusted Firmware) to implement the SET_CONFIGURATION SMC call. I just sent a trivial pull request [1] to ATF to add this call. With this in place, the path of the cfg obj is U-Boot -> ATF -> PMUFW.
This is a rather simple approach that works in many cases, but not all, as pointed out by Michal Simek. Some boards (reportedly zcu100 and ultra96 according to Michal) need the cfg obj loaded in SPL, before applying psu_init. Such boards cannot boot with my patches.
Michal also suggested that the cfg obj loading code should be available both in SPL (configured at build time) and in U-Boot proper (loading an object from a file) in order to support different FPGA configuration and partial reconfiguration at runtime. Even with these limitations Michal suggested to send this work as an RFC to start the discussion.
These patches are tested on the ZCU106 and UltraZed EV boards.
[0] https://github.com/topic-embedded-products/meta-topic/blob/master/recipes-bs...
[1] https://github.com/ARM-software/arm-trusted-firmware/pull/1850
Luca
Luca Ceresoli (2): arm64: zynqmp: add minimal include files to build a pm_cfg_obj.c arm64: zynqmp: install a PMU firmware config object at runtime
arch/arm/mach-zynqmp/include/mach/sys_proto.h | 1 + board/xilinx/zynqmp/Kconfig | 27 ++ board/xilinx/zynqmp/Makefile | 4 + board/xilinx/zynqmp/pm_defs.h | 254 ++++++++++++++++++ board/xilinx/zynqmp/pmu_global.h | 0 board/xilinx/zynqmp/xil_types.h | 1 + board/xilinx/zynqmp/zynqmp.c | 23 ++ 7 files changed, 310 insertions(+) create mode 100644 board/xilinx/zynqmp/pm_defs.h create mode 100644 board/xilinx/zynqmp/pmu_global.h create mode 100644 board/xilinx/zynqmp/xil_types.h

A following commit will allow U-Boot to pass a configuration object to the ZynqMP PMU firmware. This configuration object is generated by Xilinx tools in the form of a C file (pm_cfg_obj.c), which #includes a few headers with constants definitions.
In order to allow pm_cfg_obj.c to build, include in U-Boot a minimal version of those headers files:
- pm_defs: a copy of [0], reduced to remove unneeded values - pmu_global.h: empty file, it is included but not really needed - xil_types.h: just includes common.h which has all the needed types
[0] https://github.com/Xilinx/embeddedsw/blob/xilinx-v2018.3/lib/sw_services/xil...
Signed-off-by: Luca Ceresoli luca@lucaceresoli.net --- board/xilinx/zynqmp/pm_defs.h | 254 +++++++++++++++++++++++++++++++ board/xilinx/zynqmp/pmu_global.h | 0 board/xilinx/zynqmp/xil_types.h | 1 + 3 files changed, 255 insertions(+) create mode 100644 board/xilinx/zynqmp/pm_defs.h create mode 100644 board/xilinx/zynqmp/pmu_global.h create mode 100644 board/xilinx/zynqmp/xil_types.h
diff --git a/board/xilinx/zynqmp/pm_defs.h b/board/xilinx/zynqmp/pm_defs.h new file mode 100644 index 000000000000..a339d5ef4fd1 --- /dev/null +++ b/board/xilinx/zynqmp/pm_defs.h @@ -0,0 +1,254 @@ +/****************************************************************************** +* +* Copyright (C) 2015-2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +/*****************************************************************************/ +/** + * @file pm_defs.h + * + * PM Definitions implementation + * @addtogroup xpm_apis XilPM APIs + * @{ + *****************************************************************************/ + +#ifndef PM_DEFS_H_ +#define PM_DEFS_H_ + +/** @name Capabilities for RAM + * + * @{ + */ +#define PM_CAP_ACCESS 0x1U +#define PM_CAP_CONTEXT 0x2U +#define PM_CAP_WAKEUP 0x4U +/**@}*/ + +/** + * PM Node ID Enum + */ +enum XPmNodeId { + NODE_UNKNOWN, + NODE_APU, + NODE_APU_0, + NODE_APU_1, + NODE_APU_2, + NODE_APU_3, + NODE_RPU, + NODE_RPU_0, + NODE_RPU_1, + NODE_PLD, + NODE_FPD, + NODE_OCM_BANK_0, + NODE_OCM_BANK_1, + NODE_OCM_BANK_2, + NODE_OCM_BANK_3, + NODE_TCM_0_A, + NODE_TCM_0_B, + NODE_TCM_1_A, + NODE_TCM_1_B, + NODE_L2, + NODE_GPU_PP_0, + NODE_GPU_PP_1, + NODE_USB_0, + NODE_USB_1, + NODE_TTC_0, + NODE_TTC_1, + NODE_TTC_2, + NODE_TTC_3, + NODE_SATA, + NODE_ETH_0, + NODE_ETH_1, + NODE_ETH_2, + NODE_ETH_3, + NODE_UART_0, + NODE_UART_1, + NODE_SPI_0, + NODE_SPI_1, + NODE_I2C_0, + NODE_I2C_1, + NODE_SD_0, + NODE_SD_1, + NODE_DP, + NODE_GDMA, + NODE_ADMA, + NODE_NAND, + NODE_QSPI, + NODE_GPIO, + NODE_CAN_0, + NODE_CAN_1, + NODE_EXTERN, + NODE_APLL, + NODE_VPLL, + NODE_DPLL, + NODE_RPLL, + NODE_IOPLL, + NODE_DDR, + NODE_IPI_APU, + NODE_IPI_RPU_0, + NODE_GPU, + NODE_PCIE, + NODE_PCAP, + NODE_RTC, + NODE_LPD, + NODE_VCU, + NODE_IPI_RPU_1, + NODE_IPI_PL_0, + NODE_IPI_PL_1, + NODE_IPI_PL_2, + NODE_IPI_PL_3, + NODE_PL, + NODE_ID_MAX +}; + +/** + * PM Reset Line IDs + */ +enum XPmReset { + XILPM_RESET_PCIE_CFG = 1000, + XILPM_RESET_PCIE_BRIDGE, + XILPM_RESET_PCIE_CTRL, + XILPM_RESET_DP, + XILPM_RESET_SWDT_CRF, + XILPM_RESET_AFI_FM5, + XILPM_RESET_AFI_FM4, + XILPM_RESET_AFI_FM3, + XILPM_RESET_AFI_FM2, + XILPM_RESET_AFI_FM1, + XILPM_RESET_AFI_FM0, + XILPM_RESET_GDMA, + XILPM_RESET_GPU_PP1, + XILPM_RESET_GPU_PP0, + XILPM_RESET_GPU, + XILPM_RESET_GT, + XILPM_RESET_SATA, + XILPM_RESET_ACPU3_PWRON, + XILPM_RESET_ACPU2_PWRON, + XILPM_RESET_ACPU1_PWRON, + XILPM_RESET_ACPU0_PWRON, + XILPM_RESET_APU_L2, + XILPM_RESET_ACPU3, + XILPM_RESET_ACPU2, + XILPM_RESET_ACPU1, + XILPM_RESET_ACPU0, + XILPM_RESET_DDR, + XILPM_RESET_APM_FPD, + XILPM_RESET_SOFT, + XILPM_RESET_GEM0, + XILPM_RESET_GEM1, + XILPM_RESET_GEM2, + XILPM_RESET_GEM3, + XILPM_RESET_QSPI, + XILPM_RESET_UART0, + XILPM_RESET_UART1, + XILPM_RESET_SPI0, + XILPM_RESET_SPI1, + XILPM_RESET_SDIO0, + XILPM_RESET_SDIO1, + XILPM_RESET_CAN0, + XILPM_RESET_CAN1, + XILPM_RESET_I2C0, + XILPM_RESET_I2C1, + XILPM_RESET_TTC0, + XILPM_RESET_TTC1, + XILPM_RESET_TTC2, + XILPM_RESET_TTC3, + XILPM_RESET_SWDT_CRL, + XILPM_RESET_NAND, + XILPM_RESET_ADMA, + XILPM_RESET_GPIO, + XILPM_RESET_IOU_CC, + XILPM_RESET_TIMESTAMP, + XILPM_RESET_RPU_R50, + XILPM_RESET_RPU_R51, + XILPM_RESET_RPU_AMBA, + XILPM_RESET_OCM, + XILPM_RESET_RPU_PGE, + XILPM_RESET_USB0_CORERESET, + XILPM_RESET_USB1_CORERESET, + XILPM_RESET_USB0_HIBERRESET, + XILPM_RESET_USB1_HIBERRESET, + XILPM_RESET_USB0_APB, + XILPM_RESET_USB1_APB, + XILPM_RESET_IPI, + XILPM_RESET_APM_LPD, + XILPM_RESET_RTC, + XILPM_RESET_SYSMON, + XILPM_RESET_AFI_FM6, + XILPM_RESET_LPD_SWDT, + XILPM_RESET_FPD, + XILPM_RESET_RPU_DBG1, + XILPM_RESET_RPU_DBG0, + XILPM_RESET_DBG_LPD, + XILPM_RESET_DBG_FPD, + XILPM_RESET_APLL, + XILPM_RESET_DPLL, + XILPM_RESET_VPLL, + XILPM_RESET_IOPLL, + XILPM_RESET_RPLL, + XILPM_RESET_GPO3_PL_0, + XILPM_RESET_GPO3_PL_1, + XILPM_RESET_GPO3_PL_2, + XILPM_RESET_GPO3_PL_3, + XILPM_RESET_GPO3_PL_4, + XILPM_RESET_GPO3_PL_5, + XILPM_RESET_GPO3_PL_6, + XILPM_RESET_GPO3_PL_7, + XILPM_RESET_GPO3_PL_8, + XILPM_RESET_GPO3_PL_9, + XILPM_RESET_GPO3_PL_10, + XILPM_RESET_GPO3_PL_11, + XILPM_RESET_GPO3_PL_12, + XILPM_RESET_GPO3_PL_13, + XILPM_RESET_GPO3_PL_14, + XILPM_RESET_GPO3_PL_15, + XILPM_RESET_GPO3_PL_16, + XILPM_RESET_GPO3_PL_17, + XILPM_RESET_GPO3_PL_18, + XILPM_RESET_GPO3_PL_19, + XILPM_RESET_GPO3_PL_20, + XILPM_RESET_GPO3_PL_21, + XILPM_RESET_GPO3_PL_22, + XILPM_RESET_GPO3_PL_23, + XILPM_RESET_GPO3_PL_24, + XILPM_RESET_GPO3_PL_25, + XILPM_RESET_GPO3_PL_26, + XILPM_RESET_GPO3_PL_27, + XILPM_RESET_GPO3_PL_28, + XILPM_RESET_GPO3_PL_29, + XILPM_RESET_GPO3_PL_30, + XILPM_RESET_GPO3_PL_31, + XILPM_RESET_RPU_LS, + XILPM_RESET_PS_ONLY, + XILPM_RESET_PL, + XILPM_RESET_GPIO5_EMIO_92, + XILPM_RESET_GPIO5_EMIO_93, + XILPM_RESET_GPIO5_EMIO_94, + XILPM_RESET_GPIO5_EMIO_95, +}; + + /** @} */ +#endif /* PM_DEFS_H_ */ diff --git a/board/xilinx/zynqmp/pmu_global.h b/board/xilinx/zynqmp/pmu_global.h new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/board/xilinx/zynqmp/xil_types.h b/board/xilinx/zynqmp/xil_types.h new file mode 100644 index 000000000000..65e11030d85e --- /dev/null +++ b/board/xilinx/zynqmp/xil_types.h @@ -0,0 +1 @@ +#include <common.h>

On 28. 02. 19 23:28, Luca Ceresoli wrote:
A following commit will allow U-Boot to pass a configuration object to the ZynqMP PMU firmware. This configuration object is generated by Xilinx tools in the form of a C file (pm_cfg_obj.c), which #includes a few headers with constants definitions.
In order to allow pm_cfg_obj.c to build, include in U-Boot a minimal version of those headers files:
- pm_defs: a copy of [0], reduced to remove unneeded values
- pmu_global.h: empty file, it is included but not really needed
- xil_types.h: just includes common.h which has all the needed types
[0] https://github.com/Xilinx/embeddedsw/blob/xilinx-v2018.3/lib/sw_services/xil...
Signed-off-by: Luca Ceresoli luca@lucaceresoli.net
board/xilinx/zynqmp/pm_defs.h | 254 +++++++++++++++++++++++++++++++ board/xilinx/zynqmp/pmu_global.h | 0 board/xilinx/zynqmp/xil_types.h | 1 + 3 files changed, 255 insertions(+) create mode 100644 board/xilinx/zynqmp/pm_defs.h create mode 100644 board/xilinx/zynqmp/pmu_global.h create mode 100644 board/xilinx/zynqmp/xil_types.h
diff --git a/board/xilinx/zynqmp/pm_defs.h b/board/xilinx/zynqmp/pm_defs.h new file mode 100644 index 000000000000..a339d5ef4fd1 --- /dev/null +++ b/board/xilinx/zynqmp/pm_defs.h @@ -0,0 +1,254 @@ +/****************************************************************************** +* +* Copyright (C) 2015-2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/
+/*****************************************************************************/ +/**
- @file pm_defs.h
- PM Definitions implementation
- @addtogroup xpm_apis XilPM APIs
- @{
- *****************************************************************************/
+#ifndef PM_DEFS_H_ +#define PM_DEFS_H_
+/** @name Capabilities for RAM
- @{
- */
+#define PM_CAP_ACCESS 0x1U +#define PM_CAP_CONTEXT 0x2U +#define PM_CAP_WAKEUP 0x4U +/**@}*/
+/**
- PM Node ID Enum
- */
+enum XPmNodeId {
- NODE_UNKNOWN,
- NODE_APU,
- NODE_APU_0,
- NODE_APU_1,
- NODE_APU_2,
- NODE_APU_3,
- NODE_RPU,
- NODE_RPU_0,
- NODE_RPU_1,
- NODE_PLD,
- NODE_FPD,
- NODE_OCM_BANK_0,
- NODE_OCM_BANK_1,
- NODE_OCM_BANK_2,
- NODE_OCM_BANK_3,
- NODE_TCM_0_A,
- NODE_TCM_0_B,
- NODE_TCM_1_A,
- NODE_TCM_1_B,
- NODE_L2,
- NODE_GPU_PP_0,
- NODE_GPU_PP_1,
- NODE_USB_0,
- NODE_USB_1,
- NODE_TTC_0,
- NODE_TTC_1,
- NODE_TTC_2,
- NODE_TTC_3,
- NODE_SATA,
- NODE_ETH_0,
- NODE_ETH_1,
- NODE_ETH_2,
- NODE_ETH_3,
- NODE_UART_0,
- NODE_UART_1,
- NODE_SPI_0,
- NODE_SPI_1,
- NODE_I2C_0,
- NODE_I2C_1,
- NODE_SD_0,
- NODE_SD_1,
- NODE_DP,
- NODE_GDMA,
- NODE_ADMA,
- NODE_NAND,
- NODE_QSPI,
- NODE_GPIO,
- NODE_CAN_0,
- NODE_CAN_1,
- NODE_EXTERN,
- NODE_APLL,
- NODE_VPLL,
- NODE_DPLL,
- NODE_RPLL,
- NODE_IOPLL,
- NODE_DDR,
- NODE_IPI_APU,
- NODE_IPI_RPU_0,
- NODE_GPU,
- NODE_PCIE,
- NODE_PCAP,
- NODE_RTC,
- NODE_LPD,
- NODE_VCU,
- NODE_IPI_RPU_1,
- NODE_IPI_PL_0,
- NODE_IPI_PL_1,
- NODE_IPI_PL_2,
- NODE_IPI_PL_3,
- NODE_PL,
- NODE_ID_MAX
+};
+/**
- PM Reset Line IDs
- */
+enum XPmReset {
- XILPM_RESET_PCIE_CFG = 1000,
- XILPM_RESET_PCIE_BRIDGE,
- XILPM_RESET_PCIE_CTRL,
- XILPM_RESET_DP,
- XILPM_RESET_SWDT_CRF,
- XILPM_RESET_AFI_FM5,
- XILPM_RESET_AFI_FM4,
- XILPM_RESET_AFI_FM3,
- XILPM_RESET_AFI_FM2,
- XILPM_RESET_AFI_FM1,
- XILPM_RESET_AFI_FM0,
- XILPM_RESET_GDMA,
- XILPM_RESET_GPU_PP1,
- XILPM_RESET_GPU_PP0,
- XILPM_RESET_GPU,
- XILPM_RESET_GT,
- XILPM_RESET_SATA,
- XILPM_RESET_ACPU3_PWRON,
- XILPM_RESET_ACPU2_PWRON,
- XILPM_RESET_ACPU1_PWRON,
- XILPM_RESET_ACPU0_PWRON,
- XILPM_RESET_APU_L2,
- XILPM_RESET_ACPU3,
- XILPM_RESET_ACPU2,
- XILPM_RESET_ACPU1,
- XILPM_RESET_ACPU0,
- XILPM_RESET_DDR,
- XILPM_RESET_APM_FPD,
- XILPM_RESET_SOFT,
- XILPM_RESET_GEM0,
- XILPM_RESET_GEM1,
- XILPM_RESET_GEM2,
- XILPM_RESET_GEM3,
- XILPM_RESET_QSPI,
- XILPM_RESET_UART0,
- XILPM_RESET_UART1,
- XILPM_RESET_SPI0,
- XILPM_RESET_SPI1,
- XILPM_RESET_SDIO0,
- XILPM_RESET_SDIO1,
- XILPM_RESET_CAN0,
- XILPM_RESET_CAN1,
- XILPM_RESET_I2C0,
- XILPM_RESET_I2C1,
- XILPM_RESET_TTC0,
- XILPM_RESET_TTC1,
- XILPM_RESET_TTC2,
- XILPM_RESET_TTC3,
- XILPM_RESET_SWDT_CRL,
- XILPM_RESET_NAND,
- XILPM_RESET_ADMA,
- XILPM_RESET_GPIO,
- XILPM_RESET_IOU_CC,
- XILPM_RESET_TIMESTAMP,
- XILPM_RESET_RPU_R50,
- XILPM_RESET_RPU_R51,
- XILPM_RESET_RPU_AMBA,
- XILPM_RESET_OCM,
- XILPM_RESET_RPU_PGE,
- XILPM_RESET_USB0_CORERESET,
- XILPM_RESET_USB1_CORERESET,
- XILPM_RESET_USB0_HIBERRESET,
- XILPM_RESET_USB1_HIBERRESET,
- XILPM_RESET_USB0_APB,
- XILPM_RESET_USB1_APB,
- XILPM_RESET_IPI,
- XILPM_RESET_APM_LPD,
- XILPM_RESET_RTC,
- XILPM_RESET_SYSMON,
- XILPM_RESET_AFI_FM6,
- XILPM_RESET_LPD_SWDT,
- XILPM_RESET_FPD,
- XILPM_RESET_RPU_DBG1,
- XILPM_RESET_RPU_DBG0,
- XILPM_RESET_DBG_LPD,
- XILPM_RESET_DBG_FPD,
- XILPM_RESET_APLL,
- XILPM_RESET_DPLL,
- XILPM_RESET_VPLL,
- XILPM_RESET_IOPLL,
- XILPM_RESET_RPLL,
- XILPM_RESET_GPO3_PL_0,
- XILPM_RESET_GPO3_PL_1,
- XILPM_RESET_GPO3_PL_2,
- XILPM_RESET_GPO3_PL_3,
- XILPM_RESET_GPO3_PL_4,
- XILPM_RESET_GPO3_PL_5,
- XILPM_RESET_GPO3_PL_6,
- XILPM_RESET_GPO3_PL_7,
- XILPM_RESET_GPO3_PL_8,
- XILPM_RESET_GPO3_PL_9,
- XILPM_RESET_GPO3_PL_10,
- XILPM_RESET_GPO3_PL_11,
- XILPM_RESET_GPO3_PL_12,
- XILPM_RESET_GPO3_PL_13,
- XILPM_RESET_GPO3_PL_14,
- XILPM_RESET_GPO3_PL_15,
- XILPM_RESET_GPO3_PL_16,
- XILPM_RESET_GPO3_PL_17,
- XILPM_RESET_GPO3_PL_18,
- XILPM_RESET_GPO3_PL_19,
- XILPM_RESET_GPO3_PL_20,
- XILPM_RESET_GPO3_PL_21,
- XILPM_RESET_GPO3_PL_22,
- XILPM_RESET_GPO3_PL_23,
- XILPM_RESET_GPO3_PL_24,
- XILPM_RESET_GPO3_PL_25,
- XILPM_RESET_GPO3_PL_26,
- XILPM_RESET_GPO3_PL_27,
- XILPM_RESET_GPO3_PL_28,
- XILPM_RESET_GPO3_PL_29,
- XILPM_RESET_GPO3_PL_30,
- XILPM_RESET_GPO3_PL_31,
- XILPM_RESET_RPU_LS,
- XILPM_RESET_PS_ONLY,
- XILPM_RESET_PL,
- XILPM_RESET_GPIO5_EMIO_92,
- XILPM_RESET_GPIO5_EMIO_93,
- XILPM_RESET_GPIO5_EMIO_94,
- XILPM_RESET_GPIO5_EMIO_95,
+};
- /** @} */
+#endif /* PM_DEFS_H_ */ diff --git a/board/xilinx/zynqmp/pmu_global.h b/board/xilinx/zynqmp/pmu_global.h new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/board/xilinx/zynqmp/xil_types.h b/board/xilinx/zynqmp/xil_types.h new file mode 100644 index 000000000000..65e11030d85e --- /dev/null +++ b/board/xilinx/zynqmp/xil_types.h @@ -0,0 +1 @@ +#include <common.h>
As we discussed. I don't think this is needed. pmufw config file should be handled as blob instead of trying to compose it from C.
M

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@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)

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 luca@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)
Definitely thanks for sharing this. I would convert this to zynqmp pmufw(whatever) command that you can pass this any time. It means you will get new pmufw config object to memory and push it to pmufw. And you will handle that pmufw config object as binary data file. It general it is - but it is composed via C.
Thanks, Michal
participants (2)
-
Luca Ceresoli
-
Michal Simek