summaryrefslogtreecommitdiff
path: root/plat/nvidia
diff options
context:
space:
mode:
authorVarun Wadekar <vwadekar@nvidia.com>2015-07-23 10:07:54 +0530
committerVarun Wadekar <vwadekar@nvidia.com>2015-07-24 09:08:27 +0530
commit93eafbcad46b83bb0db3b86b1508f08efce25519 (patch)
tree2019de1ff4cfa73e2458d1deae26404ef82ed15f /plat/nvidia
parentfb11a62fede3d76506ba353f93264569e711cf74 (diff)
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')
-rw-r--r--plat/nvidia/tegra/common/tegra_pm.c38
-rw-r--r--plat/nvidia/tegra/include/tegra_private.h3
-rw-r--r--plat/nvidia/tegra/soc/t210/plat_psci_handlers.c36
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 bcaaf412..87f72403 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 d0cde2af..dbd66893 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 010899ac..578dd8e1 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;