diff options
| author | Archana Sathyakumar <asathyak@codeaurora.org> | 2015-12-04 15:52:17 -0700 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 21:17:31 -0700 |
| commit | bda3760199251da579e1af65d764b02fdc7bf240 (patch) | |
| tree | adccb8761cbaaea00d8cbac4a3ec7aac54bf0527 /drivers/cpuidle | |
| parent | 82d7fa326e62081173263b775768ebafa4494dd6 (diff) | |
lpm: Allow cpu to enter FPC from hypervisor
FPC using PSCI is entered from PSCI layer that is in Secure EL1.
Switching of EL layers incur additional latency, making FPC slower.
Issue wfi within hypervisor for cpu only sleep. This makes FPC much
faster than entering from PSCI layer.
Change-Id: Icf4c5f2484fdda79c991b842cb3a3185b638bfdb
Signed-off-by: Archana Sathyakumar <asathyak@codeaurora.org>
Diffstat (limited to 'drivers/cpuidle')
| -rw-r--r-- | drivers/cpuidle/lpm-levels-of.c | 5 | ||||
| -rw-r--r-- | drivers/cpuidle/lpm-levels.c | 10 | ||||
| -rw-r--r-- | drivers/cpuidle/lpm-levels.h | 3 |
3 files changed, 15 insertions, 3 deletions
diff --git a/drivers/cpuidle/lpm-levels-of.c b/drivers/cpuidle/lpm-levels-of.c index bbe88b6fe8e6..4476771a637b 100644 --- a/drivers/cpuidle/lpm-levels-of.c +++ b/drivers/cpuidle/lpm-levels-of.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -563,6 +563,9 @@ static int parse_cpu_mode(struct device_node *n, struct lpm_cpu_level *l) n->name); return ret; } + key = "qcom,hyp-psci"; + + l->hyp_psci = of_property_read_bool(n, key); } else { l->mode = parse_cpu_spm_mode(l->name); diff --git a/drivers/cpuidle/lpm-levels.c b/drivers/cpuidle/lpm-levels.c index 7e3a83aed092..9d53c3af5f5a 100644 --- a/drivers/cpuidle/lpm-levels.c +++ b/drivers/cpuidle/lpm-levels.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -766,6 +766,7 @@ unlock_and_return: #if !defined(CONFIG_CPU_V7) #include <asm/cpuidle.h> +asmlinkage int __invoke_psci_fn_smc(u64, u64, u64, u64); bool psci_enter_sleep(struct lpm_cluster *cluster, int idx, bool from_idle) { /* @@ -783,6 +784,13 @@ bool psci_enter_sleep(struct lpm_cluster *cluster, int idx, bool from_idle) PSCI_POWER_STATE(cluster->cpu->levels[idx].is_reset); bool success = false; + if (cluster->cpu->levels[idx].hyp_psci) { + stop_critical_timings(); + __invoke_psci_fn_smc(0xC4000021, 0, 0, 0); + start_critical_timings(); + return 1; + } + affinity_level = PSCI_AFFINITY_LEVEL(affinity_level); state_id |= (power_state | affinity_level | cluster->cpu->levels[idx].psci_id); diff --git a/drivers/cpuidle/lpm-levels.h b/drivers/cpuidle/lpm-levels.h index 6117ba334fe6..2071935625d1 100644 --- a/drivers/cpuidle/lpm-levels.h +++ b/drivers/cpuidle/lpm-levels.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2014, 2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -37,6 +37,7 @@ struct lpm_cpu_level { unsigned int psci_id; bool is_reset; bool jtag_save_restore; + bool hyp_psci; }; struct lpm_cpu { |
