Commit 93eafbca authored by Varun Wadekar's avatar Varun Wadekar
Browse files

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: default avatarVarun Wadekar <vwadekar@nvidia.com>
parent fb11a62f
...@@ -51,27 +51,27 @@ static int system_suspended; ...@@ -51,27 +51,27 @@ static int system_suspended;
* The following platform setup functions are weakly defined. They * The following platform setup functions are weakly defined. They
* provide typical implementations that will be overridden by a SoC. * provide typical implementations that will be overridden by a SoC.
*/ */
#pragma weak tegra_prepare_cpu_suspend #pragma weak tegra_soc_prepare_cpu_suspend
#pragma weak tegra_prepare_cpu_on #pragma weak tegra_soc_prepare_cpu_on
#pragma weak tegra_prepare_cpu_off #pragma weak tegra_soc_prepare_cpu_off
#pragma weak tegra_prepare_cpu_on_finish #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; 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; 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; 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; return PSCI_E_SUCCESS;
} }
...@@ -134,17 +134,7 @@ unsigned int tegra_get_sys_suspend_power_state(void) ...@@ -134,17 +134,7 @@ unsigned int tegra_get_sys_suspend_power_state(void)
******************************************************************************/ ******************************************************************************/
int32_t tegra_validate_power_state(unsigned int power_state) int32_t tegra_validate_power_state(unsigned int power_state)
{ {
/* Sanity check the requested state */ return tegra_soc_validate_power_state(power_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;
} }
/******************************************************************************* /*******************************************************************************
...@@ -171,7 +161,7 @@ int tegra_affinst_on(unsigned long mpidr, ...@@ -171,7 +161,7 @@ int tegra_affinst_on(unsigned long mpidr,
sec_entry_point[cpu] = sec_entrypoint; sec_entry_point[cpu] = sec_entrypoint;
flush_dcache_range((uint64_t)&sec_entry_point[cpu], sizeof(uint64_t)); 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) ...@@ -194,7 +184,7 @@ void tegra_affinst_off(unsigned int afflvl, unsigned int state)
if (afflvl > MPIDR_AFFLVL0) if (afflvl > MPIDR_AFFLVL0)
return; 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, ...@@ -227,7 +217,7 @@ void tegra_affinst_suspend(unsigned long sec_entrypoint,
sec_entry_point[cpu] = sec_entrypoint; sec_entry_point[cpu] = sec_entrypoint;
flush_dcache_range((uint64_t)&sec_entry_point[cpu], sizeof(uint64_t)); 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 */ /* disable GICC */
tegra_gic_cpuif_deactivate(); tegra_gic_cpuif_deactivate();
...@@ -280,7 +270,7 @@ void tegra_affinst_on_finish(unsigned int afflvl, unsigned int state) ...@@ -280,7 +270,7 @@ void tegra_affinst_on_finish(unsigned int afflvl, unsigned int state)
/* /*
* Reset hardware settings. * 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) ...@@ -338,7 +328,7 @@ int platform_setup_pm(const plat_pm_ops_t **plat_ops)
/* /*
* Reset hardware settings. * Reset hardware settings.
*/ */
tegra_prepare_cpu_on_finish(read_mpidr()); tegra_soc_prepare_cpu_on_finish(read_mpidr());
/* /*
* Initialize PM ops struct * Initialize PM ops struct
......
...@@ -45,6 +45,9 @@ typedef struct plat_params_from_bl2 { ...@@ -45,6 +45,9 @@ typedef struct plat_params_from_bl2 {
uintptr_t bl32_params; uintptr_t bl32_params;
} plat_params_from_bl2_t; } 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 */ /* Declarations for plat_setup.c */
const mmap_region_t *plat_get_mmio_map(void); const mmap_region_t *plat_get_mmio_map(void);
uint64_t plat_get_syscnt_freq(void); uint64_t plat_get_syscnt_freq(void);
......
...@@ -49,7 +49,35 @@ ...@@ -49,7 +49,35 @@
static int cpu_powergate_mask[PLATFORM_MAX_CPUS_PER_CLUSTER]; 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 */ /* There's nothing to be done for affinity level 1 */
if (afflvl == MPIDR_AFFLVL1) if (afflvl == MPIDR_AFFLVL1)
...@@ -90,7 +118,7 @@ int tegra_prepare_cpu_suspend(unsigned int id, unsigned int afflvl) ...@@ -90,7 +118,7 @@ int tegra_prepare_cpu_suspend(unsigned int id, unsigned int afflvl)
return PSCI_E_NOT_SUPPORTED; 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. * Check if we are exiting from SOC_POWERDN.
...@@ -120,7 +148,7 @@ int tegra_prepare_cpu_on_finish(unsigned long mpidr) ...@@ -120,7 +148,7 @@ int tegra_prepare_cpu_on_finish(unsigned long mpidr)
return PSCI_E_SUCCESS; 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; int cpu = mpidr & MPIDR_CPU_MASK;
uint32_t mask = CPU_CORE_RESET_MASK << cpu; uint32_t mask = CPU_CORE_RESET_MASK << cpu;
...@@ -139,7 +167,7 @@ int tegra_prepare_cpu_on(unsigned long mpidr) ...@@ -139,7 +167,7 @@ int tegra_prepare_cpu_on(unsigned long mpidr)
return PSCI_E_SUCCESS; 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); tegra_fc_cpu_off(mpidr & MPIDR_CPU_MASK);
return PSCI_E_SUCCESS; return PSCI_E_SUCCESS;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment