summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/pm-t3.c
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2013-08-13 00:14:20 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2013-09-14 13:41:09 -0700
commit052ca0ae17cc32784e95e9762b197d7fa179076f (patch)
tree5e6f3ca03961ef14cf88959a983aa732449e5df4 /arch/arm/mach-tegra/pm-t3.c
parente2478be857fd99abf772ee39d6644bac72a70722 (diff)
ARM: tegra: power: Keep interrupts ON for LP CPU delay
- Moved LP CPU minimum residency delay out of the interrupt-disabled section of the cluster switch to reduce interrupt disabled time. - Time stamped start of LP CPU residency, and rail statistic after the cluster switch is completed, still within interrupt disabled section to make sure LP residency restriction is applied on top of cluster transition latency. Change-Id: I55f769af197bbd757966bafe37a10a6e43b7bf2e Signed-off-by: Alex Frid <afrid@nvidia.com> Reviewed-on: http://git-master/r/261328 GVS: Gerrit_Virtual_Submit Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/pm-t3.c')
-rw-r--r--arch/arm/mach-tegra/pm-t3.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/arch/arm/mach-tegra/pm-t3.c b/arch/arm/mach-tegra/pm-t3.c
index 8f9ac0c77259..c346cb356400 100644
--- a/arch/arm/mach-tegra/pm-t3.c
+++ b/arch/arm/mach-tegra/pm-t3.c
@@ -3,7 +3,7 @@
*
* Tegra3 SOC-specific power and cluster management
*
- * Copyright (c) 2009-2012, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2009-2013, NVIDIA CORPORATION. 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 as published by
@@ -409,28 +409,28 @@ int tegra_cluster_control(unsigned int us, unsigned int flags)
(flags & TEGRA_POWER_CLUSTER_FORCE) ? "force" : "",
us));
- local_irq_save(irq_flags);
-
if (current_cluster != target_cluster && !timekeeping_suspended) {
- ktime_t now = ktime_get();
if (target_cluster == TEGRA_POWER_CLUSTER_G) {
+ ktime_t now = ktime_get();
s64 t = ktime_to_us(ktime_sub(now, last_g2lp));
s64 t_off = tegra_cpu_power_off_time();
if (t_off > t)
udelay((unsigned int)(t_off - t));
+ }
+ }
+
+ local_irq_save(irq_flags);
- tegra_dvfs_rail_on(tegra_cpu_rail, now);
- } else {
#ifdef CONFIG_TEGRA_VIRTUAL_CPUID
+ if (current_cluster != target_cluster && !timekeeping_suspended) {
+ if (target_cluster == TEGRA_POWER_CLUSTER_LP) {
u32 cpu;
cpu = cpu_logical_map(smp_processor_id());
writel(cpu, FLOW_CTRL_MPID);
-#endif
- last_g2lp = now;
- tegra_dvfs_rail_off(tegra_cpu_rail, now);
}
}
+#endif
if (flags & TEGRA_POWER_SDRAM_SELFREFRESH) {
if (us)
@@ -459,6 +459,16 @@ int tegra_cluster_control(unsigned int us, unsigned int flags)
cpu_pm_exit();
tegra_clear_cpu_in_pd(cpu);
}
+
+ if (current_cluster != target_cluster && !timekeeping_suspended) {
+ ktime_t now = ktime_get();
+ if (target_cluster == TEGRA_POWER_CLUSTER_G) {
+ tegra_dvfs_rail_on(tegra_cpu_rail, now);
+ } else {
+ last_g2lp = now;
+ tegra_dvfs_rail_off(tegra_cpu_rail, now);
+ }
+ }
local_irq_restore(irq_flags);
DEBUG_CLUSTER(("%s: %s\r\n", __func__, is_lp_cluster() ? "LP" : "G"));