108438e24SVarun Wadekar /* 2500fc9e1SVarun Wadekar * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. 308438e24SVarun Wadekar * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 508438e24SVarun Wadekar */ 608438e24SVarun Wadekar 708438e24SVarun Wadekar #include <assert.h> 809d40e0eSAntonio Nino Diaz 908438e24SVarun Wadekar #include <platform_def.h> 1009d40e0eSAntonio Nino Diaz 1109d40e0eSAntonio Nino Diaz #include <arch_helpers.h> 1209d40e0eSAntonio Nino Diaz #include <common/bl_common.h> 1309d40e0eSAntonio Nino Diaz #include <common/debug.h> 1409d40e0eSAntonio Nino Diaz #include <context.h> 1509d40e0eSAntonio Nino Diaz #include <drivers/console.h> 1609d40e0eSAntonio Nino Diaz #include <lib/el3_runtime/context_mgmt.h> 1709d40e0eSAntonio Nino Diaz #include <lib/mmio.h> 1809d40e0eSAntonio Nino Diaz #include <lib/psci/psci.h> 1909d40e0eSAntonio Nino Diaz #include <plat/common/platform.h> 2009d40e0eSAntonio Nino Diaz 2109d40e0eSAntonio Nino Diaz #include <memctrl.h> 2208438e24SVarun Wadekar #include <pmc.h> 2308438e24SVarun Wadekar #include <tegra_def.h> 24322e7c3eSHarvey Hsieh #include <tegra_platform.h> 2508438e24SVarun Wadekar #include <tegra_private.h> 2608438e24SVarun Wadekar 2708438e24SVarun Wadekar extern uint64_t tegra_bl31_phys_base; 2871cb26eaSVarun Wadekar extern uint64_t tegra_sec_entry_point; 2908438e24SVarun Wadekar 3008438e24SVarun Wadekar /* 3108438e24SVarun Wadekar * The following platform setup functions are weakly defined. They 3208438e24SVarun Wadekar * provide typical implementations that will be overridden by a SoC. 3308438e24SVarun Wadekar */ 34cb95a19aSVarun Wadekar #pragma weak tegra_soc_pwr_domain_suspend_pwrdown_early 350887026eSVarun Wadekar #pragma weak tegra_soc_cpu_standby 3671cb26eaSVarun Wadekar #pragma weak tegra_soc_pwr_domain_suspend 3771cb26eaSVarun Wadekar #pragma weak tegra_soc_pwr_domain_on 3871cb26eaSVarun Wadekar #pragma weak tegra_soc_pwr_domain_off 3971cb26eaSVarun Wadekar #pragma weak tegra_soc_pwr_domain_on_finish 4026c0d9b2SVarun Wadekar #pragma weak tegra_soc_pwr_domain_power_down_wfi 413b40f993SVarun Wadekar #pragma weak tegra_soc_prepare_system_reset 4231a4957cSVarun Wadekar #pragma weak tegra_soc_prepare_system_off 43a7cd0953SVarun Wadekar #pragma weak tegra_soc_get_target_pwr_state 4408438e24SVarun Wadekar 45b36aea5aSAnthony Zhou int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state) 46cb95a19aSVarun Wadekar { 47cb95a19aSVarun Wadekar return PSCI_E_NOT_SUPPORTED; 48cb95a19aSVarun Wadekar } 49cb95a19aSVarun Wadekar 500887026eSVarun Wadekar int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state) 510887026eSVarun Wadekar { 520887026eSVarun Wadekar (void)cpu_state; 530887026eSVarun Wadekar return PSCI_E_SUCCESS; 540887026eSVarun Wadekar } 550887026eSVarun Wadekar 56b36aea5aSAnthony Zhou int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) 5708438e24SVarun Wadekar { 58b36aea5aSAnthony Zhou (void)target_state; 5908438e24SVarun Wadekar return PSCI_E_NOT_SUPPORTED; 6008438e24SVarun Wadekar } 6108438e24SVarun Wadekar 62b36aea5aSAnthony Zhou int32_t tegra_soc_pwr_domain_on(u_register_t mpidr) 6308438e24SVarun Wadekar { 64b36aea5aSAnthony Zhou (void)mpidr; 6508438e24SVarun Wadekar return PSCI_E_SUCCESS; 6608438e24SVarun Wadekar } 6708438e24SVarun Wadekar 68b36aea5aSAnthony Zhou int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state) 6908438e24SVarun Wadekar { 70b36aea5aSAnthony Zhou (void)target_state; 7108438e24SVarun Wadekar return PSCI_E_SUCCESS; 7208438e24SVarun Wadekar } 7308438e24SVarun Wadekar 74b36aea5aSAnthony Zhou int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) 7508438e24SVarun Wadekar { 76b36aea5aSAnthony Zhou (void)target_state; 7708438e24SVarun Wadekar return PSCI_E_SUCCESS; 7808438e24SVarun Wadekar } 7908438e24SVarun Wadekar 80b36aea5aSAnthony Zhou int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state) 8126c0d9b2SVarun Wadekar { 82b36aea5aSAnthony Zhou (void)target_state; 8326c0d9b2SVarun Wadekar return PSCI_E_SUCCESS; 8426c0d9b2SVarun Wadekar } 8526c0d9b2SVarun Wadekar 86b36aea5aSAnthony Zhou int32_t tegra_soc_prepare_system_reset(void) 873b40f993SVarun Wadekar { 883b40f993SVarun Wadekar return PSCI_E_SUCCESS; 893b40f993SVarun Wadekar } 903b40f993SVarun Wadekar 9131a4957cSVarun Wadekar __dead2 void tegra_soc_prepare_system_off(void) 9231a4957cSVarun Wadekar { 9331a4957cSVarun Wadekar ERROR("Tegra System Off: operation not handled.\n"); 9431a4957cSVarun Wadekar panic(); 9531a4957cSVarun Wadekar } 9631a4957cSVarun Wadekar 97b36aea5aSAnthony Zhou plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl, 98a7cd0953SVarun Wadekar const plat_local_state_t *states, 99b36aea5aSAnthony Zhou uint32_t ncpu) 100a7cd0953SVarun Wadekar { 1018539f45dSVarun Wadekar plat_local_state_t target = PLAT_MAX_OFF_STATE, temp; 102b36aea5aSAnthony Zhou uint32_t num_cpu = ncpu; 103b36aea5aSAnthony Zhou const plat_local_state_t *local_state = states; 104b36aea5aSAnthony Zhou 105b36aea5aSAnthony Zhou (void)lvl; 106a7cd0953SVarun Wadekar 1074c994002SAnthony Zhou assert(ncpu != 0U); 108a7cd0953SVarun Wadekar 109a7cd0953SVarun Wadekar do { 110b36aea5aSAnthony Zhou temp = *local_state; 111b36aea5aSAnthony Zhou if ((temp < target)) { 112a7cd0953SVarun Wadekar target = temp; 113b36aea5aSAnthony Zhou } 114b36aea5aSAnthony Zhou --num_cpu; 115b36aea5aSAnthony Zhou local_state++; 116b36aea5aSAnthony Zhou } while (num_cpu != 0U); 117a7cd0953SVarun Wadekar 118a7cd0953SVarun Wadekar return target; 119a7cd0953SVarun Wadekar } 120a7cd0953SVarun Wadekar 12108438e24SVarun Wadekar /******************************************************************************* 12271cb26eaSVarun Wadekar * This handler is called by the PSCI implementation during the `SYSTEM_SUSPEND` 12371cb26eaSVarun Wadekar * call to get the `power_state` parameter. This allows the platform to encode 12471cb26eaSVarun Wadekar * the appropriate State-ID field within the `power_state` parameter which can 12571cb26eaSVarun Wadekar * be utilized in `pwr_domain_suspend()` to suspend to system affinity level. 12608438e24SVarun Wadekar ******************************************************************************/ 12771cb26eaSVarun Wadekar void tegra_get_sys_suspend_power_state(psci_power_state_t *req_state) 12808438e24SVarun Wadekar { 129a7cd0953SVarun Wadekar /* all affinities use system suspend state id */ 130b36aea5aSAnthony Zhou for (uint32_t i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) { 131a7cd0953SVarun Wadekar req_state->pwr_domain_state[i] = PSTATE_ID_SOC_POWERDN; 13208438e24SVarun Wadekar } 133b36aea5aSAnthony Zhou } 13408438e24SVarun Wadekar 13508438e24SVarun Wadekar /******************************************************************************* 13608438e24SVarun Wadekar * Handler called when an affinity instance is about to enter standby. 13708438e24SVarun Wadekar ******************************************************************************/ 13871cb26eaSVarun Wadekar void tegra_cpu_standby(plat_local_state_t cpu_state) 13908438e24SVarun Wadekar { 14007faf4d8SVignesh Radhakrishnan u_register_t saved_scr_el3; 14107faf4d8SVignesh Radhakrishnan 142b36aea5aSAnthony Zhou (void)cpu_state; 143b36aea5aSAnthony Zhou 1440887026eSVarun Wadekar /* Tegra SoC specific handler */ 1450887026eSVarun Wadekar if (tegra_soc_cpu_standby(cpu_state) != PSCI_E_SUCCESS) 1460887026eSVarun Wadekar ERROR("%s failed\n", __func__); 1470887026eSVarun Wadekar 14807faf4d8SVignesh Radhakrishnan saved_scr_el3 = read_scr_el3(); 14907faf4d8SVignesh Radhakrishnan 15007faf4d8SVignesh Radhakrishnan /* 15107faf4d8SVignesh Radhakrishnan * As per ARM ARM D1.17.2, any physical IRQ interrupt received by the 15207faf4d8SVignesh Radhakrishnan * PE will be treated as a wake-up event, if SCR_EL3.IRQ is set to '1', 15307faf4d8SVignesh Radhakrishnan * irrespective of the value of the PSTATE.I bit value. 15407faf4d8SVignesh Radhakrishnan */ 15507faf4d8SVignesh Radhakrishnan write_scr_el3(saved_scr_el3 | SCR_IRQ_BIT); 15607faf4d8SVignesh Radhakrishnan 15708438e24SVarun Wadekar /* 15808438e24SVarun Wadekar * Enter standby state 15907faf4d8SVignesh Radhakrishnan * 16007faf4d8SVignesh Radhakrishnan * dsb & isb is good practice before using wfi to enter low power states 16108438e24SVarun Wadekar */ 16208438e24SVarun Wadekar dsb(); 16307faf4d8SVignesh Radhakrishnan isb(); 16408438e24SVarun Wadekar wfi(); 16507faf4d8SVignesh Radhakrishnan 16607faf4d8SVignesh Radhakrishnan /* 16707faf4d8SVignesh Radhakrishnan * Restore saved scr_el3 that has IRQ bit cleared as we don't want EL3 16807faf4d8SVignesh Radhakrishnan * handling any further interrupts 16907faf4d8SVignesh Radhakrishnan */ 17007faf4d8SVignesh Radhakrishnan write_scr_el3(saved_scr_el3); 17108438e24SVarun Wadekar } 17208438e24SVarun Wadekar 17308438e24SVarun Wadekar /******************************************************************************* 17408438e24SVarun Wadekar * Handler called when an affinity instance is about to be turned on. The 17508438e24SVarun Wadekar * level and mpidr determine the affinity instance. 17608438e24SVarun Wadekar ******************************************************************************/ 177b36aea5aSAnthony Zhou int32_t tegra_pwr_domain_on(u_register_t mpidr) 17808438e24SVarun Wadekar { 17971cb26eaSVarun Wadekar return tegra_soc_pwr_domain_on(mpidr); 18008438e24SVarun Wadekar } 18108438e24SVarun Wadekar 18208438e24SVarun Wadekar /******************************************************************************* 18371cb26eaSVarun Wadekar * Handler called when a power domain is about to be turned off. The 18471cb26eaSVarun Wadekar * target_state encodes the power state that each level should transition to. 18508438e24SVarun Wadekar ******************************************************************************/ 18671cb26eaSVarun Wadekar void tegra_pwr_domain_off(const psci_power_state_t *target_state) 18708438e24SVarun Wadekar { 188b36aea5aSAnthony Zhou (void)tegra_soc_pwr_domain_off(target_state); 18908438e24SVarun Wadekar } 19008438e24SVarun Wadekar 19108438e24SVarun Wadekar /******************************************************************************* 19226c0d9b2SVarun Wadekar * Handler called when a power domain is about to be suspended. The 19371cb26eaSVarun Wadekar * target_state encodes the power state that each level should transition to. 194cb95a19aSVarun Wadekar * This handler is called with SMP and data cache enabled, when 195cb95a19aSVarun Wadekar * HW_ASSISTED_COHERENCY = 0 196cb95a19aSVarun Wadekar ******************************************************************************/ 197cb95a19aSVarun Wadekar void tegra_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state) 198cb95a19aSVarun Wadekar { 199cb95a19aSVarun Wadekar tegra_soc_pwr_domain_suspend_pwrdown_early(target_state); 200cb95a19aSVarun Wadekar } 201cb95a19aSVarun Wadekar 202cb95a19aSVarun Wadekar /******************************************************************************* 203cb95a19aSVarun Wadekar * Handler called when a power domain is about to be suspended. The 204cb95a19aSVarun Wadekar * target_state encodes the power state that each level should transition to. 20508438e24SVarun Wadekar ******************************************************************************/ 20671cb26eaSVarun Wadekar void tegra_pwr_domain_suspend(const psci_power_state_t *target_state) 20708438e24SVarun Wadekar { 208b36aea5aSAnthony Zhou (void)tegra_soc_pwr_domain_suspend(target_state); 20908438e24SVarun Wadekar 2105b5928e8SVarun Wadekar /* Disable console if we are entering deep sleep. */ 2115b5928e8SVarun Wadekar if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] == 212b36aea5aSAnthony Zhou PSTATE_ID_SOC_POWERDN) { 213544c092bSAmbroise Vincent (void)console_flush(); 214544c092bSAmbroise Vincent console_switch_state(0); 215b36aea5aSAnthony Zhou } 2165b5928e8SVarun Wadekar 21708438e24SVarun Wadekar /* disable GICC */ 21808438e24SVarun Wadekar tegra_gic_cpuif_deactivate(); 21908438e24SVarun Wadekar } 22008438e24SVarun Wadekar 22108438e24SVarun Wadekar /******************************************************************************* 22226c0d9b2SVarun Wadekar * Handler called at the end of the power domain suspend sequence. The 22326c0d9b2SVarun Wadekar * target_state encodes the power state that each level should transition to. 22426c0d9b2SVarun Wadekar ******************************************************************************/ 22526c0d9b2SVarun Wadekar __dead2 void tegra_pwr_domain_power_down_wfi(const psci_power_state_t 22626c0d9b2SVarun Wadekar *target_state) 22726c0d9b2SVarun Wadekar { 22826c0d9b2SVarun Wadekar /* call the chip's power down handler */ 229b36aea5aSAnthony Zhou (void)tegra_soc_pwr_domain_power_down_wfi(target_state); 23026c0d9b2SVarun Wadekar 23126c0d9b2SVarun Wadekar wfi(); 23226c0d9b2SVarun Wadekar panic(); 23326c0d9b2SVarun Wadekar } 23426c0d9b2SVarun Wadekar 23526c0d9b2SVarun Wadekar /******************************************************************************* 23671cb26eaSVarun Wadekar * Handler called when a power domain has just been powered on after 23771cb26eaSVarun Wadekar * being turned off earlier. The target_state encodes the low power state that 23871cb26eaSVarun Wadekar * each level has woken up from. 23908438e24SVarun Wadekar ******************************************************************************/ 24071cb26eaSVarun Wadekar void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state) 24108438e24SVarun Wadekar { 242b36aea5aSAnthony Zhou const plat_params_from_bl2_t *plat_params; 24308438e24SVarun Wadekar 24408438e24SVarun Wadekar /* 24508438e24SVarun Wadekar * Initialize the GIC cpu and distributor interfaces 24608438e24SVarun Wadekar */ 247*e9e19fb2SVarun Wadekar tegra_gic_pcpu_init(); 24808438e24SVarun Wadekar 24908438e24SVarun Wadekar /* 25008438e24SVarun Wadekar * Check if we are exiting from deep sleep. 25108438e24SVarun Wadekar */ 25271cb26eaSVarun Wadekar if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] == 25371cb26eaSVarun Wadekar PSTATE_ID_SOC_POWERDN) { 25408438e24SVarun Wadekar 255544c092bSAmbroise Vincent /* Restart console output. */ 256544c092bSAmbroise Vincent console_switch_state(CONSOLE_FLAG_RUNTIME); 2575b5928e8SVarun Wadekar 25808438e24SVarun Wadekar /* 259102e4087SVarun Wadekar * Restore Memory Controller settings as it loses state 260102e4087SVarun Wadekar * during system suspend. 26108438e24SVarun Wadekar */ 262102e4087SVarun Wadekar tegra_memctrl_restore_settings(); 26308438e24SVarun Wadekar 26408438e24SVarun Wadekar /* 26508438e24SVarun Wadekar * Security configuration to allow DRAM/device access. 26608438e24SVarun Wadekar */ 26708438e24SVarun Wadekar plat_params = bl31_get_plat_params(); 268e0d4158cSVarun Wadekar tegra_memctrl_tzdram_setup(plat_params->tzdram_base, 269b36aea5aSAnthony Zhou (uint32_t)plat_params->tzdram_size); 270207680c6SVarun Wadekar 271207680c6SVarun Wadekar /* 272207680c6SVarun Wadekar * Set up the TZRAM memory aperture to allow only secure world 273207680c6SVarun Wadekar * access 274207680c6SVarun Wadekar */ 275207680c6SVarun Wadekar tegra_memctrl_tzram_setup(TEGRA_TZRAM_BASE, TEGRA_TZRAM_SIZE); 27608438e24SVarun Wadekar } 27708438e24SVarun Wadekar 27808438e24SVarun Wadekar /* 27908438e24SVarun Wadekar * Reset hardware settings. 28008438e24SVarun Wadekar */ 281b36aea5aSAnthony Zhou (void)tegra_soc_pwr_domain_on_finish(target_state); 28208438e24SVarun Wadekar } 28308438e24SVarun Wadekar 28408438e24SVarun Wadekar /******************************************************************************* 28571cb26eaSVarun Wadekar * Handler called when a power domain has just been powered on after 28671cb26eaSVarun Wadekar * having been suspended earlier. The target_state encodes the low power state 28771cb26eaSVarun Wadekar * that each level has woken up from. 28808438e24SVarun Wadekar ******************************************************************************/ 28971cb26eaSVarun Wadekar void tegra_pwr_domain_suspend_finish(const psci_power_state_t *target_state) 29008438e24SVarun Wadekar { 29171cb26eaSVarun Wadekar tegra_pwr_domain_on_finish(target_state); 29208438e24SVarun Wadekar } 29308438e24SVarun Wadekar 29408438e24SVarun Wadekar /******************************************************************************* 29508438e24SVarun Wadekar * Handler called when the system wants to be powered off 29608438e24SVarun Wadekar ******************************************************************************/ 29708438e24SVarun Wadekar __dead2 void tegra_system_off(void) 29808438e24SVarun Wadekar { 29931a4957cSVarun Wadekar INFO("Powering down system...\n"); 30031a4957cSVarun Wadekar 30131a4957cSVarun Wadekar tegra_soc_prepare_system_off(); 30208438e24SVarun Wadekar } 30308438e24SVarun Wadekar 30408438e24SVarun Wadekar /******************************************************************************* 30508438e24SVarun Wadekar * Handler called when the system wants to be restarted. 30608438e24SVarun Wadekar ******************************************************************************/ 30708438e24SVarun Wadekar __dead2 void tegra_system_reset(void) 30808438e24SVarun Wadekar { 30931a4957cSVarun Wadekar INFO("Restarting system...\n"); 31031a4957cSVarun Wadekar 3113b40f993SVarun Wadekar /* per-SoC system reset handler */ 312b36aea5aSAnthony Zhou (void)tegra_soc_prepare_system_reset(); 3133b40f993SVarun Wadekar 31408438e24SVarun Wadekar /* 31508438e24SVarun Wadekar * Program the PMC in order to restart the system. 31608438e24SVarun Wadekar */ 31708438e24SVarun Wadekar tegra_pmc_system_reset(); 31808438e24SVarun Wadekar } 31908438e24SVarun Wadekar 32008438e24SVarun Wadekar /******************************************************************************* 32171cb26eaSVarun Wadekar * Handler called to check the validity of the power state parameter. 32271cb26eaSVarun Wadekar ******************************************************************************/ 323b36aea5aSAnthony Zhou int32_t tegra_validate_power_state(uint32_t power_state, 32471cb26eaSVarun Wadekar psci_power_state_t *req_state) 32571cb26eaSVarun Wadekar { 3264c994002SAnthony Zhou assert(req_state != NULL); 32771cb26eaSVarun Wadekar 32871cb26eaSVarun Wadekar return tegra_soc_validate_power_state(power_state, req_state); 32971cb26eaSVarun Wadekar } 33071cb26eaSVarun Wadekar 33171cb26eaSVarun Wadekar /******************************************************************************* 33271cb26eaSVarun Wadekar * Platform handler called to check the validity of the non secure entrypoint. 33371cb26eaSVarun Wadekar ******************************************************************************/ 334b36aea5aSAnthony Zhou int32_t tegra_validate_ns_entrypoint(uintptr_t entrypoint) 33571cb26eaSVarun Wadekar { 336b36aea5aSAnthony Zhou int32_t ret = PSCI_E_INVALID_ADDRESS; 337b36aea5aSAnthony Zhou 33871cb26eaSVarun Wadekar /* 33971cb26eaSVarun Wadekar * Check if the non secure entrypoint lies within the non 34071cb26eaSVarun Wadekar * secure DRAM. 34171cb26eaSVarun Wadekar */ 342b36aea5aSAnthony Zhou if ((entrypoint >= TEGRA_DRAM_BASE) && (entrypoint <= TEGRA_DRAM_END)) { 343b36aea5aSAnthony Zhou ret = PSCI_E_SUCCESS; 344b36aea5aSAnthony Zhou } 34571cb26eaSVarun Wadekar 346b36aea5aSAnthony Zhou return ret; 34771cb26eaSVarun Wadekar } 34871cb26eaSVarun Wadekar 34971cb26eaSVarun Wadekar /******************************************************************************* 35008438e24SVarun Wadekar * Export the platform handlers to enable psci to invoke them 35108438e24SVarun Wadekar ******************************************************************************/ 35271cb26eaSVarun Wadekar static const plat_psci_ops_t tegra_plat_psci_ops = { 35371cb26eaSVarun Wadekar .cpu_standby = tegra_cpu_standby, 35471cb26eaSVarun Wadekar .pwr_domain_on = tegra_pwr_domain_on, 35571cb26eaSVarun Wadekar .pwr_domain_off = tegra_pwr_domain_off, 356cb95a19aSVarun Wadekar .pwr_domain_suspend_pwrdown_early = tegra_pwr_domain_suspend_pwrdown_early, 35771cb26eaSVarun Wadekar .pwr_domain_suspend = tegra_pwr_domain_suspend, 35871cb26eaSVarun Wadekar .pwr_domain_on_finish = tegra_pwr_domain_on_finish, 35971cb26eaSVarun Wadekar .pwr_domain_suspend_finish = tegra_pwr_domain_suspend_finish, 36026c0d9b2SVarun Wadekar .pwr_domain_pwr_down_wfi = tegra_pwr_domain_power_down_wfi, 36108438e24SVarun Wadekar .system_off = tegra_system_off, 36208438e24SVarun Wadekar .system_reset = tegra_system_reset, 36394c672e7SVarun Wadekar .validate_power_state = tegra_validate_power_state, 36471cb26eaSVarun Wadekar .validate_ns_entrypoint = tegra_validate_ns_entrypoint, 36571cb26eaSVarun Wadekar .get_sys_suspend_power_state = tegra_get_sys_suspend_power_state, 36608438e24SVarun Wadekar }; 36708438e24SVarun Wadekar 36808438e24SVarun Wadekar /******************************************************************************* 36971cb26eaSVarun Wadekar * Export the platform specific power ops and initialize Power Controller 37008438e24SVarun Wadekar ******************************************************************************/ 37171cb26eaSVarun Wadekar int plat_setup_psci_ops(uintptr_t sec_entrypoint, 37271cb26eaSVarun Wadekar const plat_psci_ops_t **psci_ops) 37308438e24SVarun Wadekar { 37471cb26eaSVarun Wadekar psci_power_state_t target_state = { { PSCI_LOCAL_STATE_RUN } }; 37571cb26eaSVarun Wadekar 37671cb26eaSVarun Wadekar /* 37771cb26eaSVarun Wadekar * Flush entrypoint variable to PoC since it will be 37871cb26eaSVarun Wadekar * accessed after a reset with the caches turned off. 37971cb26eaSVarun Wadekar */ 38071cb26eaSVarun Wadekar tegra_sec_entry_point = sec_entrypoint; 38171cb26eaSVarun Wadekar flush_dcache_range((uint64_t)&tegra_sec_entry_point, sizeof(uint64_t)); 38271cb26eaSVarun Wadekar 38308438e24SVarun Wadekar /* 38408438e24SVarun Wadekar * Reset hardware settings. 38508438e24SVarun Wadekar */ 386b36aea5aSAnthony Zhou (void)tegra_soc_pwr_domain_on_finish(&target_state); 38708438e24SVarun Wadekar 38808438e24SVarun Wadekar /* 38971cb26eaSVarun Wadekar * Initialize PSCI ops struct 39008438e24SVarun Wadekar */ 39171cb26eaSVarun Wadekar *psci_ops = &tegra_plat_psci_ops; 39208438e24SVarun Wadekar 39308438e24SVarun Wadekar return 0; 39408438e24SVarun Wadekar } 3952693f1dbSVarun Wadekar 3962693f1dbSVarun Wadekar /******************************************************************************* 3972693f1dbSVarun Wadekar * Platform handler to calculate the proper target power level at the 3982693f1dbSVarun Wadekar * specified affinity level 3992693f1dbSVarun Wadekar ******************************************************************************/ 4002693f1dbSVarun Wadekar plat_local_state_t plat_get_target_pwr_state(unsigned int lvl, 4012693f1dbSVarun Wadekar const plat_local_state_t *states, 4022693f1dbSVarun Wadekar unsigned int ncpu) 4032693f1dbSVarun Wadekar { 404a7cd0953SVarun Wadekar return tegra_soc_get_target_pwr_state(lvl, states, ncpu); 4052693f1dbSVarun Wadekar } 406