diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.c b/plat/xilinx/versal/pm_service/pm_api_sys.c index dd69f0679..3e7e8d15e 100644 --- a/plat/xilinx/versal/pm_service/pm_api_sys.c +++ b/plat/xilinx/versal/pm_service/pm_api_sys.c @@ -159,6 +159,34 @@ enum pm_ret_status pm_req_suspend(uint32_t target, uint8_t ack, return pm_ipi_send(primary_proc, payload); } +/** + * pm_req_wakeup() - PM call for processor to wake up selected processor + * or subsystem + * @target Device ID of the processor or subsystem to wake up + * @set_address Resume address presence indicator + * 1 - resume address specified, 0 - otherwise + * @address Resume address + * @ack Flag to specify whether acknowledge requested + * + * This API function is either used to power up another APU core for SMP + * (by PSCI) or to power up an entirely different PU or subsystem, such + * as RPU0, RPU, or PL_CORE_xx. Resume address for the target PU will be + * automatically set by PMC. + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_req_wakeup(uint32_t target, uint32_t set_address, + uintptr_t address, uint8_t ack) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC to perform the wake of the PU */ + PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, PM_REQ_WAKEUP, target, + set_address, address, ack); + + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); +} + /** * pm_request_device() - Request a device * @device_id Device ID diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.h b/plat/xilinx/versal/pm_service/pm_api_sys.h index 04074b18e..91d3368f9 100644 --- a/plat/xilinx/versal/pm_service/pm_api_sys.h +++ b/plat/xilinx/versal/pm_service/pm_api_sys.h @@ -24,6 +24,8 @@ enum pm_ret_status pm_req_suspend(uint32_t target, uint8_t ack, unsigned int latency, unsigned int state); +enum pm_ret_status pm_req_wakeup(uint32_t target, uint32_t set_address, + uintptr_t address, uint8_t ack); enum pm_ret_status pm_request_device(uint32_t device_id, uint32_t capabilities, uint32_t qos, uint32_t ack); enum pm_ret_status pm_release_device(uint32_t device_id); diff --git a/plat/xilinx/versal/pm_service/pm_defs.h b/plat/xilinx/versal/pm_service/pm_defs.h index e8a3f3dbd..cfb1ca6cf 100644 --- a/plat/xilinx/versal/pm_service/pm_defs.h +++ b/plat/xilinx/versal/pm_service/pm_defs.h @@ -29,6 +29,7 @@ #define PM_SELF_SUSPEND 7U #define PM_FORCE_POWERDOWN 8U #define PM_ABORT_SUSPEND 9U +#define PM_REQ_WAKEUP 10U #define PM_SYSTEM_SHUTDOWN 12U #define PM_REQUEST_DEVICE 13U #define PM_RELEASE_DEVICE 14U diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.c b/plat/xilinx/versal/pm_service/pm_svc_main.c index 9e7a5885e..bd3ebf3bd 100644 --- a/plat/xilinx/versal/pm_service/pm_svc_main.c +++ b/plat/xilinx/versal/pm_service/pm_svc_main.c @@ -107,6 +107,10 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, ret = pm_system_shutdown(pm_arg[0], pm_arg[1]); SMC_RET1(handle, (uint64_t)ret); + case PM_REQ_WAKEUP: + ret = pm_req_wakeup(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3]); + SMC_RET1(handle, (uint64_t)ret); + case PM_REQUEST_DEVICE: ret = pm_request_device(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3]);