* [PATCH 00/12] ARM: OMAP2+: powerdomain updates after the functional power state conversion
@ 2012-12-09 20:02 Paul Walmsley
2012-12-09 20:02 ` [PATCH 01/12] ARM: OMAP2+: powerdomain: consolidate arch_pwrdm check code Paul Walmsley
` (11 more replies)
0 siblings, 12 replies; 20+ messages in thread
From: Paul Walmsley @ 2012-12-09 20:02 UTC (permalink / raw)
To: linux-arm-kernel
OMAP powerdomain code updates, implemented on top of the
functional power state conversion series. This series fixes the powerdomain
handling for OMAP2xxx, adds caching for the powerdomain next-power-state
and previous-power-state register bitfields, and some cleanup that's
intended to make it easier to move the powerdomain code out to drivers/.
- Paul
---
vmlinux object size
(delta in bytes from TEST_func_powerstates_devel_3.9 (6d8345f4177c976eca1a1368cdd68e95f80c3f27)):
text data bss total kernel
-68 +48 0 -20 am33xx_only
-136 +48 0 -88 n800_multi_omap2xxx
-128 +48 0 -80 n800_only_a
0 0 0 0 omap1_defconfig
0 0 0 0 omap1_defconfig_1510innovator_only
0 0 0 0 omap1_defconfig_5912osk_only
-32 +368 0 +336 omap2plus_defconfig
+20 +16 0 +36 omap2plus_defconfig_2430sdp_only
-32 +432 0 +400 omap2plus_defconfig_cpupm
+572 +192 0 +764 omap2plus_defconfig_no_pm
-20 +208 0 +188 omap2plus_defconfig_omap2_4_only
-84 +304 0 +220 omap2plus_defconfig_omap3_4_only
+708 +200 -104 +804 rmk_omap3430_ldp_allnoconfig
+352 +128 0 +480 rmk_omap3430_ldp_oldconfig
+708 +200 -104 +804 rmk_omap4430_sdp_allnoconfig
-164 +8 0 -156 rmk_omap4430_sdp_oldconfig
Paul Walmsley (12):
ARM: OMAP2+: powerdomain: consolidate arch_pwrdm check code
ARM: OMAP2+: PM/powerdomain: move the power state time tracking into the powerdomain code
ARM: OMAP2+: powerdomain: split pwrdm_state_switch()
ARM: OMAP2+: PM: clean up some debugfs functions
ARM: OMAP2+: powerdomain: remove some redundant checks; add some notes
ARM: OMAP2+: CM: use the cached copy of the clockdomain's hwsup state
ARM: OMAP2+: powerdomain: cache the powerdomain next power state
ARM: OMAP2+: powerdomain: cache the powerdomain's previous power state
ARM: OMAP2+: powerdomain: skip register reads for powerdomains known to be on
ARM: OMAP2+: powerdomain: skip previous-power-state read if next_pwrst is ON
ARM: OMAP2xxx: powerdomain: add previous power state tracking
ARM: OMAP2xxx: PM: add pwrdm_(pre|post)_transition() calls to the 2xxx PM code
arch/arm/mach-omap2/clockdomain.c | 18 +
arch/arm/mach-omap2/clockdomain.h | 2
arch/arm/mach-omap2/cm2xxx.c | 19 -
arch/arm/mach-omap2/cm3xxx.c | 14 -
arch/arm/mach-omap2/pm-debug.c | 101 --------
arch/arm/mach-omap2/pm.h | 6
arch/arm/mach-omap2/pm24xx.c | 8 +
arch/arm/mach-omap2/powerdomain.c | 352 +++++++++++++++++++--------
arch/arm/mach-omap2/powerdomain.h | 40 +++
arch/arm/mach-omap2/powerdomains2xxx_data.c | 2
arch/arm/mach-omap2/powerdomains33xx_data.c | 3
arch/arm/mach-omap2/powerdomains3xxx_data.c | 9 -
arch/arm/mach-omap2/powerdomains44xx_data.c | 5
arch/arm/mach-omap2/prm2xxx.c | 12 +
14 files changed, 347 insertions(+), 244 deletions(-)
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 01/12] ARM: OMAP2+: powerdomain: consolidate arch_pwrdm check code
2012-12-09 20:02 [PATCH 00/12] ARM: OMAP2+: powerdomain updates after the functional power state conversion Paul Walmsley
@ 2012-12-09 20:02 ` Paul Walmsley
2012-12-09 20:03 ` [PATCH 02/12] ARM: OMAP2+: PM/powerdomain: move the power state time tracking into the powerdomain code Paul Walmsley
` (10 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Paul Walmsley @ 2012-12-09 20:02 UTC (permalink / raw)
To: linux-arm-kernel
Check for the presence of some of the arch_pwrdm function pointers
during powerdomain setup, rather than in the individual functions.
The primary motivation is to make the code slightly easier to read, but it
also should avoid a few instructions in some hot paths.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
arch/arm/mach-omap2/powerdomain.c | 43 +++++++++++++++----------------------
1 file changed, 18 insertions(+), 25 deletions(-)
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index f81aee1..b67d721 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -385,9 +385,6 @@ static int _set_logic_retst_and_pwrdm_pwrst(struct powerdomain *pwrdm,
if (!_pwrdm_pwrst_is_controllable(pwrdm))
return 0;
- if (!arch_pwrdm || !arch_pwrdm->pwrdm_set_next_pwrst)
- return -EINVAL;
-
if (!(pwrdm->pwrsts & (1 << pwrst)))
return -EINVAL;
@@ -395,13 +392,11 @@ static int _set_logic_retst_and_pwrdm_pwrst(struct powerdomain *pwrdm,
if (!(pwrdm->pwrsts_logic_ret & (1 << logic)))
return -EINVAL;
- if (arch_pwrdm->pwrdm_set_logic_retst) {
- ret = arch_pwrdm->pwrdm_set_logic_retst(pwrdm, logic);
- if (ret) {
- pr_err("%s: unable to set logic state %0x of powerdomain: %s\n",
- __func__, logic, pwrdm->name);
- return ret;
- }
+ ret = arch_pwrdm->pwrdm_set_logic_retst(pwrdm, logic);
+ if (ret) {
+ pr_err("%s: unable to set logic state %0x of powerdomain: %s\n",
+ __func__, logic, pwrdm->name);
+ return ret;
}
}
@@ -426,9 +421,6 @@ static int _pwrdm_read_next_fpwrst(struct powerdomain *pwrdm)
int next_pwrst, next_logic, ret;
u8 fpwrst;
- if (!arch_pwrdm || !arch_pwrdm->pwrdm_read_next_pwrst)
- return -EINVAL;
-
next_pwrst = arch_pwrdm->pwrdm_read_next_pwrst(pwrdm);
if (next_pwrst < 0)
return next_pwrst;
@@ -653,9 +645,12 @@ static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
*
* Register the list of function pointers used to implement the
* powerdomain functions on different OMAP SoCs. Should be called
- * before any other pwrdm_register*() function. Returns -EINVAL if
- * @po is null, -EEXIST if platform functions have already been
- * registered, or 0 upon success.
+ * before any other pwrdm_register*() function. Several function
+ * pointers in @po are required to be non-null for the powerdomain
+ * code to function: pwrdm_wait_transition, pwrdm_read_next_pwrst,
+ * pwrdm_read_pwrst, pwrdm_set_next_pwrst, pwrdm_set_logic_retst, and
+ * pwrdm_read_prev_pwrst. Returns -EINVAL if @po is null, -EEXIST if
+ * platform functions have already been registered, or 0 upon success.
*/
int pwrdm_register_platform_funcs(struct pwrdm_ops *po)
{
@@ -665,6 +660,11 @@ int pwrdm_register_platform_funcs(struct pwrdm_ops *po)
if (arch_pwrdm)
return -EEXIST;
+ if (!po->pwrdm_wait_transition || !po->pwrdm_read_next_pwrst ||
+ !po->pwrdm_read_pwrst || !po->pwrdm_set_next_pwrst ||
+ !po->pwrdm_set_logic_retst || !po->pwrdm_read_prev_pwrst)
+ return -ENOENT;
+
arch_pwrdm = po;
return 0;
@@ -1221,7 +1221,7 @@ int pwrdm_read_next_fpwrst(struct powerdomain *pwrdm)
int next_pwrst, next_logic, ret;
u8 fpwrst;
- if (!arch_pwrdm || !arch_pwrdm->pwrdm_read_next_pwrst)
+ if (!arch_pwrdm)
return -EINVAL;
pwrdm_lock(pwrdm);
@@ -1264,8 +1264,7 @@ int pwrdm_set_fpwrst(struct powerdomain *pwrdm, enum pwrdm_func_state fpwrst)
int ret = 0;
bool hwsup = false;
- if (!pwrdm || IS_ERR(pwrdm) || !arch_pwrdm ||
- !arch_pwrdm->pwrdm_read_pwrst)
+ if (!pwrdm || IS_ERR(pwrdm) || !arch_pwrdm)
return -EINVAL;
/*
@@ -1334,9 +1333,6 @@ int pwrdm_read_fpwrst(struct powerdomain *pwrdm)
if (!_pwrdm_pwrst_can_change(pwrdm))
return PWRDM_FUNC_PWRST_ON;
- if (!arch_pwrdm->pwrdm_read_pwrst)
- return -EINVAL;
-
pwrdm_lock(pwrdm);
ret = _pwrdm_read_fpwrst(pwrdm);
pwrdm_unlock(pwrdm);
@@ -1362,9 +1358,6 @@ int pwrdm_read_prev_fpwrst(struct powerdomain *pwrdm)
if (!_pwrdm_pwrst_can_change(pwrdm))
return PWRDM_FUNC_PWRST_ON;
- if (!arch_pwrdm->pwrdm_read_prev_pwrst)
- return -EINVAL;
-
pwrdm_lock(pwrdm);
ret = _pwrdm_read_prev_fpwrst(pwrdm);
pwrdm_unlock(pwrdm);
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 02/12] ARM: OMAP2+: PM/powerdomain: move the power state time tracking into the powerdomain code
2012-12-09 20:02 [PATCH 00/12] ARM: OMAP2+: powerdomain updates after the functional power state conversion Paul Walmsley
2012-12-09 20:02 ` [PATCH 01/12] ARM: OMAP2+: powerdomain: consolidate arch_pwrdm check code Paul Walmsley
@ 2012-12-09 20:03 ` Paul Walmsley
2012-12-09 20:03 ` [PATCH 03/12] ARM: OMAP2+: powerdomain: split pwrdm_state_switch() Paul Walmsley
` (9 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Paul Walmsley @ 2012-12-09 20:03 UTC (permalink / raw)
To: linux-arm-kernel
Move the power state time tracking code into the powerdomain code.
This code accesses internal powerdomain state, so this change will
allow us to reduce what is exported from the powerdomain code.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Tero Kristo <t-kristo@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
---
arch/arm/mach-omap2/pm-debug.c | 24 ------------------------
arch/arm/mach-omap2/pm.h | 6 ------
arch/arm/mach-omap2/powerdomain.c | 22 +++++++++++++++++++++-
3 files changed, 21 insertions(+), 31 deletions(-)
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 03da2e3..80c001a 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -53,21 +53,6 @@ enum {
DEBUG_FILE_TIMERS,
};
-void pm_dbg_update_time(struct powerdomain *pwrdm, int prev)
-{
- s64 t;
-
- if (!pm_dbg_init_done)
- return ;
-
- /* Update timer for previous state */
- t = sched_clock();
-
- pwrdm->fpwrst_timer[prev - PWRDM_FPWRST_OFFSET] += t - pwrdm->timer;
-
- pwrdm->timer = t;
-}
-
static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user)
{
struct seq_file *s = (struct seq_file *)user;
@@ -197,17 +182,8 @@ DEFINE_SIMPLE_ATTRIBUTE(pwrdm_suspend_fops, pwrdm_suspend_get,
static int __init pwrdms_setup(struct powerdomain *pwrdm, void *dir)
{
- int i;
- s64 t;
struct dentry *d;
- t = sched_clock();
-
- for (i = 0; i < PWRDM_FPWRSTS_COUNT; i++)
- pwrdm->fpwrst_timer[i] = 0;
-
- pwrdm->timer = t;
-
if (strncmp(pwrdm->name, "dpll", 4) == 0)
return 0;
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 19ef376..c496f27 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -59,12 +59,6 @@ extern u32 enable_off_mode;
#define enable_off_mode 0
#endif
-#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
-extern void pm_dbg_update_time(struct powerdomain *pwrdm, int prev);
-#else
-#define pm_dbg_update_time(pwrdm, prev) do {} while (0);
-#endif /* CONFIG_PM_DEBUG */
-
/* 24xx */
extern void omap24xx_idle_loop_suspend(void);
extern unsigned int omap24xx_idle_loop_suspend_sz;
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index b67d721..53bc852 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -20,6 +20,8 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/spinlock.h>
+#include <linux/sched.h>
+
#include <trace/events/power.h>
#include "cm2xxx_3xxx.h"
@@ -126,6 +128,9 @@ static int _pwrdm_register(struct powerdomain *pwrdm)
arch_pwrdm->pwrdm_wait_transition(pwrdm);
pwrdm->fpwrst = pwrdm_read_fpwrst(pwrdm);
pwrdm->fpwrst_counter[pwrdm->fpwrst - PWRDM_FPWRST_OFFSET] = 1;
+#ifdef CONFIG_PM_DEBUG
+ pwrdm->timer = sched_clock();
+#endif
return 0;
}
@@ -579,6 +584,21 @@ static int _pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
return ret;
}
+/* XXX prev is wrong type */
+/* XXX is sched_clock() correct to use here? */
+/* Update timer for previous state */
+static void _pwrdm_update_pwrst_time(struct powerdomain *pwrdm, int prev)
+{
+#ifdef CONFIG_PM_DEBUG
+ s64 t;
+
+ t = sched_clock();
+
+ pwrdm->fpwrst_timer[prev - PWRDM_FPWRST_OFFSET] += t - pwrdm->timer;
+
+ pwrdm->timer = t;
+#endif
+}
/* XXX Caller must hold pwrdm->_lock */
static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
@@ -617,7 +637,7 @@ static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
if (fpwrst != prev)
pwrdm->fpwrst_counter[fpwrst - PWRDM_FPWRST_OFFSET]++;
- pm_dbg_update_time(pwrdm, prev);
+ _pwrdm_update_pwrst_time(pwrdm, prev);
pwrdm->fpwrst = fpwrst;
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 03/12] ARM: OMAP2+: powerdomain: split pwrdm_state_switch()
2012-12-09 20:02 [PATCH 00/12] ARM: OMAP2+: powerdomain updates after the functional power state conversion Paul Walmsley
2012-12-09 20:02 ` [PATCH 01/12] ARM: OMAP2+: powerdomain: consolidate arch_pwrdm check code Paul Walmsley
2012-12-09 20:03 ` [PATCH 02/12] ARM: OMAP2+: PM/powerdomain: move the power state time tracking into the powerdomain code Paul Walmsley
@ 2012-12-09 20:03 ` Paul Walmsley
2012-12-09 20:03 ` [PATCH 04/12] ARM: OMAP2+: PM: clean up some debugfs functions Paul Walmsley
` (8 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Paul Walmsley @ 2012-12-09 20:03 UTC (permalink / raw)
To: linux-arm-kernel
Move the pwrdm_state_switch() code that deals with previous power
states into the post-transition callback. This improves the clarity
of pwrdm_state_switch() considerably. Add some sorely-needed
kerneldoc for these functions.
It should be possible to drop pwrdm_state_switch() completely during
3.9.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Tero Kristo <t-kristo@ti.com>
---
arch/arm/mach-omap2/powerdomain.c | 118 ++++++++++++++++++++++++-------------
arch/arm/mach-omap2/powerdomain.h | 1
2 files changed, 76 insertions(+), 43 deletions(-)
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 53bc852..d38f493 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -40,11 +40,6 @@
#define PWRDM_TRACE_STATES_FLAG (1<<31)
-enum {
- PWRDM_STATE_NOW = 0,
- PWRDM_STATE_PREV,
-};
-
/* Types of sleep_switch used in pwrdm_set_fpwrst() */
#define ALREADYACTIVE_SWITCH 0
#define FORCEWAKEUP_SWITCH 1
@@ -600,60 +595,97 @@ static void _pwrdm_update_pwrst_time(struct powerdomain *pwrdm, int prev)
#endif
}
-/* XXX Caller must hold pwrdm->_lock */
-static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
+/**
+ * _pwrdm_state_switch - record powerdomain usage data; track power state
+ * (before powerdomain state transition)
+ * @pwrdm: struct powerdomain * to observe
+ *
+ * If the powerdomain @pwrdm's current power state is not what we last
+ * observed it to be, then increment the counter for that power state.
+ * This is used to track context loss events, and for debugging. Also
+ * if CONFIG_PM_DEBUG=y, track the amount of time the powerdomain has
+ * spent in the current power state. Caller must hold pwrdm->_lock.
+ * Intended to be called immediately before the powerdomain's power
+ * state is likely to change. XXX Note that the counts and durations
+ * observed by this function may be inaccurate. Powerdomains can
+ * transition power states automatically, without the kernel being
+ * involved -- for example, a device can DMA data from memory while
+ * the MPU is asleep. This function does not attempt to account for
+ * that. XXX It may be possible to skip this function completely if
+ * PM debugging is not needed and off-mode and OSWR is disabled (e.g.,
+ * no context loss events). No return value.
+ */
+static void _pwrdm_state_switch(struct powerdomain *pwrdm)
{
- int prev, next, fpwrst, trace_state = 0;
-
- if (pwrdm == NULL)
- return -EINVAL;
+ int fpwrst;
fpwrst = _pwrdm_read_fpwrst(pwrdm);
-
- switch (flag) {
- case PWRDM_STATE_NOW:
- prev = pwrdm->fpwrst;
- break;
- case PWRDM_STATE_PREV:
- prev = _pwrdm_read_prev_fpwrst(pwrdm);
- if (pwrdm->fpwrst != prev)
- pwrdm->fpwrst_counter[prev - PWRDM_FPWRST_OFFSET]++;
- /*
- * If the power domain did not hit the desired state,
- * generate a trace event with both the desired and hit states
- */
- next = _pwrdm_read_next_fpwrst(pwrdm);
- if (next != prev) {
- trace_state = (PWRDM_TRACE_STATES_FLAG | next << 8 |
- prev);
- trace_power_domain_target(pwrdm->name, trace_state,
- smp_processor_id());
- }
- break;
- default:
- return -EINVAL;
- }
-
- if (fpwrst != prev)
+ if (fpwrst != pwrdm->fpwrst)
pwrdm->fpwrst_counter[fpwrst - PWRDM_FPWRST_OFFSET]++;
- _pwrdm_update_pwrst_time(pwrdm, prev);
+ _pwrdm_update_pwrst_time(pwrdm, pwrdm->fpwrst);
pwrdm->fpwrst = fpwrst;
-
- return 0;
}
static int _pwrdm_pre_transition_cb(struct powerdomain *pwrdm, void *unused)
{
pwrdm_clear_all_prev_pwrst(pwrdm);
- _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
+ _pwrdm_state_switch(pwrdm);
return 0;
}
+/**
+ * _pwrdm_post_transition_cb - record powerdomain usage data; track power state
+ * (after powerdomain power state transition)
+ * @pwrdm: struct powerdomain * to observe
+ *
+ * If the powerdomain @pwrdm's previous power state doesn't match our
+ * recollection of the powerdomain's current power state, then
+ * increment the counter for the previous power state. And if the
+ * powerdomain's previous power state doesn't match the current power
+ * state, increment the counter for the current power state. This
+ * function is used to track context loss events, and for debugging.
+ * Also if CONFIG_PM_DEBUG=y, track the approximate amount of time the
+ * powerdomain has spent in the previous power state. Caller must
+ * hold pwrdm->_lock. XXX Note that the counts and durations observed
+ * by this function may be inaccurate. Powerdomains can transition
+ * power states automatically, without the kernel being involved --
+ * for example, a device can DMA data from memory while the MPU is
+ * asleep. This function does not attempt to account for that. XXX
+ * It may be possible to skip this function completely if PM debugging
+ * is not needed and off-mode and OSWR is disabled (e.g., no context
+ * loss events). No return value.
+ */
static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
{
- _pwrdm_state_switch(pwrdm, PWRDM_STATE_PREV);
+ int prev, next, fpwrst;
+ int trace_state = 0;
+
+ prev = _pwrdm_read_prev_fpwrst(pwrdm);
+ if (pwrdm->fpwrst != prev)
+ pwrdm->fpwrst_counter[prev - PWRDM_FPWRST_OFFSET]++;
+
+ _pwrdm_update_pwrst_time(pwrdm, prev);
+
+ /*
+ * If the power domain did not hit the desired state,
+ * generate a trace event with both the desired and hit states
+ */
+ next = _pwrdm_read_next_fpwrst(pwrdm);
+ if (next != prev) {
+ trace_state = (PWRDM_TRACE_STATES_FLAG | next << 8 |
+ prev);
+ trace_power_domain_target(pwrdm->name, trace_state,
+ smp_processor_id());
+ }
+
+ fpwrst = _pwrdm_read_fpwrst(pwrdm);
+ if (fpwrst != prev)
+ pwrdm->fpwrst_counter[fpwrst - PWRDM_FPWRST_OFFSET]++;
+
+ pwrdm->fpwrst = fpwrst;
+
return 0;
}
@@ -1055,7 +1087,7 @@ int pwrdm_state_switch_nolock(struct powerdomain *pwrdm)
ret = arch_pwrdm->pwrdm_wait_transition(pwrdm);
if (!ret)
- ret = _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
+ _pwrdm_state_switch(pwrdm);
return ret;
}
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index 48bb325..ef51987b 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -237,6 +237,7 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm);
int pwrdm_state_switch_nolock(struct powerdomain *pwrdm);
int pwrdm_state_switch(struct powerdomain *pwrdm);
+int pwrdm_state_switch_nolock(struct powerdomain *pwrdm);
int pwrdm_pre_transition(struct powerdomain *pwrdm);
int pwrdm_post_transition(struct powerdomain *pwrdm);
int pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 04/12] ARM: OMAP2+: PM: clean up some debugfs functions
2012-12-09 20:02 [PATCH 00/12] ARM: OMAP2+: powerdomain updates after the functional power state conversion Paul Walmsley
` (2 preceding siblings ...)
2012-12-09 20:03 ` [PATCH 03/12] ARM: OMAP2+: powerdomain: split pwrdm_state_switch() Paul Walmsley
@ 2012-12-09 20:03 ` Paul Walmsley
2012-12-09 20:03 ` [PATCH 06/12] ARM: OMAP2+: CM: use the cached copy of the clockdomain's hwsup state Paul Walmsley
` (7 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Paul Walmsley @ 2012-12-09 20:03 UTC (permalink / raw)
To: linux-arm-kernel
Move some debugfs functions into the powerdomain and clockdomain code;
the ultimate goal is to stop exporting some of the
powerdomain/clockdomain functions. Get rid of the nasty hacks that
avoid executing some of the debug functions based on string
comparisons on powerdomain and clockdomain names. Lock the
powerdomain for the duration of these functions so that the debug
information doesn't change during execution. Also, while here, fix a
whitespace issue in mach-omap2/pm-debug.c.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Tero Kristo <t-kristo@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
---
arch/arm/mach-omap2/clockdomain.c | 18 +++++++-
arch/arm/mach-omap2/clockdomain.h | 2 +
arch/arm/mach-omap2/pm-debug.c | 77 ++--------------------------------
arch/arm/mach-omap2/powerdomain.c | 85 +++++++++++++++++++++++++++++++++++++
arch/arm/mach-omap2/powerdomain.h | 4 ++
5 files changed, 111 insertions(+), 75 deletions(-)
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index a90c0c8..bc9b79e 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -22,9 +22,8 @@
#include <linux/clk.h>
#include <linux/limits.h>
#include <linux/err.h>
-
+#include <linux/seq_file.h>
#include <linux/io.h>
-
#include <linux/bitops.h>
#include "soc.h"
@@ -1281,3 +1280,18 @@ int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh)
return _clkdm_clk_hwmod_disable(clkdm);
}
+/* Clockdomain debugfs functions */
+
+int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *seq_file)
+{
+ struct seq_file *s = (struct seq_file *)seq_file;
+
+ if (!clkdm->flags)
+ return 0;
+
+ seq_printf(s, "%s->%s (%d)\n", clkdm->name, clkdm->pwrdm.ptr->name,
+ clkdm->usecount);
+
+ return 0;
+}
+
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
index 2da3765..95e473b 100644
--- a/arch/arm/mach-omap2/clockdomain.h
+++ b/arch/arm/mach-omap2/clockdomain.h
@@ -229,4 +229,6 @@ extern struct clkdm_dep gfx_24xx_wkdeps[];
extern struct clkdm_dep dsp_24xx_wkdeps[];
extern struct clockdomain wkup_common_clkdm;
+extern int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *seq_file);
+
#endif
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 80c001a..9861069 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -53,75 +53,6 @@ enum {
DEBUG_FILE_TIMERS,
};
-static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user)
-{
- struct seq_file *s = (struct seq_file *)user;
-
- /* XXX This needs to be implemented in a better way */
- if (strcmp(clkdm->name, "emu_clkdm") == 0 ||
- strcmp(clkdm->name, "wkup_clkdm") == 0 ||
- strncmp(clkdm->name, "dpll", 4) == 0)
- return 0;
-
- seq_printf(s, "%s->%s (%d)\n", clkdm->name, clkdm->pwrdm.ptr->name,
- clkdm->usecount);
-
- return 0;
-}
-
-static int pwrdm_dbg_show_counter(struct powerdomain *pwrdm, void *user)
-{
- struct seq_file *s = (struct seq_file *)user;
- int i;
- int curr_fpwrst;
-
- if (strcmp(pwrdm->name, "emu_pwrdm") == 0 ||
- strcmp(pwrdm->name, "wkup_pwrdm") == 0 ||
- strncmp(pwrdm->name, "dpll", 4) == 0)
- return 0;
-
- curr_fpwrst = pwrdm_read_fpwrst(pwrdm);
- if (pwrdm->fpwrst != curr_fpwrst)
- pr_err("pwrdm state mismatch(%s) %s != %s\n",
- pwrdm->name,
- pwrdm_convert_fpwrst_to_name(pwrdm->fpwrst),
- pwrdm_convert_fpwrst_to_name(curr_fpwrst));
-
- seq_printf(s, "%s (%s)", pwrdm->name,
- pwrdm_convert_fpwrst_to_name(pwrdm->fpwrst));
- for (i = PWRDM_FPWRST_OFFSET; i < PWRDM_MAX_FUNC_PWRSTS; i++)
- seq_printf(s, ",%s:%d", pwrdm_convert_fpwrst_to_name(i),
- pwrdm->fpwrst_counter[i - PWRDM_FPWRST_OFFSET]);
-
- seq_printf(s, "\n");
-
- return 0;
-}
-
-static int pwrdm_dbg_show_timer(struct powerdomain *pwrdm, void *user)
-{
- struct seq_file *s = (struct seq_file *)user;
- int i;
-
- if (strcmp(pwrdm->name, "emu_pwrdm") == 0 ||
- strcmp(pwrdm->name, "wkup_pwrdm") == 0 ||
- strncmp(pwrdm->name, "dpll", 4) == 0)
- return 0;
-
- pwrdm_state_switch(pwrdm);
-
- seq_printf(s, "%s (%s)", pwrdm->name,
- pwrdm_convert_fpwrst_to_name(pwrdm->fpwrst));
-
- for (i = 0; i < PWRDM_FPWRSTS_COUNT; i++)
- seq_printf(s, ",%s:%lld",
- pwrdm_convert_fpwrst_to_name(i + PWRDM_FPWRST_OFFSET),
- pwrdm->fpwrst_timer[i]);
-
- seq_printf(s, "\n");
- return 0;
-}
-
static int pm_dbg_show_counters(struct seq_file *s, void *unused)
{
pwrdm_for_each(pwrdm_dbg_show_counter, s);
@@ -150,10 +81,10 @@ static int pm_dbg_open(struct inode *inode, struct file *file)
}
static const struct file_operations debug_fops = {
- .open = pm_dbg_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .open = pm_dbg_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
static int pwrdm_suspend_get(void *data, u64 *val)
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index d38f493..658f4ed 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -8,6 +8,10 @@
* Added OMAP4 specific support by Abhijit Pagare <abhijitpagare@ti.com>
* State counting code by Tero Kristo <tero.kristo@nokia.com>
*
+ * Contains some code previously from mach-omap2/pm-debug.c, which was:
+ * Copyright (C) 2005 Texas Instruments, Inc.
+ * Copyright (C) 2006-2008 Nokia Corporation
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
@@ -21,6 +25,7 @@
#include <linux/string.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
+#include <linux/seq_file.h>
#include <trace/events/power.h>
@@ -1447,3 +1452,83 @@ bool pwrdm_supports_fpwrst(struct powerdomain *pwrdm, u8 fpwrst)
return true;
}
+
+/* Powerdomain debugfs-related functions */
+
+/**
+ * pwrdm_dbg_show_counter - generate debugfs data for the pwrdm pwrst counters
+ * @pwrdm: struct powerdomain * to generate debugfs data for
+ * @seq_file: struct seq_file * to write data to
+ *
+ * Dump the powerdomain @pwrdm's power state counters (and current
+ * power state) to the seq_file @seq_file. Currently called by the
+ * mach-omap2/pm-debug.c code. Returns 0.
+ */
+int pwrdm_dbg_show_counter(struct powerdomain *pwrdm, void *seq_file)
+{
+ struct seq_file *s = (struct seq_file *)seq_file;
+ int i;
+ u8 curr_fpwrst;
+
+ if (!_pwrdm_pwrst_can_change(pwrdm))
+ return 0;
+
+ pwrdm_lock(pwrdm);
+
+ curr_fpwrst = _pwrdm_read_fpwrst(pwrdm);
+ if (pwrdm->fpwrst != curr_fpwrst)
+ pr_err("pwrdm state mismatch(%s) %s != %s\n",
+ pwrdm->name,
+ pwrdm_convert_fpwrst_to_name(pwrdm->fpwrst),
+ pwrdm_convert_fpwrst_to_name(curr_fpwrst));
+
+ seq_printf(s, "%s (%s)", pwrdm->name,
+ pwrdm_convert_fpwrst_to_name(pwrdm->fpwrst));
+ for (i = PWRDM_FPWRST_OFFSET; i < PWRDM_MAX_FUNC_PWRSTS; i++)
+ seq_printf(s, ",%s:%d", pwrdm_convert_fpwrst_to_name(i),
+ pwrdm->fpwrst_counter[i - PWRDM_FPWRST_OFFSET]);
+
+ seq_printf(s, "\n");
+
+ pwrdm_unlock(pwrdm);
+
+ return 0;
+}
+
+/**
+ * pwrdm_dbg_show_timer - generate debugfs data for the pwrdm pwrst timers
+ * @pwrdm: struct powerdomain * to generate debugfs data for
+ * @seq_file: struct seq_file * to write data to
+ *
+ * Dump the powerdomain @pwrdm's power state residency duration timings
+ * to the seq_file @seq_file. Currently called by the mach-omap2/pm-debug.c
+ * code. Returns 0.
+ */
+int pwrdm_dbg_show_timer(struct powerdomain *pwrdm, void *seq_file)
+{
+#ifdef CONFIG_PM_DEBUG
+ struct seq_file *s = (struct seq_file *)seq_file;
+ int i;
+
+ if (!_pwrdm_pwrst_can_change(pwrdm))
+ return 0;
+
+ pwrdm_lock(pwrdm);
+
+ pwrdm_state_switch_nolock(pwrdm);
+
+ seq_printf(s, "%s (%s)", pwrdm->name,
+ pwrdm_convert_fpwrst_to_name(pwrdm->fpwrst));
+
+ for (i = 0; i < PWRDM_FPWRSTS_COUNT; i++)
+ seq_printf(s, ",%s:%lld",
+ pwrdm_convert_fpwrst_to_name(i + PWRDM_FPWRST_OFFSET),
+ pwrdm->fpwrst_timer[i]);
+
+ seq_printf(s, "\n");
+
+ pwrdm_unlock(pwrdm);
+#endif
+ return 0;
+}
+
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index ef51987b..c19bdc3 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -276,4 +276,8 @@ extern struct powerdomain gfx_omap2_pwrdm;
extern void pwrdm_lock(struct powerdomain *pwrdm);
extern void pwrdm_unlock(struct powerdomain *pwrdm);
+/* Debugfs functions */
+extern int pwrdm_dbg_show_counter(struct powerdomain *pwrdm, void *seq_file);
+extern int pwrdm_dbg_show_timer(struct powerdomain *pwrdm, void *seq_file);
+
#endif
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 06/12] ARM: OMAP2+: CM: use the cached copy of the clockdomain's hwsup state
2012-12-09 20:02 [PATCH 00/12] ARM: OMAP2+: powerdomain updates after the functional power state conversion Paul Walmsley
` (3 preceding siblings ...)
2012-12-09 20:03 ` [PATCH 04/12] ARM: OMAP2+: PM: clean up some debugfs functions Paul Walmsley
@ 2012-12-09 20:03 ` Paul Walmsley
2012-12-09 20:03 ` [PATCH 07/12] ARM: OMAP2+: powerdomain: cache the powerdomain next power state Paul Walmsley
` (6 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Paul Walmsley @ 2012-12-09 20:03 UTC (permalink / raw)
To: linux-arm-kernel
Avoid some unnecessary CM IP block reads by using the cached copy of
the clockdomain's hardware-supervised idle state. This should
simplify the code slightly and save a few hundred nanoseconds in these
paths.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
arch/arm/mach-omap2/cm2xxx.c | 19 ++-----------------
arch/arm/mach-omap2/cm3xxx.c | 14 ++------------
2 files changed, 4 insertions(+), 29 deletions(-)
diff --git a/arch/arm/mach-omap2/cm2xxx.c b/arch/arm/mach-omap2/cm2xxx.c
index 6774a53..8ca13cd 100644
--- a/arch/arm/mach-omap2/cm2xxx.c
+++ b/arch/arm/mach-omap2/cm2xxx.c
@@ -285,14 +285,7 @@ static void omap2xxx_clkdm_deny_idle(struct clockdomain *clkdm)
static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm)
{
- bool hwsup = false;
-
- if (!clkdm->clktrctrl_mask)
- return 0;
-
- hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
- if (!hwsup && clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
+ if (!clkdm_in_hwsup(clkdm) && clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
omap2xxx_clkdm_wakeup(clkdm);
return 0;
@@ -300,15 +293,7 @@ static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm)
static int omap2xxx_clkdm_clk_disable(struct clockdomain *clkdm)
{
- bool hwsup = false;
-
- if (!clkdm->clktrctrl_mask)
- return 0;
-
- hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
-
- if (!hwsup && clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
+ if (!clkdm_in_hwsup(clkdm) && clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
omap2xxx_clkdm_sleep(clkdm);
return 0;
diff --git a/arch/arm/mach-omap2/cm3xxx.c b/arch/arm/mach-omap2/cm3xxx.c
index 9061c30..75872134 100644
--- a/arch/arm/mach-omap2/cm3xxx.c
+++ b/arch/arm/mach-omap2/cm3xxx.c
@@ -227,8 +227,6 @@ static void omap3xxx_clkdm_deny_idle(struct clockdomain *clkdm)
static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
{
- bool hwsup = false;
-
if (!clkdm->clktrctrl_mask)
return 0;
@@ -243,10 +241,7 @@ static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
return 0;
}
- hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
-
- if (hwsup) {
+ if (clkdm_in_hwsup(clkdm)) {
/* Disable HW transitions when we are changing deps */
omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
clkdm->clktrctrl_mask);
@@ -263,8 +258,6 @@ static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
{
- bool hwsup = false;
-
if (!clkdm->clktrctrl_mask)
return 0;
@@ -280,10 +273,7 @@ static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
return 0;
}
- hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
- clkdm->clktrctrl_mask);
-
- if (hwsup) {
+ if (clkdm_in_hwsup(clkdm)) {
/* Disable HW transitions when we are changing deps */
omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
clkdm->clktrctrl_mask);
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 07/12] ARM: OMAP2+: powerdomain: cache the powerdomain next power state
2012-12-09 20:02 [PATCH 00/12] ARM: OMAP2+: powerdomain updates after the functional power state conversion Paul Walmsley
` (4 preceding siblings ...)
2012-12-09 20:03 ` [PATCH 06/12] ARM: OMAP2+: CM: use the cached copy of the clockdomain's hwsup state Paul Walmsley
@ 2012-12-09 20:03 ` Paul Walmsley
2012-12-09 20:03 ` [PATCH 08/12] ARM: OMAP2+: powerdomain: cache the powerdomain's previous " Paul Walmsley
` (5 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Paul Walmsley @ 2012-12-09 20:03 UTC (permalink / raw)
To: linux-arm-kernel
Cache the powerdomain next power state registers. The objective here
is to avoid unneeded reads and writes to the next power state
registers, which are slow compared to RAM & CPU cache.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
---
arch/arm/mach-omap2/powerdomain.c | 64 +++++++++++++++++--------------------
arch/arm/mach-omap2/powerdomain.h | 17 ++++++++++
2 files changed, 46 insertions(+), 35 deletions(-)
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 62e2f75..425c868 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -376,7 +376,7 @@ static int _pwrdm_pwrst_to_fpwrst(struct powerdomain *pwrdm, u8 pwrst, u8 logic,
* software-controllable, returns 0; otherwise, passes along the
* return value from pwrdm_set_logic_retst() if there is an error
* returned by that function, otherwise, passes along the return value
- * from pwrdm_set_next_pwrst()
+ * from pwrdm_set_next_fpwrst()
*/
static int _set_logic_retst_and_pwrdm_pwrst(struct powerdomain *pwrdm,
u8 logic, u8 pwrst)
@@ -426,6 +426,9 @@ static int _pwrdm_read_next_fpwrst(struct powerdomain *pwrdm)
int next_pwrst, next_logic, ret;
u8 fpwrst;
+ if (pwrdm->_flags & _PWRDM_NEXT_FPWRST_IS_VALID)
+ return pwrdm->next_fpwrst;
+
next_pwrst = arch_pwrdm->pwrdm_read_next_pwrst(pwrdm);
if (next_pwrst < 0)
return next_pwrst;
@@ -438,6 +441,10 @@ static int _pwrdm_read_next_fpwrst(struct powerdomain *pwrdm)
return next_logic;
}
ret = _pwrdm_pwrst_to_fpwrst(pwrdm, next_pwrst, next_logic, &fpwrst);
+ if (!ret) {
+ pwrdm->next_fpwrst = fpwrst;
+ pwrdm->_flags |= _PWRDM_NEXT_FPWRST_IS_VALID;
+ }
return (ret) ? ret : fpwrst;
}
@@ -663,7 +670,7 @@ static int _pwrdm_pre_transition_cb(struct powerdomain *pwrdm, void *unused)
*/
static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
{
- int prev, next, fpwrst;
+ int prev, fpwrst;
int trace_state = 0;
prev = _pwrdm_read_prev_fpwrst(pwrdm);
@@ -676,10 +683,9 @@ static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
* If the power domain did not hit the desired state,
* generate a trace event with both the desired and hit states
*/
- next = _pwrdm_read_next_fpwrst(pwrdm);
- if (next != prev) {
- trace_state = (PWRDM_TRACE_STATES_FLAG | next << 8 |
- prev);
+ if (pwrdm->next_fpwrst != prev) {
+ trace_state = (PWRDM_TRACE_STATES_FLAG |
+ pwrdm->next_fpwrst << 8 | prev);
trace_power_domain_target(pwrdm->name, trace_state,
smp_processor_id());
}
@@ -1256,6 +1262,10 @@ int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm, u8 fpwrst)
if (ret)
return ret;
+ if (pwrdm->_flags & _PWRDM_NEXT_FPWRST_IS_VALID &&
+ pwrdm->next_fpwrst == fpwrst)
+ return 0;
+
pr_debug("%s: set fpwrst %0x to pwrdm %s\n", __func__, fpwrst,
pwrdm->name);
@@ -1264,6 +1274,10 @@ int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm, u8 fpwrst)
pwrdm_lock(pwrdm);
ret = _set_logic_retst_and_pwrdm_pwrst(pwrdm, logic, pwrst);
+ if (!ret) {
+ pwrdm->next_fpwrst = fpwrst;
+ pwrdm->_flags |= _PWRDM_NEXT_FPWRST_IS_VALID;
+ }
pwrdm_unlock(pwrdm);
return ret;
@@ -1279,36 +1293,16 @@ int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm, u8 fpwrst)
*/
int pwrdm_read_next_fpwrst(struct powerdomain *pwrdm)
{
- int next_pwrst, next_logic, ret;
- u8 fpwrst;
+ int ret;
- if (!arch_pwrdm)
+ if (!pwrdm)
return -EINVAL;
pwrdm_lock(pwrdm);
-
- next_pwrst = arch_pwrdm->pwrdm_read_next_pwrst(pwrdm);
- if (next_pwrst < 0) {
- ret = next_pwrst;
- goto prnf_out;
- }
-
- next_logic = next_pwrst;
- if (_pwrdm_logic_retst_can_change(pwrdm) &&
- arch_pwrdm->pwrdm_read_logic_pwrst) {
- next_logic = arch_pwrdm->pwrdm_read_logic_pwrst(pwrdm);
- if (next_logic < 0) {
- ret = next_logic;
- goto prnf_out;
- }
- }
-
- ret = _pwrdm_pwrst_to_fpwrst(pwrdm, next_pwrst, next_logic, &fpwrst);
-
-prnf_out:
+ ret = _pwrdm_read_next_fpwrst(pwrdm);
pwrdm_unlock(pwrdm);
- return (ret) ? ret : fpwrst;
+ return ret;
}
/**
@@ -1344,10 +1338,6 @@ int pwrdm_set_fpwrst(struct powerdomain *pwrdm, enum pwrdm_func_state fpwrst)
pwrdm_lock(pwrdm);
- /*
- * XXX quite heavyweight for what this is intended to do; the
- * next fpwrst should simply be cached
- */
next_fpwrst = _pwrdm_read_next_fpwrst(pwrdm);
if (next_fpwrst == fpwrst)
goto psf_out;
@@ -1364,9 +1354,13 @@ int pwrdm_set_fpwrst(struct powerdomain *pwrdm, enum pwrdm_func_state fpwrst)
}
ret = _set_logic_retst_and_pwrdm_pwrst(pwrdm, logic, pwrst);
- if (ret)
+ if (ret) {
pr_err("%s: unable to set power state of powerdomain: %s\n",
__func__, pwrdm->name);
+ } else {
+ pwrdm->next_fpwrst = fpwrst;
+ pwrdm->_flags |= _PWRDM_NEXT_FPWRST_IS_VALID;
+ }
_pwrdm_restore_clkdm_state(pwrdm, sleep_switch, hwsup);
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index c19bdc3..1fb21f5 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -84,6 +84,16 @@ enum pwrdm_func_state {
#define PWRDM_HAS_LOWPOWERSTATECHANGE BIT(2)
/*
+ * Powerdomain internal flags (struct powerdomain._flags)
+ *
+ * _PWRDM_NEXT_FPWRST_IS_VALID: the locally-cached copy of the
+ * powerdomain's next-functional-power-state -- struct
+ * powerdomain.next_fpwrst -- is valid. If this bit is not set,
+ * the code needs to load the current value from the hardware.
+ */
+#define _PWRDM_NEXT_FPWRST_IS_VALID BIT(0)
+
+/*
* Number of memory banks that are power-controllable. On OMAP4430, the
* maximum is 5.
*/
@@ -127,12 +137,17 @@ struct powerdomain;
* in @pwrstctrl_offs
* @fpwrst: current func power state (set in pwrdm_state_switch() or post_trans)
* @fpwrst_counter: estimated number of times the pwrdm entered the power states
+ * @next_fpwrst: cache of the powerdomain's next-power-state
* @timer: sched_clock() timestamp of last pwrdm_state_switch()
* @fpwrst_timer: estimated nanoseconds of residency in the various power states
* @_lock: spinlock used to serialize powerdomain and some clockdomain ops
* @_lock_flags: stored flags when @_lock is taken
+ * @_flags: flags (for internal use only)
*
* @prcm_partition possible values are defined in mach-omap2/prcm44xx.h.
+ *
+ * Possible values for @_flags are documented above in the
+ * "Powerdomain internal flags (struct powerdomain._flags)" comments.
*/
struct powerdomain {
const char *name;
@@ -149,6 +164,8 @@ struct powerdomain {
const u8 pwrsts_mem_on[PWRDM_MAX_MEM_BANKS];
const u8 prcm_partition;
u8 fpwrst;
+ u8 next_fpwrst;
+ u8 _flags;
struct clockdomain *pwrdm_clkdms[PWRDM_MAX_CLKDMS];
struct list_head node;
struct list_head voltdm_node;
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 08/12] ARM: OMAP2+: powerdomain: cache the powerdomain's previous power state
2012-12-09 20:02 [PATCH 00/12] ARM: OMAP2+: powerdomain updates after the functional power state conversion Paul Walmsley
` (5 preceding siblings ...)
2012-12-09 20:03 ` [PATCH 07/12] ARM: OMAP2+: powerdomain: cache the powerdomain next power state Paul Walmsley
@ 2012-12-09 20:03 ` Paul Walmsley
2012-12-09 20:03 ` [PATCH 09/12] ARM: OMAP2+: powerdomain: skip register reads for powerdomains known to be on Paul Walmsley
` (4 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Paul Walmsley @ 2012-12-09 20:03 UTC (permalink / raw)
To: linux-arm-kernel
Cache the powerdomain previous power state registers. The objective
here is to avoid unneeded reads from the previous power state
registers. Reads from these registers can be extremely slow, even by
I/O device standards. I no longer recall the exact measurements, but
my recollection was that they cost several microseconds.
The cache is invalidated as part of the powerdomain pre-transition
code, which runs shortly before WFI/WFE.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
---
arch/arm/mach-omap2/powerdomain.c | 9 +++++++++
arch/arm/mach-omap2/powerdomain.h | 14 ++++++++++++++
2 files changed, 23 insertions(+)
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 425c868..f5e2727 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -499,6 +499,9 @@ static int _pwrdm_read_prev_fpwrst(struct powerdomain *pwrdm)
if (!_pwrdm_pwrst_can_change(pwrdm))
return PWRDM_FUNC_PWRST_ON;
+ if (pwrdm->_flags & _PWRDM_PREV_FPWRST_IS_VALID)
+ return pwrdm->prev_fpwrst;
+
pwrst = arch_pwrdm->pwrdm_read_prev_pwrst(pwrdm);
if (pwrst < 0)
return pwrst;
@@ -512,6 +515,10 @@ static int _pwrdm_read_prev_fpwrst(struct powerdomain *pwrdm)
}
ret = _pwrdm_pwrst_to_fpwrst(pwrdm, pwrst, logic_pwrst, &fpwrst);
+ if (!ret) {
+ pwrdm->prev_fpwrst = fpwrst;
+ pwrdm->_flags |= _PWRDM_PREV_FPWRST_IS_VALID;
+ }
return (ret) ? ret : fpwrst;
}
@@ -1017,6 +1024,8 @@ int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
pr_debug("powerdomain: %s: clearing previous power state reg\n",
pwrdm->name);
+ pwrdm->_flags &= ~_PWRDM_PREV_FPWRST_IS_VALID;
+
if (arch_pwrdm && arch_pwrdm->pwrdm_clear_all_prev_pwrst)
ret = arch_pwrdm->pwrdm_clear_all_prev_pwrst(pwrdm);
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index 1fb21f5..f4a189a 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -90,8 +90,17 @@ enum pwrdm_func_state {
* powerdomain's next-functional-power-state -- struct
* powerdomain.next_fpwrst -- is valid. If this bit is not set,
* the code needs to load the current value from the hardware.
+ *
+ * _PWRDM_PREV_FPWRST_IS_VALID: the locally-cached copy of the
+ * powerdomain's previous-functional-power-state -- struct
+ * powerdomain.prev_fpwrst -- is valid. If this bit is not set,
+ * the code needs to load the current value from the hardware. The
+ * previous-functional-power-state cache for the CORE and MPU needs
+ * to be invalidated right before WFI, unless they were not programmed
+ * to change power states.
*/
#define _PWRDM_NEXT_FPWRST_IS_VALID BIT(0)
+#define _PWRDM_PREV_FPWRST_IS_VALID BIT(1)
/*
* Number of memory banks that are power-controllable. On OMAP4430, the
@@ -138,6 +147,7 @@ struct powerdomain;
* @fpwrst: current func power state (set in pwrdm_state_switch() or post_trans)
* @fpwrst_counter: estimated number of times the pwrdm entered the power states
* @next_fpwrst: cache of the powerdomain's next-power-state
+ * @prev_fpwrst: cache of the powerdomain's previous-power-state bitfield
* @timer: sched_clock() timestamp of last pwrdm_state_switch()
* @fpwrst_timer: estimated nanoseconds of residency in the various power states
* @_lock: spinlock used to serialize powerdomain and some clockdomain ops
@@ -146,6 +156,9 @@ struct powerdomain;
*
* @prcm_partition possible values are defined in mach-omap2/prcm44xx.h.
*
+ * @prev_fpwrst is updated during pwrdm_pre_transition(), but presumably
+ * should also be updated upon clock/IP block idle transitions.
+ *
* Possible values for @_flags are documented above in the
* "Powerdomain internal flags (struct powerdomain._flags)" comments.
*/
@@ -165,6 +178,7 @@ struct powerdomain {
const u8 prcm_partition;
u8 fpwrst;
u8 next_fpwrst;
+ u8 prev_fpwrst;
u8 _flags;
struct clockdomain *pwrdm_clkdms[PWRDM_MAX_CLKDMS];
struct list_head node;
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 09/12] ARM: OMAP2+: powerdomain: skip register reads for powerdomains known to be on
2012-12-09 20:02 [PATCH 00/12] ARM: OMAP2+: powerdomain updates after the functional power state conversion Paul Walmsley
` (6 preceding siblings ...)
2012-12-09 20:03 ` [PATCH 08/12] ARM: OMAP2+: powerdomain: cache the powerdomain's previous " Paul Walmsley
@ 2012-12-09 20:03 ` Paul Walmsley
2012-12-12 10:22 ` Vaibhav Hiremath
` (2 more replies)
2012-12-09 20:03 ` [PATCH 10/12] ARM: OMAP2+: powerdomain: skip previous-power-state read if next_pwrst is ON Paul Walmsley
` (3 subsequent siblings)
11 siblings, 3 replies; 20+ messages in thread
From: Paul Walmsley @ 2012-12-09 20:03 UTC (permalink / raw)
To: linux-arm-kernel
There's no need to determine the current power state for powerdomains
that must be on while the kernel is running. We mark these
powerdomains with a new flag, PWRDM_ACTIVE_WITH_KERNEL. Any
powerdomain marked with that flag is reported as being in the ON power
state while the kernel is running.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Beno?t Cousson <b-cousson@ti.com>
---
arch/arm/mach-omap2/powerdomain.c | 9 ++++++---
arch/arm/mach-omap2/powerdomain.h | 4 ++++
arch/arm/mach-omap2/powerdomains2xxx_data.c | 2 ++
arch/arm/mach-omap2/powerdomains33xx_data.c | 3 ++-
arch/arm/mach-omap2/powerdomains3xxx_data.c | 9 ++++++---
arch/arm/mach-omap2/powerdomains44xx_data.c | 5 ++++-
6 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index f5e2727..a4bb0bb 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -462,7 +462,8 @@ static int _pwrdm_read_fpwrst(struct powerdomain *pwrdm)
int pwrst, logic_pwrst, ret;
u8 fpwrst;
- if (!_pwrdm_pwrst_can_change(pwrdm))
+ if (!_pwrdm_pwrst_can_change(pwrdm) ||
+ pwrdm->flags & PWRDM_ACTIVE_WITH_KERNEL)
return PWRDM_FUNC_PWRST_ON;
pwrst = arch_pwrdm->pwrdm_read_pwrst(pwrdm);
@@ -1104,12 +1105,14 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm)
int pwrdm_state_switch_nolock(struct powerdomain *pwrdm)
{
- int ret;
+ int ret = 0;
if (!pwrdm || !arch_pwrdm)
return -EINVAL;
- ret = arch_pwrdm->pwrdm_wait_transition(pwrdm);
+ if (!(pwrdm->flags & PWRDM_ACTIVE_WITH_KERNEL))
+ ret = arch_pwrdm->pwrdm_wait_transition(pwrdm);
+
if (!ret)
_pwrdm_state_switch(pwrdm);
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index f4a189a..10941fd 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -78,10 +78,14 @@ enum pwrdm_func_state {
*
* PWRDM_HAS_LOWPOWERSTATECHANGE - can transition from a sleep state
* to a lower sleep state without waking up the powerdomain
+ *
+ * PWRDM_ACTIVE_WITH_KERNEL - this powerdomain's current power state is
+ * guaranteed to be ON whenever the kernel is running
*/
#define PWRDM_HAS_HDWR_SAR BIT(0)
#define PWRDM_HAS_MPU_QUIRK BIT(1)
#define PWRDM_HAS_LOWPOWERSTATECHANGE BIT(2)
+#define PWRDM_ACTIVE_WITH_KERNEL BIT(3)
/*
* Powerdomain internal flags (struct powerdomain._flags)
diff --git a/arch/arm/mach-omap2/powerdomains2xxx_data.c b/arch/arm/mach-omap2/powerdomains2xxx_data.c
index 578eef8..112927f 100644
--- a/arch/arm/mach-omap2/powerdomains2xxx_data.c
+++ b/arch/arm/mach-omap2/powerdomains2xxx_data.c
@@ -54,6 +54,7 @@ static struct powerdomain mpu_24xx_pwrdm = {
[0] = PWRSTS_ON,
},
.voltdm = { .name = "core" },
+ .flags = PWRDM_ACTIVE_WITH_KERNEL,
};
static struct powerdomain core_24xx_pwrdm = {
@@ -73,6 +74,7 @@ static struct powerdomain core_24xx_pwrdm = {
[2] = PWRSTS_OFF_RET_ON, /* MEM3ONSTATE */
},
.voltdm = { .name = "core" },
+ .flags = PWRDM_ACTIVE_WITH_KERNEL,
};
diff --git a/arch/arm/mach-omap2/powerdomains33xx_data.c b/arch/arm/mach-omap2/powerdomains33xx_data.c
index 869adb8..acb148a 100644
--- a/arch/arm/mach-omap2/powerdomains33xx_data.c
+++ b/arch/arm/mach-omap2/powerdomains33xx_data.c
@@ -123,7 +123,8 @@ static struct powerdomain mpu_33xx_pwrdm = {
.pwrstst_offs = AM33XX_PM_MPU_PWRSTST_OFFSET,
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
- .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+ .flags = (PWRDM_HAS_LOWPOWERSTATECHANGE |
+ PWRDM_ACTIVE_WITH_KERNEL),
.banks = 3,
.logicretstate_mask = AM33XX_LOGICRETSTATE_MASK,
.mem_on_mask = {
diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c
index f0e14e9ef..ade93d3 100644
--- a/arch/arm/mach-omap2/powerdomains3xxx_data.c
+++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c
@@ -58,7 +58,7 @@ static struct powerdomain mpu_3xxx_pwrdm = {
.prcm_offs = MPU_MOD,
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
- .flags = PWRDM_HAS_MPU_QUIRK,
+ .flags = (PWRDM_HAS_MPU_QUIRK | PWRDM_ACTIVE_WITH_KERNEL),
.banks = 1,
.pwrsts_mem_ret = {
[0] = PWRSTS_OFF_RET,
@@ -74,7 +74,7 @@ static struct powerdomain mpu_am35x_pwrdm = {
.prcm_offs = MPU_MOD,
.pwrsts = PWRSTS_ON,
.pwrsts_logic_ret = PWRSTS_ON,
- .flags = PWRDM_HAS_MPU_QUIRK,
+ .flags = (PWRDM_HAS_MPU_QUIRK | PWRDM_ACTIVE_WITH_KERNEL),
.banks = 1,
.pwrsts_mem_ret = {
[0] = PWRSTS_ON,
@@ -110,6 +110,7 @@ static struct powerdomain core_3xxx_pre_es3_1_pwrdm = {
[1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
},
.voltdm = { .name = "core" },
+ .flags = PWRDM_ACTIVE_WITH_KERNEL,
};
static struct powerdomain core_3xxx_es3_1_pwrdm = {
@@ -121,7 +122,8 @@ static struct powerdomain core_3xxx_es3_1_pwrdm = {
* Setting the SAR flag for errata ID i478 which applies
* to 3430 <= ES3.1
*/
- .flags = PWRDM_HAS_HDWR_SAR, /* for USBTLL only */
+ .flags = (PWRDM_HAS_HDWR_SAR | /* for USBTLL only */
+ PWRDM_ACTIVE_WITH_KERNEL),
.banks = 2,
.pwrsts_mem_ret = {
[0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */
@@ -149,6 +151,7 @@ static struct powerdomain core_am35x_pwrdm = {
[1] = PWRSTS_ON, /* MEM2ONSTATE */
},
.voltdm = { .name = "core" },
+ .flags = PWRDM_ACTIVE_WITH_KERNEL,
};
static struct powerdomain dss_pwrdm = {
diff --git a/arch/arm/mach-omap2/powerdomains44xx_data.c b/arch/arm/mach-omap2/powerdomains44xx_data.c
index 704664c..b64213c 100644
--- a/arch/arm/mach-omap2/powerdomains44xx_data.c
+++ b/arch/arm/mach-omap2/powerdomains44xx_data.c
@@ -53,7 +53,8 @@ static struct powerdomain core_44xx_pwrdm = {
[3] = PWRSTS_ON, /* ducati_l2ram */
[4] = PWRSTS_ON, /* ducati_unicache */
},
- .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+ .flags = (PWRDM_HAS_LOWPOWERSTATECHANGE |
+ PWRDM_ACTIVE_WITH_KERNEL),
};
/* gfx_44xx_pwrdm: 3D accelerator power domain */
@@ -164,6 +165,7 @@ static struct powerdomain cpu0_44xx_pwrdm = {
.pwrsts_mem_on = {
[0] = PWRSTS_ON, /* cpu0_l1 */
},
+ .flags = PWRDM_ACTIVE_WITH_KERNEL,
};
/* cpu1_44xx_pwrdm: MPU1 processor and Neon coprocessor power domain */
@@ -218,6 +220,7 @@ static struct powerdomain mpu_44xx_pwrdm = {
[1] = PWRSTS_ON, /* mpu_l2 */
[2] = PWRSTS_ON, /* mpu_ram */
},
+ .flags = PWRDM_ACTIVE_WITH_KERNEL,
};
/* ivahd_44xx_pwrdm: IVA-HD power domain */
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 10/12] ARM: OMAP2+: powerdomain: skip previous-power-state read if next_pwrst is ON
2012-12-09 20:02 [PATCH 00/12] ARM: OMAP2+: powerdomain updates after the functional power state conversion Paul Walmsley
` (7 preceding siblings ...)
2012-12-09 20:03 ` [PATCH 09/12] ARM: OMAP2+: powerdomain: skip register reads for powerdomains known to be on Paul Walmsley
@ 2012-12-09 20:03 ` Paul Walmsley
2012-12-09 20:03 ` [PATCH 11/12] ARM: OMAP2xxx: powerdomain: add previous power state tracking Paul Walmsley
` (2 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Paul Walmsley @ 2012-12-09 20:03 UTC (permalink / raw)
To: linux-arm-kernel
If the powerdomain's next-power-state is set to ON, then we can skip
the powerdomain previous-power-state read during
pwrdm_post_transition(). This is both an optimization (for all OMAPs)
and a fix (for OMAP2xxx). It turns out the OMAP2xxx previous power
state mechanism is slightly different than the OMAP3+ mechanism. The
bitfield can't be cleared, and it's only updated after a powerdomain
power state transition. So reading this value before any powerdomain
power state transition occurred will always return OFF (the reset
value). After this patch, if the power domain was programmed to stay
ON before pwrdm_pre_transition() is called, the previous power state
code will return ON during pwrdm_post_transition().
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
arch/arm/mach-omap2/powerdomain.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index a4bb0bb..72d6ce0 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -681,7 +681,9 @@ static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
int prev, fpwrst;
int trace_state = 0;
- prev = _pwrdm_read_prev_fpwrst(pwrdm);
+ prev = (pwrdm->next_fpwrst == PWRDM_FUNC_PWRST_ON) ?
+ PWRDM_FUNC_PWRST_ON : _pwrdm_read_prev_fpwrst(pwrdm);
+
if (pwrdm->fpwrst != prev)
pwrdm->fpwrst_counter[prev - PWRDM_FPWRST_OFFSET]++;
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 11/12] ARM: OMAP2xxx: powerdomain: add previous power state tracking
2012-12-09 20:02 [PATCH 00/12] ARM: OMAP2+: powerdomain updates after the functional power state conversion Paul Walmsley
` (8 preceding siblings ...)
2012-12-09 20:03 ` [PATCH 10/12] ARM: OMAP2+: powerdomain: skip previous-power-state read if next_pwrst is ON Paul Walmsley
@ 2012-12-09 20:03 ` Paul Walmsley
2012-12-09 20:03 ` [PATCH 12/12] ARM: OMAP2xxx: PM: add pwrdm_(pre|post)_transition() calls to the 2xxx PM code Paul Walmsley
2013-01-04 14:26 ` [PATCH 00/12] ARM: OMAP2+: powerdomain updates after the functional power state conversion Tero Kristo
11 siblings, 0 replies; 20+ messages in thread
From: Paul Walmsley @ 2012-12-09 20:03 UTC (permalink / raw)
To: linux-arm-kernel
The OMAP2xxx PRM does support a form of powerdomain previous-power-state
tracking; so add it. This allows the power state tracking and debugging
code to do something useful on this platform.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
arch/arm/mach-omap2/prm2xxx.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/arch/arm/mach-omap2/prm2xxx.c b/arch/arm/mach-omap2/prm2xxx.c
index e4cdb69..2d3c905 100644
--- a/arch/arm/mach-omap2/prm2xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx.c
@@ -180,10 +180,22 @@ static int omap2xxx_pwrdm_read_pwrst(struct powerdomain *pwrdm)
return omap2xxx_pwrst_to_common_pwrst(omap2xxx_pwrst);
}
+static int omap2xxx_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
+{
+ u8 omap2xxx_pwrst;
+
+ omap2xxx_pwrst = omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP2_PM_PWSTST,
+ OMAP24XX_LASTSTATEENTERED_MASK);
+
+ return omap2xxx_pwrst_to_common_pwrst(omap2xxx_pwrst);
+}
+
struct pwrdm_ops omap2_pwrdm_operations = {
.pwrdm_set_next_pwrst = omap2xxx_pwrdm_set_next_pwrst,
.pwrdm_read_next_pwrst = omap2xxx_pwrdm_read_next_pwrst,
.pwrdm_read_pwrst = omap2xxx_pwrdm_read_pwrst,
+ .pwrdm_read_prev_pwrst = omap2xxx_pwrdm_read_prev_pwrst,
.pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst,
.pwrdm_set_mem_onst = omap2_pwrdm_set_mem_onst,
.pwrdm_set_mem_retst = omap2_pwrdm_set_mem_retst,
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 12/12] ARM: OMAP2xxx: PM: add pwrdm_(pre|post)_transition() calls to the 2xxx PM code
2012-12-09 20:02 [PATCH 00/12] ARM: OMAP2+: powerdomain updates after the functional power state conversion Paul Walmsley
` (9 preceding siblings ...)
2012-12-09 20:03 ` [PATCH 11/12] ARM: OMAP2xxx: powerdomain: add previous power state tracking Paul Walmsley
@ 2012-12-09 20:03 ` Paul Walmsley
2013-01-04 14:26 ` [PATCH 00/12] ARM: OMAP2+: powerdomain updates after the functional power state conversion Tero Kristo
11 siblings, 0 replies; 20+ messages in thread
From: Paul Walmsley @ 2012-12-09 20:03 UTC (permalink / raw)
To: linux-arm-kernel
The OMAP2xxx PM code was missing calls to pwrdm_pre_transition() and
pwrdm_post_transition(). This prevented the power state debugging
from working correctly, and also violated some assumptions that are
used in future power state caching patches.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
---
arch/arm/mach-omap2/pm24xx.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index 99c16c2..896727c 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -98,6 +98,8 @@ static int omap2_enter_full_retention(void)
omap2_gpio_prepare_for_idle(0);
+ pwrdm_pre_transition(NULL);
+
/* One last check for pending IRQs to avoid extra latency due
* to sleeping unnecessarily. */
if (omap_irq_pending())
@@ -109,6 +111,8 @@ static int omap2_enter_full_retention(void)
OMAP_SDRC_REGADDR(SDRC_POWER));
no_sleep:
+ pwrdm_post_transition(NULL);
+
omap2_gpio_resume_after_idle();
clk_enable(osc_ck);
@@ -191,8 +195,12 @@ static void omap2_enter_mpu_retention(void)
WARN_ON(pwrdm_set_next_fpwrst(mpu_pwrdm, PWRDM_FUNC_PWRST_ON));
}
+ pwrdm_pre_transition(mpu_pwrdm);
+
omap2_sram_idle();
+ pwrdm_post_transition(mpu_pwrdm);
+
WARN_ON(pwrdm_set_next_fpwrst(mpu_pwrdm, PWRDM_FUNC_PWRST_ON));
}
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 09/12] ARM: OMAP2+: powerdomain: skip register reads for powerdomains known to be on
2012-12-09 20:03 ` [PATCH 09/12] ARM: OMAP2+: powerdomain: skip register reads for powerdomains known to be on Paul Walmsley
@ 2012-12-12 10:22 ` Vaibhav Hiremath
2012-12-19 21:09 ` Jon Hunter
2012-12-26 6:21 ` Bedia, Vaibhav
2 siblings, 0 replies; 20+ messages in thread
From: Vaibhav Hiremath @ 2012-12-12 10:22 UTC (permalink / raw)
To: linux-arm-kernel
On 12/10/2012 1:33 AM, Paul Walmsley wrote:
> There's no need to determine the current power state for powerdomains
> that must be on while the kernel is running. We mark these
> powerdomains with a new flag, PWRDM_ACTIVE_WITH_KERNEL. Any
> powerdomain marked with that flag is reported as being in the ON power
> state while the kernel is running.
>
> Signed-off-by: Paul Walmsley <paul@pwsan.com>
> Cc: Beno?t Cousson <b-cousson@ti.com>
> ---
> arch/arm/mach-omap2/powerdomain.c | 9 ++++++---
> arch/arm/mach-omap2/powerdomain.h | 4 ++++
> arch/arm/mach-omap2/powerdomains2xxx_data.c | 2 ++
> arch/arm/mach-omap2/powerdomains33xx_data.c | 3 ++-
> arch/arm/mach-omap2/powerdomains3xxx_data.c | 9 ++++++---
> arch/arm/mach-omap2/powerdomains44xx_data.c | 5 ++++-
> 6 files changed, 24 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
> index f5e2727..a4bb0bb 100644
> --- a/arch/arm/mach-omap2/powerdomain.c
> +++ b/arch/arm/mach-omap2/powerdomain.c
> @@ -462,7 +462,8 @@ static int _pwrdm_read_fpwrst(struct powerdomain *pwrdm)
> int pwrst, logic_pwrst, ret;
> u8 fpwrst;
>
> - if (!_pwrdm_pwrst_can_change(pwrdm))
> + if (!_pwrdm_pwrst_can_change(pwrdm) ||
> + pwrdm->flags & PWRDM_ACTIVE_WITH_KERNEL)
> return PWRDM_FUNC_PWRST_ON;
>
> pwrst = arch_pwrdm->pwrdm_read_pwrst(pwrdm);
> @@ -1104,12 +1105,14 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm)
>
> int pwrdm_state_switch_nolock(struct powerdomain *pwrdm)
> {
> - int ret;
> + int ret = 0;
>
> if (!pwrdm || !arch_pwrdm)
> return -EINVAL;
>
> - ret = arch_pwrdm->pwrdm_wait_transition(pwrdm);
> + if (!(pwrdm->flags & PWRDM_ACTIVE_WITH_KERNEL))
> + ret = arch_pwrdm->pwrdm_wait_transition(pwrdm);
> +
> if (!ret)
> _pwrdm_state_switch(pwrdm);
>
> diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
> index f4a189a..10941fd 100644
> --- a/arch/arm/mach-omap2/powerdomain.h
> +++ b/arch/arm/mach-omap2/powerdomain.h
> @@ -78,10 +78,14 @@ enum pwrdm_func_state {
> *
> * PWRDM_HAS_LOWPOWERSTATECHANGE - can transition from a sleep state
> * to a lower sleep state without waking up the powerdomain
> + *
> + * PWRDM_ACTIVE_WITH_KERNEL - this powerdomain's current power state is
> + * guaranteed to be ON whenever the kernel is running
> */
> #define PWRDM_HAS_HDWR_SAR BIT(0)
> #define PWRDM_HAS_MPU_QUIRK BIT(1)
> #define PWRDM_HAS_LOWPOWERSTATECHANGE BIT(2)
> +#define PWRDM_ACTIVE_WITH_KERNEL BIT(3)
>
> /*
> * Powerdomain internal flags (struct powerdomain._flags)
> diff --git a/arch/arm/mach-omap2/powerdomains2xxx_data.c b/arch/arm/mach-omap2/powerdomains2xxx_data.c
> index 578eef8..112927f 100644
> --- a/arch/arm/mach-omap2/powerdomains2xxx_data.c
> +++ b/arch/arm/mach-omap2/powerdomains2xxx_data.c
> @@ -54,6 +54,7 @@ static struct powerdomain mpu_24xx_pwrdm = {
> [0] = PWRSTS_ON,
> },
> .voltdm = { .name = "core" },
> + .flags = PWRDM_ACTIVE_WITH_KERNEL,
> };
>
> static struct powerdomain core_24xx_pwrdm = {
> @@ -73,6 +74,7 @@ static struct powerdomain core_24xx_pwrdm = {
> [2] = PWRSTS_OFF_RET_ON, /* MEM3ONSTATE */
> },
> .voltdm = { .name = "core" },
> + .flags = PWRDM_ACTIVE_WITH_KERNEL,
> };
>
>
> diff --git a/arch/arm/mach-omap2/powerdomains33xx_data.c b/arch/arm/mach-omap2/powerdomains33xx_data.c
> index 869adb8..acb148a 100644
> --- a/arch/arm/mach-omap2/powerdomains33xx_data.c
> +++ b/arch/arm/mach-omap2/powerdomains33xx_data.c
> @@ -123,7 +123,8 @@ static struct powerdomain mpu_33xx_pwrdm = {
> .pwrstst_offs = AM33XX_PM_MPU_PWRSTST_OFFSET,
> .pwrsts = PWRSTS_OFF_RET_ON,
> .pwrsts_logic_ret = PWRSTS_OFF_RET,
> - .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
> + .flags = (PWRDM_HAS_LOWPOWERSTATECHANGE |
> + PWRDM_ACTIVE_WITH_KERNEL),
This needs to be applicable for "wkup_pwrdm" as well.
Thanks,
Vaibhav
> .banks = 3,
> .logicretstate_mask = AM33XX_LOGICRETSTATE_MASK,
> .mem_on_mask = {
> diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c
> index f0e14e9ef..ade93d3 100644
> --- a/arch/arm/mach-omap2/powerdomains3xxx_data.c
> +++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c
> @@ -58,7 +58,7 @@ static struct powerdomain mpu_3xxx_pwrdm = {
> .prcm_offs = MPU_MOD,
> .pwrsts = PWRSTS_OFF_RET_ON,
> .pwrsts_logic_ret = PWRSTS_OFF_RET,
> - .flags = PWRDM_HAS_MPU_QUIRK,
> + .flags = (PWRDM_HAS_MPU_QUIRK | PWRDM_ACTIVE_WITH_KERNEL),
> .banks = 1,
> .pwrsts_mem_ret = {
> [0] = PWRSTS_OFF_RET,
> @@ -74,7 +74,7 @@ static struct powerdomain mpu_am35x_pwrdm = {
> .prcm_offs = MPU_MOD,
> .pwrsts = PWRSTS_ON,
> .pwrsts_logic_ret = PWRSTS_ON,
> - .flags = PWRDM_HAS_MPU_QUIRK,
> + .flags = (PWRDM_HAS_MPU_QUIRK | PWRDM_ACTIVE_WITH_KERNEL),
> .banks = 1,
> .pwrsts_mem_ret = {
> [0] = PWRSTS_ON,
> @@ -110,6 +110,7 @@ static struct powerdomain core_3xxx_pre_es3_1_pwrdm = {
> [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
> },
> .voltdm = { .name = "core" },
> + .flags = PWRDM_ACTIVE_WITH_KERNEL,
> };
>
> static struct powerdomain core_3xxx_es3_1_pwrdm = {
> @@ -121,7 +122,8 @@ static struct powerdomain core_3xxx_es3_1_pwrdm = {
> * Setting the SAR flag for errata ID i478 which applies
> * to 3430 <= ES3.1
> */
> - .flags = PWRDM_HAS_HDWR_SAR, /* for USBTLL only */
> + .flags = (PWRDM_HAS_HDWR_SAR | /* for USBTLL only */
> + PWRDM_ACTIVE_WITH_KERNEL),
> .banks = 2,
> .pwrsts_mem_ret = {
> [0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */
> @@ -149,6 +151,7 @@ static struct powerdomain core_am35x_pwrdm = {
> [1] = PWRSTS_ON, /* MEM2ONSTATE */
> },
> .voltdm = { .name = "core" },
> + .flags = PWRDM_ACTIVE_WITH_KERNEL,
> };
>
> static struct powerdomain dss_pwrdm = {
> diff --git a/arch/arm/mach-omap2/powerdomains44xx_data.c b/arch/arm/mach-omap2/powerdomains44xx_data.c
> index 704664c..b64213c 100644
> --- a/arch/arm/mach-omap2/powerdomains44xx_data.c
> +++ b/arch/arm/mach-omap2/powerdomains44xx_data.c
> @@ -53,7 +53,8 @@ static struct powerdomain core_44xx_pwrdm = {
> [3] = PWRSTS_ON, /* ducati_l2ram */
> [4] = PWRSTS_ON, /* ducati_unicache */
> },
> - .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
> + .flags = (PWRDM_HAS_LOWPOWERSTATECHANGE |
> + PWRDM_ACTIVE_WITH_KERNEL),
> };
>
> /* gfx_44xx_pwrdm: 3D accelerator power domain */
> @@ -164,6 +165,7 @@ static struct powerdomain cpu0_44xx_pwrdm = {
> .pwrsts_mem_on = {
> [0] = PWRSTS_ON, /* cpu0_l1 */
> },
> + .flags = PWRDM_ACTIVE_WITH_KERNEL,
> };
>
> /* cpu1_44xx_pwrdm: MPU1 processor and Neon coprocessor power domain */
> @@ -218,6 +220,7 @@ static struct powerdomain mpu_44xx_pwrdm = {
> [1] = PWRSTS_ON, /* mpu_l2 */
> [2] = PWRSTS_ON, /* mpu_ram */
> },
> + .flags = PWRDM_ACTIVE_WITH_KERNEL,
> };
>
> /* ivahd_44xx_pwrdm: IVA-HD power domain */
>
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 09/12] ARM: OMAP2+: powerdomain: skip register reads for powerdomains known to be on
2012-12-09 20:03 ` [PATCH 09/12] ARM: OMAP2+: powerdomain: skip register reads for powerdomains known to be on Paul Walmsley
2012-12-12 10:22 ` Vaibhav Hiremath
@ 2012-12-19 21:09 ` Jon Hunter
2012-12-20 17:22 ` Paul Walmsley
2012-12-26 6:21 ` Bedia, Vaibhav
2 siblings, 1 reply; 20+ messages in thread
From: Jon Hunter @ 2012-12-19 21:09 UTC (permalink / raw)
To: linux-arm-kernel
Hi Paul,
On 12/09/2012 02:03 PM, Paul Walmsley wrote:
> There's no need to determine the current power state for powerdomains
> that must be on while the kernel is running. We mark these
> powerdomains with a new flag, PWRDM_ACTIVE_WITH_KERNEL. Any
> powerdomain marked with that flag is reported as being in the ON power
> state while the kernel is running.
>
> Signed-off-by: Paul Walmsley <paul@pwsan.com>
> Cc: Beno?t Cousson <b-cousson@ti.com>
> ---
> arch/arm/mach-omap2/powerdomain.c | 9 ++++++---
> arch/arm/mach-omap2/powerdomain.h | 4 ++++
> arch/arm/mach-omap2/powerdomains2xxx_data.c | 2 ++
> arch/arm/mach-omap2/powerdomains33xx_data.c | 3 ++-
> arch/arm/mach-omap2/powerdomains3xxx_data.c | 9 ++++++---
> arch/arm/mach-omap2/powerdomains44xx_data.c | 5 ++++-
> 6 files changed, 24 insertions(+), 8 deletions(-)
[snip]
> diff --git a/arch/arm/mach-omap2/powerdomains44xx_data.c b/arch/arm/mach-omap2/powerdomains44xx_data.c
> index 704664c..b64213c 100644
> --- a/arch/arm/mach-omap2/powerdomains44xx_data.c
> +++ b/arch/arm/mach-omap2/powerdomains44xx_data.c
> @@ -53,7 +53,8 @@ static struct powerdomain core_44xx_pwrdm = {
> [3] = PWRSTS_ON, /* ducati_l2ram */
> [4] = PWRSTS_ON, /* ducati_unicache */
> },
> - .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
> + .flags = (PWRDM_HAS_LOWPOWERSTATECHANGE |
> + PWRDM_ACTIVE_WITH_KERNEL),
> };
My understanding is that for OMAP4 devices, the core power domain may
not be active the same time as the MPU power domain. The Cortex-A9 has
the ability to access some peripherals (such as timer, McBSP) via a
private bus that does not require the core domain to be active. This is
a difference from OMAP3 devices, where the core would always be on with
the MPU power domain.
Hopefully, Benoit will chime in if I have gotten this wrong ;-)
Cheers
Jon
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 09/12] ARM: OMAP2+: powerdomain: skip register reads for powerdomains known to be on
2012-12-19 21:09 ` Jon Hunter
@ 2012-12-20 17:22 ` Paul Walmsley
2012-12-21 6:33 ` Santosh Shilimkar
0 siblings, 1 reply; 20+ messages in thread
From: Paul Walmsley @ 2012-12-20 17:22 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, 19 Dec 2012, Jon Hunter wrote:
> My understanding is that for OMAP4 devices, the core power domain may
> not be active the same time as the MPU power domain. The Cortex-A9 has
> the ability to access some peripherals (such as timer, McBSP) via a
> private bus that does not require the core domain to be active. This is
> a difference from OMAP3 devices, where the core would always be on with
> the MPU power domain.
You are absolutely right and I will drop that part from this patch.
- Paul
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 09/12] ARM: OMAP2+: powerdomain: skip register reads for powerdomains known to be on
2012-12-20 17:22 ` Paul Walmsley
@ 2012-12-21 6:33 ` Santosh Shilimkar
0 siblings, 0 replies; 20+ messages in thread
From: Santosh Shilimkar @ 2012-12-21 6:33 UTC (permalink / raw)
To: linux-arm-kernel
On Thursday 20 December 2012 10:52 PM, Paul Walmsley wrote:
> On Wed, 19 Dec 2012, Jon Hunter wrote:
>
>> My understanding is that for OMAP4 devices, the core power domain may
>> not be active the same time as the MPU power domain. The Cortex-A9 has
>> the ability to access some peripherals (such as timer, McBSP) via a
>> private bus that does not require the core domain to be active. This is
>> a difference from OMAP3 devices, where the core would always be on with
>> the MPU power domain.
>
> You are absolutely right and I will drop that part from this patch.
>
Just to be clear, MPU has direct path to ABE domain peripherals on
OMAP4. As Jon pointed out MCBSP and few timers are put under this
domain can be directly accessed by MPU without L3. ABE also can
be accessed via L3 by MPU. ABE has a dual map with MPU.
Regards
Santosh
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 09/12] ARM: OMAP2+: powerdomain: skip register reads for powerdomains known to be on
2012-12-09 20:03 ` [PATCH 09/12] ARM: OMAP2+: powerdomain: skip register reads for powerdomains known to be on Paul Walmsley
2012-12-12 10:22 ` Vaibhav Hiremath
2012-12-19 21:09 ` Jon Hunter
@ 2012-12-26 6:21 ` Bedia, Vaibhav
2012-12-26 6:31 ` Bedia, Vaibhav
2012-12-26 20:49 ` Paul Walmsley
2 siblings, 2 replies; 20+ messages in thread
From: Bedia, Vaibhav @ 2012-12-26 6:21 UTC (permalink / raw)
To: linux-arm-kernel
Hi Paul,
On Mon, Dec 10, 2012 at 01:33:28, Paul Walmsley wrote:
> There's no need to determine the current power state for powerdomains
> that must be on while the kernel is running. We mark these
> powerdomains with a new flag, PWRDM_ACTIVE_WITH_KERNEL. Any
> powerdomain marked with that flag is reported as being in the ON power
> state while the kernel is running.
[...]
> diff --git a/arch/arm/mach-omap2/powerdomains33xx_data.c b/arch/arm/mach-omap2/powerdomains33xx_data.c
> index 869adb8..acb148a 100644
> --- a/arch/arm/mach-omap2/powerdomains33xx_data.c
> +++ b/arch/arm/mach-omap2/powerdomains33xx_data.c
> @@ -123,7 +123,8 @@ static struct powerdomain mpu_33xx_pwrdm = {
> .pwrstst_offs = AM33XX_PM_MPU_PWRSTST_OFFSET,
> .pwrsts = PWRSTS_OFF_RET_ON,
> .pwrsts_logic_ret = PWRSTS_OFF_RET,
> - .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
> + .flags = (PWRDM_HAS_LOWPOWERSTATECHANGE |
> + PWRDM_ACTIVE_WITH_KERNEL),
In case of AM33xx, this flag should be set for PER and WKUP pwrdms also.
EMIF, L3, L4 etc come under PER so this domain can't transition on an active
system. PRCM and Control module come under WKUP, so the WKUP should the kernel
should attempt to transition WKUP domain also.
Regards,
Vaibhav
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 09/12] ARM: OMAP2+: powerdomain: skip register reads for powerdomains known to be on
2012-12-26 6:21 ` Bedia, Vaibhav
@ 2012-12-26 6:31 ` Bedia, Vaibhav
2012-12-26 20:49 ` Paul Walmsley
1 sibling, 0 replies; 20+ messages in thread
From: Bedia, Vaibhav @ 2012-12-26 6:31 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 26, 2012 at 11:51:46, Bedia, Vaibhav wrote:
> Hi Paul,
>
> On Mon, Dec 10, 2012 at 01:33:28, Paul Walmsley wrote:
> > There's no need to determine the current power state for powerdomains
> > that must be on while the kernel is running. We mark these
> > powerdomains with a new flag, PWRDM_ACTIVE_WITH_KERNEL. Any
> > powerdomain marked with that flag is reported as being in the ON power
> > state while the kernel is running.
> [...]
> > diff --git a/arch/arm/mach-omap2/powerdomains33xx_data.c b/arch/arm/mach-omap2/powerdomains33xx_data.c
> > index 869adb8..acb148a 100644
> > --- a/arch/arm/mach-omap2/powerdomains33xx_data.c
> > +++ b/arch/arm/mach-omap2/powerdomains33xx_data.c
> > @@ -123,7 +123,8 @@ static struct powerdomain mpu_33xx_pwrdm = {
> > .pwrstst_offs = AM33XX_PM_MPU_PWRSTST_OFFSET,
> > .pwrsts = PWRSTS_OFF_RET_ON,
> > .pwrsts_logic_ret = PWRSTS_OFF_RET,
> > - .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
> > + .flags = (PWRDM_HAS_LOWPOWERSTATECHANGE |
> > + PWRDM_ACTIVE_WITH_KERNEL),
>
> In case of AM33xx, this flag should be set for PER and WKUP pwrdms also.
> EMIF, L3, L4 etc come under PER so this domain can't transition on an active
> system. PRCM and Control module come under WKUP, so
... the kernel should not attempt to change the WKUP power domain state.
Regards,
Vaibhav
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 09/12] ARM: OMAP2+: powerdomain: skip register reads for powerdomains known to be on
2012-12-26 6:21 ` Bedia, Vaibhav
2012-12-26 6:31 ` Bedia, Vaibhav
@ 2012-12-26 20:49 ` Paul Walmsley
1 sibling, 0 replies; 20+ messages in thread
From: Paul Walmsley @ 2012-12-26 20:49 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, 26 Dec 2012, Bedia, Vaibhav wrote:
> In case of AM33xx, this flag should be set for PER and WKUP pwrdms also.
> EMIF, L3, L4 etc come under PER so this domain can't transition on an active
> system. PRCM and Control module come under WKUP, so the WKUP should the kernel
> should attempt to transition WKUP domain also.
Thanks - the patch has been updated to reflect this.
- Paul
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 00/12] ARM: OMAP2+: powerdomain updates after the functional power state conversion
2012-12-09 20:02 [PATCH 00/12] ARM: OMAP2+: powerdomain updates after the functional power state conversion Paul Walmsley
` (10 preceding siblings ...)
2012-12-09 20:03 ` [PATCH 12/12] ARM: OMAP2xxx: PM: add pwrdm_(pre|post)_transition() calls to the 2xxx PM code Paul Walmsley
@ 2013-01-04 14:26 ` Tero Kristo
11 siblings, 0 replies; 20+ messages in thread
From: Tero Kristo @ 2013-01-04 14:26 UTC (permalink / raw)
To: linux-arm-kernel
Hi Paul,
Tested this whole set on omap3beagle and omap4panda. The only regression
I noticed was that cpu0 debug counters do not increment on omap4 after
this set. The patch at the end fixes this problem. Other than that, you
can add acked-by tag from me if you want, I went the code through
quickly and don't have any comments to it.
-Tero
From: Tero Kristo <t-kristo@ti.com>
Date: Thu, 3 Jan 2013 20:07:27 +0200
Subject: [PATCH] ARM: OMAP4: PM: fix cpu0 statistics update during idle
Cpu0 PM counters do not update, as the cpu0 fpwrst is set to ON before
calling pwrdm_post_transition. The optimized code checks whether the
fpwrst is ON, and skips any further checks if this is the case. Fixed
by re-ordering the code within omap4_mpuss_enter_lowpower function.
Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
arch/arm/mach-omap2/omap-mpuss-lowpower.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index 9acd52a..1bdd59e 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -269,10 +269,16 @@ int omap4_mpuss_enter_lowpower(unsigned int cpu,
u8 fpwrst)
* domain transition
*/
wakeup_cpu = smp_processor_id();
- WARN_ON(pwrdm_set_next_fpwrst(pm_info->pwrdm, PWRDM_FUNC_PWRST_ON));
+ /*
+ * Due to optimizations to the code, pwrdm_post_transition
+ * must be called prior to resetting cpu0 pwrst to ON,
+ * otherwise cpu0 powerstate statistics don't update properly
+ */
pwrdm_post_transition(NULL);
+ WARN_ON(pwrdm_set_next_fpwrst(pm_info->pwrdm, PWRDM_FUNC_PWRST_ON));
+
return 0;
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
end of thread, other threads:[~2013-01-04 14:26 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-12-09 20:02 [PATCH 00/12] ARM: OMAP2+: powerdomain updates after the functional power state conversion Paul Walmsley
2012-12-09 20:02 ` [PATCH 01/12] ARM: OMAP2+: powerdomain: consolidate arch_pwrdm check code Paul Walmsley
2012-12-09 20:03 ` [PATCH 02/12] ARM: OMAP2+: PM/powerdomain: move the power state time tracking into the powerdomain code Paul Walmsley
2012-12-09 20:03 ` [PATCH 03/12] ARM: OMAP2+: powerdomain: split pwrdm_state_switch() Paul Walmsley
2012-12-09 20:03 ` [PATCH 04/12] ARM: OMAP2+: PM: clean up some debugfs functions Paul Walmsley
2012-12-09 20:03 ` [PATCH 06/12] ARM: OMAP2+: CM: use the cached copy of the clockdomain's hwsup state Paul Walmsley
2012-12-09 20:03 ` [PATCH 07/12] ARM: OMAP2+: powerdomain: cache the powerdomain next power state Paul Walmsley
2012-12-09 20:03 ` [PATCH 08/12] ARM: OMAP2+: powerdomain: cache the powerdomain's previous " Paul Walmsley
2012-12-09 20:03 ` [PATCH 09/12] ARM: OMAP2+: powerdomain: skip register reads for powerdomains known to be on Paul Walmsley
2012-12-12 10:22 ` Vaibhav Hiremath
2012-12-19 21:09 ` Jon Hunter
2012-12-20 17:22 ` Paul Walmsley
2012-12-21 6:33 ` Santosh Shilimkar
2012-12-26 6:21 ` Bedia, Vaibhav
2012-12-26 6:31 ` Bedia, Vaibhav
2012-12-26 20:49 ` Paul Walmsley
2012-12-09 20:03 ` [PATCH 10/12] ARM: OMAP2+: powerdomain: skip previous-power-state read if next_pwrst is ON Paul Walmsley
2012-12-09 20:03 ` [PATCH 11/12] ARM: OMAP2xxx: powerdomain: add previous power state tracking Paul Walmsley
2012-12-09 20:03 ` [PATCH 12/12] ARM: OMAP2xxx: PM: add pwrdm_(pre|post)_transition() calls to the 2xxx PM code Paul Walmsley
2013-01-04 14:26 ` [PATCH 00/12] ARM: OMAP2+: powerdomain updates after the functional power state conversion Tero Kristo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).