1*414cf08bSSenthil Nathan Thangaraj /* 2*414cf08bSSenthil Nathan Thangaraj * Copyright (c) 2022, Xilinx, Inc. All rights reserved. 3*414cf08bSSenthil Nathan Thangaraj * Copyright (c) 2022-2025, Advanced Micro Devices, Inc. All rights reserved. 4*414cf08bSSenthil Nathan Thangaraj * 5*414cf08bSSenthil Nathan Thangaraj * SPDX-License-Identifier: BSD-3-Clause 6*414cf08bSSenthil Nathan Thangaraj */ 7*414cf08bSSenthil Nathan Thangaraj 8*414cf08bSSenthil Nathan Thangaraj /* 9*414cf08bSSenthil Nathan Thangaraj * APU specific definition of processors in the subsystem as well as functions 10*414cf08bSSenthil Nathan Thangaraj * for getting information about and changing state of the APU. 11*414cf08bSSenthil Nathan Thangaraj */ 12*414cf08bSSenthil Nathan Thangaraj 13*414cf08bSSenthil Nathan Thangaraj #include <assert.h> 14*414cf08bSSenthil Nathan Thangaraj 15*414cf08bSSenthil Nathan Thangaraj #include <drivers/arm/gic_common.h> 16*414cf08bSSenthil Nathan Thangaraj #include <drivers/arm/gicv3.h> 17*414cf08bSSenthil Nathan Thangaraj #include <lib/bakery_lock.h> 18*414cf08bSSenthil Nathan Thangaraj #include <lib/mmio.h> 19*414cf08bSSenthil Nathan Thangaraj #include <lib/spinlock.h> 20*414cf08bSSenthil Nathan Thangaraj #include <lib/utils.h> 21*414cf08bSSenthil Nathan Thangaraj #include <plat/common/platform.h> 22*414cf08bSSenthil Nathan Thangaraj 23*414cf08bSSenthil Nathan Thangaraj #include <platform_def.h> 24*414cf08bSSenthil Nathan Thangaraj #include "def.h" 25*414cf08bSSenthil Nathan Thangaraj #include <plat_ipi.h> 26*414cf08bSSenthil Nathan Thangaraj #include "pm_api_sys.h" 27*414cf08bSSenthil Nathan Thangaraj #include "pm_client.h" 28*414cf08bSSenthil Nathan Thangaraj 29*414cf08bSSenthil Nathan Thangaraj #define UNDEFINED_CPUID UINT32_MAX 30*414cf08bSSenthil Nathan Thangaraj 31*414cf08bSSenthil Nathan Thangaraj DEFINE_RENAME_SYSREG_RW_FUNCS(cpu_pwrctrl_val, S3_0_C15_C2_7) 32*414cf08bSSenthil Nathan Thangaraj 33*414cf08bSSenthil Nathan Thangaraj /* 34*414cf08bSSenthil Nathan Thangaraj * ARM v8.2, the cache will turn off automatically when cpu 35*414cf08bSSenthil Nathan Thangaraj * power down. Therefore, there is no doubt to use the spin_lock here. 36*414cf08bSSenthil Nathan Thangaraj */ 37*414cf08bSSenthil Nathan Thangaraj static spinlock_t pm_client_secure_lock; 38*414cf08bSSenthil Nathan Thangaraj static inline void pm_client_lock_get(void) 39*414cf08bSSenthil Nathan Thangaraj { 40*414cf08bSSenthil Nathan Thangaraj spin_lock(&pm_client_secure_lock); 41*414cf08bSSenthil Nathan Thangaraj } 42*414cf08bSSenthil Nathan Thangaraj 43*414cf08bSSenthil Nathan Thangaraj static inline void pm_client_lock_release(void) 44*414cf08bSSenthil Nathan Thangaraj { 45*414cf08bSSenthil Nathan Thangaraj spin_unlock(&pm_client_secure_lock); 46*414cf08bSSenthil Nathan Thangaraj } 47*414cf08bSSenthil Nathan Thangaraj 48*414cf08bSSenthil Nathan Thangaraj static const struct pm_ipi apu_ipi = { 49*414cf08bSSenthil Nathan Thangaraj .local_ipi_id = IPI_LOCAL_ID, 50*414cf08bSSenthil Nathan Thangaraj .remote_ipi_id = IPI_REMOTE_ID, 51*414cf08bSSenthil Nathan Thangaraj .buffer_base = IPI_BUFFER_LOCAL_BASE, 52*414cf08bSSenthil Nathan Thangaraj }; 53*414cf08bSSenthil Nathan Thangaraj 54*414cf08bSSenthil Nathan Thangaraj /* Order in pm_procs_all array must match cpu ids */ 55*414cf08bSSenthil Nathan Thangaraj static const struct pm_proc pm_procs_all[] = { 56*414cf08bSSenthil Nathan Thangaraj { 57*414cf08bSSenthil Nathan Thangaraj .node_id = PM_DEV_CLUSTER0_ACPU_0, 58*414cf08bSSenthil Nathan Thangaraj .ipi = &apu_ipi, 59*414cf08bSSenthil Nathan Thangaraj }, 60*414cf08bSSenthil Nathan Thangaraj { 61*414cf08bSSenthil Nathan Thangaraj .node_id = PM_DEV_CLUSTER0_ACPU_1, 62*414cf08bSSenthil Nathan Thangaraj .ipi = &apu_ipi, 63*414cf08bSSenthil Nathan Thangaraj }, 64*414cf08bSSenthil Nathan Thangaraj { 65*414cf08bSSenthil Nathan Thangaraj .node_id = PM_DEV_CLUSTER1_ACPU_0, 66*414cf08bSSenthil Nathan Thangaraj .ipi = &apu_ipi, 67*414cf08bSSenthil Nathan Thangaraj }, 68*414cf08bSSenthil Nathan Thangaraj { 69*414cf08bSSenthil Nathan Thangaraj .node_id = PM_DEV_CLUSTER1_ACPU_1, 70*414cf08bSSenthil Nathan Thangaraj .ipi = &apu_ipi, 71*414cf08bSSenthil Nathan Thangaraj }, 72*414cf08bSSenthil Nathan Thangaraj { 73*414cf08bSSenthil Nathan Thangaraj .node_id = PM_DEV_CLUSTER2_ACPU_0, 74*414cf08bSSenthil Nathan Thangaraj .ipi = &apu_ipi, 75*414cf08bSSenthil Nathan Thangaraj }, 76*414cf08bSSenthil Nathan Thangaraj { 77*414cf08bSSenthil Nathan Thangaraj .node_id = PM_DEV_CLUSTER2_ACPU_1, 78*414cf08bSSenthil Nathan Thangaraj .ipi = &apu_ipi, 79*414cf08bSSenthil Nathan Thangaraj }, 80*414cf08bSSenthil Nathan Thangaraj { 81*414cf08bSSenthil Nathan Thangaraj .node_id = PM_DEV_CLUSTER3_ACPU_0, 82*414cf08bSSenthil Nathan Thangaraj .ipi = &apu_ipi, 83*414cf08bSSenthil Nathan Thangaraj }, 84*414cf08bSSenthil Nathan Thangaraj { 85*414cf08bSSenthil Nathan Thangaraj .node_id = PM_DEV_CLUSTER3_ACPU_1, 86*414cf08bSSenthil Nathan Thangaraj .ipi = &apu_ipi, 87*414cf08bSSenthil Nathan Thangaraj }, 88*414cf08bSSenthil Nathan Thangaraj }; 89*414cf08bSSenthil Nathan Thangaraj 90*414cf08bSSenthil Nathan Thangaraj const struct pm_proc *primary_proc = &pm_procs_all[0]; 91*414cf08bSSenthil Nathan Thangaraj 92*414cf08bSSenthil Nathan Thangaraj /** 93*414cf08bSSenthil Nathan Thangaraj * pm_get_proc() - returns pointer to the proc structure. 94*414cf08bSSenthil Nathan Thangaraj * @cpuid: id of the cpu whose proc struct pointer should be returned. 95*414cf08bSSenthil Nathan Thangaraj * 96*414cf08bSSenthil Nathan Thangaraj * Return: Pointer to a proc structure if proc is found, otherwise NULL. 97*414cf08bSSenthil Nathan Thangaraj */ 98*414cf08bSSenthil Nathan Thangaraj const struct pm_proc *pm_get_proc(uint32_t cpuid) 99*414cf08bSSenthil Nathan Thangaraj { 100*414cf08bSSenthil Nathan Thangaraj const struct pm_proc *proc = NULL; 101*414cf08bSSenthil Nathan Thangaraj 102*414cf08bSSenthil Nathan Thangaraj if (cpuid < ARRAY_SIZE(pm_procs_all)) { 103*414cf08bSSenthil Nathan Thangaraj proc = &pm_procs_all[cpuid]; 104*414cf08bSSenthil Nathan Thangaraj } else { 105*414cf08bSSenthil Nathan Thangaraj ERROR("cpuid: %d proc NULL\n", cpuid); 106*414cf08bSSenthil Nathan Thangaraj } 107*414cf08bSSenthil Nathan Thangaraj 108*414cf08bSSenthil Nathan Thangaraj return proc; 109*414cf08bSSenthil Nathan Thangaraj } 110*414cf08bSSenthil Nathan Thangaraj 111*414cf08bSSenthil Nathan Thangaraj /** 112*414cf08bSSenthil Nathan Thangaraj * irq_to_pm_node_idx - Get PM node index corresponding to the interrupt number. 113*414cf08bSSenthil Nathan Thangaraj * @irq: Interrupt number. 114*414cf08bSSenthil Nathan Thangaraj * 115*414cf08bSSenthil Nathan Thangaraj * Return: PM node index corresponding to the specified interrupt. 116*414cf08bSSenthil Nathan Thangaraj */ 117*414cf08bSSenthil Nathan Thangaraj enum pm_device_node_idx irq_to_pm_node_idx(uint32_t irq) 118*414cf08bSSenthil Nathan Thangaraj { 119*414cf08bSSenthil Nathan Thangaraj enum pm_device_node_idx dev_idx = XPM_NODEIDX_DEV_MIN; 120*414cf08bSSenthil Nathan Thangaraj 121*414cf08bSSenthil Nathan Thangaraj assert(irq <= IRQ_MAX); 122*414cf08bSSenthil Nathan Thangaraj 123*414cf08bSSenthil Nathan Thangaraj switch (irq) { 124*414cf08bSSenthil Nathan Thangaraj case 11: 125*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_I2C_2; 126*414cf08bSSenthil Nathan Thangaraj break; 127*414cf08bSSenthil Nathan Thangaraj case 12: 128*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_I2C_3; 129*414cf08bSSenthil Nathan Thangaraj break; 130*414cf08bSSenthil Nathan Thangaraj case 13: 131*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_I2C_4; 132*414cf08bSSenthil Nathan Thangaraj break; 133*414cf08bSSenthil Nathan Thangaraj case 20: 134*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_GPIO; 135*414cf08bSSenthil Nathan Thangaraj break; 136*414cf08bSSenthil Nathan Thangaraj case 21: 137*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_I2C_0; 138*414cf08bSSenthil Nathan Thangaraj break; 139*414cf08bSSenthil Nathan Thangaraj case 22: 140*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_I2C_1; 141*414cf08bSSenthil Nathan Thangaraj break; 142*414cf08bSSenthil Nathan Thangaraj case 23: 143*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_SPI_0; 144*414cf08bSSenthil Nathan Thangaraj break; 145*414cf08bSSenthil Nathan Thangaraj case 24: 146*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_SPI_1; 147*414cf08bSSenthil Nathan Thangaraj break; 148*414cf08bSSenthil Nathan Thangaraj case 25: 149*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_UART_0; 150*414cf08bSSenthil Nathan Thangaraj break; 151*414cf08bSSenthil Nathan Thangaraj case 26: 152*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_UART_1; 153*414cf08bSSenthil Nathan Thangaraj break; 154*414cf08bSSenthil Nathan Thangaraj case 27: 155*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_CAN_FD_0; 156*414cf08bSSenthil Nathan Thangaraj break; 157*414cf08bSSenthil Nathan Thangaraj case 28: 158*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_CAN_FD_1; 159*414cf08bSSenthil Nathan Thangaraj break; 160*414cf08bSSenthil Nathan Thangaraj case 29: 161*414cf08bSSenthil Nathan Thangaraj case 30: 162*414cf08bSSenthil Nathan Thangaraj case 31: 163*414cf08bSSenthil Nathan Thangaraj case 32: 164*414cf08bSSenthil Nathan Thangaraj case 33: 165*414cf08bSSenthil Nathan Thangaraj case 98: 166*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_USB_0; 167*414cf08bSSenthil Nathan Thangaraj break; 168*414cf08bSSenthil Nathan Thangaraj case 34: 169*414cf08bSSenthil Nathan Thangaraj case 35: 170*414cf08bSSenthil Nathan Thangaraj case 36: 171*414cf08bSSenthil Nathan Thangaraj case 37: 172*414cf08bSSenthil Nathan Thangaraj case 38: 173*414cf08bSSenthil Nathan Thangaraj case 99: 174*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_USB_1; 175*414cf08bSSenthil Nathan Thangaraj break; 176*414cf08bSSenthil Nathan Thangaraj case 39: 177*414cf08bSSenthil Nathan Thangaraj case 40: 178*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_GEM_0; 179*414cf08bSSenthil Nathan Thangaraj break; 180*414cf08bSSenthil Nathan Thangaraj case 41: 181*414cf08bSSenthil Nathan Thangaraj case 42: 182*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_GEM_1; 183*414cf08bSSenthil Nathan Thangaraj break; 184*414cf08bSSenthil Nathan Thangaraj case 43: 185*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_TTC_0; 186*414cf08bSSenthil Nathan Thangaraj break; 187*414cf08bSSenthil Nathan Thangaraj case 44: 188*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_TTC_1; 189*414cf08bSSenthil Nathan Thangaraj break; 190*414cf08bSSenthil Nathan Thangaraj case 45: 191*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_TTC_2; 192*414cf08bSSenthil Nathan Thangaraj break; 193*414cf08bSSenthil Nathan Thangaraj case 46: 194*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_TTC_3; 195*414cf08bSSenthil Nathan Thangaraj break; 196*414cf08bSSenthil Nathan Thangaraj case 47: 197*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_TTC_4; 198*414cf08bSSenthil Nathan Thangaraj break; 199*414cf08bSSenthil Nathan Thangaraj case 48: 200*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_TTC_5; 201*414cf08bSSenthil Nathan Thangaraj break; 202*414cf08bSSenthil Nathan Thangaraj case 49: 203*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_TTC_6; 204*414cf08bSSenthil Nathan Thangaraj break; 205*414cf08bSSenthil Nathan Thangaraj case 50: 206*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_TTC_7; 207*414cf08bSSenthil Nathan Thangaraj break; 208*414cf08bSSenthil Nathan Thangaraj case 72: 209*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_ADMA_0; 210*414cf08bSSenthil Nathan Thangaraj break; 211*414cf08bSSenthil Nathan Thangaraj case 73: 212*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_ADMA_1; 213*414cf08bSSenthil Nathan Thangaraj break; 214*414cf08bSSenthil Nathan Thangaraj case 74: 215*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_ADMA_2; 216*414cf08bSSenthil Nathan Thangaraj break; 217*414cf08bSSenthil Nathan Thangaraj case 75: 218*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_ADMA_3; 219*414cf08bSSenthil Nathan Thangaraj break; 220*414cf08bSSenthil Nathan Thangaraj case 76: 221*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_ADMA_4; 222*414cf08bSSenthil Nathan Thangaraj break; 223*414cf08bSSenthil Nathan Thangaraj case 77: 224*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_ADMA_5; 225*414cf08bSSenthil Nathan Thangaraj break; 226*414cf08bSSenthil Nathan Thangaraj case 78: 227*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_ADMA_6; 228*414cf08bSSenthil Nathan Thangaraj break; 229*414cf08bSSenthil Nathan Thangaraj case 79: 230*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_ADMA_7; 231*414cf08bSSenthil Nathan Thangaraj break; 232*414cf08bSSenthil Nathan Thangaraj case 95: 233*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_CAN_FD_2; 234*414cf08bSSenthil Nathan Thangaraj break; 235*414cf08bSSenthil Nathan Thangaraj case 96: 236*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_CAN_FD_3; 237*414cf08bSSenthil Nathan Thangaraj break; 238*414cf08bSSenthil Nathan Thangaraj case 100: 239*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_I2C_5; 240*414cf08bSSenthil Nathan Thangaraj break; 241*414cf08bSSenthil Nathan Thangaraj case 101: 242*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_I2C_6; 243*414cf08bSSenthil Nathan Thangaraj break; 244*414cf08bSSenthil Nathan Thangaraj case 102: 245*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_I2C_7; 246*414cf08bSSenthil Nathan Thangaraj break; 247*414cf08bSSenthil Nathan Thangaraj case 200: 248*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_RTC; 249*414cf08bSSenthil Nathan Thangaraj break; 250*414cf08bSSenthil Nathan Thangaraj case 218: 251*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_SDIO_0; 252*414cf08bSSenthil Nathan Thangaraj break; 253*414cf08bSSenthil Nathan Thangaraj case 220: 254*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_SDIO_1; 255*414cf08bSSenthil Nathan Thangaraj break; 256*414cf08bSSenthil Nathan Thangaraj default: 257*414cf08bSSenthil Nathan Thangaraj dev_idx = XPM_NODEIDX_DEV_MIN; 258*414cf08bSSenthil Nathan Thangaraj break; 259*414cf08bSSenthil Nathan Thangaraj } 260*414cf08bSSenthil Nathan Thangaraj 261*414cf08bSSenthil Nathan Thangaraj return dev_idx; 262*414cf08bSSenthil Nathan Thangaraj } 263*414cf08bSSenthil Nathan Thangaraj 264*414cf08bSSenthil Nathan Thangaraj /** 265*414cf08bSSenthil Nathan Thangaraj * pm_client_suspend() - Client-specific suspend actions. This function 266*414cf08bSSenthil Nathan Thangaraj * perform actions required prior to sending suspend 267*414cf08bSSenthil Nathan Thangaraj * request. 268*414cf08bSSenthil Nathan Thangaraj * Actions taken depend on the state system is 269*414cf08bSSenthil Nathan Thangaraj * suspending to. 270*414cf08bSSenthil Nathan Thangaraj * @proc: processor which need to suspend. 271*414cf08bSSenthil Nathan Thangaraj * @state: desired suspend state. 272*414cf08bSSenthil Nathan Thangaraj */ 273*414cf08bSSenthil Nathan Thangaraj void pm_client_suspend(const struct pm_proc *proc, uint32_t state) 274*414cf08bSSenthil Nathan Thangaraj { 275*414cf08bSSenthil Nathan Thangaraj uint32_t cpu_id = plat_my_core_pos(); 276*414cf08bSSenthil Nathan Thangaraj uintptr_t val; 277*414cf08bSSenthil Nathan Thangaraj /* 278*414cf08bSSenthil Nathan Thangaraj * Get the core index, use it calculate offset for secondary cores 279*414cf08bSSenthil Nathan Thangaraj * to match with register database 280*414cf08bSSenthil Nathan Thangaraj */ 281*414cf08bSSenthil Nathan Thangaraj uint32_t core_index = cpu_id + ((cpu_id / 2U) * 2U); 282*414cf08bSSenthil Nathan Thangaraj 283*414cf08bSSenthil Nathan Thangaraj pm_client_lock_get(); 284*414cf08bSSenthil Nathan Thangaraj 285*414cf08bSSenthil Nathan Thangaraj if (state == PM_STATE_SUSPEND_TO_RAM) { 286*414cf08bSSenthil Nathan Thangaraj pm_client_set_wakeup_sources((uint32_t)proc->node_id); 287*414cf08bSSenthil Nathan Thangaraj } 288*414cf08bSSenthil Nathan Thangaraj 289*414cf08bSSenthil Nathan Thangaraj val = read_cpu_pwrctrl_val(); 290*414cf08bSSenthil Nathan Thangaraj val |= CORE_PWRDN_EN_BIT_MASK; 291*414cf08bSSenthil Nathan Thangaraj write_cpu_pwrctrl_val(val); 292*414cf08bSSenthil Nathan Thangaraj 293*414cf08bSSenthil Nathan Thangaraj isb(); 294*414cf08bSSenthil Nathan Thangaraj 295*414cf08bSSenthil Nathan Thangaraj /* Enable power down interrupt */ 296*414cf08bSSenthil Nathan Thangaraj mmio_write_32(APU_PCIL_CORE_X_IEN_POWER_REG(core_index), 297*414cf08bSSenthil Nathan Thangaraj APU_PCIL_CORE_X_IEN_POWER_MASK); 298*414cf08bSSenthil Nathan Thangaraj /* Enable wake interrupt */ 299*414cf08bSSenthil Nathan Thangaraj mmio_write_32(APU_PCIL_CORE_X_IEN_WAKE_REG(core_index), 300*414cf08bSSenthil Nathan Thangaraj APU_PCIL_CORE_X_IEN_WAKE_MASK); 301*414cf08bSSenthil Nathan Thangaraj 302*414cf08bSSenthil Nathan Thangaraj pm_client_lock_release(); 303*414cf08bSSenthil Nathan Thangaraj } 304*414cf08bSSenthil Nathan Thangaraj 305*414cf08bSSenthil Nathan Thangaraj /** 306*414cf08bSSenthil Nathan Thangaraj * pm_get_cpuid() - get the local cpu ID for a global node ID. 307*414cf08bSSenthil Nathan Thangaraj * @nid: node id of the processor. 308*414cf08bSSenthil Nathan Thangaraj * 309*414cf08bSSenthil Nathan Thangaraj * Return: the cpu ID (starting from 0) for the subsystem. 310*414cf08bSSenthil Nathan Thangaraj */ 311*414cf08bSSenthil Nathan Thangaraj static uint32_t pm_get_cpuid(uint32_t nid) 312*414cf08bSSenthil Nathan Thangaraj { 313*414cf08bSSenthil Nathan Thangaraj uint32_t ret = (uint32_t) UNDEFINED_CPUID; 314*414cf08bSSenthil Nathan Thangaraj size_t i; 315*414cf08bSSenthil Nathan Thangaraj 316*414cf08bSSenthil Nathan Thangaraj for (i = 0; i < ARRAY_SIZE(pm_procs_all); i++) { 317*414cf08bSSenthil Nathan Thangaraj if (pm_procs_all[i].node_id == nid) { 318*414cf08bSSenthil Nathan Thangaraj ret = (uint32_t)i; 319*414cf08bSSenthil Nathan Thangaraj break; 320*414cf08bSSenthil Nathan Thangaraj } 321*414cf08bSSenthil Nathan Thangaraj } 322*414cf08bSSenthil Nathan Thangaraj 323*414cf08bSSenthil Nathan Thangaraj return ret; 324*414cf08bSSenthil Nathan Thangaraj } 325*414cf08bSSenthil Nathan Thangaraj 326*414cf08bSSenthil Nathan Thangaraj /** 327*414cf08bSSenthil Nathan Thangaraj * pm_client_wakeup() - Client-specific wakeup actions. 328*414cf08bSSenthil Nathan Thangaraj * @proc: Processor which need to wakeup. 329*414cf08bSSenthil Nathan Thangaraj * 330*414cf08bSSenthil Nathan Thangaraj * This function should contain any PU-specific actions 331*414cf08bSSenthil Nathan Thangaraj * required for waking up another APU core. 332*414cf08bSSenthil Nathan Thangaraj */ 333*414cf08bSSenthil Nathan Thangaraj void pm_client_wakeup(const struct pm_proc *proc) 334*414cf08bSSenthil Nathan Thangaraj { 335*414cf08bSSenthil Nathan Thangaraj uint32_t cpuid = pm_get_cpuid(proc->node_id); 336*414cf08bSSenthil Nathan Thangaraj uintptr_t val; 337*414cf08bSSenthil Nathan Thangaraj 338*414cf08bSSenthil Nathan Thangaraj if (cpuid != (uint32_t) UNDEFINED_CPUID) { 339*414cf08bSSenthil Nathan Thangaraj pm_client_lock_get(); 340*414cf08bSSenthil Nathan Thangaraj 341*414cf08bSSenthil Nathan Thangaraj /* Clear powerdown request */ 342*414cf08bSSenthil Nathan Thangaraj val = read_cpu_pwrctrl_val(); 343*414cf08bSSenthil Nathan Thangaraj val &= ~CORE_PWRDN_EN_BIT_MASK; 344*414cf08bSSenthil Nathan Thangaraj write_cpu_pwrctrl_val(val); 345*414cf08bSSenthil Nathan Thangaraj 346*414cf08bSSenthil Nathan Thangaraj isb(); 347*414cf08bSSenthil Nathan Thangaraj 348*414cf08bSSenthil Nathan Thangaraj /* Disabled power down interrupt */ 349*414cf08bSSenthil Nathan Thangaraj mmio_write_32(APU_PCIL_CORE_X_IDS_POWER_REG(cpuid), 350*414cf08bSSenthil Nathan Thangaraj APU_PCIL_CORE_X_IDS_POWER_MASK); 351*414cf08bSSenthil Nathan Thangaraj /* Disable wake interrupt */ 352*414cf08bSSenthil Nathan Thangaraj mmio_write_32(APU_PCIL_CORE_X_IDS_WAKE_REG(cpuid), 353*414cf08bSSenthil Nathan Thangaraj APU_PCIL_CORE_X_IDS_WAKE_MASK); 354*414cf08bSSenthil Nathan Thangaraj 355*414cf08bSSenthil Nathan Thangaraj pm_client_lock_release(); 356*414cf08bSSenthil Nathan Thangaraj } 357*414cf08bSSenthil Nathan Thangaraj } 358*414cf08bSSenthil Nathan Thangaraj 359*414cf08bSSenthil Nathan Thangaraj /** 360*414cf08bSSenthil Nathan Thangaraj * pm_client_abort_suspend() - Client-specific abort-suspend actions. 361*414cf08bSSenthil Nathan Thangaraj * 362*414cf08bSSenthil Nathan Thangaraj * This function should contain any PU-specific actions 363*414cf08bSSenthil Nathan Thangaraj * required for aborting a prior suspend request. 364*414cf08bSSenthil Nathan Thangaraj */ 365*414cf08bSSenthil Nathan Thangaraj void pm_client_abort_suspend(void) 366*414cf08bSSenthil Nathan Thangaraj { 367*414cf08bSSenthil Nathan Thangaraj uint32_t cpu_id = plat_my_core_pos(); 368*414cf08bSSenthil Nathan Thangaraj uintptr_t val; 369*414cf08bSSenthil Nathan Thangaraj 370*414cf08bSSenthil Nathan Thangaraj /* Enable interrupts at processor level (for current cpu) */ 371*414cf08bSSenthil Nathan Thangaraj gicv3_cpuif_enable(plat_my_core_pos()); 372*414cf08bSSenthil Nathan Thangaraj 373*414cf08bSSenthil Nathan Thangaraj pm_client_lock_get(); 374*414cf08bSSenthil Nathan Thangaraj 375*414cf08bSSenthil Nathan Thangaraj /* Clear powerdown request */ 376*414cf08bSSenthil Nathan Thangaraj val = read_cpu_pwrctrl_val(); 377*414cf08bSSenthil Nathan Thangaraj val &= ~CORE_PWRDN_EN_BIT_MASK; 378*414cf08bSSenthil Nathan Thangaraj write_cpu_pwrctrl_val(val); 379*414cf08bSSenthil Nathan Thangaraj 380*414cf08bSSenthil Nathan Thangaraj isb(); 381*414cf08bSSenthil Nathan Thangaraj 382*414cf08bSSenthil Nathan Thangaraj /* Disabled power down interrupt */ 383*414cf08bSSenthil Nathan Thangaraj mmio_write_32(APU_PCIL_CORE_X_IDS_POWER_REG(cpu_id), 384*414cf08bSSenthil Nathan Thangaraj APU_PCIL_CORE_X_IDS_POWER_MASK); 385*414cf08bSSenthil Nathan Thangaraj 386*414cf08bSSenthil Nathan Thangaraj pm_client_lock_release(); 387*414cf08bSSenthil Nathan Thangaraj } 388