1414cf08bSSenthil Nathan Thangaraj /* 2414cf08bSSenthil Nathan Thangaraj * Copyright (c) 2022, Xilinx, Inc. All rights reserved. 3414cf08bSSenthil Nathan Thangaraj * Copyright (c) 2022-2025, Advanced Micro Devices, Inc. All rights reserved. 4414cf08bSSenthil Nathan Thangaraj * 5414cf08bSSenthil Nathan Thangaraj * SPDX-License-Identifier: BSD-3-Clause 6414cf08bSSenthil Nathan Thangaraj */ 7414cf08bSSenthil Nathan Thangaraj 8414cf08bSSenthil Nathan Thangaraj /* 9414cf08bSSenthil Nathan Thangaraj * APU specific definition of processors in the subsystem as well as functions 10414cf08bSSenthil Nathan Thangaraj * for getting information about and changing state of the APU. 11414cf08bSSenthil Nathan Thangaraj */ 12414cf08bSSenthil Nathan Thangaraj 13414cf08bSSenthil Nathan Thangaraj #include <assert.h> 14414cf08bSSenthil Nathan Thangaraj 15414cf08bSSenthil Nathan Thangaraj #include <drivers/arm/gic_common.h> 16414cf08bSSenthil Nathan Thangaraj #include <drivers/arm/gicv3.h> 17414cf08bSSenthil Nathan Thangaraj #include <lib/bakery_lock.h> 18414cf08bSSenthil Nathan Thangaraj #include <lib/mmio.h> 19414cf08bSSenthil Nathan Thangaraj #include <lib/spinlock.h> 20414cf08bSSenthil Nathan Thangaraj #include <lib/utils.h> 21414cf08bSSenthil Nathan Thangaraj #include <plat/common/platform.h> 22414cf08bSSenthil Nathan Thangaraj 23414cf08bSSenthil Nathan Thangaraj #include <platform_def.h> 24414cf08bSSenthil Nathan Thangaraj #include "def.h" 25414cf08bSSenthil Nathan Thangaraj #include <plat_ipi.h> 26*4fd510e0SRonak Jain #include <plat_pm_common.h> 27414cf08bSSenthil Nathan Thangaraj #include "pm_api_sys.h" 28414cf08bSSenthil Nathan Thangaraj #include "pm_client.h" 29414cf08bSSenthil Nathan Thangaraj 30414cf08bSSenthil Nathan Thangaraj #define UNDEFINED_CPUID UINT32_MAX 31414cf08bSSenthil Nathan Thangaraj 32414cf08bSSenthil Nathan Thangaraj DEFINE_RENAME_SYSREG_RW_FUNCS(cpu_pwrctrl_val, S3_0_C15_C2_7) 33414cf08bSSenthil Nathan Thangaraj 34414cf08bSSenthil Nathan Thangaraj /* 35414cf08bSSenthil Nathan Thangaraj * ARM v8.2, the cache will turn off automatically when cpu 36414cf08bSSenthil Nathan Thangaraj * power down. Therefore, there is no doubt to use the spin_lock here. 37414cf08bSSenthil Nathan Thangaraj */ 38414cf08bSSenthil Nathan Thangaraj static spinlock_t pm_client_secure_lock; 39414cf08bSSenthil Nathan Thangaraj static inline void pm_client_lock_get(void) 40414cf08bSSenthil Nathan Thangaraj { 41414cf08bSSenthil Nathan Thangaraj spin_lock(&pm_client_secure_lock); 42414cf08bSSenthil Nathan Thangaraj } 43414cf08bSSenthil Nathan Thangaraj 44414cf08bSSenthil Nathan Thangaraj static inline void pm_client_lock_release(void) 45414cf08bSSenthil Nathan Thangaraj { 46414cf08bSSenthil Nathan Thangaraj spin_unlock(&pm_client_secure_lock); 47414cf08bSSenthil Nathan Thangaraj } 48414cf08bSSenthil Nathan Thangaraj 49414cf08bSSenthil Nathan Thangaraj static const struct pm_ipi apu_ipi = { 50414cf08bSSenthil Nathan Thangaraj .local_ipi_id = IPI_LOCAL_ID, 51414cf08bSSenthil Nathan Thangaraj .remote_ipi_id = IPI_REMOTE_ID, 52414cf08bSSenthil Nathan Thangaraj .buffer_base = IPI_BUFFER_LOCAL_BASE, 53414cf08bSSenthil Nathan Thangaraj }; 54414cf08bSSenthil Nathan Thangaraj 55414cf08bSSenthil Nathan Thangaraj /* Order in pm_procs_all array must match cpu ids */ 56414cf08bSSenthil Nathan Thangaraj static const struct pm_proc pm_procs_all[] = { 57414cf08bSSenthil Nathan Thangaraj { 58414cf08bSSenthil Nathan Thangaraj .node_id = PM_DEV_CLUSTER0_ACPU_0, 59414cf08bSSenthil Nathan Thangaraj .ipi = &apu_ipi, 60414cf08bSSenthil Nathan Thangaraj }, 61414cf08bSSenthil Nathan Thangaraj { 62414cf08bSSenthil Nathan Thangaraj .node_id = PM_DEV_CLUSTER0_ACPU_1, 63414cf08bSSenthil Nathan Thangaraj .ipi = &apu_ipi, 64414cf08bSSenthil Nathan Thangaraj }, 65414cf08bSSenthil Nathan Thangaraj { 66414cf08bSSenthil Nathan Thangaraj .node_id = PM_DEV_CLUSTER1_ACPU_0, 67414cf08bSSenthil Nathan Thangaraj .ipi = &apu_ipi, 68414cf08bSSenthil Nathan Thangaraj }, 69414cf08bSSenthil Nathan Thangaraj { 70414cf08bSSenthil Nathan Thangaraj .node_id = PM_DEV_CLUSTER1_ACPU_1, 71414cf08bSSenthil Nathan Thangaraj .ipi = &apu_ipi, 72414cf08bSSenthil Nathan Thangaraj }, 73414cf08bSSenthil Nathan Thangaraj { 74414cf08bSSenthil Nathan Thangaraj .node_id = PM_DEV_CLUSTER2_ACPU_0, 75414cf08bSSenthil Nathan Thangaraj .ipi = &apu_ipi, 76414cf08bSSenthil Nathan Thangaraj }, 77414cf08bSSenthil Nathan Thangaraj { 78414cf08bSSenthil Nathan Thangaraj .node_id = PM_DEV_CLUSTER2_ACPU_1, 79414cf08bSSenthil Nathan Thangaraj .ipi = &apu_ipi, 80414cf08bSSenthil Nathan Thangaraj }, 81414cf08bSSenthil Nathan Thangaraj { 82414cf08bSSenthil Nathan Thangaraj .node_id = PM_DEV_CLUSTER3_ACPU_0, 83414cf08bSSenthil Nathan Thangaraj .ipi = &apu_ipi, 84414cf08bSSenthil Nathan Thangaraj }, 85414cf08bSSenthil Nathan Thangaraj { 86414cf08bSSenthil Nathan Thangaraj .node_id = PM_DEV_CLUSTER3_ACPU_1, 87414cf08bSSenthil Nathan Thangaraj .ipi = &apu_ipi, 88414cf08bSSenthil Nathan Thangaraj }, 89414cf08bSSenthil Nathan Thangaraj }; 90414cf08bSSenthil Nathan Thangaraj 91414cf08bSSenthil Nathan Thangaraj const struct pm_proc *primary_proc = &pm_procs_all[0]; 92414cf08bSSenthil Nathan Thangaraj 93414cf08bSSenthil Nathan Thangaraj /** 94414cf08bSSenthil Nathan Thangaraj * pm_get_proc() - returns pointer to the proc structure. 95414cf08bSSenthil Nathan Thangaraj * @cpuid: id of the cpu whose proc struct pointer should be returned. 96414cf08bSSenthil Nathan Thangaraj * 97414cf08bSSenthil Nathan Thangaraj * Return: Pointer to a proc structure if proc is found, otherwise NULL. 98414cf08bSSenthil Nathan Thangaraj */ 99414cf08bSSenthil Nathan Thangaraj const struct pm_proc *pm_get_proc(uint32_t cpuid) 100414cf08bSSenthil Nathan Thangaraj { 101414cf08bSSenthil Nathan Thangaraj const struct pm_proc *proc = NULL; 102414cf08bSSenthil Nathan Thangaraj 103414cf08bSSenthil Nathan Thangaraj if (cpuid < ARRAY_SIZE(pm_procs_all)) { 104414cf08bSSenthil Nathan Thangaraj proc = &pm_procs_all[cpuid]; 105414cf08bSSenthil Nathan Thangaraj } else { 106414cf08bSSenthil Nathan Thangaraj ERROR("cpuid: %d proc NULL\n", cpuid); 107414cf08bSSenthil Nathan Thangaraj } 108414cf08bSSenthil Nathan Thangaraj 109414cf08bSSenthil Nathan Thangaraj return proc; 110414cf08bSSenthil Nathan Thangaraj } 111414cf08bSSenthil Nathan Thangaraj 112414cf08bSSenthil Nathan Thangaraj /** 113414cf08bSSenthil Nathan Thangaraj * irq_to_pm_node_idx - Get PM node index corresponding to the interrupt number. 114414cf08bSSenthil Nathan Thangaraj * @irq: Interrupt number. 115414cf08bSSenthil Nathan Thangaraj * 116414cf08bSSenthil Nathan Thangaraj * Return: PM node index corresponding to the specified interrupt. 117414cf08bSSenthil Nathan Thangaraj */ 118414cf08bSSenthil Nathan Thangaraj enum pm_device_node_idx irq_to_pm_node_idx(uint32_t irq) 119414cf08bSSenthil Nathan Thangaraj { 120414cf08bSSenthil Nathan Thangaraj enum pm_device_node_idx dev_idx = XPM_NODEIDX_DEV_MIN; 121414cf08bSSenthil Nathan Thangaraj 122414cf08bSSenthil Nathan Thangaraj assert(irq <= IRQ_MAX); 123414cf08bSSenthil Nathan Thangaraj 124414cf08bSSenthil Nathan Thangaraj switch (irq) { 125414cf08bSSenthil Nathan Thangaraj case 11: 126414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_I2C_2; 127414cf08bSSenthil Nathan Thangaraj break; 128414cf08bSSenthil Nathan Thangaraj case 12: 129414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_I2C_3; 130414cf08bSSenthil Nathan Thangaraj break; 131414cf08bSSenthil Nathan Thangaraj case 13: 132414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_I2C_4; 133414cf08bSSenthil Nathan Thangaraj break; 134414cf08bSSenthil Nathan Thangaraj case 20: 135414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_GPIO; 136414cf08bSSenthil Nathan Thangaraj break; 137414cf08bSSenthil Nathan Thangaraj case 21: 138414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_I2C_0; 139414cf08bSSenthil Nathan Thangaraj break; 140414cf08bSSenthil Nathan Thangaraj case 22: 141414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_I2C_1; 142414cf08bSSenthil Nathan Thangaraj break; 143414cf08bSSenthil Nathan Thangaraj case 23: 144414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_SPI_0; 145414cf08bSSenthil Nathan Thangaraj break; 146414cf08bSSenthil Nathan Thangaraj case 24: 147414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_SPI_1; 148414cf08bSSenthil Nathan Thangaraj break; 149414cf08bSSenthil Nathan Thangaraj case 25: 150414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_UART_0; 151414cf08bSSenthil Nathan Thangaraj break; 152414cf08bSSenthil Nathan Thangaraj case 26: 153414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_UART_1; 154414cf08bSSenthil Nathan Thangaraj break; 155414cf08bSSenthil Nathan Thangaraj case 27: 156414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_CAN_FD_0; 157414cf08bSSenthil Nathan Thangaraj break; 158414cf08bSSenthil Nathan Thangaraj case 28: 159414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_CAN_FD_1; 160414cf08bSSenthil Nathan Thangaraj break; 161414cf08bSSenthil Nathan Thangaraj case 29: 162414cf08bSSenthil Nathan Thangaraj case 30: 163414cf08bSSenthil Nathan Thangaraj case 31: 164414cf08bSSenthil Nathan Thangaraj case 32: 165414cf08bSSenthil Nathan Thangaraj case 33: 166414cf08bSSenthil Nathan Thangaraj case 98: 167414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_USB_0; 168414cf08bSSenthil Nathan Thangaraj break; 169414cf08bSSenthil Nathan Thangaraj case 34: 170414cf08bSSenthil Nathan Thangaraj case 35: 171414cf08bSSenthil Nathan Thangaraj case 36: 172414cf08bSSenthil Nathan Thangaraj case 37: 173414cf08bSSenthil Nathan Thangaraj case 38: 174414cf08bSSenthil Nathan Thangaraj case 99: 175414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_USB_1; 176414cf08bSSenthil Nathan Thangaraj break; 177414cf08bSSenthil Nathan Thangaraj case 39: 178414cf08bSSenthil Nathan Thangaraj case 40: 179414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_GEM_0; 180414cf08bSSenthil Nathan Thangaraj break; 181414cf08bSSenthil Nathan Thangaraj case 41: 182414cf08bSSenthil Nathan Thangaraj case 42: 183414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_GEM_1; 184414cf08bSSenthil Nathan Thangaraj break; 185414cf08bSSenthil Nathan Thangaraj case 43: 186414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_TTC_0; 187414cf08bSSenthil Nathan Thangaraj break; 188414cf08bSSenthil Nathan Thangaraj case 44: 189414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_TTC_1; 190414cf08bSSenthil Nathan Thangaraj break; 191414cf08bSSenthil Nathan Thangaraj case 45: 192414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_TTC_2; 193414cf08bSSenthil Nathan Thangaraj break; 194414cf08bSSenthil Nathan Thangaraj case 46: 195414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_TTC_3; 196414cf08bSSenthil Nathan Thangaraj break; 197414cf08bSSenthil Nathan Thangaraj case 47: 198414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_TTC_4; 199414cf08bSSenthil Nathan Thangaraj break; 200414cf08bSSenthil Nathan Thangaraj case 48: 201414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_TTC_5; 202414cf08bSSenthil Nathan Thangaraj break; 203414cf08bSSenthil Nathan Thangaraj case 49: 204414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_TTC_6; 205414cf08bSSenthil Nathan Thangaraj break; 206414cf08bSSenthil Nathan Thangaraj case 50: 207414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_TTC_7; 208414cf08bSSenthil Nathan Thangaraj break; 209414cf08bSSenthil Nathan Thangaraj case 72: 210414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_ADMA_0; 211414cf08bSSenthil Nathan Thangaraj break; 212414cf08bSSenthil Nathan Thangaraj case 73: 213414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_ADMA_1; 214414cf08bSSenthil Nathan Thangaraj break; 215414cf08bSSenthil Nathan Thangaraj case 74: 216414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_ADMA_2; 217414cf08bSSenthil Nathan Thangaraj break; 218414cf08bSSenthil Nathan Thangaraj case 75: 219414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_ADMA_3; 220414cf08bSSenthil Nathan Thangaraj break; 221414cf08bSSenthil Nathan Thangaraj case 76: 222414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_ADMA_4; 223414cf08bSSenthil Nathan Thangaraj break; 224414cf08bSSenthil Nathan Thangaraj case 77: 225414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_ADMA_5; 226414cf08bSSenthil Nathan Thangaraj break; 227414cf08bSSenthil Nathan Thangaraj case 78: 228414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_ADMA_6; 229414cf08bSSenthil Nathan Thangaraj break; 230414cf08bSSenthil Nathan Thangaraj case 79: 231414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_ADMA_7; 232414cf08bSSenthil Nathan Thangaraj break; 233414cf08bSSenthil Nathan Thangaraj case 95: 234414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_CAN_FD_2; 235414cf08bSSenthil Nathan Thangaraj break; 236414cf08bSSenthil Nathan Thangaraj case 96: 237414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_CAN_FD_3; 238414cf08bSSenthil Nathan Thangaraj break; 239414cf08bSSenthil Nathan Thangaraj case 100: 240414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_I2C_5; 241414cf08bSSenthil Nathan Thangaraj break; 242414cf08bSSenthil Nathan Thangaraj case 101: 243414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_I2C_6; 244414cf08bSSenthil Nathan Thangaraj break; 245414cf08bSSenthil Nathan Thangaraj case 102: 246414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_I2C_7; 247414cf08bSSenthil Nathan Thangaraj break; 2484589ce0aSNaman Trivedi case 164: 2494589ce0aSNaman Trivedi dev_idx = XPM_NODEIDX_DEV_MMI_GEM; 2504589ce0aSNaman Trivedi break; 251414cf08bSSenthil Nathan Thangaraj case 200: 252414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_RTC; 253414cf08bSSenthil Nathan Thangaraj break; 254414cf08bSSenthil Nathan Thangaraj case 218: 255414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_SDIO_0; 256414cf08bSSenthil Nathan Thangaraj break; 257414cf08bSSenthil Nathan Thangaraj case 220: 258414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_SDIO_1; 259414cf08bSSenthil Nathan Thangaraj break; 260414cf08bSSenthil Nathan Thangaraj default: 261414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_MIN; 262414cf08bSSenthil Nathan Thangaraj break; 263414cf08bSSenthil Nathan Thangaraj } 264414cf08bSSenthil Nathan Thangaraj 265414cf08bSSenthil Nathan Thangaraj return dev_idx; 266414cf08bSSenthil Nathan Thangaraj } 267414cf08bSSenthil Nathan Thangaraj 268414cf08bSSenthil Nathan Thangaraj /** 269414cf08bSSenthil Nathan Thangaraj * pm_client_suspend() - Client-specific suspend actions. This function 270414cf08bSSenthil Nathan Thangaraj * perform actions required prior to sending suspend 271414cf08bSSenthil Nathan Thangaraj * request. 272414cf08bSSenthil Nathan Thangaraj * Actions taken depend on the state system is 273414cf08bSSenthil Nathan Thangaraj * suspending to. 274414cf08bSSenthil Nathan Thangaraj * @proc: processor which need to suspend. 275414cf08bSSenthil Nathan Thangaraj * @state: desired suspend state. 2765cac1d85SRonak Jain * @flag: 0 - Call from secure source. 2775cac1d85SRonak Jain * 1 - Call from non-secure source. 278414cf08bSSenthil Nathan Thangaraj */ 2795cac1d85SRonak Jain void pm_client_suspend(const struct pm_proc *proc, uint32_t state, uint32_t flag) 280414cf08bSSenthil Nathan Thangaraj { 281414cf08bSSenthil Nathan Thangaraj uint32_t cpu_id = plat_my_core_pos(); 282414cf08bSSenthil Nathan Thangaraj uintptr_t val; 283414cf08bSSenthil Nathan Thangaraj /* 284414cf08bSSenthil Nathan Thangaraj * Get the core index, use it calculate offset for secondary cores 285414cf08bSSenthil Nathan Thangaraj * to match with register database 286414cf08bSSenthil Nathan Thangaraj */ 287414cf08bSSenthil Nathan Thangaraj uint32_t core_index = cpu_id + ((cpu_id / 2U) * 2U); 288414cf08bSSenthil Nathan Thangaraj 289414cf08bSSenthil Nathan Thangaraj pm_client_lock_get(); 290414cf08bSSenthil Nathan Thangaraj 291414cf08bSSenthil Nathan Thangaraj if (state == PM_STATE_SUSPEND_TO_RAM) { 2925cac1d85SRonak Jain pm_client_set_wakeup_sources((uint32_t)proc->node_id, flag); 293414cf08bSSenthil Nathan Thangaraj } 294414cf08bSSenthil Nathan Thangaraj 295414cf08bSSenthil Nathan Thangaraj val = read_cpu_pwrctrl_val(); 296414cf08bSSenthil Nathan Thangaraj val |= CORE_PWRDN_EN_BIT_MASK; 297414cf08bSSenthil Nathan Thangaraj write_cpu_pwrctrl_val(val); 298414cf08bSSenthil Nathan Thangaraj 299414cf08bSSenthil Nathan Thangaraj isb(); 300414cf08bSSenthil Nathan Thangaraj 301414cf08bSSenthil Nathan Thangaraj /* Enable power down interrupt */ 302414cf08bSSenthil Nathan Thangaraj mmio_write_32(APU_PCIL_CORE_X_IEN_POWER_REG(core_index), 303414cf08bSSenthil Nathan Thangaraj APU_PCIL_CORE_X_IEN_POWER_MASK); 304414cf08bSSenthil Nathan Thangaraj /* Enable wake interrupt */ 305414cf08bSSenthil Nathan Thangaraj mmio_write_32(APU_PCIL_CORE_X_IEN_WAKE_REG(core_index), 306414cf08bSSenthil Nathan Thangaraj APU_PCIL_CORE_X_IEN_WAKE_MASK); 307414cf08bSSenthil Nathan Thangaraj 308414cf08bSSenthil Nathan Thangaraj pm_client_lock_release(); 309414cf08bSSenthil Nathan Thangaraj } 310414cf08bSSenthil Nathan Thangaraj 311414cf08bSSenthil Nathan Thangaraj /** 312414cf08bSSenthil Nathan Thangaraj * pm_get_cpuid() - get the local cpu ID for a global node ID. 313414cf08bSSenthil Nathan Thangaraj * @nid: node id of the processor. 314414cf08bSSenthil Nathan Thangaraj * 315414cf08bSSenthil Nathan Thangaraj * Return: the cpu ID (starting from 0) for the subsystem. 316414cf08bSSenthil Nathan Thangaraj */ 317414cf08bSSenthil Nathan Thangaraj static uint32_t pm_get_cpuid(uint32_t nid) 318414cf08bSSenthil Nathan Thangaraj { 319414cf08bSSenthil Nathan Thangaraj uint32_t ret = (uint32_t) UNDEFINED_CPUID; 320414cf08bSSenthil Nathan Thangaraj size_t i; 321414cf08bSSenthil Nathan Thangaraj 322414cf08bSSenthil Nathan Thangaraj for (i = 0; i < ARRAY_SIZE(pm_procs_all); i++) { 323414cf08bSSenthil Nathan Thangaraj if (pm_procs_all[i].node_id == nid) { 324414cf08bSSenthil Nathan Thangaraj ret = (uint32_t)i; 325414cf08bSSenthil Nathan Thangaraj break; 326414cf08bSSenthil Nathan Thangaraj } 327414cf08bSSenthil Nathan Thangaraj } 328414cf08bSSenthil Nathan Thangaraj 329414cf08bSSenthil Nathan Thangaraj return ret; 330414cf08bSSenthil Nathan Thangaraj } 331414cf08bSSenthil Nathan Thangaraj 332414cf08bSSenthil Nathan Thangaraj /** 333414cf08bSSenthil Nathan Thangaraj * pm_client_wakeup() - Client-specific wakeup actions. 334414cf08bSSenthil Nathan Thangaraj * @proc: Processor which need to wakeup. 335414cf08bSSenthil Nathan Thangaraj * 336414cf08bSSenthil Nathan Thangaraj * This function should contain any PU-specific actions 337414cf08bSSenthil Nathan Thangaraj * required for waking up another APU core. 338414cf08bSSenthil Nathan Thangaraj */ 339414cf08bSSenthil Nathan Thangaraj void pm_client_wakeup(const struct pm_proc *proc) 340414cf08bSSenthil Nathan Thangaraj { 341414cf08bSSenthil Nathan Thangaraj uint32_t cpuid = pm_get_cpuid(proc->node_id); 342414cf08bSSenthil Nathan Thangaraj uintptr_t val; 343414cf08bSSenthil Nathan Thangaraj 344414cf08bSSenthil Nathan Thangaraj if (cpuid != (uint32_t) UNDEFINED_CPUID) { 34502210f63SJay Buddhabhatti /* 34602210f63SJay Buddhabhatti * Get the core index and use it to calculate offset for 34702210f63SJay Buddhabhatti * disabling power down and wakeup interrupts. 34802210f63SJay Buddhabhatti * i.e., Convert cpu-id to core_index with the following mapping: 34902210f63SJay Buddhabhatti * cpu-id -> core_index 35002210f63SJay Buddhabhatti * 0 -> 0 35102210f63SJay Buddhabhatti * 1 -> 1 35202210f63SJay Buddhabhatti * 2 -> 4 35302210f63SJay Buddhabhatti * 3 -> 5 35402210f63SJay Buddhabhatti * 4 -> 8 35502210f63SJay Buddhabhatti * 5 -> 9 35602210f63SJay Buddhabhatti * 6 -> 12 35702210f63SJay Buddhabhatti * 7 -> 13 35802210f63SJay Buddhabhatti * to match with register database. 35902210f63SJay Buddhabhatti */ 36002210f63SJay Buddhabhatti uint32_t core_index = cpuid + ((cpuid / 2U) * 2U); 36102210f63SJay Buddhabhatti 362414cf08bSSenthil Nathan Thangaraj pm_client_lock_get(); 363414cf08bSSenthil Nathan Thangaraj 364414cf08bSSenthil Nathan Thangaraj /* Clear powerdown request */ 365414cf08bSSenthil Nathan Thangaraj val = read_cpu_pwrctrl_val(); 366414cf08bSSenthil Nathan Thangaraj val &= ~CORE_PWRDN_EN_BIT_MASK; 367414cf08bSSenthil Nathan Thangaraj write_cpu_pwrctrl_val(val); 368414cf08bSSenthil Nathan Thangaraj 369414cf08bSSenthil Nathan Thangaraj isb(); 370414cf08bSSenthil Nathan Thangaraj 371414cf08bSSenthil Nathan Thangaraj /* Disabled power down interrupt */ 37202210f63SJay Buddhabhatti mmio_write_32(APU_PCIL_CORE_X_IDS_POWER_REG(core_index), 373414cf08bSSenthil Nathan Thangaraj APU_PCIL_CORE_X_IDS_POWER_MASK); 374414cf08bSSenthil Nathan Thangaraj /* Disable wake interrupt */ 37502210f63SJay Buddhabhatti mmio_write_32(APU_PCIL_CORE_X_IDS_WAKE_REG(core_index), 376414cf08bSSenthil Nathan Thangaraj APU_PCIL_CORE_X_IDS_WAKE_MASK); 377414cf08bSSenthil Nathan Thangaraj 378414cf08bSSenthil Nathan Thangaraj pm_client_lock_release(); 379414cf08bSSenthil Nathan Thangaraj } 380414cf08bSSenthil Nathan Thangaraj } 381414cf08bSSenthil Nathan Thangaraj 382414cf08bSSenthil Nathan Thangaraj /** 383414cf08bSSenthil Nathan Thangaraj * pm_client_abort_suspend() - Client-specific abort-suspend actions. 384414cf08bSSenthil Nathan Thangaraj * 385414cf08bSSenthil Nathan Thangaraj * This function should contain any PU-specific actions 386414cf08bSSenthil Nathan Thangaraj * required for aborting a prior suspend request. 387414cf08bSSenthil Nathan Thangaraj */ 388414cf08bSSenthil Nathan Thangaraj void pm_client_abort_suspend(void) 389414cf08bSSenthil Nathan Thangaraj { 390414cf08bSSenthil Nathan Thangaraj uint32_t cpu_id = plat_my_core_pos(); 391414cf08bSSenthil Nathan Thangaraj uintptr_t val; 392414cf08bSSenthil Nathan Thangaraj 393414cf08bSSenthil Nathan Thangaraj /* Enable interrupts at processor level (for current cpu) */ 394414cf08bSSenthil Nathan Thangaraj gicv3_cpuif_enable(plat_my_core_pos()); 395414cf08bSSenthil Nathan Thangaraj 396414cf08bSSenthil Nathan Thangaraj pm_client_lock_get(); 397414cf08bSSenthil Nathan Thangaraj 398414cf08bSSenthil Nathan Thangaraj /* Clear powerdown request */ 399414cf08bSSenthil Nathan Thangaraj val = read_cpu_pwrctrl_val(); 400414cf08bSSenthil Nathan Thangaraj val &= ~CORE_PWRDN_EN_BIT_MASK; 401414cf08bSSenthil Nathan Thangaraj write_cpu_pwrctrl_val(val); 402414cf08bSSenthil Nathan Thangaraj 403414cf08bSSenthil Nathan Thangaraj isb(); 404414cf08bSSenthil Nathan Thangaraj 405414cf08bSSenthil Nathan Thangaraj /* Disabled power down interrupt */ 406414cf08bSSenthil Nathan Thangaraj mmio_write_32(APU_PCIL_CORE_X_IDS_POWER_REG(cpu_id), 407414cf08bSSenthil Nathan Thangaraj APU_PCIL_CORE_X_IDS_POWER_MASK); 408414cf08bSSenthil Nathan Thangaraj 409414cf08bSSenthil Nathan Thangaraj pm_client_lock_release(); 410414cf08bSSenthil Nathan Thangaraj } 411