aboutsummaryrefslogtreecommitdiffstats
path: root/plat/nvidia/tegra/common/tegra_pm.c
diff options
context:
space:
mode:
Diffstat (limited to 'plat/nvidia/tegra/common/tegra_pm.c')
-rw-r--r--plat/nvidia/tegra/common/tegra_pm.c172
1 files changed, 48 insertions, 124 deletions
diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c
index 39dc42c5b..ec34a850d 100644
--- a/plat/nvidia/tegra/common/tegra_pm.c
+++ b/plat/nvidia/tegra/common/tegra_pm.c
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -27,104 +28,13 @@
extern uint64_t tegra_bl31_phys_base;
extern uint64_t tegra_sec_entry_point;
-/*
- * The following platform setup functions are weakly defined. They
- * provide typical implementations that will be overridden by a SoC.
- */
-#pragma weak tegra_soc_pwr_domain_suspend_pwrdown_early
-#pragma weak tegra_soc_cpu_standby
-#pragma weak tegra_soc_pwr_domain_suspend
-#pragma weak tegra_soc_pwr_domain_on
-#pragma weak tegra_soc_pwr_domain_off
-#pragma weak tegra_soc_pwr_domain_on_finish
-#pragma weak tegra_soc_pwr_domain_power_down_wfi
-#pragma weak tegra_soc_prepare_system_reset
-#pragma weak tegra_soc_prepare_system_off
-#pragma weak tegra_soc_get_target_pwr_state
-
-int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
-{
- return PSCI_E_NOT_SUPPORTED;
-}
-
-int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state)
-{
- (void)cpu_state;
- return PSCI_E_SUCCESS;
-}
-
-int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
-{
- (void)target_state;
- return PSCI_E_NOT_SUPPORTED;
-}
-
-int32_t tegra_soc_pwr_domain_on(u_register_t mpidr)
-{
- (void)mpidr;
- return PSCI_E_SUCCESS;
-}
-
-int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
-{
- (void)target_state;
- return PSCI_E_SUCCESS;
-}
-
-int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
-{
- (void)target_state;
- return PSCI_E_SUCCESS;
-}
-
-int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
-{
- (void)target_state;
- return PSCI_E_SUCCESS;
-}
-
-int32_t tegra_soc_prepare_system_reset(void)
-{
- return PSCI_E_SUCCESS;
-}
-
-__dead2 void tegra_soc_prepare_system_off(void)
-{
- ERROR("Tegra System Off: operation not handled.\n");
- panic();
-}
-
-plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl,
- const plat_local_state_t *states,
- uint32_t ncpu)
-{
- plat_local_state_t target = PLAT_MAX_OFF_STATE, temp;
- uint32_t num_cpu = ncpu;
- const plat_local_state_t *local_state = states;
-
- (void)lvl;
-
- assert(ncpu != 0U);
-
- do {
- temp = *local_state;
- if ((temp < target)) {
- target = temp;
- }
- --num_cpu;
- local_state++;
- } while (num_cpu != 0U);
-
- return target;
-}
-
/*******************************************************************************
* This handler is called by the PSCI implementation during the `SYSTEM_SUSPEND`
* call to get the `power_state` parameter. This allows the platform to encode
* the appropriate State-ID field within the `power_state` parameter which can
* be utilized in `pwr_domain_suspend()` to suspend to system affinity level.
******************************************************************************/
-void tegra_get_sys_suspend_power_state(psci_power_state_t *req_state)
+static void tegra_get_sys_suspend_power_state(psci_power_state_t *req_state)
{
/* all affinities use system suspend state id */
for (uint32_t i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) {
@@ -135,7 +45,7 @@ void tegra_get_sys_suspend_power_state(psci_power_state_t *req_state)
/*******************************************************************************
* Handler called when an affinity instance is about to enter standby.
******************************************************************************/
-void tegra_cpu_standby(plat_local_state_t cpu_state)
+static void tegra_cpu_standby(plat_local_state_t cpu_state)
{
u_register_t saved_scr_el3;
@@ -174,7 +84,7 @@ void tegra_cpu_standby(plat_local_state_t cpu_state)
* Handler called when an affinity instance is about to be turned on. The
* level and mpidr determine the affinity instance.
******************************************************************************/
-int32_t tegra_pwr_domain_on(u_register_t mpidr)
+static int32_t tegra_pwr_domain_on(u_register_t mpidr)
{
return tegra_soc_pwr_domain_on(mpidr);
}
@@ -183,9 +93,12 @@ int32_t tegra_pwr_domain_on(u_register_t mpidr)
* Handler called when a power domain is about to be turned off. The
* target_state encodes the power state that each level should transition to.
******************************************************************************/
-void tegra_pwr_domain_off(const psci_power_state_t *target_state)
+static void tegra_pwr_domain_off(const psci_power_state_t *target_state)
{
(void)tegra_soc_pwr_domain_off(target_state);
+
+ /* disable GICC */
+ tegra_gic_cpuif_deactivate();
}
/*******************************************************************************
@@ -203,17 +116,10 @@ void tegra_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_sta
* Handler called when a power domain is about to be suspended. The
* target_state encodes the power state that each level should transition to.
******************************************************************************/
-void tegra_pwr_domain_suspend(const psci_power_state_t *target_state)
+static void tegra_pwr_domain_suspend(const psci_power_state_t *target_state)
{
(void)tegra_soc_pwr_domain_suspend(target_state);
- /* Disable console if we are entering deep sleep. */
- if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] ==
- PSTATE_ID_SOC_POWERDN) {
- (void)console_flush();
- console_switch_state(0);
- }
-
/* disable GICC */
tegra_gic_cpuif_deactivate();
}
@@ -222,12 +128,20 @@ void tegra_pwr_domain_suspend(const psci_power_state_t *target_state)
* Handler called at the end of the power domain suspend sequence. The
* target_state encodes the power state that each level should transition to.
******************************************************************************/
-__dead2 void tegra_pwr_domain_power_down_wfi(const psci_power_state_t
+static __dead2 void tegra_pwr_domain_power_down_wfi(const psci_power_state_t
*target_state)
{
/* call the chip's power down handler */
(void)tegra_soc_pwr_domain_power_down_wfi(target_state);
+ /* Disable console if we are entering deep sleep. */
+ if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] ==
+ PSTATE_ID_SOC_POWERDN) {
+ INFO("%s: complete. Entering System Suspend...\n", __func__);
+ console_flush();
+ console_switch_state(0);
+ }
+
wfi();
panic();
}
@@ -237,21 +151,23 @@ __dead2 void tegra_pwr_domain_power_down_wfi(const psci_power_state_t
* being turned off earlier. The target_state encodes the low power state that
* each level has woken up from.
******************************************************************************/
-void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state)
+static void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
const plat_params_from_bl2_t *plat_params;
/*
- * Initialize the GIC cpu and distributor interfaces
- */
- tegra_gic_pcpu_init();
-
- /*
* Check if we are exiting from deep sleep.
*/
if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] ==
PSTATE_ID_SOC_POWERDN) {
+ /*
+ * On entering System Suspend state, the GIC loses power
+ * completely. Initialize the GIC global distributor and
+ * GIC cpu interfaces.
+ */
+ tegra_gic_init();
+
/* Restart console output. */
console_switch_state(CONSOLE_FLAG_RUNTIME);
@@ -268,11 +184,11 @@ void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state)
tegra_memctrl_tzdram_setup(plat_params->tzdram_base,
(uint32_t)plat_params->tzdram_size);
+ } else {
/*
- * Set up the TZRAM memory aperture to allow only secure world
- * access
+ * Initialize the GIC cpu and distributor interfaces
*/
- tegra_memctrl_tzram_setup(TEGRA_TZRAM_BASE, TEGRA_TZRAM_SIZE);
+ tegra_gic_pcpu_init();
}
/*
@@ -286,7 +202,7 @@ void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state)
* having been suspended earlier. The target_state encodes the low power state
* that each level has woken up from.
******************************************************************************/
-void tegra_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
+static void tegra_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
{
tegra_pwr_domain_on_finish(target_state);
}
@@ -294,7 +210,7 @@ void tegra_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
/*******************************************************************************
* Handler called when the system wants to be powered off
******************************************************************************/
-__dead2 void tegra_system_off(void)
+static __dead2 void tegra_system_off(void)
{
INFO("Powering down system...\n");
@@ -304,23 +220,23 @@ __dead2 void tegra_system_off(void)
/*******************************************************************************
* Handler called when the system wants to be restarted.
******************************************************************************/
-__dead2 void tegra_system_reset(void)
+static __dead2 void tegra_system_reset(void)
{
INFO("Restarting system...\n");
/* per-SoC system reset handler */
(void)tegra_soc_prepare_system_reset();
- /*
- * Program the PMC in order to restart the system.
- */
- tegra_pmc_system_reset();
+ /* wait for the system to reset */
+ for (;;) {
+ ;
+ }
}
/*******************************************************************************
* Handler called to check the validity of the power state parameter.
******************************************************************************/
-int32_t tegra_validate_power_state(uint32_t power_state,
+static int32_t tegra_validate_power_state(uint32_t power_state,
psci_power_state_t *req_state)
{
assert(req_state != NULL);
@@ -331,7 +247,7 @@ int32_t tegra_validate_power_state(uint32_t power_state,
/*******************************************************************************
* Platform handler called to check the validity of the non secure entrypoint.
******************************************************************************/
-int32_t tegra_validate_ns_entrypoint(uintptr_t entrypoint)
+static int32_t tegra_validate_ns_entrypoint(uintptr_t entrypoint)
{
int32_t ret = PSCI_E_INVALID_ADDRESS;
@@ -349,7 +265,7 @@ int32_t tegra_validate_ns_entrypoint(uintptr_t entrypoint)
/*******************************************************************************
* Export the platform handlers to enable psci to invoke them
******************************************************************************/
-static const plat_psci_ops_t tegra_plat_psci_ops = {
+static plat_psci_ops_t tegra_plat_psci_ops = {
.cpu_standby = tegra_cpu_standby,
.pwr_domain_on = tegra_pwr_domain_on,
.pwr_domain_off = tegra_pwr_domain_off,
@@ -386,6 +302,14 @@ int plat_setup_psci_ops(uintptr_t sec_entrypoint,
(void)tegra_soc_pwr_domain_on_finish(&target_state);
/*
+ * Disable System Suspend if the platform does not
+ * support it
+ */
+ if (!plat_supports_system_suspend()) {
+ tegra_plat_psci_ops.get_sys_suspend_power_state = NULL;
+ }
+
+ /*
* Initialize PSCI ops struct
*/
*psci_ops = &tegra_plat_psci_ops;