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