Re: [PATCH 7/8] OMAP3 PM: Support for Open Switch Retention for Core and MPU power domains in cpuidle path

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Thara Gopinath <thara@xxxxxx> 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@xxxxxx>
> ---
>  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@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux