From: Kevin Hilman <khilman@deeprootsystems.com>
To: Thara Gopinath <thara@ti.com>
Cc: linux-omap@vger.kernel.org
Subject: Re: [PATCH 7/8] OMAP3 PM: Support for Open Switch Retention for Core and MPU power domains in cpuidle path
Date: Fri, 22 Jan 2010 16:35:52 -0800 [thread overview]
Message-ID: <87aaw5zmhj.fsf@deeprootsystems.com> (raw)
In-Reply-To: <1264001442-20078-8-git-send-email-thara@ti.com> (Thara Gopinath's message of "Wed\, 20 Jan 2010 21\:00\:41 +0530")
Thara Gopinath <thara@ti.com> writes:
> This patch adds Open SWitch Retention (OSWR) support for
> MPU/CORE domains in Cpuidle. In addition to the normal
> power domain retention(Closed SWitch retention) in OSWR,
> the powerdomain logic is turned OFF. Power domain memory
> banks can be chosen to be retained or turned off. In this
> implementation both MPU and Core domain memory banks are
> turned off during OSWR.
> This patch also adds counters ret_logic_off_counter and
> ret_mem_off_counter for each power domain. This keeps track
> of power domain logic and memory off during powerdomain
> retention. These counters together with the retention counter
> can be used to find out whether a power domain has entered
> OSWR or not. In case of OSWR both the retention counter and
> ret_logic_off_counter will get incremented. ret_mem_off_counter
> will get incremented if memory bank off during retention
> is implemented. In this implementation in case of core or mpu
> domain entering OSWR all three flags will be incremented. In
> case of normal retention or CSWR only the retention counter
> will be incremented
>
> To support this feature two new C states are being added to
> the existing C states which makes the new states look like below.
>
> C1 - MPU WFI + Core active
> C2 - MPU WFI + Core inactive
> C3 - MPU CSWR + Core inactive
> C4 - MPU OFF + Core inactive
> C5 - MPU CSWR + Core CSWR
> C6 - MPU OFF + Core CSWR
> C7 - MPU OSWR + CORE OSWR (New State)
> C8 - MPU OFF + CORE OSWR (New State)
> C9 - MPU OFF + CORE OFF
>
> Signed-off-by: Thara Gopinath <thara@ti.com>
> ---
> arch/arm/mach-omap2/board-3430sdp.c | 4 +
> arch/arm/mach-omap2/cpuidle34xx.c | 129 +++++++++++++++++++++++--
> arch/arm/mach-omap2/pm-debug.c | 3 +
> arch/arm/mach-omap2/pm34xx.c | 55 +++++++++--
> arch/arm/mach-omap2/powerdomain.c | 13 +++
> arch/arm/mach-omap2/sleep34xx.S | 4 +
> arch/arm/plat-omap/include/plat/powerdomain.h | 2 +
> 7 files changed, 194 insertions(+), 16 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
> index 7d68445..071cf22 100644
> --- a/arch/arm/mach-omap2/board-3430sdp.c
> +++ b/arch/arm/mach-omap2/board-3430sdp.c
> @@ -72,6 +72,10 @@ static struct cpuidle_params omap3_cpuidle_params_table[] = {
> /* C6 */
> {1, 3000, 8500, 15000},
> /* C7 */
> + {1, 4000, 10000, 150000},
> + /* C8 */
> + {1, 8000, 25000, 250000},
> + /* C9 */
> {1, 10000, 30000, 300000},
> };
>
> diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
> index 1cfa5a6..419f683 100644
> --- a/arch/arm/mach-omap2/cpuidle34xx.c
> +++ b/arch/arm/mach-omap2/cpuidle34xx.c
> @@ -36,14 +36,16 @@
>
> #ifdef CONFIG_CPU_IDLE
>
> -#define OMAP3_MAX_STATES 7
> +#define OMAP3_MAX_STATES 9
> #define OMAP3_STATE_C1 0 /* C1 - MPU WFI + Core active */
> #define OMAP3_STATE_C2 1 /* C2 - MPU WFI + Core inactive */
> #define OMAP3_STATE_C3 2 /* C3 - MPU CSWR + Core inactive */
> #define OMAP3_STATE_C4 3 /* C4 - MPU OFF + Core iactive */
> -#define OMAP3_STATE_C5 4 /* C5 - MPU RET + Core RET */
> -#define OMAP3_STATE_C6 5 /* C6 - MPU OFF + Core RET */
> -#define OMAP3_STATE_C7 6 /* C7 - MPU OFF + Core OFF */
> +#define OMAP3_STATE_C5 4 /* C5 - MPU CSWR + Core CSWR */
> +#define OMAP3_STATE_C6 5 /* C6 - MPU OFF + Core CSWR */
> +#define OMAP3_STATE_C7 6 /* C7 - MPU OSWR + Core OSWR */
> +#define OMAP3_STATE_C8 7 /* C8 - MPU OFF + Core OSWR */
> +#define OMAP3_STATE_C9 8 /* C9 - MPU OFF + CORE OFF */
>
> struct omap3_processor_cx {
> u8 valid;
> @@ -52,6 +54,11 @@ struct omap3_processor_cx {
> u32 wakeup_latency;
> u32 mpu_state;
> u32 core_state;
> + u32 mpu_logicl1_ret_state;
> + u32 mpu_l2cache_ret_state;
> + u32 core_logic_state;
> + u32 core_mem1_ret_state;
> + u32 core_mem2_ret_state;
> u32 threshold;
> u32 flags;
> };
> @@ -81,6 +88,10 @@ static struct cpuidle_params cpuidle_params_table[] = {
> /* C6 */
> {1, 3000, 8500, 15000},
> /* C7 */
> + {1, 4000, 10000, 150000},
> + /* C8 */
> + {1, 8000, 25000, 250000},
> + /* C9 */
> {1, 10000, 30000, 300000},
> };
>
> @@ -119,6 +130,11 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
> struct omap3_processor_cx *cx = cpuidle_get_statedata(state);
> struct timespec ts_preidle, ts_postidle, ts_idle;
> u32 mpu_state = cx->mpu_state, core_state = cx->core_state;
> + u32 mpu_logicl1_ret_state = cx->mpu_logicl1_ret_state;
> + u32 mpu_l2cache_ret_state = cx->mpu_l2cache_ret_state;
> + u32 core_logic_state = cx->core_logic_state;
> + u32 core_mem1_ret_state = cx->core_mem1_ret_state;
> + u32 core_mem2_ret_state = cx->core_mem2_ret_state;
>
> current_cx_state = *cx;
>
> @@ -135,6 +151,20 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
> core_state = PWRDM_POWER_RET;
> }
>
> + /* For any state above inactive set the logic and memory retention
> + * bits in case the powerdomain enters retention
> + */
> + if (mpu_state <= PWRDM_POWER_RET) {
> + pwrdm_set_logic_retst(mpu_pd, mpu_logicl1_ret_state);
> + pwrdm_set_mem_retst(mpu_pd, 0, mpu_l2cache_ret_state);
> + }
> +
> + if (core_state <= PWRDM_POWER_RET) {
> + pwrdm_set_logic_retst(core_pd, core_logic_state);
> + pwrdm_set_mem_retst(core_pd, 0, core_mem1_ret_state);
> + pwrdm_set_mem_retst(core_pd, 1, core_mem2_ret_state);
> + }
> +
> pwrdm_set_next_pwrst(mpu_pd, mpu_state);
> pwrdm_set_next_pwrst(core_pd, core_state);
>
> @@ -217,7 +247,7 @@ void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params)
> * C3 . MPU CSWR + Core inactive
> * C4 . MPU OFF + Core inactive
> * C5 . MPU CSWR + Core CSWR
> - * C6 . MPU OFF + Core CSWR
> + * C6 . MPU OFF + Core OSWR
> * C7 . MPU OFF + Core OFF
> */
> void omap_init_power_states(void)
> @@ -262,6 +292,10 @@ void omap_init_power_states(void)
> cpuidle_params_table[OMAP3_STATE_C3].threshold;
> omap3_power_states[OMAP3_STATE_C3].mpu_state = PWRDM_POWER_RET;
> omap3_power_states[OMAP3_STATE_C3].core_state = PWRDM_POWER_ON;
> + omap3_power_states[OMAP3_STATE_C3].mpu_logicl1_ret_state =
> + PWRDM_POWER_RET;
> + omap3_power_states[OMAP3_STATE_C3].mpu_l2cache_ret_state =
> + PWRDM_POWER_RET;
> omap3_power_states[OMAP3_STATE_C3].flags = CPUIDLE_FLAG_TIME_VALID |
> CPUIDLE_FLAG_CHECK_BM;
>
> @@ -277,6 +311,10 @@ void omap_init_power_states(void)
> cpuidle_params_table[OMAP3_STATE_C4].threshold;
> omap3_power_states[OMAP3_STATE_C4].mpu_state = PWRDM_POWER_OFF;
> omap3_power_states[OMAP3_STATE_C4].core_state = PWRDM_POWER_ON;
> + omap3_power_states[OMAP3_STATE_C4].mpu_logicl1_ret_state =
> + PWRDM_POWER_RET;
> + omap3_power_states[OMAP3_STATE_C4].mpu_l2cache_ret_state =
> + PWRDM_POWER_RET;
> omap3_power_states[OMAP3_STATE_C4].flags = CPUIDLE_FLAG_TIME_VALID |
> CPUIDLE_FLAG_CHECK_BM;
>
> @@ -292,6 +330,15 @@ void omap_init_power_states(void)
> cpuidle_params_table[OMAP3_STATE_C5].threshold;
> omap3_power_states[OMAP3_STATE_C5].mpu_state = PWRDM_POWER_RET;
> omap3_power_states[OMAP3_STATE_C5].core_state = PWRDM_POWER_RET;
> + omap3_power_states[OMAP3_STATE_C5].mpu_logicl1_ret_state =
> + PWRDM_POWER_RET;
> + omap3_power_states[OMAP3_STATE_C5].mpu_l2cache_ret_state =
> + PWRDM_POWER_RET;
> + omap3_power_states[OMAP3_STATE_C5].core_logic_state = PWRDM_POWER_RET;
> + omap3_power_states[OMAP3_STATE_C5].core_mem1_ret_state =
> + PWRDM_POWER_RET;
> + omap3_power_states[OMAP3_STATE_C5].core_mem2_ret_state =
> + PWRDM_POWER_RET;
> omap3_power_states[OMAP3_STATE_C5].flags = CPUIDLE_FLAG_TIME_VALID |
> CPUIDLE_FLAG_CHECK_BM;
>
> @@ -307,10 +354,19 @@ void omap_init_power_states(void)
> cpuidle_params_table[OMAP3_STATE_C6].threshold;
> omap3_power_states[OMAP3_STATE_C6].mpu_state = PWRDM_POWER_OFF;
> omap3_power_states[OMAP3_STATE_C6].core_state = PWRDM_POWER_RET;
> + omap3_power_states[OMAP3_STATE_C6].mpu_logicl1_ret_state =
> + PWRDM_POWER_RET;
> + omap3_power_states[OMAP3_STATE_C6].mpu_l2cache_ret_state =
> + PWRDM_POWER_RET;
> + omap3_power_states[OMAP3_STATE_C6].core_logic_state = PWRDM_POWER_RET;
> + omap3_power_states[OMAP3_STATE_C6].core_mem1_ret_state =
> + PWRDM_POWER_RET;
> + omap3_power_states[OMAP3_STATE_C6].core_mem2_ret_state =
> + PWRDM_POWER_RET;
> omap3_power_states[OMAP3_STATE_C6].flags = CPUIDLE_FLAG_TIME_VALID |
> CPUIDLE_FLAG_CHECK_BM;
>
> - /* C7 . MPU OFF + Core OFF */
> + /* C7 . MPU OSWR + Core OSWR */
> omap3_power_states[OMAP3_STATE_C7].valid =
> cpuidle_params_table[OMAP3_STATE_C7].valid;
> omap3_power_states[OMAP3_STATE_C7].type = OMAP3_STATE_C7;
> @@ -320,10 +376,67 @@ void omap_init_power_states(void)
> cpuidle_params_table[OMAP3_STATE_C7].wake_latency;
> omap3_power_states[OMAP3_STATE_C7].threshold =
> cpuidle_params_table[OMAP3_STATE_C7].threshold;
> - omap3_power_states[OMAP3_STATE_C7].mpu_state = PWRDM_POWER_OFF;
> - omap3_power_states[OMAP3_STATE_C7].core_state = PWRDM_POWER_OFF;
> + omap3_power_states[OMAP3_STATE_C7].mpu_state = PWRDM_POWER_RET;
> + omap3_power_states[OMAP3_STATE_C7].core_state = PWRDM_POWER_RET;
> + omap3_power_states[OMAP3_STATE_C7].mpu_logicl1_ret_state =
> + PWRDM_POWER_OFF;
> + omap3_power_states[OMAP3_STATE_C7].mpu_l2cache_ret_state =
> + PWRDM_POWER_OFF;
> + omap3_power_states[OMAP3_STATE_C7].core_logic_state = PWRDM_POWER_OFF;
> + omap3_power_states[OMAP3_STATE_C7].core_mem1_ret_state =
> + PWRDM_POWER_OFF;
> + omap3_power_states[OMAP3_STATE_C7].core_mem2_ret_state =
> + PWRDM_POWER_OFF;
> omap3_power_states[OMAP3_STATE_C7].flags = CPUIDLE_FLAG_TIME_VALID |
> CPUIDLE_FLAG_CHECK_BM;
> +
> + /* C8 . MPU OFF + Core OSWR */
> + omap3_power_states[OMAP3_STATE_C8].valid =
> + cpuidle_params_table[OMAP3_STATE_C8].valid;
> + omap3_power_states[OMAP3_STATE_C8].type = OMAP3_STATE_C8;
> + omap3_power_states[OMAP3_STATE_C8].sleep_latency =
> + cpuidle_params_table[OMAP3_STATE_C8].sleep_latency;
> + omap3_power_states[OMAP3_STATE_C8].wakeup_latency =
> + cpuidle_params_table[OMAP3_STATE_C8].wake_latency;
> + omap3_power_states[OMAP3_STATE_C8].threshold =
> + cpuidle_params_table[OMAP3_STATE_C8].threshold;
> + omap3_power_states[OMAP3_STATE_C8].mpu_state = PWRDM_POWER_OFF;
> + omap3_power_states[OMAP3_STATE_C8].core_state = PWRDM_POWER_RET;
> + omap3_power_states[OMAP3_STATE_C8].mpu_logicl1_ret_state =
> + PWRDM_POWER_OFF;
> + omap3_power_states[OMAP3_STATE_C8].mpu_l2cache_ret_state =
> + PWRDM_POWER_OFF;
> + omap3_power_states[OMAP3_STATE_C8].core_logic_state = PWRDM_POWER_OFF;
> + omap3_power_states[OMAP3_STATE_C8].core_mem1_ret_state =
> + PWRDM_POWER_OFF;
> + omap3_power_states[OMAP3_STATE_C8].core_mem2_ret_state =
> + PWRDM_POWER_OFF;
> + omap3_power_states[OMAP3_STATE_C8].flags = CPUIDLE_FLAG_TIME_VALID |
> + CPUIDLE_FLAG_CHECK_BM;
> +
> + /* C9 . MPU OFF + Core OFF */
> + omap3_power_states[OMAP3_STATE_C9].valid =
> + cpuidle_params_table[OMAP3_STATE_C9].valid;
> + omap3_power_states[OMAP3_STATE_C9].type = OMAP3_STATE_C9;
> + omap3_power_states[OMAP3_STATE_C9].sleep_latency =
> + cpuidle_params_table[OMAP3_STATE_C9].sleep_latency;
> + omap3_power_states[OMAP3_STATE_C9].wakeup_latency =
> + cpuidle_params_table[OMAP3_STATE_C9].wake_latency;
> + omap3_power_states[OMAP3_STATE_C9].threshold =
> + cpuidle_params_table[OMAP3_STATE_C9].threshold;
> + omap3_power_states[OMAP3_STATE_C9].mpu_state = PWRDM_POWER_OFF;
> + omap3_power_states[OMAP3_STATE_C9].core_state = PWRDM_POWER_OFF;
> + omap3_power_states[OMAP3_STATE_C9].mpu_logicl1_ret_state =
> + PWRDM_POWER_OFF;
> + omap3_power_states[OMAP3_STATE_C9].mpu_l2cache_ret_state =
> + PWRDM_POWER_OFF;
> + omap3_power_states[OMAP3_STATE_C9].core_logic_state = PWRDM_POWER_OFF;
> + omap3_power_states[OMAP3_STATE_C9].core_mem1_ret_state =
> + PWRDM_POWER_OFF;
> + omap3_power_states[OMAP3_STATE_C9].core_mem2_ret_state =
> + PWRDM_POWER_OFF;
> + omap3_power_states[OMAP3_STATE_C9].flags = CPUIDLE_FLAG_TIME_VALID |
> + CPUIDLE_FLAG_CHECK_BM;
> }
>
> struct cpuidle_driver omap3_idle_driver = {
> diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
> index 85a8c6e..035cfa7 100644
> --- a/arch/arm/mach-omap2/pm-debug.c
> +++ b/arch/arm/mach-omap2/pm-debug.c
> @@ -385,6 +385,9 @@ static int pwrdm_dbg_show_counter(struct powerdomain *pwrdm, void *user)
> for (i = 0; i < PWRDM_MAX_PWRSTS; i++)
> seq_printf(s, ",%s:%d", pwrdm_state_names[i],
> pwrdm->state_counter[i]);
> + seq_printf(s, ",RET-LOGIC-OFF:%d,RET-MEM-OFF:%d",
> + pwrdm->ret_logic_off_counter,
> + pwrdm->ret_mem_off_counter);
>
> seq_printf(s, "\n");
>
> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
> index 6e6d954..bfdcac2 100644
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -384,7 +384,8 @@ void omap_sram_idle(void)
> int mpu_next_state = PWRDM_POWER_ON;
> int per_next_state = PWRDM_POWER_ON;
> int core_next_state = PWRDM_POWER_ON;
> - int core_prev_state, per_prev_state;
> + int mpu_prev_state, core_prev_state, per_prev_state;
> + int mpu_logic_state, mpu_mem_state, core_logic_state;
> u32 sdrc_pwr = 0;
> int per_state_modified = 0;
>
> @@ -397,12 +398,25 @@ void omap_sram_idle(void)
> pwrdm_clear_all_prev_pwrst(per_pwrdm);
>
> mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
> + mpu_logic_state = pwrdm_read_next_logic_pwrst(mpu_pwrdm);
> + mpu_mem_state = pwrdm_read_next_mem_pwrst(mpu_pwrdm, 0);
> +
> switch (mpu_next_state) {
> case PWRDM_POWER_ON:
> - case PWRDM_POWER_RET:
> /* No need to save context */
> save_state = 0;
> break;
> + case PWRDM_POWER_RET:
> + if (!mpu_logic_state && !mpu_mem_state)
> + save_state = 3;
> + else if (!mpu_mem_state)
> + save_state = 2;
> + else if (!mpu_logic_state)
> + save_state = 1;
> + else
> + /* No need to save context */
> + save_state = 0;
> + break;
> case PWRDM_POWER_OFF:
> save_state = 3;
> break;
> @@ -421,6 +435,8 @@ void omap_sram_idle(void)
> /* PER */
> per_next_state = pwrdm_read_next_pwrst(per_pwrdm);
> core_next_state = pwrdm_read_next_pwrst(core_pwrdm);
> + core_logic_state = pwrdm_read_next_logic_pwrst(core_pwrdm);
> +
> if (per_next_state < PWRDM_POWER_ON) {
> omap2_gpio_prepare_for_idle(per_next_state);
> if (per_next_state == PWRDM_POWER_OFF) {
> @@ -448,8 +464,8 @@ void omap_sram_idle(void)
>
> /* CORE */
> if (core_next_state < PWRDM_POWER_ON) {
> - omap_uart_prepare_idle(0, core_next_state);
> - omap_uart_prepare_idle(1, core_next_state);
> + omap_uart_prepare_idle(0, core_next_state & core_logic_state);
> + omap_uart_prepare_idle(1, core_next_state & core_logic_state);
Hmm this (core_next_state & core_logic_state) bitwise AND logic isn't
terribly clear at first glance (at least to me) as it assumes that the
off value is zero.
For readability, I think we need something like:
uart_power_state = ((core_next_state == PWRDM_POWER_OFF) ||
(core_logic_state == PWRDM_POWER_OFF))
[...]
omap_uart_prepare_idle(x, uart_power_state);
> if (core_next_state == PWRDM_POWER_OFF) {
> u32 voltctrl = OMAP3430_AUTO_OFF;
>
> @@ -460,6 +476,20 @@ void omap_sram_idle(void)
> OMAP3_PRM_VOLTCTRL_OFFSET);
> omap3_core_save_context(PWRDM_POWER_OFF);
> omap3_prcm_save_context();
> + } else if ((core_next_state == PWRDM_POWER_RET) &&
> + (core_logic_state == PWRDM_POWER_OFF)) {
> + /* Disable DPLL4 autoidle bit so that register
> + * contents match with that stored in the
> + * scratchpad. If this is not done rom code
> + * enters into some wrong path while coming
> + * out of coreOSWR and causes a crash.
> + */
> + cm_rmw_mod_reg_bits(OMAP3430_AUTO_PERIPH_DPLL_MASK,
> + 0x0, PLL_MOD, CM_AUTOIDLE);
> + omap3_core_save_context(PWRDM_POWER_RET);
> + prm_set_mod_reg_bits(OMAP3430_AUTO_RET,
> + OMAP3430_GR_MOD,
> + OMAP3_PRM_VOLTCTRL_OFFSET);
> } else if (core_next_state == PWRDM_POWER_RET) {
> prm_set_mod_reg_bits(OMAP3430_AUTO_RET,
> OMAP3430_GR_MOD,
> @@ -502,18 +532,27 @@ void omap_sram_idle(void)
> core_next_state == PWRDM_POWER_OFF)
> sdrc_write_reg(sdrc_pwr, SDRC_POWER);
>
> + mpu_prev_state = pwrdm_read_prev_pwrst(mpu_pwrdm);
> /* Restore table entry modified during MMU restoration */
> - if (pwrdm_read_prev_pwrst(mpu_pwrdm) == PWRDM_POWER_OFF)
> + if (((mpu_prev_state == PWRDM_POWER_RET) &&
> + (pwrdm_read_prev_logic_pwrst(mpu_pwrdm) ==
> + PWRDM_POWER_OFF)) || (mpu_prev_state ==
> + PWRDM_POWER_OFF))
minor: for consistency with below checks for CORE, check for OFF
first, then for RET/OSWR.
> restore_table_entry();
>
> /* CORE */
> if (core_next_state < PWRDM_POWER_ON) {
> core_prev_state = pwrdm_read_prev_pwrst(core_pwrdm);
> - if (core_prev_state == PWRDM_POWER_OFF) {
> + if ((core_prev_state == PWRDM_POWER_OFF) ||
> + (core_prev_state == PWRDM_POWER_RET &&
> + pwrdm_read_prev_logic_pwrst(core_pwrdm) ==
> + PWRDM_POWER_OFF)) {
> omap3_core_restore_context(core_prev_state);
> - omap3_prcm_restore_context();
> + if (core_prev_state == PWRDM_POWER_OFF) {
> + omap3_prcm_restore_context();
> + omap2_sms_restore_context();
> + }
> omap3_sram_restore_context();
> - omap2_sms_restore_context();
> /*
> * Errata 1.164 fix : OTG autoidle can prevent
> * sleep
> diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
> index 06bf290..ef9f1bb 100644
> --- a/arch/arm/mach-omap2/powerdomain.c
> +++ b/arch/arm/mach-omap2/powerdomain.c
> @@ -126,6 +126,16 @@ static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
> prev = pwrdm_read_prev_pwrst(pwrdm);
> if (pwrdm->state != prev)
> pwrdm->state_counter[prev]++;
> + if (prev == PWRDM_POWER_RET) {
> + if ((pwrdm->pwrsts_logic_ret == PWRSTS_OFF_RET) &&
> + (pwrdm_read_prev_logic_pwrst(pwrdm) ==
> + PWRDM_POWER_OFF))
> + pwrdm->ret_logic_off_counter++;
> + if ((pwrdm->pwrsts_mem_ret[0] == PWRSTS_OFF_RET) &&
> + (pwrdm_read_prev_mem_pwrst(pwrdm, 0) ==
> + PWRDM_POWER_OFF))
> + pwrdm->ret_mem_off_counter++;
> + }
> break;
> default:
> return -EINVAL;
> @@ -161,6 +171,9 @@ static __init void _pwrdm_setup(struct powerdomain *pwrdm)
> for (i = 0; i < PWRDM_MAX_PWRSTS; i++)
> pwrdm->state_counter[i] = 0;
>
> + pwrdm->ret_logic_off_counter = 0;
> + pwrdm->ret_mem_off_counter = 0;
> +
> pwrdm_wait_transition(pwrdm);
> pwrdm->state = pwrdm_read_pwrst(pwrdm);
> pwrdm->state_counter[pwrdm->state] = 1;
> diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
> index 69521be..1d88ef3 100644
> --- a/arch/arm/mach-omap2/sleep34xx.S
> +++ b/arch/arm/mach-omap2/sleep34xx.S
> @@ -256,8 +256,12 @@ restore:
> and r2, r2, #0x3
> cmp r2, #0x0 @ Check if target power state was OFF or RET
> moveq r9, #0x3 @ MPU OFF => L1 and L2 lost
> + beq restore_from_off
> + cmp r2, #0x1
> + moveq r9, #0x3
> movne r9, #0x1 @ Only L1 and L2 lost => avoid L2 invalidation
> bne logic_l1_restore
> +restore_from_off:
> ldr r0, control_stat
> ldr r1, [r0]
> and r1, #0x700
> diff --git a/arch/arm/plat-omap/include/plat/powerdomain.h b/arch/arm/plat-omap/include/plat/powerdomain.h
> index 7576559..405ccd6 100644
> --- a/arch/arm/plat-omap/include/plat/powerdomain.h
> +++ b/arch/arm/plat-omap/include/plat/powerdomain.h
> @@ -124,6 +124,8 @@ struct powerdomain {
>
> int state;
> unsigned state_counter[PWRDM_MAX_PWRSTS];
> + unsigned ret_logic_off_counter;
> + unsigned ret_mem_off_counter;
>
> #ifdef CONFIG_PM_DEBUG
> s64 timer;
> --
> 1.5.6.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2010-01-23 0:35 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-01-20 15:30 [PATCH 0/8] OMAP3: PM: Open Switch Retention support in the cpuidle thread Thara Gopinath
2010-01-20 15:30 ` [PATCH 1/8] PM: Increase the cpu idle max state Thara Gopinath
2010-01-20 15:30 ` [PATCH 2/8] OMAP3 PM: Conditional UART context save restore Thara Gopinath
2010-01-20 15:30 ` [PATCH 3/8] OMAP2/3 PM: Adding powerdomain APIs for reading the next logic and mem state Thara Gopinath
2010-01-20 15:30 ` [PATCH 4/8] OMAP3 PM: Defining .pwrsts_logic_ret field for core power domain structure Thara Gopinath
2010-01-20 15:30 ` [PATCH 5/8] OMAP3 PM: Adding conditional core powerdomain context save and restore Thara Gopinath
2010-01-20 15:30 ` [PATCH 6/8] OMAP3 PM: Enable DPLL4 autoidle after system off Thara Gopinath
2010-01-20 15:30 ` [PATCH 7/8] OMAP3 PM: Support for Open Switch Retention for Core and MPU power domains in cpuidle path Thara Gopinath
2010-01-20 15:30 ` [PATCH 8/8] OMAP3 PM: Support to enable disable OSWR feature from pm debug fs Thara Gopinath
2010-01-23 0:42 ` Kevin Hilman
2010-01-24 4:12 ` Gopinath, Thara
2010-01-25 19:55 ` Kevin Hilman
2010-01-21 5:59 ` [PATCH 7/8] OMAP3 PM: Support for Open Switch Retention for Core and MPU power domains in cpuidle path Paul Walmsley
2010-01-23 0:35 ` Kevin Hilman [this message]
2010-01-20 17:34 ` [PATCH 6/8] OMAP3 PM: Enable DPLL4 autoidle after system off Paul Walmsley
2010-01-21 5:33 ` Gopinath, Thara
2010-01-21 5:58 ` Paul Walmsley
2010-01-21 7:01 ` Gopinath, Thara
2010-01-21 7:12 ` Paul Walmsley
2010-01-23 0:15 ` [PATCH 5/8] OMAP3 PM: Adding conditional core powerdomain context save and restore Kevin Hilman
2010-01-21 6:25 ` [PATCH 4/8] OMAP3 PM: Defining .pwrsts_logic_ret field for core power domain structure Paul Walmsley
2010-01-21 6:12 ` [PATCH 3/8] OMAP2/3 PM: Adding powerdomain APIs for reading the next logic and mem state Paul Walmsley
2010-01-21 7:02 ` Gopinath, Thara
2010-01-22 23:44 ` [PATCH 2/8] OMAP3 PM: Conditional UART context save restore Kevin Hilman
2010-01-21 6:23 ` [PATCH 0/8] OMAP3: PM: Open Switch Retention support in the cpuidle thread Paul Walmsley
2010-01-21 7:08 ` Gopinath, Thara
2010-01-21 7:18 ` Paul Walmsley
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87aaw5zmhj.fsf@deeprootsystems.com \
--to=khilman@deeprootsystems.com \
--cc=linux-omap@vger.kernel.org \
--cc=thara@ti.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.