[UBOOT PATCH] xilinx: versal: Add firmware access to CRP Boot mode register
Michal Simek
michal.simek at amd.com
Wed Feb 26 10:53:06 CET 2025
On 2/21/25 10:22, Venkatesh Yadav Abbarapu wrote:
> From: Prasad Kummari <prasad.kummari at amd.com>
>
> Added extended support for retrieving the boot mode register
> via the firmware interface, which is preferred when U-Boot
> runs in EL2 and cannot directly access CRP registers via raw
> reads. Ideally, all secure registers should be accessed via
> xilinx_pm_request(). Introduced the secure zynqmp_pm_get_bootmode_reg()
> call, which uses xilinx_pm_request() to read the boot mode register.
>
> When CONFIG_ZYNQMP_FIRMWARE is enabled, the secure
> zynqmp_pm_get_bootmode_reg() call is used; otherwise,
> direct raw reads are performed in the case of mini U-Boot.
>
> Signed-off-by: Prasad Kummari <prasad.kummari at amd.com>
> Signed-off-by: Venkatesh Yadav Abbarapu <venkatesh.abbarapu at amd.com>
> ---
> board/xilinx/versal-net/board.c | 7 ++++++-
> board/xilinx/versal/board.c | 7 ++++++-
> drivers/firmware/firmware-zynqmp.c | 23 +++++++++++++++++++++++
> include/zynqmp_firmware.h | 4 ++++
> 4 files changed, 39 insertions(+), 2 deletions(-)
>
> diff --git a/board/xilinx/versal-net/board.c b/board/xilinx/versal-net/board.c
> index 4d5913cff1d..f8ac54e35a8 100644
> --- a/board/xilinx/versal-net/board.c
> +++ b/board/xilinx/versal-net/board.c
> @@ -21,6 +21,7 @@
> #include <asm/arch/sys_proto.h>
> #include <dm/device.h>
> #include <dm/uclass.h>
> +#include <zynqmp_firmware.h>
> #include "../common/board.h"
>
> #include <linux/bitfield.h>
> @@ -184,7 +185,11 @@ static u8 versal_net_get_bootmode(void)
> u8 bootmode;
> u32 reg = 0;
>
> - reg = readl(&crp_base->boot_mode_usr);
> + if (IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE) && current_el() != 3) {
> + reg = zynqmp_pm_get_bootmode_reg();
> + } else {
> + reg = readl(&crp_base->boot_mode_usr);
> + }
>
> if (reg >> BOOT_MODE_ALT_SHIFT)
> reg >>= BOOT_MODE_ALT_SHIFT;
> diff --git a/board/xilinx/versal/board.c b/board/xilinx/versal/board.c
> index b4483d00ad1..3046fd7e5f0 100644
> --- a/board/xilinx/versal/board.c
> +++ b/board/xilinx/versal/board.c
> @@ -26,6 +26,7 @@
> #include <dm/device.h>
> #include <dm/uclass.h>
> #include <versalpl.h>
> +#include <zynqmp_firmware.h>
> #include "../common/board.h"
>
> DECLARE_GLOBAL_DATA_PTR;
> @@ -42,7 +43,11 @@ static u8 versal_get_bootmode(void)
> u8 bootmode;
> u32 reg = 0;
>
> - reg = readl(&crp_base->boot_mode_usr);
> + if (IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE) && current_el() != 3) {
> + reg = zynqmp_pm_get_bootmode_reg();
> + } else {
> + reg = readl(&crp_base->boot_mode_usr);
> + }
>
> if (reg >> BOOT_MODE_ALT_SHIFT)
> reg >>= BOOT_MODE_ALT_SHIFT;
> diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c
> index 4b1b80d7abe..2adc132b4cc 100644
> --- a/drivers/firmware/firmware-zynqmp.c
> +++ b/drivers/firmware/firmware-zynqmp.c
> @@ -195,6 +195,29 @@ int zynqmp_pm_set_sd_config(u32 node, enum pm_sd_config_type config, u32 value)
> return ret;
> }
>
> +u32 zynqmp_pm_get_bootmode_reg(void)
> +{
> + int ret;
> + u32 ret_payload[PAYLOAD_ARG_CNT];
> +
> + ret = zynqmp_pm_is_function_supported(PM_IOCTL, IOCTL_READ_REG);
> + if (ret) {
> + printf("%s: IOCTL_READ_REG is not supported failed with error code: %d\n"
> + , __func__, ret);
> + return 0;
> + }
> +
> + ret = xilinx_pm_request(PM_IOCTL, CRP_BOOT_MODE_REG_NODE, IOCTL_READ_REG,
> + CRP_BOOT_MODE_REG_OFFSET, 0, ret_payload);
> + if (ret) {
> + printf("%s: node 0x%x: get_bootmode 0x%x failed\n",
> + __func__, CRP_BOOT_MODE_REG_NODE, CRP_BOOT_MODE_REG_OFFSET);
> + return 0;
> + }
> +
> + return ret_payload[1];
> +}
> +
> int zynqmp_pm_feature(const u32 api_id)
> {
> int ret;
> diff --git a/include/zynqmp_firmware.h b/include/zynqmp_firmware.h
> index 73198a6a6ea..e7275f72fac 100644
> --- a/include/zynqmp_firmware.h
> +++ b/include/zynqmp_firmware.h
> @@ -457,6 +457,7 @@ int zynqmp_pm_is_function_supported(const u32 api_id, const u32 id);
> int zynqmp_mmio_read(const u32 address, u32 *value);
> int zynqmp_mmio_write(const u32 address, const u32 mask, const u32 value);
> int zynqmp_pm_feature(const u32 api_id);
> +u32 zynqmp_pm_get_bootmode_reg(void);
>
> /* Type of Config Object */
> #define PM_CONFIG_OBJECT_TYPE_BASE 0x1U
> @@ -500,4 +501,7 @@ struct zynqmp_ipi_msg {
> u32 *buf;
> };
>
> +#define CRP_BOOT_MODE_REG_NODE 0x30000001
> +#define CRP_BOOT_MODE_REG_OFFSET 0x200
> +
> #endif /* _ZYNQMP_FIRMWARE_H_ */
Applied.
M
More information about the U-Boot
mailing list