From 3ae28aa44ed1f46bfa71c5aed3a6e67b17aed422 Mon Sep 17 00:00:00 2001 From: Jay Buddhabhatti Date: Tue, 28 Feb 2023 02:22:02 -0800 Subject: [PATCH] refactor(versal): move set wake src fn to common place Moved pm_client_set_wakeup_sources() to make common for both Versal and Versal NET platforms. Signed-off-by: Jay Buddhabhatti Change-Id: Ib82c5f85a0a27bc47940f6796f1cf68b2c38a908 --- plat/xilinx/common/include/pm_api_sys.h | 1 + plat/xilinx/common/include/pm_client.h | 6 +- plat/xilinx/common/pm_service/pm_api_sys.c | 65 +++++++++++++++++-- plat/xilinx/versal/include/platform_def.h | 2 + plat/xilinx/versal/pm_service/pm_client.c | 54 +-------------- plat/xilinx/versal_net/include/platform_def.h | 2 + 6 files changed, 72 insertions(+), 58 deletions(-) diff --git a/plat/xilinx/common/include/pm_api_sys.h b/plat/xilinx/common/include/pm_api_sys.h index e7b1567dd..baed43d6b 100644 --- a/plat/xilinx/common/include/pm_api_sys.h +++ b/plat/xilinx/common/include/pm_api_sys.h @@ -40,6 +40,7 @@ enum pm_ret_status pm_set_wakeup_source(uint32_t target, uint32_t device_id, uint8_t enable, uint32_t flag); enum pm_ret_status pm_get_callbackdata(uint32_t *data, size_t count, uint32_t flag, uint32_t ack); +void pm_client_set_wakeup_sources(uint32_t node_id); enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param, uint32_t value, uint32_t flag); enum pm_ret_status pm_pll_get_param(uint32_t clk_id, uint32_t param, diff --git a/plat/xilinx/common/include/pm_client.h b/plat/xilinx/common/include/pm_client.h index eae1d9860..8bf4ae3e2 100644 --- a/plat/xilinx/common/include/pm_client.h +++ b/plat/xilinx/common/include/pm_client.h @@ -1,7 +1,7 @@ /* * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2020-2022, Xilinx, Inc. All rights reserved. - * Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -22,6 +22,10 @@ void pm_client_suspend(const struct pm_proc *proc, uint32_t state); void pm_client_abort_suspend(void); void pm_client_wakeup(const struct pm_proc *proc); +#if !defined(PLAT_zynqmp) +enum pm_device_node_idx irq_to_pm_node_idx(uint32_t irq); +#endif + /* Global variables to be set in pm_client.c */ extern const struct pm_proc *primary_proc; diff --git a/plat/xilinx/common/pm_service/pm_api_sys.c b/plat/xilinx/common/pm_service/pm_api_sys.c index 6ff61af9e..2122d98f3 100644 --- a/plat/xilinx/common/pm_service/pm_api_sys.c +++ b/plat/xilinx/common/pm_service/pm_api_sys.c @@ -10,14 +10,20 @@ * IPI interrupts */ +#include +#include +#include +#include +#include +#include +#include #include +#include #include -#include -#include "pm_api_sys.h" -#include "pm_client.h" -#include "pm_defs.h" #include "pm_svc_main.h" +#define NUM_GICD_ISENABLER ((IRQ_MAX >> 5U) + 1U) + /* default shutdown/reboot scope is system(2) */ static uint32_t pm_shutdown_scope = XPM_SHUTDOWN_SUBTYPE_RST_SYSTEM; @@ -33,6 +39,57 @@ uint32_t pm_get_shutdown_scope(void) /* PM API functions */ +/** + * pm_client_set_wakeup_sources - Set all devices with enabled interrupts as + * wake sources in the XilPM. + * @node_id: Node id of processor + */ +void pm_client_set_wakeup_sources(uint32_t node_id) +{ + uint32_t reg_num, device_id; + uint8_t pm_wakeup_nodes_set[XPM_NODEIDX_DEV_MAX] = {0U}; + uintptr_t isenabler1 = PLAT_GICD_BASE_VALUE + GICD_ISENABLER + 4U; + + zeromem(&pm_wakeup_nodes_set, (u_register_t)sizeof(pm_wakeup_nodes_set)); + + for (reg_num = 0U; reg_num < NUM_GICD_ISENABLER; reg_num++) { + uint32_t base_irq = reg_num << ISENABLER_SHIFT; + uint32_t reg = mmio_read_32(isenabler1 + (reg_num << 2)); + + if (reg == 0U) { + continue; + } + + while (reg != 0U) { + enum pm_device_node_idx node_idx; + uint32_t idx, irq, lowest_set = reg & (-reg); + enum pm_ret_status ret; + + idx = __builtin_ctz(lowest_set); + irq = base_irq + idx; + + if (irq > IRQ_MAX) { + break; + } + + node_idx = irq_to_pm_node_idx(irq); + reg &= ~lowest_set; + + if ((node_idx > XPM_NODEIDX_DEV_MIN) && (node_idx < XPM_NODEIDX_DEV_MAX)) { + if (pm_wakeup_nodes_set[node_idx] == 0U) { + /* Get device ID from node index */ + device_id = PERIPH_DEVID(node_idx); + ret = pm_set_wakeup_source(node_id, + device_id, 1U, + SECURE_FLAG); + pm_wakeup_nodes_set[node_idx] = (ret == PM_RET_SUCCESS) ? + 1U : 0U; + } + } + } + } +} + /** * pm_handle_eemi_call() - PM call for processor to send eemi payload * @flag 0 - Call from secure source diff --git a/plat/xilinx/versal/include/platform_def.h b/plat/xilinx/versal/include/platform_def.h index e47a6b599..bd23bfb88 100644 --- a/plat/xilinx/versal/include/platform_def.h +++ b/plat/xilinx/versal/include/platform_def.h @@ -102,4 +102,6 @@ INTR_PROP_DESC(PLAT_VERSAL_IPI_IRQ, GIC_HIGHEST_SEC_PRIORITY, grp, \ GIC_INTR_CFG_EDGE), \ +#define IRQ_MAX 142U + #endif /* PLATFORM_DEF_H */ diff --git a/plat/xilinx/versal/pm_service/pm_client.c b/plat/xilinx/versal/pm_service/pm_client.c index 7910d8fc1..d61788dc3 100644 --- a/plat/xilinx/versal/pm_service/pm_client.c +++ b/plat/xilinx/versal/pm_service/pm_client.c @@ -25,8 +25,6 @@ #include "pm_defs.h" #define UNDEFINED_CPUID (~0) -#define IRQ_MAX 142U -#define NUM_GICD_ISENABLER ((IRQ_MAX >> 5U) + 1U) DEFINE_BAKERY_LOCK(pm_client_secure_lock); @@ -106,62 +104,12 @@ static enum pm_device_node_idx irq_node_map[IRQ_MAX + 1] = { * * Return: PM node index corresponding to the specified interrupt */ -static enum pm_device_node_idx irq_to_pm_node_idx(uint32_t irq) +enum pm_device_node_idx irq_to_pm_node_idx(uint32_t irq) { assert(irq <= IRQ_MAX); return irq_node_map[irq]; } -/** - * pm_client_set_wakeup_sources - Set all devices with enabled interrupts as - * wake sources in the LibPM. - * @node_id: Node id of processor - */ -static void pm_client_set_wakeup_sources(uint32_t node_id) -{ - uint32_t reg_num; - uint32_t device_id; - uint8_t pm_wakeup_nodes_set[XPM_NODEIDX_DEV_MAX] = { 0U }; - uintptr_t isenabler1 = PLAT_GICD_BASE_VALUE + GICD_ISENABLER + 4; - - for (reg_num = 0U; reg_num < NUM_GICD_ISENABLER; reg_num++) { - uint32_t base_irq = reg_num << ISENABLER_SHIFT; - uint32_t reg = mmio_read_32(isenabler1 + (reg_num << 2)); - - if (reg == 0U) { - continue; - } - - while (reg != 0U) { - enum pm_device_node_idx node_idx; - uint32_t idx, irq, lowest_set = reg & (-reg); - enum pm_ret_status ret; - - idx = __builtin_ctz(lowest_set); - irq = base_irq + idx; - - if (irq > IRQ_MAX) { - break; - } - - node_idx = irq_to_pm_node_idx(irq); - reg &= ~lowest_set; - - if (node_idx > XPM_NODEIDX_DEV_MIN && node_idx < XPM_NODEIDX_DEV_MAX) { - if (pm_wakeup_nodes_set[node_idx] == 0U) { - /* Get device ID from node index */ - device_id = PERIPH_DEVID(node_idx); - ret = pm_set_wakeup_source(node_id, - device_id, 1, - SECURE_FLAG); - pm_wakeup_nodes_set[node_idx] = (ret == PM_RET_SUCCESS) ? - 1 : 0; - } - } - } - } -} - /** * pm_client_suspend() - Client-specific suspend actions * diff --git a/plat/xilinx/versal_net/include/platform_def.h b/plat/xilinx/versal_net/include/platform_def.h index 4ce2cc8b5..f74cb1e60 100644 --- a/plat/xilinx/versal_net/include/platform_def.h +++ b/plat/xilinx/versal_net/include/platform_def.h @@ -114,4 +114,6 @@ INTR_PROP_DESC(PLAT_VERSAL_IPI_IRQ, GIC_HIGHEST_SEC_PRIORITY, grp, \ GIC_INTR_CFG_EDGE), \ +#define IRQ_MAX 200U + #endif /* PLATFORM_DEF_H */