roundup(sizeof(struct zynqmp_aes), ARCH_DMA_MINALIGN));
ret = xilinx_pm_request(PM_SECURE_AES, upper_32_bits((ulong)aes),
- lower_32_bits((ulong)aes), 0, 0, ret_payload);
+ lower_32_bits((ulong)aes), 0, 0, 0, 0,
+ ret_payload);
if (ret || ret_payload[1]) {
printf("Failed: AES op status:0x%x, errcode:0x%x\n",
ret, ret_payload[1]);
#if defined(CONFIG_ZYNQMP_FIRMWARE)
else
return xilinx_pm_request(PM_MMIO_WRITE, address, mask,
- value, 0, NULL);
+ value, 0, 0, 0, NULL);
#endif
return -EINVAL;
u32 ret_payload[PAYLOAD_ARG_CNT];
ret = xilinx_pm_request(PM_MMIO_READ, address, 0, 0,
- 0, ret_payload);
+ 0, 0, 0, ret_payload);
*value = ret_payload[1];
}
#endif
}
ret = xilinx_pm_request(PM_SECURE_IMAGE, src_lo, src_hi,
- key_lo, key_hi, ret_payload);
+ key_lo, key_hi, 0, 0, ret_payload);
if (ret) {
printf("Failed: secure op status:0x%x\n", ret);
} else {
ret = xilinx_pm_request(PM_SECURE_RSA, upper_32_bits((ulong)srcaddr),
lower_32_bits((ulong)srcaddr), srclen, rsaop,
- ret_payload);
+ 0, 0, ret_payload);
if (ret || ret_payload[1]) {
printf("Failed: RSA status:0x%x, errcode:0x%x\n",
ret, ret_payload[1]);
srcaddr + roundup(srclen, ARCH_DMA_MINALIGN));
ret = xilinx_pm_request(PM_SECURE_SHA, 0, 0, 0,
- ZYNQMP_SHA3_INIT, ret_payload);
+ ZYNQMP_SHA3_INIT, 0, 0, ret_payload);
if (ret || ret_payload[1]) {
printf("Failed: SHA INIT status:0x%x, errcode:0x%x\n",
ret, ret_payload[1]);
ret = xilinx_pm_request(PM_SECURE_SHA, upper_32_bits((ulong)srcaddr),
lower_32_bits((ulong)srcaddr),
- srclen, ZYNQMP_SHA3_UPDATE, ret_payload);
+ srclen, ZYNQMP_SHA3_UPDATE, 0, 0, ret_payload);
if (ret || ret_payload[1]) {
printf("Failed: SHA UPDATE status:0x%x, errcode:0x%x\n",
ret, ret_payload[1]);
ret = xilinx_pm_request(PM_SECURE_SHA, upper_32_bits((ulong)hashaddr),
lower_32_bits((ulong)hashaddr),
ZYNQMP_SHA3_SIZE, ZYNQMP_SHA3_FINAL,
- ret_payload);
+ 0, 0, ret_payload);
if (ret || ret_payload[1]) {
printf("Failed: SHA FINAL status:0x%x, errcode:0x%x\n",
ret, ret_payload[1]);
* will send command over IPI and requires pmufw to be present.
*/
xilinx_pm_request(PM_RESET_ASSERT, ZYNQMP_PM_RESET_SOFT,
- PM_RESET_ACTION_ASSERT, 0, 0, NULL);
+ PM_RESET_ACTION_ASSERT, 0, 0, 0, 0, NULL);
}
#endif
int ret;
ret = smc_call_handler(PM_QUERY_DATA, qdata.qid, qdata.arg1, qdata.arg2,
- qdata.arg3, ret_payload);
+ qdata.arg3, 0, 0, ret_payload);
return qdata.qid == PM_QID_CLOCK_GET_NAME ? 0 : ret;
}
u32 ret_payload[PAYLOAD_ARG_CNT];
u32 div;
- xilinx_pm_request(PM_CLOCK_GETDIVIDER, clk_id, 0, 0, 0, ret_payload);
+ xilinx_pm_request(PM_CLOCK_GETDIVIDER, clk_id, 0, 0, 0, 0, 0,
+ ret_payload);
div = ret_payload[1];
return div;
{
u32 ret_payload[PAYLOAD_ARG_CNT];
- xilinx_pm_request(PM_CLOCK_SETDIVIDER, clk_id, div, 0, 0, ret_payload);
+ xilinx_pm_request(PM_CLOCK_SETDIVIDER, clk_id, div, 0, 0, 0, 0,
+ ret_payload);
return div;
}
if (versal_clock_mux(clk_id)) {
xilinx_pm_request(PM_CLOCK_GETPARENT, clk_id, 0, 0, 0,
- ret_payload);
+ 0, 0, ret_payload);
parent_id = ret_payload[1];
}
u32 parent_rate, parent_id, parent_ref_clk_id;
u32 id = clk_id & 0xFFF;
- xilinx_pm_request(PM_CLOCK_GETSTATE, clk_id, 0, 0, 0, ret_payload);
+ xilinx_pm_request(PM_CLOCK_GETSTATE, clk_id, 0, 0, 0, 0, 0,
+ ret_payload);
res = ret_payload[1];
if (!res) {
printf("0%x PLL not enabled\n", clk_id);
parent_ref_clk_id = versal_clock_get_parentid(parent_id);
parent_rate = versal_clock_get_ref_rate(parent_ref_clk_id);
- xilinx_pm_request(PM_CLOCK_GETDIVIDER, clk_id, 0, 0, 0, ret_payload);
+ xilinx_pm_request(PM_CLOCK_GETDIVIDER, clk_id, 0, 0, 0, 0, 0,
+ ret_payload);
fbdiv = ret_payload[1];
- xilinx_pm_request(PM_CLOCK_PLL_GETPARAM, clk_id, 2, 0, 0, ret_payload);
+ xilinx_pm_request(PM_CLOCK_PLL_GETPARAM, clk_id, 2, 0, 0, 0, 0,
+ ret_payload);
frac = ret_payload[1];
freq = (fbdiv * parent_rate) >> (1 << frac);
clk_id = priv->clk[clk->id].clk_id;
- if (versal_clock_gate(clk_id))
- return xilinx_pm_request(PM_CLOCK_ENABLE, clk_id, 0, 0, 0, NULL);
+ if (versal_clock_gate(clk_id)) {
+ return xilinx_pm_request(PM_CLOCK_ENABLE, clk_id, 0, 0, 0,
+ 0, 0, NULL);
+ }
return 0;
}
* Xilinx Zynq MPSoC Firmware driver
*
* Copyright (C) 2018-2019 Xilinx, Inc.
+ * Copyright (C) 2022 - 2025, Advanced Micro Devices, Inc.
*/
#include <asm/arch/hardware.h>
if (pm_api_version == ZYNQMP_PM_VERSION_INVALID) {
ret = xilinx_pm_request(PM_GET_API_VERSION, 0, 0, 0, 0,
- ret_payload);
+ 0, 0, ret_payload);
if (ret)
panic("PMUFW is not found - Please load it!\n");
int ret;
ret = xilinx_pm_request(PM_IOCTL, node, IOCTL_SET_GEM_CONFIG,
- config, value, NULL);
+ config, value, 0, 0, NULL);
if (ret)
printf("%s: node %d: set_gem_config %d failed\n",
__func__, node, config);
int ret;
ret = xilinx_pm_request(PM_IOCTL, node, IOCTL_SET_SD_CONFIG,
- config, value, NULL);
+ config, value, 0, 0, NULL);
if (ret)
printf("%s: node %d: set_sd_config %d failed\n",
__func__, node, config);
}
ret = xilinx_pm_request(PM_IOCTL, CRP_BOOT_MODE_REG_NODE, IOCTL_READ_REG,
- CRP_BOOT_MODE_REG_OFFSET, 0, ret_payload);
+ CRP_BOOT_MODE_REG_OFFSET, 0, 0, 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);
}
ret = xilinx_pm_request(PM_IOCTL, PM_REG_PMC_GLOBAL_NODE, IOCTL_READ_REG,
- PMC_MULTI_BOOT_MODE_REG_OFFSET, 0, ret_payload);
+ PMC_MULTI_BOOT_MODE_REG_OFFSET, 0, 0, 0,
+ ret_payload);
if (ret) {
printf("%s: node 0x%x: get_bootmode 0x%x failed\n",
__func__, PM_REG_PMC_GLOBAL_NODE, PMC_MULTI_BOOT_MODE_REG_OFFSET);
/* Check feature check API version */
ret = xilinx_pm_request(PM_FEATURE_CHECK, api_id, 0, 0, 0,
- ret_payload);
+ 0, 0, ret_payload);
if (ret)
return ret;
/* Check feature check API version */
ret = xilinx_pm_request(PM_FEATURE_CHECK, PM_FEATURE_CHECK, 0, 0, 0,
- ret_payload);
+ 0, 0, ret_payload);
if (ret)
return ret;
*/
ret = xilinx_pm_request(PM_FEATURE_CHECK, api_id, 0, 0, 0,
- ret_payload);
+ 0, 0, ret_payload);
if (ret)
return ret;
flush_dcache_range((ulong)cfg_obj, (ulong)(cfg_obj + size));
err = xilinx_pm_request(PM_SET_CONFIGURATION, (u32)(u64)cfg_obj, 0, 0,
- 0, ret_payload);
+ 0, 0, 0, ret_payload);
if (err == XST_PM_NO_ACCESS) {
return -EACCES;
}
smc_call_handler_t __data smc_call_handler;
static int smc_call_legacy(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
- u32 arg3, u32 *ret_payload)
+ u32 arg3, u32 arg4, u32 arg5, u32 *ret_payload)
{
struct pt_regs regs;
regs.regs[0] = PM_SIP_SVC | api_id;
regs.regs[1] = ((u64)arg1 << 32) | arg0;
regs.regs[2] = ((u64)arg3 << 32) | arg2;
+ regs.regs[3] = arg4;
smc_call(®s);
ret_payload[2] = (u32)regs.regs[1];
ret_payload[3] = upper_32_bits(regs.regs[1]);
ret_payload[4] = (u32)regs.regs[2];
+ ret_payload[5] = upper_32_bits((u32)regs.regs[2]);
+ ret_payload[6] = (u32)regs.regs[3];
}
return (ret_payload) ? ret_payload[0] : 0;
}
int __maybe_unused xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
- u32 arg3, u32 *ret_payload)
+ u32 arg3, u32 arg4, u32 arg5, u32 *ret_payload)
{
- debug("%s at EL%d, API ID: 0x%0x, 0x%0x, 0x%0x, 0x%0x, 0x%0x\n",
- __func__, current_el(), api_id, arg0, arg1, arg2, arg3);
+ debug("%s at EL%d, API ID: 0x%0x, 0x%0x, 0x%0x, 0x%0x, 0x%0x, 0x%0x, 0x%0x\n",
+ __func__, current_el(), api_id, arg0, arg1, arg2, arg3, arg4, arg5);
if (IS_ENABLED(CONFIG_XPL_BUILD) || current_el() == 3) {
#if defined(CONFIG_ZYNQMP_IPI)
* is capable to handle PMUFW_PAYLOAD_ARG_CNT bytes but the
* firmware API is limited by the SMC call size
*/
- u32 regs[] = {api_id, arg0, arg1, arg2, arg3};
+ u32 regs[] = {api_id, arg0, arg1, arg2, arg3, arg4, arg5};
int ret;
if (api_id == PM_FPGA_LOAD) {
#endif
}
- return smc_call_handler(api_id, arg0, arg1, arg2, arg3, ret_payload);
+ return smc_call_handler(api_id, arg0, arg1, arg2, arg3, arg4,
+ arg5, ret_payload);
}
static const struct udevice_id zynqmp_firmware_ids[] = {
buf_lo = lower_32_bits(bin_buf);
buf_hi = upper_32_bits(bin_buf);
-
if (desc->family == xilinx_versal2) {
ret = xilinx_pm_request(VERSAL_PM_LOAD_PDI, VERSAL_PM_PDI_TYPE, buf_hi,
- buf_lo, 0, ret_payload);
+ buf_lo, 0, 0, 0, ret_payload);
} else {
ret = xilinx_pm_request(VERSAL_PM_LOAD_PDI, VERSAL_PM_PDI_TYPE, buf_lo,
- buf_hi, 0, ret_payload);
+ buf_hi, 0, 0, 0, ret_payload);
}
if (ret)
buf_hi = upper_32_bits(bin_buf);
ret = xilinx_pm_request(PM_FPGA_LOAD, buf_lo, buf_hi,
- bsize_req, bstype, ret_payload);
+ bsize_req, bstype, 0, 0, ret_payload);
if (ret)
printf("PL FPGA LOAD failed with err: 0x%08x\n", ret);
ret = xilinx_pm_request(PM_FPGA_LOAD, buf_lo,
buf_hi,
(u32)(uintptr_t)fpga_sec_info->userkey_addr,
- flag, ret_payload);
+ flag, 0, 0, ret_payload);
else
ret = xilinx_pm_request(PM_FPGA_LOAD, buf_lo,
buf_hi, (u32)bsize,
- flag, ret_payload);
+ flag, 0, 0, ret_payload);
if (ret)
puts("PL FPGA LOAD fail\n");
u32 ret_payload[PAYLOAD_ARG_CNT];
ret = xilinx_pm_request(PM_FPGA_GET_STATUS, 0, 0, 0,
- 0, ret_payload);
+ 0, 0, 0, ret_payload);
if (!ret)
printf("PCAP status\t0x%x\n", ret_payload[1]);
static int get_gpio_modepin(u32 *ret_payload)
{
return xilinx_pm_request(PM_MMIO_READ, ZYNQMP_CRL_APB_BOOT_PIN_CTRL,
- 0, 0, 0, ret_payload);
+ 0, 0, 0, 0, 0, ret_payload);
}
static int set_gpio_modepin(int val)
{
return xilinx_pm_request(PM_MMIO_WRITE, ZYNQMP_CRL_APB_BOOT_PIN_CTRL,
ZYNQMP_CRL_APB_BOOTPIN_CTRL_MASK,
- val, 0, NULL);
+ val, 0, 0, 0, NULL);
}
static int modepin_gpio_direction_input(struct udevice *dev,
}
__weak int xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
- u32 arg3, u32 *ret_payload)
+ u32 arg3, u32 arg4, u32 arg5, u32 *ret_payload)
{
return 0;
}
} else {
return xilinx_pm_request(PM_IOCTL, node_id,
IOCTL_SET_SD_TAPDELAY,
- PM_TAPDELAY_INPUT, itap_delay, NULL);
+ PM_TAPDELAY_INPUT, itap_delay, 0, 0,
+ NULL);
}
return 0;
} else {
return xilinx_pm_request(PM_IOCTL, node_id,
IOCTL_SET_SD_TAPDELAY,
- PM_TAPDELAY_OUTPUT, otap_delay, NULL);
+ PM_TAPDELAY_OUTPUT, otap_delay, 0, 0,
+ NULL);
}
}
SD1_DLL_RST : 0);
} else {
return xilinx_pm_request(PM_IOCTL, node_id,
- IOCTL_SD_DLL_RESET, type, 0, NULL);
+ IOCTL_SD_DLL_RESET, type, 0, 0, 0,
+ NULL);
}
}
ret = xilinx_pm_request(PM_REQUEST_NODE, priv->node_id,
ZYNQMP_PM_CAPABILITY_ACCESS, ZYNQMP_PM_MAX_QOS,
- ZYNQMP_PM_REQUEST_ACK_NO, NULL);
+ ZYNQMP_PM_REQUEST_ACK_NO, 0, 0, NULL);
if (ret) {
dev_err(dev, "Request node failed for %d\n", priv->node_id);
return ret;
int ret;
u32 ret_payload[PAYLOAD_ARG_CNT];
- ret = xilinx_pm_request(PM_QUERY_DATA, qid, arg1, arg2, 0, ret_payload);
+ ret = xilinx_pm_request(PM_QUERY_DATA, qid, arg1, arg2, 0, 0,
+ 0, ret_payload);
if (ret)
return ret;
u32 ret_payload[PAYLOAD_ARG_CNT];
/* Get config for the pin */
- ret = xilinx_pm_request(PM_PINCTRL_CONFIG_PARAM_GET, pin, param, 0, 0, ret_payload);
+ ret = xilinx_pm_request(PM_PINCTRL_CONFIG_PARAM_GET, pin, param, 0, 0, 0,
+ 0, ret_payload);
if (ret) {
printf("%s failed\n", __func__);
return ret;
}
/* Request the pin first */
- ret = xilinx_pm_request(PM_PINCTRL_REQUEST, pin, 0, 0, 0, NULL);
+ ret = xilinx_pm_request(PM_PINCTRL_REQUEST, pin, 0, 0, 0, 0, 0, NULL);
if (ret) {
printf("%s: pin request failed\n", __func__);
return ret;
}
/* Set config for the pin */
- ret = xilinx_pm_request(PM_PINCTRL_CONFIG_PARAM_SET, pin, param, value, 0, NULL);
+ ret = xilinx_pm_request(PM_PINCTRL_CONFIG_PARAM_SET, pin, param, value,
+ 0, 0, 0, NULL);
if (ret) {
printf("%s failed\n", __func__);
return ret;
u32 ret_payload[PAYLOAD_ARG_CNT];
ret = xilinx_pm_request(PM_QUERY_DATA, PM_QID_PINCTRL_GET_FUNCTION_GROUPS,
- fid, index, 0, ret_payload);
+ fid, index, 0, 0, 0, ret_payload);
if (ret) {
printf("%s failed\n", __func__);
return ret;
u32 ret_payload[PAYLOAD_ARG_CNT];
ret = xilinx_pm_request(PM_QUERY_DATA, PM_QID_PINCTRL_GET_PIN_GROUPS,
- pin, index, 0, ret_payload);
+ pin, index, 0, 0, 0, ret_payload);
if (ret) {
printf("%s failed to get pin groups\n", __func__);
return ret;
for (i = 0; i < priv->nfuncs; i++) {
/* Get function name for the function and fill */
xilinx_pm_request(PM_QUERY_DATA, PM_QID_PINCTRL_GET_FUNCTION_NAME,
- i, 0, 0, ret_payload);
+ i, 0, 0, 0, 0, ret_payload);
memcpy((void *)priv->funcs[i].name, ret_payload, MAX_FUNC_NAME_LEN);
/* And fill number of groups available for certain function */
xilinx_pm_request(PM_QUERY_DATA, PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS,
- i, 0, 0, ret_payload);
+ i, 0, 0, 0, 0, ret_payload);
priv->funcs[i].ngroups = ret_payload[1];
priv->ngroups += priv->funcs[i].ngroups;
int ret;
/* Request the pin first */
- ret = xilinx_pm_request(PM_PINCTRL_REQUEST, selector, 0, 0, 0, NULL);
+ ret = xilinx_pm_request(PM_PINCTRL_REQUEST, selector, 0, 0, 0, 0,
+ 0, NULL);
if (ret) {
printf("%s: pin request failed\n", __func__);
return ret;
/* Set the pin function */
ret = xilinx_pm_request(PM_PINCTRL_SET_FUNCTION, selector, func_selector,
- 0, 0, NULL);
+ 0, 0, 0, 0, NULL);
if (ret) {
printf("%s: Failed to set pinmux function\n", __func__);
return ret;
const u32 qos, const enum zynqmp_pm_request_ack ack)
{
return xilinx_pm_request(PM_REQUEST_NODE, node, capabilities,
- qos, ack, NULL);
+ qos, ack, 0, 0, NULL);
}
static int zynqmp_power_domain_request(struct power_domain *power_domain)
const enum zynqmp_pm_reset_action assert_flag)
{
return xilinx_pm_request(PM_RESET_ASSERT, reset, assert_flag, 0, 0,
- NULL);
+ 0, 0, NULL);
}
static int zynqmp_reset_assert(struct reset_ctl *rst)
if (IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE)) {
ret = xilinx_pm_request(PM_GET_CHIPID, 0, 0, 0, 0,
- ret_payload);
+ 0, 0, ret_payload);
if (ret)
return ret;
} else {
if (IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE)) {
ret = xilinx_pm_request(PM_GET_CHIPID, 0, 0, 0, 0,
- ret_payload);
+ 0, 0, ret_payload);
if (ret)
return ret;
} else {
if (IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE)) {
ret = xilinx_pm_request(PM_GET_CHIPID, 0, 0, 0, 0,
- ret_payload);
+ 0, 0, ret_payload);
if (ret)
return ret;
} else {
ret = zynqmp_mmio_read(ZYNQMP_PS_VERSION, &ret_payload[2]);
else
ret = xilinx_pm_request(PM_GET_CHIPID, 0, 0, 0, 0,
- ret_payload);
+ 0, 0, ret_payload);
if (ret < 0)
return ret;
/* ahb read mode */
xilinx_pm_request(PM_IOCTL, PM_DEV_OSPI,
IOCTL_OSPI_MUX_SELECT,
- PM_OSPI_MUX_SEL_LINEAR, 0, NULL);
+ PM_OSPI_MUX_SEL_LINEAR, 0, 0, 0, NULL);
else
/* DMA mode */
xilinx_pm_request(PM_IOCTL, PM_DEV_OSPI,
IOCTL_OSPI_MUX_SELECT,
- PM_OSPI_MUX_SEL_DMA, 0, NULL);
+ PM_OSPI_MUX_SEL_DMA, 0, 0, 0, NULL);
} else {
if (enable)
writel(readl(VERSAL_AXI_MUX_SEL) |
if (IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE))
xilinx_pm_request(PM_REQUEST_NODE, PM_DEV_OSPI,
ZYNQMP_PM_CAPABILITY_ACCESS, ZYNQMP_PM_MAX_QOS,
- ZYNQMP_PM_REQUEST_ACK_NO, NULL);
+ ZYNQMP_PM_REQUEST_ACK_NO, 0, 0, NULL);
if (priv->ref_clk_hz == 0) {
ret = clk_get_by_index(bus, 0, &clk);
/*
* Return payload size
* Not every firmware call expects the same amount of return bytes, however the
- * firmware driver always copies 5 bytes from RX buffer to the ret_payload
+ * firmware driver always copies 7 words from RX buffer to the ret_payload
* buffer. Therefore allocating with this defined value is recommended to avoid
* overflows.
*/
-#define PAYLOAD_ARG_CNT 5U
+#define PAYLOAD_ARG_CNT 7U
unsigned int zynqmp_firmware_version(void);
int zynqmp_pmufw_node(u32 id);
int zynqmp_pmufw_config_close(void);
int zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size);
int xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
- u32 arg3, u32 *ret_payload);
+ u32 arg3, u32 arg4, u32 arg5, u32 *ret_payload);
int zynqmp_pm_set_sd_config(u32 node, enum pm_sd_config_type config, u32 value);
int zynqmp_pm_set_gem_config(u32 node, enum pm_gem_config_type config,
u32 value);
#define __data __section(".data")
typedef int (*smc_call_handler_t)(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
- u32 arg3, u32 *ret_payload);
+ u32 arg3, u32 arg4, u32 arg5, u32 *ret_payload);
extern smc_call_handler_t __data smc_call_handler;