108438e24SVarun Wadekar /* 2a9e0260cSVignesh Radhakrishnan * Copyright (c) 2015-2017, 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> 24*322e7c3eSHarvey 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; 295b5928e8SVarun Wadekar extern uint64_t tegra_console_base; 3008438e24SVarun Wadekar 3108438e24SVarun Wadekar /* 32a9e0260cSVignesh Radhakrishnan * tegra_fake_system_suspend acts as a boolean var controlling whether 33a9e0260cSVignesh Radhakrishnan * we are going to take fake system suspend code or normal system suspend code 34a9e0260cSVignesh Radhakrishnan * path. This variable is set inside the sip call handlers,when the kernel 35a9e0260cSVignesh Radhakrishnan * requests a SIP call to set the suspend debug flags. 36a9e0260cSVignesh Radhakrishnan */ 37a9e0260cSVignesh Radhakrishnan uint8_t tegra_fake_system_suspend; 38a9e0260cSVignesh Radhakrishnan 39a9e0260cSVignesh Radhakrishnan /* 4008438e24SVarun Wadekar * The following platform setup functions are weakly defined. They 4108438e24SVarun Wadekar * provide typical implementations that will be overridden by a SoC. 4208438e24SVarun Wadekar */ 43cb95a19aSVarun Wadekar #pragma weak tegra_soc_pwr_domain_suspend_pwrdown_early 4471cb26eaSVarun Wadekar #pragma weak tegra_soc_pwr_domain_suspend 4571cb26eaSVarun Wadekar #pragma weak tegra_soc_pwr_domain_on 4671cb26eaSVarun Wadekar #pragma weak tegra_soc_pwr_domain_off 4771cb26eaSVarun Wadekar #pragma weak tegra_soc_pwr_domain_on_finish 4826c0d9b2SVarun Wadekar #pragma weak tegra_soc_pwr_domain_power_down_wfi 493b40f993SVarun Wadekar #pragma weak tegra_soc_prepare_system_reset 5031a4957cSVarun Wadekar #pragma weak tegra_soc_prepare_system_off 51a7cd0953SVarun Wadekar #pragma weak tegra_soc_get_target_pwr_state 5208438e24SVarun Wadekar 53cb95a19aSVarun Wadekar int tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state) 54cb95a19aSVarun Wadekar { 55cb95a19aSVarun Wadekar return PSCI_E_NOT_SUPPORTED; 56cb95a19aSVarun Wadekar } 57cb95a19aSVarun Wadekar 5871cb26eaSVarun Wadekar int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) 5908438e24SVarun Wadekar { 6008438e24SVarun Wadekar return PSCI_E_NOT_SUPPORTED; 6108438e24SVarun Wadekar } 6208438e24SVarun Wadekar 6371cb26eaSVarun Wadekar int tegra_soc_pwr_domain_on(u_register_t mpidr) 6408438e24SVarun Wadekar { 6508438e24SVarun Wadekar return PSCI_E_SUCCESS; 6608438e24SVarun Wadekar } 6708438e24SVarun Wadekar 6871cb26eaSVarun Wadekar int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state) 6908438e24SVarun Wadekar { 7008438e24SVarun Wadekar return PSCI_E_SUCCESS; 7108438e24SVarun Wadekar } 7208438e24SVarun Wadekar 7371cb26eaSVarun Wadekar int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) 7408438e24SVarun Wadekar { 7508438e24SVarun Wadekar return PSCI_E_SUCCESS; 7608438e24SVarun Wadekar } 7708438e24SVarun Wadekar 7826c0d9b2SVarun Wadekar int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state) 7926c0d9b2SVarun Wadekar { 8026c0d9b2SVarun Wadekar return PSCI_E_SUCCESS; 8126c0d9b2SVarun Wadekar } 8226c0d9b2SVarun Wadekar 833b40f993SVarun Wadekar int tegra_soc_prepare_system_reset(void) 843b40f993SVarun Wadekar { 853b40f993SVarun Wadekar return PSCI_E_SUCCESS; 863b40f993SVarun Wadekar } 873b40f993SVarun Wadekar 8831a4957cSVarun Wadekar __dead2 void tegra_soc_prepare_system_off(void) 8931a4957cSVarun Wadekar { 9031a4957cSVarun Wadekar ERROR("Tegra System Off: operation not handled.\n"); 9131a4957cSVarun Wadekar panic(); 9231a4957cSVarun Wadekar } 9331a4957cSVarun Wadekar 94a7cd0953SVarun Wadekar plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl, 95a7cd0953SVarun Wadekar const plat_local_state_t *states, 96a7cd0953SVarun Wadekar unsigned int ncpu) 97a7cd0953SVarun Wadekar { 988539f45dSVarun Wadekar plat_local_state_t target = PLAT_MAX_OFF_STATE, temp; 99a7cd0953SVarun Wadekar 100a7cd0953SVarun Wadekar assert(ncpu); 101a7cd0953SVarun Wadekar 102a7cd0953SVarun Wadekar do { 103a7cd0953SVarun Wadekar temp = *states++; 1048539f45dSVarun Wadekar if ((temp < target)) 105a7cd0953SVarun Wadekar target = temp; 106a7cd0953SVarun Wadekar } while (--ncpu); 107a7cd0953SVarun Wadekar 108a7cd0953SVarun Wadekar return target; 109a7cd0953SVarun Wadekar } 110a7cd0953SVarun Wadekar 11108438e24SVarun Wadekar /******************************************************************************* 11271cb26eaSVarun Wadekar * This handler is called by the PSCI implementation during the `SYSTEM_SUSPEND` 11371cb26eaSVarun Wadekar * call to get the `power_state` parameter. This allows the platform to encode 11471cb26eaSVarun Wadekar * the appropriate State-ID field within the `power_state` parameter which can 11571cb26eaSVarun Wadekar * be utilized in `pwr_domain_suspend()` to suspend to system affinity level. 11608438e24SVarun Wadekar ******************************************************************************/ 11771cb26eaSVarun Wadekar void tegra_get_sys_suspend_power_state(psci_power_state_t *req_state) 11808438e24SVarun Wadekar { 119a7cd0953SVarun Wadekar /* all affinities use system suspend state id */ 1206311f63dSVarun Wadekar for (uint32_t i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) 121a7cd0953SVarun Wadekar req_state->pwr_domain_state[i] = PSTATE_ID_SOC_POWERDN; 12208438e24SVarun Wadekar } 12308438e24SVarun Wadekar 12408438e24SVarun Wadekar /******************************************************************************* 12508438e24SVarun Wadekar * Handler called when an affinity instance is about to enter standby. 12608438e24SVarun Wadekar ******************************************************************************/ 12771cb26eaSVarun Wadekar void tegra_cpu_standby(plat_local_state_t cpu_state) 12808438e24SVarun Wadekar { 12908438e24SVarun Wadekar /* 13008438e24SVarun Wadekar * Enter standby state 13108438e24SVarun Wadekar * dsb is good practice before using wfi to enter low power states 13208438e24SVarun Wadekar */ 13308438e24SVarun Wadekar dsb(); 13408438e24SVarun Wadekar wfi(); 13508438e24SVarun Wadekar } 13608438e24SVarun Wadekar 13708438e24SVarun Wadekar /******************************************************************************* 13808438e24SVarun Wadekar * Handler called when an affinity instance is about to be turned on. The 13908438e24SVarun Wadekar * level and mpidr determine the affinity instance. 14008438e24SVarun Wadekar ******************************************************************************/ 14171cb26eaSVarun Wadekar int tegra_pwr_domain_on(u_register_t mpidr) 14208438e24SVarun Wadekar { 14371cb26eaSVarun Wadekar return tegra_soc_pwr_domain_on(mpidr); 14408438e24SVarun Wadekar } 14508438e24SVarun Wadekar 14608438e24SVarun Wadekar /******************************************************************************* 14771cb26eaSVarun Wadekar * Handler called when a power domain is about to be turned off. The 14871cb26eaSVarun Wadekar * target_state encodes the power state that each level should transition to. 14908438e24SVarun Wadekar ******************************************************************************/ 15071cb26eaSVarun Wadekar void tegra_pwr_domain_off(const psci_power_state_t *target_state) 15108438e24SVarun Wadekar { 15271cb26eaSVarun Wadekar tegra_soc_pwr_domain_off(target_state); 15308438e24SVarun Wadekar } 15408438e24SVarun Wadekar 15508438e24SVarun Wadekar /******************************************************************************* 15626c0d9b2SVarun Wadekar * Handler called when a power domain is about to be suspended. The 15771cb26eaSVarun Wadekar * target_state encodes the power state that each level should transition to. 158cb95a19aSVarun Wadekar * This handler is called with SMP and data cache enabled, when 159cb95a19aSVarun Wadekar * HW_ASSISTED_COHERENCY = 0 160cb95a19aSVarun Wadekar ******************************************************************************/ 161cb95a19aSVarun Wadekar void tegra_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state) 162cb95a19aSVarun Wadekar { 163cb95a19aSVarun Wadekar tegra_soc_pwr_domain_suspend_pwrdown_early(target_state); 164cb95a19aSVarun Wadekar } 165cb95a19aSVarun Wadekar 166cb95a19aSVarun Wadekar /******************************************************************************* 167cb95a19aSVarun Wadekar * Handler called when a power domain is about to be suspended. The 168cb95a19aSVarun Wadekar * target_state encodes the power state that each level should transition to. 16908438e24SVarun Wadekar ******************************************************************************/ 17071cb26eaSVarun Wadekar void tegra_pwr_domain_suspend(const psci_power_state_t *target_state) 17108438e24SVarun Wadekar { 17271cb26eaSVarun Wadekar tegra_soc_pwr_domain_suspend(target_state); 17308438e24SVarun Wadekar 1745b5928e8SVarun Wadekar /* Disable console if we are entering deep sleep. */ 1755b5928e8SVarun Wadekar if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] == 1765b5928e8SVarun Wadekar PSTATE_ID_SOC_POWERDN) 1775b5928e8SVarun Wadekar console_uninit(); 1785b5928e8SVarun Wadekar 17908438e24SVarun Wadekar /* disable GICC */ 18008438e24SVarun Wadekar tegra_gic_cpuif_deactivate(); 18108438e24SVarun Wadekar } 18208438e24SVarun Wadekar 18308438e24SVarun Wadekar /******************************************************************************* 18426c0d9b2SVarun Wadekar * Handler called at the end of the power domain suspend sequence. The 18526c0d9b2SVarun Wadekar * target_state encodes the power state that each level should transition to. 18626c0d9b2SVarun Wadekar ******************************************************************************/ 18726c0d9b2SVarun Wadekar __dead2 void tegra_pwr_domain_power_down_wfi(const psci_power_state_t 18826c0d9b2SVarun Wadekar *target_state) 18926c0d9b2SVarun Wadekar { 190a9e0260cSVignesh Radhakrishnan uint8_t pwr_state = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]; 191a9e0260cSVignesh Radhakrishnan uint64_t rmr_el3 = 0; 192a9e0260cSVignesh Radhakrishnan 19326c0d9b2SVarun Wadekar /* call the chip's power down handler */ 19426c0d9b2SVarun Wadekar tegra_soc_pwr_domain_power_down_wfi(target_state); 19526c0d9b2SVarun Wadekar 196a9e0260cSVignesh Radhakrishnan /* 197a9e0260cSVignesh Radhakrishnan * If we are in fake system suspend mode, ensure we start doing 198a9e0260cSVignesh Radhakrishnan * procedures that help in looping back towards system suspend exit 199a9e0260cSVignesh Radhakrishnan * instead of calling WFI by requesting a warm reset. 200a9e0260cSVignesh Radhakrishnan * Else, just call WFI to enter low power state. 201a9e0260cSVignesh Radhakrishnan */ 202a9e0260cSVignesh Radhakrishnan if ((tegra_fake_system_suspend != 0U) && 203a9e0260cSVignesh Radhakrishnan (pwr_state == (uint8_t)PSTATE_ID_SOC_POWERDN)) { 204a9e0260cSVignesh Radhakrishnan 205a9e0260cSVignesh Radhakrishnan /* warm reboot */ 206a9e0260cSVignesh Radhakrishnan rmr_el3 = read_rmr_el3(); 207a9e0260cSVignesh Radhakrishnan write_rmr_el3(rmr_el3 | RMR_WARM_RESET_CPU); 208a9e0260cSVignesh Radhakrishnan 209a9e0260cSVignesh Radhakrishnan } else { 21026c0d9b2SVarun Wadekar /* enter power down state */ 21126c0d9b2SVarun Wadekar wfi(); 212a9e0260cSVignesh Radhakrishnan } 21326c0d9b2SVarun Wadekar 21426c0d9b2SVarun Wadekar /* we can never reach here */ 21526c0d9b2SVarun Wadekar panic(); 21626c0d9b2SVarun Wadekar } 21726c0d9b2SVarun Wadekar 21826c0d9b2SVarun Wadekar /******************************************************************************* 21971cb26eaSVarun Wadekar * Handler called when a power domain has just been powered on after 22071cb26eaSVarun Wadekar * being turned off earlier. The target_state encodes the low power state that 22171cb26eaSVarun Wadekar * each level has woken up from. 22208438e24SVarun Wadekar ******************************************************************************/ 22371cb26eaSVarun Wadekar void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state) 22408438e24SVarun Wadekar { 22508438e24SVarun Wadekar plat_params_from_bl2_t *plat_params; 226*322e7c3eSHarvey Hsieh uint32_t console_clock; 22708438e24SVarun Wadekar 22808438e24SVarun Wadekar /* 22908438e24SVarun Wadekar * Initialize the GIC cpu and distributor interfaces 23008438e24SVarun Wadekar */ 231d3360301SVarun Wadekar plat_gic_setup(); 23208438e24SVarun Wadekar 23308438e24SVarun Wadekar /* 23408438e24SVarun Wadekar * Check if we are exiting from deep sleep. 23508438e24SVarun Wadekar */ 23671cb26eaSVarun Wadekar if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] == 23771cb26eaSVarun Wadekar PSTATE_ID_SOC_POWERDN) { 23808438e24SVarun Wadekar 239*322e7c3eSHarvey Hsieh /* 240*322e7c3eSHarvey Hsieh * Reference clock used by the FPGAs is a lot slower. 241*322e7c3eSHarvey Hsieh */ 242*322e7c3eSHarvey Hsieh if (tegra_platform_is_fpga() == 1U) { 243*322e7c3eSHarvey Hsieh console_clock = TEGRA_BOOT_UART_CLK_13_MHZ; 244*322e7c3eSHarvey Hsieh } else { 245*322e7c3eSHarvey Hsieh console_clock = TEGRA_BOOT_UART_CLK_408_MHZ; 246*322e7c3eSHarvey Hsieh } 247*322e7c3eSHarvey Hsieh 2485b5928e8SVarun Wadekar /* Initialize the runtime console */ 2499b514f83SDamon Duan if (tegra_console_base != (uint64_t)0) { 250*322e7c3eSHarvey Hsieh console_init(tegra_console_base, console_clock, 2515b5928e8SVarun Wadekar TEGRA_CONSOLE_BAUDRATE); 2529b514f83SDamon Duan } 2535b5928e8SVarun Wadekar 25408438e24SVarun Wadekar /* 255102e4087SVarun Wadekar * Restore Memory Controller settings as it loses state 256102e4087SVarun Wadekar * during system suspend. 25708438e24SVarun Wadekar */ 258102e4087SVarun Wadekar tegra_memctrl_restore_settings(); 25908438e24SVarun Wadekar 26008438e24SVarun Wadekar /* 26108438e24SVarun Wadekar * Security configuration to allow DRAM/device access. 26208438e24SVarun Wadekar */ 26308438e24SVarun Wadekar plat_params = bl31_get_plat_params(); 264e0d4158cSVarun Wadekar tegra_memctrl_tzdram_setup(plat_params->tzdram_base, 26508438e24SVarun Wadekar plat_params->tzdram_size); 266207680c6SVarun Wadekar 267207680c6SVarun Wadekar /* 268207680c6SVarun Wadekar * Set up the TZRAM memory aperture to allow only secure world 269207680c6SVarun Wadekar * access 270207680c6SVarun Wadekar */ 271207680c6SVarun Wadekar tegra_memctrl_tzram_setup(TEGRA_TZRAM_BASE, TEGRA_TZRAM_SIZE); 27208438e24SVarun Wadekar } 27308438e24SVarun Wadekar 27408438e24SVarun Wadekar /* 27508438e24SVarun Wadekar * Reset hardware settings. 27608438e24SVarun Wadekar */ 27771cb26eaSVarun Wadekar tegra_soc_pwr_domain_on_finish(target_state); 27808438e24SVarun Wadekar } 27908438e24SVarun Wadekar 28008438e24SVarun Wadekar /******************************************************************************* 28171cb26eaSVarun Wadekar * Handler called when a power domain has just been powered on after 28271cb26eaSVarun Wadekar * having been suspended earlier. The target_state encodes the low power state 28371cb26eaSVarun Wadekar * that each level has woken up from. 28408438e24SVarun Wadekar ******************************************************************************/ 28571cb26eaSVarun Wadekar void tegra_pwr_domain_suspend_finish(const psci_power_state_t *target_state) 28608438e24SVarun Wadekar { 28771cb26eaSVarun Wadekar tegra_pwr_domain_on_finish(target_state); 28808438e24SVarun Wadekar } 28908438e24SVarun Wadekar 29008438e24SVarun Wadekar /******************************************************************************* 29108438e24SVarun Wadekar * Handler called when the system wants to be powered off 29208438e24SVarun Wadekar ******************************************************************************/ 29308438e24SVarun Wadekar __dead2 void tegra_system_off(void) 29408438e24SVarun Wadekar { 29531a4957cSVarun Wadekar INFO("Powering down system...\n"); 29631a4957cSVarun Wadekar 29731a4957cSVarun Wadekar tegra_soc_prepare_system_off(); 29808438e24SVarun Wadekar } 29908438e24SVarun Wadekar 30008438e24SVarun Wadekar /******************************************************************************* 30108438e24SVarun Wadekar * Handler called when the system wants to be restarted. 30208438e24SVarun Wadekar ******************************************************************************/ 30308438e24SVarun Wadekar __dead2 void tegra_system_reset(void) 30408438e24SVarun Wadekar { 30531a4957cSVarun Wadekar INFO("Restarting system...\n"); 30631a4957cSVarun Wadekar 3073b40f993SVarun Wadekar /* per-SoC system reset handler */ 3083b40f993SVarun Wadekar tegra_soc_prepare_system_reset(); 3093b40f993SVarun Wadekar 31008438e24SVarun Wadekar /* 31108438e24SVarun Wadekar * Program the PMC in order to restart the system. 31208438e24SVarun Wadekar */ 31308438e24SVarun Wadekar tegra_pmc_system_reset(); 31408438e24SVarun Wadekar } 31508438e24SVarun Wadekar 31608438e24SVarun Wadekar /******************************************************************************* 31771cb26eaSVarun Wadekar * Handler called to check the validity of the power state parameter. 31871cb26eaSVarun Wadekar ******************************************************************************/ 31971cb26eaSVarun Wadekar int32_t tegra_validate_power_state(unsigned int power_state, 32071cb26eaSVarun Wadekar psci_power_state_t *req_state) 32171cb26eaSVarun Wadekar { 32271cb26eaSVarun Wadekar assert(req_state); 32371cb26eaSVarun Wadekar 32471cb26eaSVarun Wadekar return tegra_soc_validate_power_state(power_state, req_state); 32571cb26eaSVarun Wadekar } 32671cb26eaSVarun Wadekar 32771cb26eaSVarun Wadekar /******************************************************************************* 32871cb26eaSVarun Wadekar * Platform handler called to check the validity of the non secure entrypoint. 32971cb26eaSVarun Wadekar ******************************************************************************/ 33071cb26eaSVarun Wadekar int tegra_validate_ns_entrypoint(uintptr_t entrypoint) 33171cb26eaSVarun Wadekar { 33271cb26eaSVarun Wadekar /* 33371cb26eaSVarun Wadekar * Check if the non secure entrypoint lies within the non 33471cb26eaSVarun Wadekar * secure DRAM. 33571cb26eaSVarun Wadekar */ 33671cb26eaSVarun Wadekar if ((entrypoint >= TEGRA_DRAM_BASE) && (entrypoint <= TEGRA_DRAM_END)) 33771cb26eaSVarun Wadekar return PSCI_E_SUCCESS; 33871cb26eaSVarun Wadekar 33971cb26eaSVarun Wadekar return PSCI_E_INVALID_ADDRESS; 34071cb26eaSVarun Wadekar } 34171cb26eaSVarun Wadekar 34271cb26eaSVarun Wadekar /******************************************************************************* 34308438e24SVarun Wadekar * Export the platform handlers to enable psci to invoke them 34408438e24SVarun Wadekar ******************************************************************************/ 34571cb26eaSVarun Wadekar static const plat_psci_ops_t tegra_plat_psci_ops = { 34671cb26eaSVarun Wadekar .cpu_standby = tegra_cpu_standby, 34771cb26eaSVarun Wadekar .pwr_domain_on = tegra_pwr_domain_on, 34871cb26eaSVarun Wadekar .pwr_domain_off = tegra_pwr_domain_off, 349cb95a19aSVarun Wadekar .pwr_domain_suspend_pwrdown_early = tegra_pwr_domain_suspend_pwrdown_early, 35071cb26eaSVarun Wadekar .pwr_domain_suspend = tegra_pwr_domain_suspend, 35171cb26eaSVarun Wadekar .pwr_domain_on_finish = tegra_pwr_domain_on_finish, 35271cb26eaSVarun Wadekar .pwr_domain_suspend_finish = tegra_pwr_domain_suspend_finish, 35326c0d9b2SVarun Wadekar .pwr_domain_pwr_down_wfi = tegra_pwr_domain_power_down_wfi, 35408438e24SVarun Wadekar .system_off = tegra_system_off, 35508438e24SVarun Wadekar .system_reset = tegra_system_reset, 35694c672e7SVarun Wadekar .validate_power_state = tegra_validate_power_state, 35771cb26eaSVarun Wadekar .validate_ns_entrypoint = tegra_validate_ns_entrypoint, 35871cb26eaSVarun Wadekar .get_sys_suspend_power_state = tegra_get_sys_suspend_power_state, 35908438e24SVarun Wadekar }; 36008438e24SVarun Wadekar 36108438e24SVarun Wadekar /******************************************************************************* 36271cb26eaSVarun Wadekar * Export the platform specific power ops and initialize Power Controller 36308438e24SVarun Wadekar ******************************************************************************/ 36471cb26eaSVarun Wadekar int plat_setup_psci_ops(uintptr_t sec_entrypoint, 36571cb26eaSVarun Wadekar const plat_psci_ops_t **psci_ops) 36608438e24SVarun Wadekar { 36771cb26eaSVarun Wadekar psci_power_state_t target_state = { { PSCI_LOCAL_STATE_RUN } }; 36871cb26eaSVarun Wadekar 36971cb26eaSVarun Wadekar /* 37071cb26eaSVarun Wadekar * Flush entrypoint variable to PoC since it will be 37171cb26eaSVarun Wadekar * accessed after a reset with the caches turned off. 37271cb26eaSVarun Wadekar */ 37371cb26eaSVarun Wadekar tegra_sec_entry_point = sec_entrypoint; 37471cb26eaSVarun Wadekar flush_dcache_range((uint64_t)&tegra_sec_entry_point, sizeof(uint64_t)); 37571cb26eaSVarun Wadekar 37608438e24SVarun Wadekar /* 37708438e24SVarun Wadekar * Reset hardware settings. 37808438e24SVarun Wadekar */ 37971cb26eaSVarun Wadekar tegra_soc_pwr_domain_on_finish(&target_state); 38008438e24SVarun Wadekar 38108438e24SVarun Wadekar /* 38271cb26eaSVarun Wadekar * Initialize PSCI ops struct 38308438e24SVarun Wadekar */ 38471cb26eaSVarun Wadekar *psci_ops = &tegra_plat_psci_ops; 38508438e24SVarun Wadekar 38608438e24SVarun Wadekar return 0; 38708438e24SVarun Wadekar } 3882693f1dbSVarun Wadekar 3892693f1dbSVarun Wadekar /******************************************************************************* 3902693f1dbSVarun Wadekar * Platform handler to calculate the proper target power level at the 3912693f1dbSVarun Wadekar * specified affinity level 3922693f1dbSVarun Wadekar ******************************************************************************/ 3932693f1dbSVarun Wadekar plat_local_state_t plat_get_target_pwr_state(unsigned int lvl, 3942693f1dbSVarun Wadekar const plat_local_state_t *states, 3952693f1dbSVarun Wadekar unsigned int ncpu) 3962693f1dbSVarun Wadekar { 397a7cd0953SVarun Wadekar return tegra_soc_get_target_pwr_state(lvl, states, ncpu); 3982693f1dbSVarun Wadekar } 399