From 25b1a91033ae3e4220c933333764c01c7a687c2d Mon Sep 17 00:00:00 2001 From: Tejas Patel Date: Wed, 27 Feb 2019 18:44:54 +0530 Subject: [PATCH] xilinx: versal: Add client wakeup API Implement client wakeup API for versal. Signed-off-by: Tejas Patel Signed-off-by: Rajan Vaja Signed-off-by: Jolly Shah Change-Id: I31b1b362fe645a82f89ce2d698ee71eb00cf15dc --- plat/xilinx/versal/pm_service/pm_client.c | 40 +++++++++++++++++++++++ plat/xilinx/versal/pm_service/pm_client.h | 1 + 2 files changed, 41 insertions(+) diff --git a/plat/xilinx/versal/pm_service/pm_client.c b/plat/xilinx/versal/pm_service/pm_client.c index 636b719fd..b234e1bfa 100644 --- a/plat/xilinx/versal/pm_service/pm_client.c +++ b/plat/xilinx/versal/pm_service/pm_client.c @@ -18,6 +18,8 @@ #include #include "pm_client.h" +#define UNDEFINED_CPUID (~0) + DEFINE_BAKERY_LOCK(pm_client_secure_lock); static const struct pm_ipi apu_ipi = { @@ -80,6 +82,44 @@ void pm_client_abort_suspend(void) bakery_lock_release(&pm_client_secure_lock); } +/** + * 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 228094e67..91f135c06 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 */