summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNishanth Menon <nm@ti.com>2012-02-23 16:30:50 +0800
committerAndy Green <andy.green@linaro.org>2012-06-20 10:27:01 +0800
commit9b26c994968f22d9e035dda73d8559875fd21d93 (patch)
tree7bf21d419612d31fa975a914e6a490c3eb4796ba
parent07390a6eb00c719fed062007eb14427e85d18379 (diff)
OMAP4: PM: skip going through the LP sleep sequence if conflict with DVFS
Currently we consider Core and MPU dvfs transitions independently. In the case of core PD: With frequency dependency on core domain, we have almost all devices depending to scale core domain frequency scaling. Currently, we restrict ourselves to checking just core or IVA domain before deciding the domains should remain ON, instead we should be checking for all devices scaling. In the case of MPU PD: If we interrupt dvfs scaling executing on MPU for a different domain(e.g IVA), we should let it complete rather than go through the motions of programming and exiting the transition, and leaving the dvfs transition which had started half done and mpu hitting idle state. In cases such as IVA dvfs, this might tend to become even fatal as clk configurations need to go through syslink on A9 when requested from Ducati - So even if A9 is not really busy, Ducati could be waiting for the action to complete. Currently we can create all kind of weird cases with DVFS Vs LP use cases such as MPUSS successfully in OSWR but CORE in ON because we interrupted SGX dvfs scale or something similar. Instead, simplify sequencing by denying transition to LP if DVFS was caught when we dont want to be interrupted. We do this after clearing the previous states to allow the callers to detect a failed transition. Also suspend is prevented if there is an ongoing DVFS. If we interrupt an device scale operation, it is possible that we might have caught the operation off-guard such as in the middle of voltage scale or even frequency change operation. we might be unable to guarentee that all cross domain dependencies are taken care as well. Instead, we will abort suspend and priortize device scale operation and allow the system to re-attempt suspend when the conditions are right for the operation to proceed. Signed-off-by: Nishanth Menon <nm@ti.com> Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
-rw-r--r--arch/arm/mach-omap2/pm44xx.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 5c69e3bf4ee..6edfe976465 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -40,6 +40,9 @@
#include "prm44xx.h"
#include "prm-regbits-44xx.h"
#include "cm2_54xx.h"
+#include "cm44xx.h"
+#include "prm54xx.h"
+#include "dvfs.h"
static const char * const autoidle_hwmods[] = {
"gpio2",
@@ -181,6 +184,13 @@ void omap_pm_idle(u32 cpu_id, int state)
pwrdm_clear_all_prev_pwrst(per_pwrdm);
omap4_device_clear_prev_off_state();
+ /*
+ * Just return if we detect a scenario where we conflict
+ * with DVFS
+ */
+ if (omap_dvfs_is_any_dev_scaling())
+ return;
+
if (omap4_device_next_state_off()) {
/* Save the device context to SAR RAM */
if (omap_sar_save())
@@ -208,6 +218,17 @@ static int omap4_pm_suspend(void)
int state, ret = 0, logic_state;
u32 cpu_id = smp_processor_id();
+ /*
+ * If any device was in the middle of a scale operation
+ * then abort, as we cannot predict which part of the scale
+ * operation we interrupted.
+ */
+ if (omap_dvfs_is_any_dev_scaling()) {
+ pr_err("%s: oops.. middle of scale op.. aborting suspend\n",
+ __func__);
+ return -EBUSY;
+ }
+
/* Save current powerdomain state */
list_for_each_entry(pwrst, &pwrst_list, node) {
pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm);