xilinx: versal: Add request wakeup API

Implement request wakeup API for versal.

Signed-off-by: Tejas Patel <tejas.patel@xilinx.com>
Signed-off-by: Jolly Shah <jolly.shah@xilinx.com>
Change-Id: I40a2a4ea85bf05623ac8a17ef4a6fa329babd27e
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.c b/plat/xilinx/versal/pm_service/pm_api_sys.c
index dd69f06..3e7e8d1 100644
--- a/plat/xilinx/versal/pm_service/pm_api_sys.c
+++ b/plat/xilinx/versal/pm_service/pm_api_sys.c
@@ -160,6 +160,34 @@
 }
 
 /**
+ * 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
  * @capabilities	Requested capabilities for the device
diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.h b/plat/xilinx/versal/pm_service/pm_api_sys.h
index 04074b1..91d3368 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 @@
 				  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 e8a3f3d..cfb1ca6 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 9e7a588..bd3ebf3 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 @@
 		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]);