summaryrefslogtreecommitdiff
path: root/drivers/firmware
diff options
context:
space:
mode:
authorMichal Simek <michal.simek@xilinx.com>2019-10-04 15:45:29 +0200
committerMichal Simek <michal.simek@xilinx.com>2019-10-24 13:37:01 +0200
commit866225f394a9b3174d9ea39d2d19ac0d2c07a516 (patch)
tree888ed3852c5fb966b3468dbbfb7687d7cab76721 /drivers/firmware
parent0f3604a2b3882bc0f6c66cfd5acbd074703a5814 (diff)
arm64: xilinx: Move firmware functions from platform to driver
versal_pm_request() and invoke_smc() are almost the same. Only one difference is that versal_pm_request is adding PM_SIP_SVC offset to api_id. The patch is moving platform implementation to firmware driver code for synchronization. Signed-off-by: Michal Simek <michal.simek@xilinx.com> Reviewed-by: Luca Ceresoli <luca@lucaceresoli.net>
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/firmware-zynqmp.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c
index 15e82ac3b3..840c68d45a 100644
--- a/drivers/firmware/firmware-zynqmp.c
+++ b/drivers/firmware/firmware-zynqmp.c
@@ -7,10 +7,10 @@
#include <common.h>
#include <dm.h>
+#include <zynqmp_firmware.h>
#if defined(CONFIG_ZYNQMP_IPI)
#include <mailbox.h>
-#include <zynqmp_firmware.h>
#include <asm/arch/sys_proto.h>
#define PMUFW_PAYLOAD_ARG_CNT 8
@@ -147,6 +147,42 @@ U_BOOT_DRIVER(zynqmp_power) = {
};
#endif
+int __maybe_unused invoke_smc(u32 pm_api_id, u32 arg0, u32 arg1, u32 arg2,
+ u32 arg3, u32 *ret_payload)
+{
+ /*
+ * Added SIP service call Function Identifier
+ * Make sure to stay in x0 register
+ */
+ struct pt_regs regs;
+
+ if (current_el() == 3)
+ return 0;
+
+ regs.regs[0] = pm_api_id;
+ regs.regs[1] = ((u64)arg1 << 32) | arg0;
+ regs.regs[2] = ((u64)arg3 << 32) | arg2;
+
+ smc_call(&regs);
+
+ if (ret_payload) {
+ ret_payload[0] = (u32)regs.regs[0];
+ ret_payload[1] = upper_32_bits(regs.regs[0]);
+ ret_payload[2] = (u32)regs.regs[1];
+ ret_payload[3] = upper_32_bits(regs.regs[1]);
+ ret_payload[4] = (u32)regs.regs[2];
+ }
+
+ return regs.regs[0];
+}
+
+int __maybe_unused versal_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
+ u32 arg3, u32 *ret_payload)
+{
+ return invoke_smc(PM_SIP_SVC | api_id, arg0, arg1, arg2, arg3,
+ ret_payload);
+}
+
static const struct udevice_id zynqmp_firmware_ids[] = {
{ .compatible = "xlnx,zynqmp-firmware" },
{ .compatible = "xlnx,versal-firmware"},