diff options
author | Varun Wadekar <vwadekar@nvidia.com> | 2015-07-23 10:07:54 +0530 |
---|---|---|
committer | Varun Wadekar <vwadekar@nvidia.com> | 2015-07-24 09:08:27 +0530 |
commit | 93eafbcad46b83bb0db3b86b1508f08efce25519 (patch) | |
tree | 2019de1ff4cfa73e2458d1deae26404ef82ed15f /plat/nvidia/tegra | |
parent | fb11a62fede3d76506ba353f93264569e711cf74 (diff) | |
download | arm-trusted-firmware-93eafbcad46b83bb0db3b86b1508f08efce25519.tar.gz |
Tegra: implement per-SoC validate_power_state() handler
The validate_power_state() handler checks the power_state for a valid afflvl
and state id. Although the afflvl check is common, the state ids are implementation
defined.
This patch moves the handler to the tegra/soc folder to allow each SoC to validate
the power_state for supported parameters.
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
Diffstat (limited to 'plat/nvidia/tegra')
-rw-r--r-- | plat/nvidia/tegra/common/tegra_pm.c | 38 | ||||
-rw-r--r-- | plat/nvidia/tegra/include/tegra_private.h | 3 | ||||
-rw-r--r-- | plat/nvidia/tegra/soc/t210/plat_psci_handlers.c | 36 |
3 files changed, 49 insertions, 28 deletions
diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c index bcaaf412b..87f72403c 100644 --- a/plat/nvidia/tegra/common/tegra_pm.c +++ b/plat/nvidia/tegra/common/tegra_pm.c @@ -51,27 +51,27 @@ static int system_suspended; * The following platform setup functions are weakly defined. They * provide typical implementations that will be overridden by a SoC. */ -#pragma weak tegra_prepare_cpu_suspend -#pragma weak tegra_prepare_cpu_on -#pragma weak tegra_prepare_cpu_off -#pragma weak tegra_prepare_cpu_on_finish +#pragma weak tegra_soc_prepare_cpu_suspend +#pragma weak tegra_soc_prepare_cpu_on +#pragma weak tegra_soc_prepare_cpu_off +#pragma weak tegra_soc_prepare_cpu_on_finish -int tegra_prepare_cpu_suspend(unsigned int id, unsigned int afflvl) +int tegra_soc_prepare_cpu_suspend(unsigned int id, unsigned int afflvl) { return PSCI_E_NOT_SUPPORTED; } -int tegra_prepare_cpu_on(unsigned long mpidr) +int tegra_soc_prepare_cpu_on(unsigned long mpidr) { return PSCI_E_SUCCESS; } -int tegra_prepare_cpu_off(unsigned long mpidr) +int tegra_soc_prepare_cpu_off(unsigned long mpidr) { return PSCI_E_SUCCESS; } -int tegra_prepare_cpu_on_finish(unsigned long mpidr) +int tegra_soc_prepare_cpu_on_finish(unsigned long mpidr) { return PSCI_E_SUCCESS; } @@ -134,17 +134,7 @@ unsigned int tegra_get_sys_suspend_power_state(void) ******************************************************************************/ int32_t tegra_validate_power_state(unsigned int power_state) { - /* Sanity check the requested state */ - if (psci_get_pstate_type(power_state) == PSTATE_TYPE_STANDBY) { - /* - * It's possible to enter standby only on affinity level 0 i.e. - * a cpu on Tegra. Ignore any other affinity level. - */ - if (psci_get_pstate_afflvl(power_state) != MPIDR_AFFLVL0) - return PSCI_E_INVALID_PARAMS; - } - - return PSCI_E_SUCCESS; + return tegra_soc_validate_power_state(power_state); } /******************************************************************************* @@ -171,7 +161,7 @@ int tegra_affinst_on(unsigned long mpidr, sec_entry_point[cpu] = sec_entrypoint; flush_dcache_range((uint64_t)&sec_entry_point[cpu], sizeof(uint64_t)); - return tegra_prepare_cpu_on(mpidr); + return tegra_soc_prepare_cpu_on(mpidr); } /******************************************************************************* @@ -194,7 +184,7 @@ void tegra_affinst_off(unsigned int afflvl, unsigned int state) if (afflvl > MPIDR_AFFLVL0) return; - tegra_prepare_cpu_off(read_mpidr()); + tegra_soc_prepare_cpu_off(read_mpidr()); } /******************************************************************************* @@ -227,7 +217,7 @@ void tegra_affinst_suspend(unsigned long sec_entrypoint, sec_entry_point[cpu] = sec_entrypoint; flush_dcache_range((uint64_t)&sec_entry_point[cpu], sizeof(uint64_t)); - tegra_prepare_cpu_suspend(id, afflvl); + tegra_soc_prepare_cpu_suspend(id, afflvl); /* disable GICC */ tegra_gic_cpuif_deactivate(); @@ -280,7 +270,7 @@ void tegra_affinst_on_finish(unsigned int afflvl, unsigned int state) /* * Reset hardware settings. */ - tegra_prepare_cpu_on_finish(read_mpidr()); + tegra_soc_prepare_cpu_on_finish(read_mpidr()); } /******************************************************************************* @@ -338,7 +328,7 @@ int platform_setup_pm(const plat_pm_ops_t **plat_ops) /* * Reset hardware settings. */ - tegra_prepare_cpu_on_finish(read_mpidr()); + tegra_soc_prepare_cpu_on_finish(read_mpidr()); /* * Initialize PM ops struct diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h index d0cde2afd..dbd668938 100644 --- a/plat/nvidia/tegra/include/tegra_private.h +++ b/plat/nvidia/tegra/include/tegra_private.h @@ -45,6 +45,9 @@ typedef struct plat_params_from_bl2 { uintptr_t bl32_params; } plat_params_from_bl2_t; +/* Declarations for plat_psci_handlers.c */ +int32_t tegra_soc_validate_power_state(unsigned int power_state); + /* Declarations for plat_setup.c */ const mmap_region_t *plat_get_mmio_map(void); uint64_t plat_get_syscnt_freq(void); diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c index 010899ac3..578dd8e10 100644 --- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c @@ -49,7 +49,35 @@ static int cpu_powergate_mask[PLATFORM_MAX_CPUS_PER_CLUSTER]; -int tegra_prepare_cpu_suspend(unsigned int id, unsigned int afflvl) +int32_t tegra_soc_validate_power_state(unsigned int power_state) +{ + /* Sanity check the requested afflvl */ + if (psci_get_pstate_type(power_state) == PSTATE_TYPE_STANDBY) { + /* + * It's possible to enter standby only on affinity level 0 i.e. + * a cpu on Tegra. Ignore any other affinity level. + */ + if (psci_get_pstate_afflvl(power_state) != MPIDR_AFFLVL0) + return PSCI_E_INVALID_PARAMS; + } + + /* Sanity check the requested state id */ + switch (psci_get_pstate_id(power_state)) { + case PSTATE_ID_CORE_POWERDN: + case PSTATE_ID_CLUSTER_IDLE: + case PSTATE_ID_CLUSTER_POWERDN: + case PSTATE_ID_SOC_POWERDN: + break; + + default: + ERROR("unsupported state id\n"); + return PSCI_E_NOT_SUPPORTED; + } + + return PSCI_E_SUCCESS; +} + +int tegra_soc_prepare_cpu_suspend(unsigned int id, unsigned int afflvl) { /* There's nothing to be done for affinity level 1 */ if (afflvl == MPIDR_AFFLVL1) @@ -90,7 +118,7 @@ int tegra_prepare_cpu_suspend(unsigned int id, unsigned int afflvl) return PSCI_E_NOT_SUPPORTED; } -int tegra_prepare_cpu_on_finish(unsigned long mpidr) +int tegra_soc_prepare_cpu_on_finish(unsigned long mpidr) { /* * Check if we are exiting from SOC_POWERDN. @@ -120,7 +148,7 @@ int tegra_prepare_cpu_on_finish(unsigned long mpidr) return PSCI_E_SUCCESS; } -int tegra_prepare_cpu_on(unsigned long mpidr) +int tegra_soc_prepare_cpu_on(unsigned long mpidr) { int cpu = mpidr & MPIDR_CPU_MASK; uint32_t mask = CPU_CORE_RESET_MASK << cpu; @@ -139,7 +167,7 @@ int tegra_prepare_cpu_on(unsigned long mpidr) return PSCI_E_SUCCESS; } -int tegra_prepare_cpu_off(unsigned long mpidr) +int tegra_soc_prepare_cpu_off(unsigned long mpidr) { tegra_fc_cpu_off(mpidr & MPIDR_CPU_MASK); return PSCI_E_SUCCESS; |