mirror of
https://github.com/u-boot/u-boot.git
synced 2024-11-27 22:56:49 +08:00
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>
This commit is contained in:
parent
0f3604a2b3
commit
866225f394
@ -9,7 +9,6 @@
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <zynqmp_firmware.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
@ -108,28 +107,3 @@ int reserve_mmu(void)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int versal_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
|
||||
u32 arg3, u32 *ret_payload)
|
||||
{
|
||||
struct pt_regs regs;
|
||||
|
||||
if (current_el() == 3)
|
||||
return 0;
|
||||
|
||||
regs.regs[0] = PM_SIP_SVC | api_id;
|
||||
regs.regs[1] = ((u64)arg1 << 32) | arg0;
|
||||
regs.regs[2] = ((u64)arg3 << 32) | arg2;
|
||||
|
||||
smc_call(®s);
|
||||
|
||||
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];
|
||||
}
|
||||
|
@ -12,6 +12,3 @@ enum {
|
||||
|
||||
void tcm_init(u8 mode);
|
||||
void mem_map_fill(void);
|
||||
|
||||
int versal_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
|
||||
u32 arg3, u32 *ret_payload);
|
||||
|
@ -154,32 +154,6 @@ unsigned int zynqmp_get_silicon_version(void)
|
||||
#define ZYNQMP_MMIO_READ 0xC2000014
|
||||
#define ZYNQMP_MMIO_WRITE 0xC2000013
|
||||
|
||||
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;
|
||||
|
||||
regs.regs[0] = pm_api_id;
|
||||
regs.regs[1] = ((u64)arg1 << 32) | arg0;
|
||||
regs.regs[2] = ((u64)arg3 << 32) | arg2;
|
||||
|
||||
smc_call(®s);
|
||||
|
||||
if (ret_payload != NULL) {
|
||||
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];
|
||||
}
|
||||
|
||||
static int zynqmp_mmio_rawwrite(const u32 address,
|
||||
const u32 mask,
|
||||
const u32 value)
|
||||
@ -211,28 +185,34 @@ int zynqmp_mmio_write(const u32 address,
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3)
|
||||
return zynqmp_mmio_rawwrite(address, mask, value);
|
||||
#if defined(CONFIG_ZYNQMP_FIRMWARE)
|
||||
else
|
||||
return invoke_smc(ZYNQMP_MMIO_WRITE, address, mask,
|
||||
value, 0, NULL);
|
||||
#endif
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int zynqmp_mmio_read(const u32 address, u32 *value)
|
||||
{
|
||||
u32 ret_payload[PAYLOAD_ARG_CNT];
|
||||
u32 ret;
|
||||
u32 ret = -EINVAL;
|
||||
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
return ret;
|
||||
|
||||
if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) {
|
||||
ret = zynqmp_mmio_rawread(address, value);
|
||||
} else {
|
||||
}
|
||||
#if defined(CONFIG_ZYNQMP_FIRMWARE)
|
||||
else {
|
||||
u32 ret_payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
ret = invoke_smc(ZYNQMP_MMIO_READ, address, 0, 0,
|
||||
0, ret_payload);
|
||||
*value = ret_payload[1];
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -50,8 +50,6 @@ void handoff_setup(void);
|
||||
|
||||
int zynqmp_mmio_write(const u32 address, const u32 mask, const u32 value);
|
||||
int zynqmp_mmio_read(const u32 address, u32 *value);
|
||||
int invoke_smc(u32 pm_api_id, u32 arg0, u32 arg1, u32 arg2, u32 arg3,
|
||||
u32 *ret_payload);
|
||||
|
||||
void initialize_tcm(bool mode);
|
||||
void mem_map_fill(void);
|
||||
|
@ -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(®s);
|
||||
|
||||
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"},
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <memalign.h>
|
||||
#include <versalpl.h>
|
||||
#include <zynqmp_firmware.h>
|
||||
|
||||
static ulong versal_align_dma_buffer(ulong *buf, u32 len)
|
||||
{
|
||||
|
@ -81,5 +81,9 @@ enum pm_api_id {
|
||||
|
||||
unsigned int zynqmp_firmware_version(void);
|
||||
void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size);
|
||||
int invoke_smc(u32 pm_api_id, u32 arg0, u32 arg1, u32 arg2, u32 arg3,
|
||||
u32 *ret_payload);
|
||||
int versal_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
|
||||
u32 arg3, u32 *ret_payload);
|
||||
|
||||
#endif /* _ZYNQMP_FIRMWARE_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user