xilinx: versal: Add client wakeup API

Implement client wakeup API for versal.

Signed-off-by: Tejas Patel <tejas.patel@xilinx.com>
Signed-off-by: Rajan Vaja <rajan.vaja@xilinx.com>
Signed-off-by: Jolly Shah <jolly.shah@xilinx.com>
Change-Id: I31b1b362fe645a82f89ce2d698ee71eb00cf15dc
diff --git a/plat/xilinx/versal/pm_service/pm_client.c b/plat/xilinx/versal/pm_service/pm_client.c
index 636b719..b234e1b 100644
--- a/plat/xilinx/versal/pm_service/pm_client.c
+++ b/plat/xilinx/versal/pm_service/pm_client.c
@@ -18,6 +18,8 @@
 #include <plat/common/platform.h>
 #include "pm_client.h"
 
+#define UNDEFINED_CPUID		(~0)
+
 DEFINE_BAKERY_LOCK(pm_client_secure_lock);
 
 static const struct pm_ipi apu_ipi = {
@@ -81,6 +83,44 @@
 }
 
 /**
+ * pm_get_cpuid() - get the local cpu ID for a global node ID
+ * @nid:	node id of the processor
+ *
+ * Return: the cpu ID (starting from 0) for the subsystem
+ */
+static unsigned int pm_get_cpuid(uint32_t nid)
+{
+	for (size_t i = 0; i < ARRAY_SIZE(pm_procs_all); i++) {
+		if (pm_procs_all[i].node_id == nid)
+			return i;
+	}
+	return UNDEFINED_CPUID;
+}
+
+/**
+ * pm_client_wakeup() - Client-specific wakeup actions
+ *
+ * This function should contain any PU-specific actions
+ * required for waking up another APU core
+ */
+void pm_client_wakeup(const struct pm_proc *proc)
+{
+	unsigned int cpuid = pm_get_cpuid(proc->node_id);
+
+	if (cpuid == UNDEFINED_CPUID)
+		return;
+
+	bakery_lock_get(&pm_client_secure_lock);
+
+	/* clear powerdown bit for affected cpu */
+	uint32_t val = mmio_read_32(FPD_APU_PWRCTL);
+	val &= ~(proc->pwrdn_mask);
+	mmio_write_32(FPD_APU_PWRCTL, val);
+
+	bakery_lock_release(&pm_client_secure_lock);
+}
+
+/**
  * pm_get_proc() - returns pointer to the proc structure
  * @cpuid:	id of the cpu whose proc struct pointer should be returned
  *
diff --git a/plat/xilinx/versal/pm_service/pm_client.h b/plat/xilinx/versal/pm_service/pm_client.h
index 228094e..91f135c 100644
--- a/plat/xilinx/versal/pm_service/pm_client.h
+++ b/plat/xilinx/versal/pm_service/pm_client.h
@@ -17,6 +17,7 @@
 
 /* Functions to be implemented by each PU */
 void pm_client_suspend(const struct pm_proc *proc, unsigned int state);
+void pm_client_wakeup(const struct pm_proc *proc);
 void pm_client_abort_suspend(void);
 
 /* Global variables to be set in pm_client.c */