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 #include <assert.h> 9414cf08bSSenthil Nathan Thangaraj 10414cf08bSSenthil Nathan Thangaraj #include <common/debug.h> 113e3cdf26SRonak Jain #include <common/ep_info.h> 12414cf08bSSenthil Nathan Thangaraj #include <drivers/delay_timer.h> 13414cf08bSSenthil Nathan Thangaraj #include <lib/mmio.h> 14414cf08bSSenthil Nathan Thangaraj #include <lib/psci/psci.h> 15414cf08bSSenthil Nathan Thangaraj #include <plat/arm/common/plat_arm.h> 16414cf08bSSenthil Nathan Thangaraj #include <plat/common/platform.h> 17414cf08bSSenthil Nathan Thangaraj #include <plat_arm.h> 1827e72221SMaheedhar Bollapalli #include <plat_fdt.h> 19414cf08bSSenthil Nathan Thangaraj 20414cf08bSSenthil Nathan Thangaraj #include "def.h" 21414cf08bSSenthil Nathan Thangaraj #include <ipi.h> 22414cf08bSSenthil Nathan Thangaraj #include <plat_private.h> 23414cf08bSSenthil Nathan Thangaraj #include "pm_api_sys.h" 24414cf08bSSenthil Nathan Thangaraj #include "pm_client.h" 25414cf08bSSenthil Nathan Thangaraj #include <pm_common.h> 26414cf08bSSenthil Nathan Thangaraj #include "pm_defs.h" 27414cf08bSSenthil Nathan Thangaraj #include "pm_svc_main.h" 28414cf08bSSenthil Nathan Thangaraj 29414cf08bSSenthil Nathan Thangaraj static uintptr_t sec_entry; 30414cf08bSSenthil Nathan Thangaraj 31*08ae97c1SNaman Trivedi /* 1 sec of wait timeout for receiving idle callback */ 32*08ae97c1SNaman Trivedi #define IDLE_CB_WAIT_TIMEOUT (1000000U) 33*08ae97c1SNaman Trivedi 34414cf08bSSenthil Nathan Thangaraj static int32_t versal2_pwr_domain_on(u_register_t mpidr) 35414cf08bSSenthil Nathan Thangaraj { 36414cf08bSSenthil Nathan Thangaraj int32_t cpu_id = plat_core_pos_by_mpidr(mpidr); 37414cf08bSSenthil Nathan Thangaraj int32_t ret = (int32_t) PSCI_E_INTERN_FAIL; 38414cf08bSSenthil Nathan Thangaraj enum pm_ret_status pm_ret; 39414cf08bSSenthil Nathan Thangaraj const struct pm_proc *proc; 40414cf08bSSenthil Nathan Thangaraj 41414cf08bSSenthil Nathan Thangaraj if (cpu_id != -1) { 42414cf08bSSenthil Nathan Thangaraj proc = pm_get_proc((uint32_t)cpu_id); 43414cf08bSSenthil Nathan Thangaraj if (proc != NULL) { 44414cf08bSSenthil Nathan Thangaraj pm_ret = pm_req_wakeup(proc->node_id, 45414cf08bSSenthil Nathan Thangaraj (uint32_t) 46414cf08bSSenthil Nathan Thangaraj ((sec_entry & 0xFFFFFFFFU) | 0x1U), 47414cf08bSSenthil Nathan Thangaraj sec_entry >> 32, 0, 0); 48414cf08bSSenthil Nathan Thangaraj 49414cf08bSSenthil Nathan Thangaraj if (pm_ret == PM_RET_SUCCESS) { 50414cf08bSSenthil Nathan Thangaraj /* Clear power down request */ 51414cf08bSSenthil Nathan Thangaraj pm_client_wakeup(proc); 52414cf08bSSenthil Nathan Thangaraj ret = (int32_t) PSCI_E_SUCCESS; 53414cf08bSSenthil Nathan Thangaraj } 54414cf08bSSenthil Nathan Thangaraj } 55414cf08bSSenthil Nathan Thangaraj } 56414cf08bSSenthil Nathan Thangaraj 57414cf08bSSenthil Nathan Thangaraj return ret; 58414cf08bSSenthil Nathan Thangaraj } 59414cf08bSSenthil Nathan Thangaraj 60414cf08bSSenthil Nathan Thangaraj /** 61414cf08bSSenthil Nathan Thangaraj * versal2_pwr_domain_off() - Turn off core. 62414cf08bSSenthil Nathan Thangaraj * @target_state: Targeted state. 63414cf08bSSenthil Nathan Thangaraj */ 64414cf08bSSenthil Nathan Thangaraj static void versal2_pwr_domain_off(const psci_power_state_t *target_state) 65414cf08bSSenthil Nathan Thangaraj { 66414cf08bSSenthil Nathan Thangaraj const struct pm_proc *proc; 67414cf08bSSenthil Nathan Thangaraj uint32_t cpu_id = plat_my_core_pos(); 68414cf08bSSenthil Nathan Thangaraj enum pm_ret_status pm_ret; 69414cf08bSSenthil Nathan Thangaraj size_t i; 70414cf08bSSenthil Nathan Thangaraj 71414cf08bSSenthil Nathan Thangaraj proc = pm_get_proc(cpu_id); 72414cf08bSSenthil Nathan Thangaraj if (proc == NULL) { 73414cf08bSSenthil Nathan Thangaraj ERROR("Failed to get proc %d\n", cpu_id); 74414cf08bSSenthil Nathan Thangaraj goto err; 75414cf08bSSenthil Nathan Thangaraj } 76414cf08bSSenthil Nathan Thangaraj 77414cf08bSSenthil Nathan Thangaraj for (i = 0; i <= PLAT_MAX_PWR_LVL; i++) { 78414cf08bSSenthil Nathan Thangaraj VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n", 79414cf08bSSenthil Nathan Thangaraj __func__, i, target_state->pwr_domain_state[i]); 80414cf08bSSenthil Nathan Thangaraj } 81414cf08bSSenthil Nathan Thangaraj 82414cf08bSSenthil Nathan Thangaraj plat_gic_cpuif_disable(); 83414cf08bSSenthil Nathan Thangaraj /* 84414cf08bSSenthil Nathan Thangaraj * Send request to PMC to power down the appropriate APU CPU 85414cf08bSSenthil Nathan Thangaraj * core. 86414cf08bSSenthil Nathan Thangaraj * According to PSCI specification, CPU_off function does not 87414cf08bSSenthil Nathan Thangaraj * have resume address and CPU core can only be woken up 88414cf08bSSenthil Nathan Thangaraj * invoking CPU_on function, during which resume address will 89414cf08bSSenthil Nathan Thangaraj * be set. 90414cf08bSSenthil Nathan Thangaraj */ 919cfc7235SNaman Trivedi pm_ret = pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_OFF, 0, 923e3cdf26SRonak Jain NON_SECURE); 93414cf08bSSenthil Nathan Thangaraj 94414cf08bSSenthil Nathan Thangaraj if (pm_ret != PM_RET_SUCCESS) { 95414cf08bSSenthil Nathan Thangaraj ERROR("Failed to power down CPU %d\n", cpu_id); 96414cf08bSSenthil Nathan Thangaraj } 97414cf08bSSenthil Nathan Thangaraj err: 98414cf08bSSenthil Nathan Thangaraj return; 99414cf08bSSenthil Nathan Thangaraj } 100414cf08bSSenthil Nathan Thangaraj 101414cf08bSSenthil Nathan Thangaraj /** 102414cf08bSSenthil Nathan Thangaraj * versal2_system_reset() - Send the reset request to firmware for the 103414cf08bSSenthil Nathan Thangaraj * system to reset. This function does not 104414cf08bSSenthil Nathan Thangaraj * return as it resets system. 105414cf08bSSenthil Nathan Thangaraj */ 106414cf08bSSenthil Nathan Thangaraj static void __dead2 versal2_system_reset(void) 107414cf08bSSenthil Nathan Thangaraj { 108414cf08bSSenthil Nathan Thangaraj uint32_t timeout = 10000U; 109414cf08bSSenthil Nathan Thangaraj enum pm_ret_status pm_ret; 110414cf08bSSenthil Nathan Thangaraj int32_t ret; 111414cf08bSSenthil Nathan Thangaraj 112414cf08bSSenthil Nathan Thangaraj request_cpu_pwrdwn(); 113414cf08bSSenthil Nathan Thangaraj 114414cf08bSSenthil Nathan Thangaraj /* 115414cf08bSSenthil Nathan Thangaraj * Send the system reset request to the firmware if power down request 116414cf08bSSenthil Nathan Thangaraj * is not received from firmware. 117414cf08bSSenthil Nathan Thangaraj */ 118c0719d21SDevanshi Chauhan if (pm_pwrdwn_req_status() == false) { 119414cf08bSSenthil Nathan Thangaraj /* 120414cf08bSSenthil Nathan Thangaraj * TODO: shutdown scope for this reset needs be revised once 121414cf08bSSenthil Nathan Thangaraj * we have a clearer understanding of the overall reset scoping 122414cf08bSSenthil Nathan Thangaraj * including the implementation of SYSTEM_RESET2. 123414cf08bSSenthil Nathan Thangaraj */ 124414cf08bSSenthil Nathan Thangaraj pm_ret = pm_system_shutdown(XPM_SHUTDOWN_TYPE_RESET, 1253e3cdf26SRonak Jain pm_get_shutdown_scope(), NON_SECURE); 126414cf08bSSenthil Nathan Thangaraj 127414cf08bSSenthil Nathan Thangaraj if (pm_ret != PM_RET_SUCCESS) { 128414cf08bSSenthil Nathan Thangaraj WARN("System shutdown failed\n"); 129414cf08bSSenthil Nathan Thangaraj } 130414cf08bSSenthil Nathan Thangaraj 131414cf08bSSenthil Nathan Thangaraj /* 132414cf08bSSenthil Nathan Thangaraj * Wait for system shutdown request completed and idle callback 133414cf08bSSenthil Nathan Thangaraj * not received. 134414cf08bSSenthil Nathan Thangaraj */ 135414cf08bSSenthil Nathan Thangaraj do { 136414cf08bSSenthil Nathan Thangaraj ret = ipi_mb_enquire_status(primary_proc->ipi->local_ipi_id, 137414cf08bSSenthil Nathan Thangaraj primary_proc->ipi->remote_ipi_id); 138414cf08bSSenthil Nathan Thangaraj udelay(100); 139414cf08bSSenthil Nathan Thangaraj timeout--; 140414cf08bSSenthil Nathan Thangaraj } while ((ret != (int32_t)IPI_MB_STATUS_RECV_PENDING) && (timeout > 0U)); 141414cf08bSSenthil Nathan Thangaraj } 142414cf08bSSenthil Nathan Thangaraj 143414cf08bSSenthil Nathan Thangaraj (void)psci_cpu_off(); 144414cf08bSSenthil Nathan Thangaraj 145414cf08bSSenthil Nathan Thangaraj while (true) { 146414cf08bSSenthil Nathan Thangaraj wfi(); 147414cf08bSSenthil Nathan Thangaraj } 148414cf08bSSenthil Nathan Thangaraj } 149414cf08bSSenthil Nathan Thangaraj 150414cf08bSSenthil Nathan Thangaraj /** 151414cf08bSSenthil Nathan Thangaraj * versal2_pwr_domain_suspend() - Send request to PMC to suspend core. 152414cf08bSSenthil Nathan Thangaraj * @target_state: Targeted state. 153414cf08bSSenthil Nathan Thangaraj */ 154414cf08bSSenthil Nathan Thangaraj static void versal2_pwr_domain_suspend(const psci_power_state_t *target_state) 155414cf08bSSenthil Nathan Thangaraj { 156414cf08bSSenthil Nathan Thangaraj const struct pm_proc *proc; 157414cf08bSSenthil Nathan Thangaraj uint32_t cpu_id = plat_my_core_pos(); 158414cf08bSSenthil Nathan Thangaraj uint32_t state; 159414cf08bSSenthil Nathan Thangaraj enum pm_ret_status ret; 160414cf08bSSenthil Nathan Thangaraj size_t i; 161414cf08bSSenthil Nathan Thangaraj 162414cf08bSSenthil Nathan Thangaraj proc = pm_get_proc(cpu_id); 163414cf08bSSenthil Nathan Thangaraj if (proc == NULL) { 164414cf08bSSenthil Nathan Thangaraj ERROR("Failed to get proc %d\n", cpu_id); 165414cf08bSSenthil Nathan Thangaraj goto err; 166414cf08bSSenthil Nathan Thangaraj } 167414cf08bSSenthil Nathan Thangaraj 168414cf08bSSenthil Nathan Thangaraj for (i = 0; i <= PLAT_MAX_PWR_LVL; i++) { 169414cf08bSSenthil Nathan Thangaraj VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n", 170414cf08bSSenthil Nathan Thangaraj __func__, i, target_state->pwr_domain_state[i]); 171414cf08bSSenthil Nathan Thangaraj } 172414cf08bSSenthil Nathan Thangaraj 173414cf08bSSenthil Nathan Thangaraj plat_gic_cpuif_disable(); 174414cf08bSSenthil Nathan Thangaraj 175414cf08bSSenthil Nathan Thangaraj if (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) { 176414cf08bSSenthil Nathan Thangaraj plat_gic_save(); 177414cf08bSSenthil Nathan Thangaraj } 178414cf08bSSenthil Nathan Thangaraj 179414cf08bSSenthil Nathan Thangaraj state = (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) ? 180414cf08bSSenthil Nathan Thangaraj PM_STATE_SUSPEND_TO_RAM : PM_STATE_CPU_IDLE; 181414cf08bSSenthil Nathan Thangaraj 182414cf08bSSenthil Nathan Thangaraj /* Send request to PMC to suspend this core */ 183414cf08bSSenthil Nathan Thangaraj ret = pm_self_suspend(proc->node_id, MAX_LATENCY, state, sec_entry, 1843e3cdf26SRonak Jain NON_SECURE); 185414cf08bSSenthil Nathan Thangaraj 186414cf08bSSenthil Nathan Thangaraj if (ret != PM_RET_SUCCESS) { 187414cf08bSSenthil Nathan Thangaraj ERROR("Failed to power down CPU %d\n", cpu_id); 188414cf08bSSenthil Nathan Thangaraj } 189414cf08bSSenthil Nathan Thangaraj 190414cf08bSSenthil Nathan Thangaraj err: 191414cf08bSSenthil Nathan Thangaraj return; 192414cf08bSSenthil Nathan Thangaraj } 193414cf08bSSenthil Nathan Thangaraj 19427e72221SMaheedhar Bollapalli static int32_t versal2_validate_ns_entrypoint(uint64_t ns_entrypoint) 19527e72221SMaheedhar Bollapalli { 19627e72221SMaheedhar Bollapalli int32_t ret = PSCI_E_SUCCESS; 19727e72221SMaheedhar Bollapalli struct reserve_mem_range *rmr; 19827e72221SMaheedhar Bollapalli uint32_t index = 0, counter = 0; 19927e72221SMaheedhar Bollapalli 20027e72221SMaheedhar Bollapalli rmr = get_reserved_entries_fdt(&counter); 20127e72221SMaheedhar Bollapalli 20227e72221SMaheedhar Bollapalli VERBOSE("Validate ns_entry point %lx\n", ns_entrypoint); 20327e72221SMaheedhar Bollapalli 20427e72221SMaheedhar Bollapalli if (counter != 0) { 20527e72221SMaheedhar Bollapalli while (index < counter) { 20627e72221SMaheedhar Bollapalli if ((ns_entrypoint >= rmr[index].base) && 20727e72221SMaheedhar Bollapalli (ns_entrypoint <= rmr[index].size)) { 20827e72221SMaheedhar Bollapalli ret = PSCI_E_INVALID_ADDRESS; 20927e72221SMaheedhar Bollapalli break; 21027e72221SMaheedhar Bollapalli } 21127e72221SMaheedhar Bollapalli index++; 21227e72221SMaheedhar Bollapalli } 21327e72221SMaheedhar Bollapalli } else { 21427e72221SMaheedhar Bollapalli if ((ns_entrypoint >= BL31_BASE) && (ns_entrypoint <= BL31_LIMIT)) { 21527e72221SMaheedhar Bollapalli ret = PSCI_E_INVALID_ADDRESS; 21627e72221SMaheedhar Bollapalli } 21727e72221SMaheedhar Bollapalli } 21827e72221SMaheedhar Bollapalli 21927e72221SMaheedhar Bollapalli return ret; 22027e72221SMaheedhar Bollapalli } 22127e72221SMaheedhar Bollapalli 222414cf08bSSenthil Nathan Thangaraj static void versal2_pwr_domain_on_finish(const psci_power_state_t *target_state) 223414cf08bSSenthil Nathan Thangaraj { 224414cf08bSSenthil Nathan Thangaraj (void)target_state; 225414cf08bSSenthil Nathan Thangaraj 226414cf08bSSenthil Nathan Thangaraj /* Enable the gic cpu interface */ 227414cf08bSSenthil Nathan Thangaraj plat_gic_pcpu_init(); 228414cf08bSSenthil Nathan Thangaraj 229414cf08bSSenthil Nathan Thangaraj /* Program the gic per-cpu distributor or re-distributor interface */ 230414cf08bSSenthil Nathan Thangaraj plat_gic_cpuif_enable(); 231414cf08bSSenthil Nathan Thangaraj } 232414cf08bSSenthil Nathan Thangaraj 233414cf08bSSenthil Nathan Thangaraj /** 234414cf08bSSenthil Nathan Thangaraj * versal2_pwr_domain_suspend_finish() - Performs actions to finish 235414cf08bSSenthil Nathan Thangaraj * suspend procedure. 236414cf08bSSenthil Nathan Thangaraj * @target_state: Targeted state. 237414cf08bSSenthil Nathan Thangaraj */ 238414cf08bSSenthil Nathan Thangaraj static void versal2_pwr_domain_suspend_finish(const psci_power_state_t *target_state) 239414cf08bSSenthil Nathan Thangaraj { 240414cf08bSSenthil Nathan Thangaraj const struct pm_proc *proc; 241414cf08bSSenthil Nathan Thangaraj uint32_t cpu_id = plat_my_core_pos(); 242414cf08bSSenthil Nathan Thangaraj size_t i; 243414cf08bSSenthil Nathan Thangaraj 244414cf08bSSenthil Nathan Thangaraj proc = pm_get_proc(cpu_id); 245414cf08bSSenthil Nathan Thangaraj if (proc == NULL) { 246414cf08bSSenthil Nathan Thangaraj ERROR("Failed to get proc %d\n", cpu_id); 247414cf08bSSenthil Nathan Thangaraj goto err; 248414cf08bSSenthil Nathan Thangaraj } 249414cf08bSSenthil Nathan Thangaraj 250414cf08bSSenthil Nathan Thangaraj for (i = 0; i <= PLAT_MAX_PWR_LVL; i++) { 251414cf08bSSenthil Nathan Thangaraj VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n", 252414cf08bSSenthil Nathan Thangaraj __func__, i, target_state->pwr_domain_state[i]); 253414cf08bSSenthil Nathan Thangaraj } 254414cf08bSSenthil Nathan Thangaraj 255414cf08bSSenthil Nathan Thangaraj /* Clear the APU power control register for this cpu */ 256414cf08bSSenthil Nathan Thangaraj pm_client_wakeup(proc); 257414cf08bSSenthil Nathan Thangaraj 258414cf08bSSenthil Nathan Thangaraj /* APU was turned off, so restore GIC context */ 259414cf08bSSenthil Nathan Thangaraj if (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) { 260414cf08bSSenthil Nathan Thangaraj plat_gic_resume(); 261414cf08bSSenthil Nathan Thangaraj } 262414cf08bSSenthil Nathan Thangaraj 263414cf08bSSenthil Nathan Thangaraj plat_gic_cpuif_enable(); 264414cf08bSSenthil Nathan Thangaraj 265414cf08bSSenthil Nathan Thangaraj err: 266414cf08bSSenthil Nathan Thangaraj return; 267414cf08bSSenthil Nathan Thangaraj } 268414cf08bSSenthil Nathan Thangaraj 269414cf08bSSenthil Nathan Thangaraj /** 270414cf08bSSenthil Nathan Thangaraj * versal2_system_off() - Send the system off request to firmware. 271414cf08bSSenthil Nathan Thangaraj * This function does not return as it puts core into WFI 272414cf08bSSenthil Nathan Thangaraj */ 273414cf08bSSenthil Nathan Thangaraj static void __dead2 versal2_system_off(void) 274414cf08bSSenthil Nathan Thangaraj { 275*08ae97c1SNaman Trivedi uint64_t timeout; 276414cf08bSSenthil Nathan Thangaraj enum pm_ret_status ret; 277414cf08bSSenthil Nathan Thangaraj 278*08ae97c1SNaman Trivedi request_cpu_pwrdwn(); 279*08ae97c1SNaman Trivedi 280414cf08bSSenthil Nathan Thangaraj /* Send the power down request to the PMC */ 281414cf08bSSenthil Nathan Thangaraj ret = pm_system_shutdown(XPM_SHUTDOWN_TYPE_SHUTDOWN, 2823e3cdf26SRonak Jain pm_get_shutdown_scope(), NON_SECURE); 283414cf08bSSenthil Nathan Thangaraj 284414cf08bSSenthil Nathan Thangaraj if (ret != PM_RET_SUCCESS) { 285414cf08bSSenthil Nathan Thangaraj ERROR("System shutdown failed\n"); 286414cf08bSSenthil Nathan Thangaraj } 287414cf08bSSenthil Nathan Thangaraj 288*08ae97c1SNaman Trivedi /* 289*08ae97c1SNaman Trivedi * Wait for system shutdown request completed and idle callback 290*08ae97c1SNaman Trivedi * not received. 291*08ae97c1SNaman Trivedi */ 292*08ae97c1SNaman Trivedi timeout = timeout_init_us(IDLE_CB_WAIT_TIMEOUT); 293*08ae97c1SNaman Trivedi do { 294*08ae97c1SNaman Trivedi ret = ipi_mb_enquire_status(primary_proc->ipi->local_ipi_id, 295*08ae97c1SNaman Trivedi primary_proc->ipi->remote_ipi_id); 296*08ae97c1SNaman Trivedi udelay(100); 297*08ae97c1SNaman Trivedi } while ((ret != (int32_t)IPI_MB_STATUS_RECV_PENDING) && !timeout_elapsed(timeout)); 298*08ae97c1SNaman Trivedi 299*08ae97c1SNaman Trivedi (void)psci_cpu_off(); 300*08ae97c1SNaman Trivedi 301414cf08bSSenthil Nathan Thangaraj while (true) { 302414cf08bSSenthil Nathan Thangaraj wfi(); 303414cf08bSSenthil Nathan Thangaraj } 304414cf08bSSenthil Nathan Thangaraj } 305414cf08bSSenthil Nathan Thangaraj 306414cf08bSSenthil Nathan Thangaraj /** 307414cf08bSSenthil Nathan Thangaraj * versal2_validate_power_state() - Ensure that the power state 308414cf08bSSenthil Nathan Thangaraj * parameter in request is valid. 309414cf08bSSenthil Nathan Thangaraj * @power_state: Power state of core. 310414cf08bSSenthil Nathan Thangaraj * @req_state: Requested state. 311414cf08bSSenthil Nathan Thangaraj * 312414cf08bSSenthil Nathan Thangaraj * Return: Returns status, either PSCI_E_SUCCESS or reason. 313414cf08bSSenthil Nathan Thangaraj */ 314414cf08bSSenthil Nathan Thangaraj static int32_t versal2_validate_power_state(unsigned int power_state, 315414cf08bSSenthil Nathan Thangaraj psci_power_state_t *req_state) 316414cf08bSSenthil Nathan Thangaraj { 317414cf08bSSenthil Nathan Thangaraj uint32_t pstate = psci_get_pstate_type(power_state); 318414cf08bSSenthil Nathan Thangaraj int32_t ret = PSCI_E_SUCCESS; 319414cf08bSSenthil Nathan Thangaraj 320414cf08bSSenthil Nathan Thangaraj VERBOSE("%s: power_state: 0x%x\n", __func__, power_state); 321414cf08bSSenthil Nathan Thangaraj 322414cf08bSSenthil Nathan Thangaraj assert(req_state); 323414cf08bSSenthil Nathan Thangaraj 324414cf08bSSenthil Nathan Thangaraj /* Sanity check the requested state */ 325414cf08bSSenthil Nathan Thangaraj if (pstate == PSTATE_TYPE_STANDBY) { 326414cf08bSSenthil Nathan Thangaraj req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_RET_STATE; 327414cf08bSSenthil Nathan Thangaraj } else { 328414cf08bSSenthil Nathan Thangaraj req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_OFF_STATE; 329414cf08bSSenthil Nathan Thangaraj } 330414cf08bSSenthil Nathan Thangaraj 331414cf08bSSenthil Nathan Thangaraj /* The 'state_id' is expected to be zero */ 332414cf08bSSenthil Nathan Thangaraj if (psci_get_pstate_id(power_state) != 0U) { 333414cf08bSSenthil Nathan Thangaraj ret = PSCI_E_INVALID_PARAMS; 334414cf08bSSenthil Nathan Thangaraj } 335414cf08bSSenthil Nathan Thangaraj 336414cf08bSSenthil Nathan Thangaraj return ret; 337414cf08bSSenthil Nathan Thangaraj } 338414cf08bSSenthil Nathan Thangaraj 339414cf08bSSenthil Nathan Thangaraj /** 340414cf08bSSenthil Nathan Thangaraj * versal2_get_sys_suspend_power_state() - Get power state for system 341414cf08bSSenthil Nathan Thangaraj * suspend. 342414cf08bSSenthil Nathan Thangaraj * @req_state: Requested state. 343414cf08bSSenthil Nathan Thangaraj */ 344414cf08bSSenthil Nathan Thangaraj static void versal2_get_sys_suspend_power_state(psci_power_state_t *req_state) 345414cf08bSSenthil Nathan Thangaraj { 346414cf08bSSenthil Nathan Thangaraj uint64_t i; 347414cf08bSSenthil Nathan Thangaraj 348414cf08bSSenthil Nathan Thangaraj for (i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) { 349414cf08bSSenthil Nathan Thangaraj req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE; 350414cf08bSSenthil Nathan Thangaraj } 351414cf08bSSenthil Nathan Thangaraj } 352414cf08bSSenthil Nathan Thangaraj 353414cf08bSSenthil Nathan Thangaraj /** 354414cf08bSSenthil Nathan Thangaraj * Export the platform specific power ops. 355414cf08bSSenthil Nathan Thangaraj */ 356414cf08bSSenthil Nathan Thangaraj static const struct plat_psci_ops versal2_nopmc_psci_ops = { 357414cf08bSSenthil Nathan Thangaraj .pwr_domain_on = versal2_pwr_domain_on, 358414cf08bSSenthil Nathan Thangaraj .pwr_domain_off = versal2_pwr_domain_off, 359414cf08bSSenthil Nathan Thangaraj .pwr_domain_on_finish = versal2_pwr_domain_on_finish, 360414cf08bSSenthil Nathan Thangaraj .pwr_domain_suspend = versal2_pwr_domain_suspend, 361414cf08bSSenthil Nathan Thangaraj .pwr_domain_suspend_finish = versal2_pwr_domain_suspend_finish, 362414cf08bSSenthil Nathan Thangaraj .system_off = versal2_system_off, 363414cf08bSSenthil Nathan Thangaraj .system_reset = versal2_system_reset, 36427e72221SMaheedhar Bollapalli .validate_ns_entrypoint = versal2_validate_ns_entrypoint, 365414cf08bSSenthil Nathan Thangaraj .validate_power_state = versal2_validate_power_state, 366414cf08bSSenthil Nathan Thangaraj .get_sys_suspend_power_state = versal2_get_sys_suspend_power_state, 367414cf08bSSenthil Nathan Thangaraj }; 368414cf08bSSenthil Nathan Thangaraj 369414cf08bSSenthil Nathan Thangaraj int plat_setup_psci_ops(uintptr_t sec_entrypoint, 370414cf08bSSenthil Nathan Thangaraj const struct plat_psci_ops **psci_ops) 371414cf08bSSenthil Nathan Thangaraj { 372414cf08bSSenthil Nathan Thangaraj sec_entry = sec_entrypoint; 373414cf08bSSenthil Nathan Thangaraj 374414cf08bSSenthil Nathan Thangaraj VERBOSE("Setting up entry point %lx\n", sec_entry); 375414cf08bSSenthil Nathan Thangaraj 376414cf08bSSenthil Nathan Thangaraj *psci_ops = &versal2_nopmc_psci_ops; 377414cf08bSSenthil Nathan Thangaraj 378414cf08bSSenthil Nathan Thangaraj return 0; 379414cf08bSSenthil Nathan Thangaraj } 380414cf08bSSenthil Nathan Thangaraj 381414cf08bSSenthil Nathan Thangaraj int32_t sip_svc_setup_init(void) 382414cf08bSSenthil Nathan Thangaraj { 383414cf08bSSenthil Nathan Thangaraj return pm_setup(); 384414cf08bSSenthil Nathan Thangaraj } 385414cf08bSSenthil Nathan Thangaraj 386414cf08bSSenthil Nathan Thangaraj uint64_t smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, 387414cf08bSSenthil Nathan Thangaraj const void *cookie, void *handle, uint64_t flags) 388414cf08bSSenthil Nathan Thangaraj { 389414cf08bSSenthil Nathan Thangaraj return pm_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags); 390414cf08bSSenthil Nathan Thangaraj } 391