108438e24SVarun Wadekar /* 2*a9e0260cSVignesh Radhakrishnan * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. 308438e24SVarun Wadekar * 408438e24SVarun Wadekar * Redistribution and use in source and binary forms, with or without 508438e24SVarun Wadekar * modification, are permitted provided that the following conditions are met: 608438e24SVarun Wadekar * 708438e24SVarun Wadekar * Redistributions of source code must retain the above copyright notice, this 808438e24SVarun Wadekar * list of conditions and the following disclaimer. 908438e24SVarun Wadekar * 1008438e24SVarun Wadekar * Redistributions in binary form must reproduce the above copyright notice, 1108438e24SVarun Wadekar * this list of conditions and the following disclaimer in the documentation 1208438e24SVarun Wadekar * and/or other materials provided with the distribution. 1308438e24SVarun Wadekar * 1408438e24SVarun Wadekar * Neither the name of ARM nor the names of its contributors may be used 1508438e24SVarun Wadekar * to endorse or promote products derived from this software without specific 1608438e24SVarun Wadekar * prior written permission. 1708438e24SVarun Wadekar * 1808438e24SVarun Wadekar * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 1908438e24SVarun Wadekar * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2008438e24SVarun Wadekar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2108438e24SVarun Wadekar * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 2208438e24SVarun Wadekar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2308438e24SVarun Wadekar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2408438e24SVarun Wadekar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2508438e24SVarun Wadekar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2608438e24SVarun Wadekar * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2708438e24SVarun Wadekar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2808438e24SVarun Wadekar * POSSIBILITY OF SUCH DAMAGE. 2908438e24SVarun Wadekar */ 3008438e24SVarun Wadekar 3108438e24SVarun Wadekar #include <arch_helpers.h> 3208438e24SVarun Wadekar #include <assert.h> 3308438e24SVarun Wadekar #include <bl_common.h> 3408438e24SVarun Wadekar #include <context.h> 3508438e24SVarun Wadekar #include <context_mgmt.h> 365b5928e8SVarun Wadekar #include <console.h> 3708438e24SVarun Wadekar #include <debug.h> 3808438e24SVarun Wadekar #include <memctrl.h> 3908438e24SVarun Wadekar #include <mmio.h> 4008438e24SVarun Wadekar #include <platform.h> 4108438e24SVarun Wadekar #include <platform_def.h> 4208438e24SVarun Wadekar #include <pmc.h> 4308438e24SVarun Wadekar #include <psci.h> 4408438e24SVarun Wadekar #include <tegra_def.h> 4508438e24SVarun Wadekar #include <tegra_private.h> 4608438e24SVarun Wadekar 4708438e24SVarun Wadekar extern uint64_t tegra_bl31_phys_base; 4871cb26eaSVarun Wadekar extern uint64_t tegra_sec_entry_point; 495b5928e8SVarun Wadekar extern uint64_t tegra_console_base; 5008438e24SVarun Wadekar 5108438e24SVarun Wadekar /* 52*a9e0260cSVignesh Radhakrishnan * tegra_fake_system_suspend acts as a boolean var controlling whether 53*a9e0260cSVignesh Radhakrishnan * we are going to take fake system suspend code or normal system suspend code 54*a9e0260cSVignesh Radhakrishnan * path. This variable is set inside the sip call handlers,when the kernel 55*a9e0260cSVignesh Radhakrishnan * requests a SIP call to set the suspend debug flags. 56*a9e0260cSVignesh Radhakrishnan */ 57*a9e0260cSVignesh Radhakrishnan uint8_t tegra_fake_system_suspend; 58*a9e0260cSVignesh Radhakrishnan 59*a9e0260cSVignesh Radhakrishnan /* 6008438e24SVarun Wadekar * The following platform setup functions are weakly defined. They 6108438e24SVarun Wadekar * provide typical implementations that will be overridden by a SoC. 6208438e24SVarun Wadekar */ 6371cb26eaSVarun Wadekar #pragma weak tegra_soc_pwr_domain_suspend 6471cb26eaSVarun Wadekar #pragma weak tegra_soc_pwr_domain_on 6571cb26eaSVarun Wadekar #pragma weak tegra_soc_pwr_domain_off 6671cb26eaSVarun Wadekar #pragma weak tegra_soc_pwr_domain_on_finish 6726c0d9b2SVarun Wadekar #pragma weak tegra_soc_pwr_domain_power_down_wfi 683b40f993SVarun Wadekar #pragma weak tegra_soc_prepare_system_reset 6931a4957cSVarun Wadekar #pragma weak tegra_soc_prepare_system_off 70a7cd0953SVarun Wadekar #pragma weak tegra_soc_get_target_pwr_state 7108438e24SVarun Wadekar 7271cb26eaSVarun Wadekar int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) 7308438e24SVarun Wadekar { 7408438e24SVarun Wadekar return PSCI_E_NOT_SUPPORTED; 7508438e24SVarun Wadekar } 7608438e24SVarun Wadekar 7771cb26eaSVarun Wadekar int tegra_soc_pwr_domain_on(u_register_t mpidr) 7808438e24SVarun Wadekar { 7908438e24SVarun Wadekar return PSCI_E_SUCCESS; 8008438e24SVarun Wadekar } 8108438e24SVarun Wadekar 8271cb26eaSVarun Wadekar int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state) 8308438e24SVarun Wadekar { 8408438e24SVarun Wadekar return PSCI_E_SUCCESS; 8508438e24SVarun Wadekar } 8608438e24SVarun Wadekar 8771cb26eaSVarun Wadekar int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) 8808438e24SVarun Wadekar { 8908438e24SVarun Wadekar return PSCI_E_SUCCESS; 9008438e24SVarun Wadekar } 9108438e24SVarun Wadekar 9226c0d9b2SVarun Wadekar int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state) 9326c0d9b2SVarun Wadekar { 9426c0d9b2SVarun Wadekar return PSCI_E_SUCCESS; 9526c0d9b2SVarun Wadekar } 9626c0d9b2SVarun Wadekar 973b40f993SVarun Wadekar int tegra_soc_prepare_system_reset(void) 983b40f993SVarun Wadekar { 993b40f993SVarun Wadekar return PSCI_E_SUCCESS; 1003b40f993SVarun Wadekar } 1013b40f993SVarun Wadekar 10231a4957cSVarun Wadekar __dead2 void tegra_soc_prepare_system_off(void) 10331a4957cSVarun Wadekar { 10431a4957cSVarun Wadekar ERROR("Tegra System Off: operation not handled.\n"); 10531a4957cSVarun Wadekar panic(); 10631a4957cSVarun Wadekar } 10731a4957cSVarun Wadekar 108a7cd0953SVarun Wadekar plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl, 109a7cd0953SVarun Wadekar const plat_local_state_t *states, 110a7cd0953SVarun Wadekar unsigned int ncpu) 111a7cd0953SVarun Wadekar { 1128539f45dSVarun Wadekar plat_local_state_t target = PLAT_MAX_OFF_STATE, temp; 113a7cd0953SVarun Wadekar 114a7cd0953SVarun Wadekar assert(ncpu); 115a7cd0953SVarun Wadekar 116a7cd0953SVarun Wadekar do { 117a7cd0953SVarun Wadekar temp = *states++; 1188539f45dSVarun Wadekar if ((temp < target)) 119a7cd0953SVarun Wadekar target = temp; 120a7cd0953SVarun Wadekar } while (--ncpu); 121a7cd0953SVarun Wadekar 122a7cd0953SVarun Wadekar return target; 123a7cd0953SVarun Wadekar } 124a7cd0953SVarun Wadekar 12508438e24SVarun Wadekar /******************************************************************************* 12671cb26eaSVarun Wadekar * This handler is called by the PSCI implementation during the `SYSTEM_SUSPEND` 12771cb26eaSVarun Wadekar * call to get the `power_state` parameter. This allows the platform to encode 12871cb26eaSVarun Wadekar * the appropriate State-ID field within the `power_state` parameter which can 12971cb26eaSVarun Wadekar * be utilized in `pwr_domain_suspend()` to suspend to system affinity level. 13008438e24SVarun Wadekar ******************************************************************************/ 13171cb26eaSVarun Wadekar void tegra_get_sys_suspend_power_state(psci_power_state_t *req_state) 13208438e24SVarun Wadekar { 133a7cd0953SVarun Wadekar /* all affinities use system suspend state id */ 134a7cd0953SVarun Wadekar for (int i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) 135a7cd0953SVarun Wadekar req_state->pwr_domain_state[i] = PSTATE_ID_SOC_POWERDN; 13608438e24SVarun Wadekar } 13708438e24SVarun Wadekar 13808438e24SVarun Wadekar /******************************************************************************* 13908438e24SVarun Wadekar * Handler called when an affinity instance is about to enter standby. 14008438e24SVarun Wadekar ******************************************************************************/ 14171cb26eaSVarun Wadekar void tegra_cpu_standby(plat_local_state_t cpu_state) 14208438e24SVarun Wadekar { 14308438e24SVarun Wadekar /* 14408438e24SVarun Wadekar * Enter standby state 14508438e24SVarun Wadekar * dsb is good practice before using wfi to enter low power states 14608438e24SVarun Wadekar */ 14708438e24SVarun Wadekar dsb(); 14808438e24SVarun Wadekar wfi(); 14908438e24SVarun Wadekar } 15008438e24SVarun Wadekar 15108438e24SVarun Wadekar /******************************************************************************* 15208438e24SVarun Wadekar * Handler called when an affinity instance is about to be turned on. The 15308438e24SVarun Wadekar * level and mpidr determine the affinity instance. 15408438e24SVarun Wadekar ******************************************************************************/ 15571cb26eaSVarun Wadekar int tegra_pwr_domain_on(u_register_t mpidr) 15608438e24SVarun Wadekar { 15771cb26eaSVarun Wadekar return tegra_soc_pwr_domain_on(mpidr); 15808438e24SVarun Wadekar } 15908438e24SVarun Wadekar 16008438e24SVarun Wadekar /******************************************************************************* 16171cb26eaSVarun Wadekar * Handler called when a power domain is about to be turned off. The 16271cb26eaSVarun Wadekar * target_state encodes the power state that each level should transition to. 16308438e24SVarun Wadekar ******************************************************************************/ 16471cb26eaSVarun Wadekar void tegra_pwr_domain_off(const psci_power_state_t *target_state) 16508438e24SVarun Wadekar { 16671cb26eaSVarun Wadekar tegra_soc_pwr_domain_off(target_state); 16708438e24SVarun Wadekar } 16808438e24SVarun Wadekar 16908438e24SVarun Wadekar /******************************************************************************* 17026c0d9b2SVarun Wadekar * Handler called when a power domain is about to be suspended. The 17171cb26eaSVarun Wadekar * target_state encodes the power state that each level should transition to. 17208438e24SVarun Wadekar ******************************************************************************/ 17371cb26eaSVarun Wadekar void tegra_pwr_domain_suspend(const psci_power_state_t *target_state) 17408438e24SVarun Wadekar { 17571cb26eaSVarun Wadekar tegra_soc_pwr_domain_suspend(target_state); 17608438e24SVarun Wadekar 1775b5928e8SVarun Wadekar /* Disable console if we are entering deep sleep. */ 1785b5928e8SVarun Wadekar if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] == 1795b5928e8SVarun Wadekar PSTATE_ID_SOC_POWERDN) 1805b5928e8SVarun Wadekar console_uninit(); 1815b5928e8SVarun Wadekar 18208438e24SVarun Wadekar /* disable GICC */ 18308438e24SVarun Wadekar tegra_gic_cpuif_deactivate(); 18408438e24SVarun Wadekar } 18508438e24SVarun Wadekar 18608438e24SVarun Wadekar /******************************************************************************* 18726c0d9b2SVarun Wadekar * Handler called at the end of the power domain suspend sequence. The 18826c0d9b2SVarun Wadekar * target_state encodes the power state that each level should transition to. 18926c0d9b2SVarun Wadekar ******************************************************************************/ 19026c0d9b2SVarun Wadekar __dead2 void tegra_pwr_domain_power_down_wfi(const psci_power_state_t 19126c0d9b2SVarun Wadekar *target_state) 19226c0d9b2SVarun Wadekar { 193*a9e0260cSVignesh Radhakrishnan uint8_t pwr_state = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]; 194*a9e0260cSVignesh Radhakrishnan uint64_t rmr_el3 = 0; 195*a9e0260cSVignesh Radhakrishnan 19626c0d9b2SVarun Wadekar /* call the chip's power down handler */ 19726c0d9b2SVarun Wadekar tegra_soc_pwr_domain_power_down_wfi(target_state); 19826c0d9b2SVarun Wadekar 199*a9e0260cSVignesh Radhakrishnan /* 200*a9e0260cSVignesh Radhakrishnan * If we are in fake system suspend mode, ensure we start doing 201*a9e0260cSVignesh Radhakrishnan * procedures that help in looping back towards system suspend exit 202*a9e0260cSVignesh Radhakrishnan * instead of calling WFI by requesting a warm reset. 203*a9e0260cSVignesh Radhakrishnan * Else, just call WFI to enter low power state. 204*a9e0260cSVignesh Radhakrishnan */ 205*a9e0260cSVignesh Radhakrishnan if ((tegra_fake_system_suspend != 0U) && 206*a9e0260cSVignesh Radhakrishnan (pwr_state == (uint8_t)PSTATE_ID_SOC_POWERDN)) { 207*a9e0260cSVignesh Radhakrishnan 208*a9e0260cSVignesh Radhakrishnan /* warm reboot */ 209*a9e0260cSVignesh Radhakrishnan rmr_el3 = read_rmr_el3(); 210*a9e0260cSVignesh Radhakrishnan write_rmr_el3(rmr_el3 | RMR_WARM_RESET_CPU); 211*a9e0260cSVignesh Radhakrishnan 212*a9e0260cSVignesh Radhakrishnan } else { 21326c0d9b2SVarun Wadekar /* enter power down state */ 21426c0d9b2SVarun Wadekar wfi(); 215*a9e0260cSVignesh Radhakrishnan } 21626c0d9b2SVarun Wadekar 21726c0d9b2SVarun Wadekar /* we can never reach here */ 21826c0d9b2SVarun Wadekar panic(); 21926c0d9b2SVarun Wadekar } 22026c0d9b2SVarun Wadekar 22126c0d9b2SVarun Wadekar /******************************************************************************* 22271cb26eaSVarun Wadekar * Handler called when a power domain has just been powered on after 22371cb26eaSVarun Wadekar * being turned off earlier. The target_state encodes the low power state that 22471cb26eaSVarun Wadekar * each level has woken up from. 22508438e24SVarun Wadekar ******************************************************************************/ 22671cb26eaSVarun Wadekar void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state) 22708438e24SVarun Wadekar { 22808438e24SVarun Wadekar plat_params_from_bl2_t *plat_params; 22908438e24SVarun Wadekar 23008438e24SVarun Wadekar /* 23108438e24SVarun Wadekar * Initialize the GIC cpu and distributor interfaces 23208438e24SVarun Wadekar */ 233d3360301SVarun Wadekar plat_gic_setup(); 23408438e24SVarun Wadekar 23508438e24SVarun Wadekar /* 23608438e24SVarun Wadekar * Check if we are exiting from deep sleep. 23708438e24SVarun Wadekar */ 23871cb26eaSVarun Wadekar if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] == 23971cb26eaSVarun Wadekar PSTATE_ID_SOC_POWERDN) { 24008438e24SVarun Wadekar 2415b5928e8SVarun Wadekar /* Initialize the runtime console */ 2429b514f83SDamon Duan if (tegra_console_base != (uint64_t)0) { 2435b5928e8SVarun Wadekar console_init(tegra_console_base, TEGRA_BOOT_UART_CLK_IN_HZ, 2445b5928e8SVarun Wadekar TEGRA_CONSOLE_BAUDRATE); 2459b514f83SDamon Duan } 2465b5928e8SVarun Wadekar 24708438e24SVarun Wadekar /* 248102e4087SVarun Wadekar * Restore Memory Controller settings as it loses state 249102e4087SVarun Wadekar * during system suspend. 25008438e24SVarun Wadekar */ 251102e4087SVarun Wadekar tegra_memctrl_restore_settings(); 25208438e24SVarun Wadekar 25308438e24SVarun Wadekar /* 25408438e24SVarun Wadekar * Security configuration to allow DRAM/device access. 25508438e24SVarun Wadekar */ 25608438e24SVarun Wadekar plat_params = bl31_get_plat_params(); 257e0d4158cSVarun Wadekar tegra_memctrl_tzdram_setup(plat_params->tzdram_base, 25808438e24SVarun Wadekar plat_params->tzdram_size); 259207680c6SVarun Wadekar 260207680c6SVarun Wadekar /* 261207680c6SVarun Wadekar * Set up the TZRAM memory aperture to allow only secure world 262207680c6SVarun Wadekar * access 263207680c6SVarun Wadekar */ 264207680c6SVarun Wadekar tegra_memctrl_tzram_setup(TEGRA_TZRAM_BASE, TEGRA_TZRAM_SIZE); 26508438e24SVarun Wadekar } 26608438e24SVarun Wadekar 26708438e24SVarun Wadekar /* 26808438e24SVarun Wadekar * Reset hardware settings. 26908438e24SVarun Wadekar */ 27071cb26eaSVarun Wadekar tegra_soc_pwr_domain_on_finish(target_state); 27108438e24SVarun Wadekar } 27208438e24SVarun Wadekar 27308438e24SVarun Wadekar /******************************************************************************* 27471cb26eaSVarun Wadekar * Handler called when a power domain has just been powered on after 27571cb26eaSVarun Wadekar * having been suspended earlier. The target_state encodes the low power state 27671cb26eaSVarun Wadekar * that each level has woken up from. 27708438e24SVarun Wadekar ******************************************************************************/ 27871cb26eaSVarun Wadekar void tegra_pwr_domain_suspend_finish(const psci_power_state_t *target_state) 27908438e24SVarun Wadekar { 28071cb26eaSVarun Wadekar tegra_pwr_domain_on_finish(target_state); 28108438e24SVarun Wadekar } 28208438e24SVarun Wadekar 28308438e24SVarun Wadekar /******************************************************************************* 28408438e24SVarun Wadekar * Handler called when the system wants to be powered off 28508438e24SVarun Wadekar ******************************************************************************/ 28608438e24SVarun Wadekar __dead2 void tegra_system_off(void) 28708438e24SVarun Wadekar { 28831a4957cSVarun Wadekar INFO("Powering down system...\n"); 28931a4957cSVarun Wadekar 29031a4957cSVarun Wadekar tegra_soc_prepare_system_off(); 29108438e24SVarun Wadekar } 29208438e24SVarun Wadekar 29308438e24SVarun Wadekar /******************************************************************************* 29408438e24SVarun Wadekar * Handler called when the system wants to be restarted. 29508438e24SVarun Wadekar ******************************************************************************/ 29608438e24SVarun Wadekar __dead2 void tegra_system_reset(void) 29708438e24SVarun Wadekar { 29831a4957cSVarun Wadekar INFO("Restarting system...\n"); 29931a4957cSVarun Wadekar 3003b40f993SVarun Wadekar /* per-SoC system reset handler */ 3013b40f993SVarun Wadekar tegra_soc_prepare_system_reset(); 3023b40f993SVarun Wadekar 30308438e24SVarun Wadekar /* 30408438e24SVarun Wadekar * Program the PMC in order to restart the system. 30508438e24SVarun Wadekar */ 30608438e24SVarun Wadekar tegra_pmc_system_reset(); 30708438e24SVarun Wadekar } 30808438e24SVarun Wadekar 30908438e24SVarun Wadekar /******************************************************************************* 31071cb26eaSVarun Wadekar * Handler called to check the validity of the power state parameter. 31171cb26eaSVarun Wadekar ******************************************************************************/ 31271cb26eaSVarun Wadekar int32_t tegra_validate_power_state(unsigned int power_state, 31371cb26eaSVarun Wadekar psci_power_state_t *req_state) 31471cb26eaSVarun Wadekar { 31571cb26eaSVarun Wadekar assert(req_state); 31671cb26eaSVarun Wadekar 31771cb26eaSVarun Wadekar return tegra_soc_validate_power_state(power_state, req_state); 31871cb26eaSVarun Wadekar } 31971cb26eaSVarun Wadekar 32071cb26eaSVarun Wadekar /******************************************************************************* 32171cb26eaSVarun Wadekar * Platform handler called to check the validity of the non secure entrypoint. 32271cb26eaSVarun Wadekar ******************************************************************************/ 32371cb26eaSVarun Wadekar int tegra_validate_ns_entrypoint(uintptr_t entrypoint) 32471cb26eaSVarun Wadekar { 32571cb26eaSVarun Wadekar /* 32671cb26eaSVarun Wadekar * Check if the non secure entrypoint lies within the non 32771cb26eaSVarun Wadekar * secure DRAM. 32871cb26eaSVarun Wadekar */ 32971cb26eaSVarun Wadekar if ((entrypoint >= TEGRA_DRAM_BASE) && (entrypoint <= TEGRA_DRAM_END)) 33071cb26eaSVarun Wadekar return PSCI_E_SUCCESS; 33171cb26eaSVarun Wadekar 33271cb26eaSVarun Wadekar return PSCI_E_INVALID_ADDRESS; 33371cb26eaSVarun Wadekar } 33471cb26eaSVarun Wadekar 33571cb26eaSVarun Wadekar /******************************************************************************* 33608438e24SVarun Wadekar * Export the platform handlers to enable psci to invoke them 33708438e24SVarun Wadekar ******************************************************************************/ 33871cb26eaSVarun Wadekar static const plat_psci_ops_t tegra_plat_psci_ops = { 33971cb26eaSVarun Wadekar .cpu_standby = tegra_cpu_standby, 34071cb26eaSVarun Wadekar .pwr_domain_on = tegra_pwr_domain_on, 34171cb26eaSVarun Wadekar .pwr_domain_off = tegra_pwr_domain_off, 34271cb26eaSVarun Wadekar .pwr_domain_suspend = tegra_pwr_domain_suspend, 34371cb26eaSVarun Wadekar .pwr_domain_on_finish = tegra_pwr_domain_on_finish, 34471cb26eaSVarun Wadekar .pwr_domain_suspend_finish = tegra_pwr_domain_suspend_finish, 34526c0d9b2SVarun Wadekar .pwr_domain_pwr_down_wfi = tegra_pwr_domain_power_down_wfi, 34608438e24SVarun Wadekar .system_off = tegra_system_off, 34708438e24SVarun Wadekar .system_reset = tegra_system_reset, 34894c672e7SVarun Wadekar .validate_power_state = tegra_validate_power_state, 34971cb26eaSVarun Wadekar .validate_ns_entrypoint = tegra_validate_ns_entrypoint, 35071cb26eaSVarun Wadekar .get_sys_suspend_power_state = tegra_get_sys_suspend_power_state, 35108438e24SVarun Wadekar }; 35208438e24SVarun Wadekar 35308438e24SVarun Wadekar /******************************************************************************* 35471cb26eaSVarun Wadekar * Export the platform specific power ops and initialize Power Controller 35508438e24SVarun Wadekar ******************************************************************************/ 35671cb26eaSVarun Wadekar int plat_setup_psci_ops(uintptr_t sec_entrypoint, 35771cb26eaSVarun Wadekar const plat_psci_ops_t **psci_ops) 35808438e24SVarun Wadekar { 35971cb26eaSVarun Wadekar psci_power_state_t target_state = { { PSCI_LOCAL_STATE_RUN } }; 36071cb26eaSVarun Wadekar 36171cb26eaSVarun Wadekar /* 36271cb26eaSVarun Wadekar * Flush entrypoint variable to PoC since it will be 36371cb26eaSVarun Wadekar * accessed after a reset with the caches turned off. 36471cb26eaSVarun Wadekar */ 36571cb26eaSVarun Wadekar tegra_sec_entry_point = sec_entrypoint; 36671cb26eaSVarun Wadekar flush_dcache_range((uint64_t)&tegra_sec_entry_point, sizeof(uint64_t)); 36771cb26eaSVarun Wadekar 36808438e24SVarun Wadekar /* 36908438e24SVarun Wadekar * Reset hardware settings. 37008438e24SVarun Wadekar */ 37171cb26eaSVarun Wadekar tegra_soc_pwr_domain_on_finish(&target_state); 37208438e24SVarun Wadekar 37308438e24SVarun Wadekar /* 37471cb26eaSVarun Wadekar * Initialize PSCI ops struct 37508438e24SVarun Wadekar */ 37671cb26eaSVarun Wadekar *psci_ops = &tegra_plat_psci_ops; 37708438e24SVarun Wadekar 37808438e24SVarun Wadekar return 0; 37908438e24SVarun Wadekar } 3802693f1dbSVarun Wadekar 3812693f1dbSVarun Wadekar /******************************************************************************* 3822693f1dbSVarun Wadekar * Platform handler to calculate the proper target power level at the 3832693f1dbSVarun Wadekar * specified affinity level 3842693f1dbSVarun Wadekar ******************************************************************************/ 3852693f1dbSVarun Wadekar plat_local_state_t plat_get_target_pwr_state(unsigned int lvl, 3862693f1dbSVarun Wadekar const plat_local_state_t *states, 3872693f1dbSVarun Wadekar unsigned int ncpu) 3882693f1dbSVarun Wadekar { 389a7cd0953SVarun Wadekar return tegra_soc_get_target_pwr_state(lvl, states, ncpu); 3902693f1dbSVarun Wadekar } 391