[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