"ext Tero Kristo" <[EMAIL PROTECTED]> writes:

> CPU-idle has a possibility of working now, also added full PRCM register dump
> into pm-debug.
>
> Signed-off-by: Tero Kristo <[EMAIL PROTECTED]>
> ---
>  arch/arm/mach-omap2/cpuidle34xx.c |   30 -------------------------
>  arch/arm/mach-omap2/pm-debug.c    |   17 ++++++++++----
>  arch/arm/mach-omap2/pm34xx.c      |   43 +++++++++++++++++++++++++++---------
>  3 files changed, 44 insertions(+), 46 deletions(-)
>  mode change 100644 => 100755 arch/arm/mach-omap2/pm-debug.c
>
> diff --git a/arch/arm/mach-omap2/cpuidle34xx.c 
> b/arch/arm/mach-omap2/cpuidle34xx.c
> index 7af8653..9e65631 100755
> --- a/arch/arm/mach-omap2/cpuidle34xx.c
> +++ b/arch/arm/mach-omap2/cpuidle34xx.c
> @@ -461,10 +461,6 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
>       per_pwrst = pwrdm_read_pwrst(per_pd);
>       neon_pwrst = pwrdm_read_pwrst(neon_pd);
>  
> -     /* Do this before any changes to PRCM registers */
> -     if (cx->core_state == PWRDM_POWER_OFF)
> -             omap3_save_prcm_ctx();
> -
>       /* Program MPU to target state */
>       if (cx->mpu_state < PWRDM_POWER_ON) {
>               if (neon_pwrst == PWRDM_POWER_ON) {
> @@ -478,17 +474,6 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
>  
>       /* Program CORE and PER to target state */
>       if (cx->core_state < PWRDM_POWER_ON) {
> -             if (per_pwrst == PWRDM_POWER_ON) {
> -                     omap2_gpio_prepare_for_retention();
> -                     if (clocks_off_while_idle) {
> -                             omap3_save_per_ctx();
> -                             per_gpio_clk_disable();
> -                             omap_save_uart_ctx(2);
> -                             omap_serial_enable_clocks(0, 2);
> -                     }
> -             }
> -             if (cx->core_state == PWRDM_POWER_OFF)
> -                     omap3_save_core_ctx();
>               pwrdm_set_next_pwrst(core_pd, cx->core_state);
>       }

This will leave cx->core_state to its previous value in case of ON
state. So just pwrdm_set_next_pwrst(core_pd, cx->core_state) without
if is better.

>  
> @@ -510,22 +495,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
>       }
>  
>       if (cx->core_state < PWRDM_POWER_ON) {
> -             if ((cx->core_state == PWRDM_POWER_OFF)
> -             && (pwrdm_read_prev_pwrst(core_pd) == PWRDM_POWER_OFF)) {
> -                     omap3_restore_core_ctx();
> -                     omap3_restore_prcm_ctx();
> -                     omap3_restore_sram_ctx();
> -             }
>               pwrdm_set_next_pwrst(core_pd, PWRDM_POWER_ON);
> -             if (per_pwrst == PWRDM_POWER_ON) {
> -                     if (clocks_off_while_idle) {
> -                             omap_serial_enable_clocks(1, 2);
> -                             omap_restore_uart_ctx(2);
> -                             per_gpio_clk_enable();
> -                             omap3_restore_per_ctx();
> -                     }
> -                     omap2_gpio_resume_after_retention();
> -             }
>       }
>  
>       pr_debug("MPU prev st:%x,NEON prev st:%x\n",
> diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
> old mode 100644
> new mode 100755
> index b6f8621..f35b082
> --- a/arch/arm/mach-omap2/pm-debug.c
> +++ b/arch/arm/mach-omap2/pm-debug.c
> @@ -182,26 +182,33 @@ struct pm_module_def {
>  #define MOD_PRM 1
>  
>  static const struct pm_module_def pm_dbg_reg_modules[] = {
> +     { "IVA2", MOD_CM, OMAP3430_IVA2_MOD, 0, 0x4c },
>       { "OCP", MOD_CM, OCP_MOD, 0, 0x10 },
>       { "MPU", MOD_CM, MPU_MOD, 4, 0x4c },
>       { "CORE", MOD_CM, CORE_MOD, 0, 0x4c },
> -     { "NEON", MOD_CM, OMAP3430_NEON_MOD, 0x20, 0x48 },
> +     { "SGX", MOD_CM, OMAP3430ES2_SGX_MOD, 0, 0x4c },
>       { "WKUP", MOD_CM, WKUP_MOD, 0, 0x40 },
> -     { "EMU", MOD_CM, OMAP3430_EMU_MOD, 0x40, 0x54 },
>       { "CCR", MOD_CM, PLL_MOD, 0, 0x70 },
>       { "DSS", MOD_CM, OMAP3430_DSS_MOD, 0, 0x4c },
> +     { "CAM", MOD_CM, OMAP3430_CAM_MOD, 0, 0x4c },
>       { "PER", MOD_CM, OMAP3430_PER_MOD, 0, 0x4c },
> +     { "EMU", MOD_CM, OMAP3430_EMU_MOD, 0x40, 0x54 },
> +     { "NEON", MOD_CM, OMAP3430_NEON_MOD, 0x20, 0x48 },
>       { "USB", MOD_CM, OMAP3430ES2_USBHOST_MOD, 0, 0x4c },
>  
> -     { "OCP", MOD_PRM, OCP_MOD, 0x1c },
> +     { "IVA2", MOD_PRM, OMAP3430_IVA2_MOD, 0x50, 0xfc },
> +     { "OCP", MOD_PRM, OCP_MOD, 4, 0x1c },
>       { "MPU", MOD_PRM, MPU_MOD, 0x58, 0xe8 },
>       { "CORE", MOD_PRM, CORE_MOD, 0x58, 0xf8 },
> -     { "NEON", MOD_PRM, OMAP3430_NEON_MOD, 0x58, 0xe8 },
> +     { "SGX", MOD_PRM, OMAP3430ES2_SGX_MOD, 0x58, 0xe8 },
>       { "WKUP", MOD_PRM, WKUP_MOD, 0xa0, 0xb0 },
> -     { "EMU", MOD_PRM, OMAP3430_EMU_MOD, 0x58, 0xe4 },
>       { "CCR", MOD_PRM, PLL_MOD, 0x40, 0x70 },
>       { "DSS", MOD_PRM, OMAP3430_DSS_MOD, 0x58, 0xe8 },
> +     { "CAM", MOD_PRM, OMAP3430_CAM_MOD, 0x58, 0xe8 },
>       { "PER", MOD_PRM, OMAP3430_PER_MOD, 0x58, 0xe8 },
> +     { "EMU", MOD_PRM, OMAP3430_EMU_MOD, 0x58, 0xe4 },
> +     { "GLBL", MOD_PRM, OMAP3430_GR_MOD, 0x20, 0xe4 },
> +     { "NEON", MOD_PRM, OMAP3430_NEON_MOD, 0x58, 0xe8 },
>       { "USB", MOD_PRM, OMAP3430ES2_USBHOST_MOD, 0x58, 0xe8 },
>       { "", 0, 0, 0, 0 },
>  };
> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
> index c4afa7d..3c62b68 100755
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -75,6 +75,8 @@ void (*_omap_sram_idle)(u32 *addr, int save_state);
>  static void (*saved_idle)(void);
>  
>  static struct powerdomain *mpu_pwrdm;
> +static struct powerdomain *core_pwrdm;
> +static struct powerdomain *per_pwrdm;
>  
>  /* XXX This is for gpio fclk hack. Will be removed as gpio driver
>   * handles fcks correctly */
> @@ -235,6 +237,8 @@ void omap_sram_idle(void)
>       /* save_state = 2 => Only L2 lost */
>       /* save_state = 3 => L1, L2 and logic lost */
>       int save_state = 0, mpu_next_state;
> +     int save_core;
> +     int save_per;
>  
>       if (!_omap_sram_idle)
>               return;
> @@ -255,17 +259,26 @@ void omap_sram_idle(void)
>               return;
>       }
>  
> -     omap3_save_core_ctx();
> -     omap3_save_prcm_ctx();
> +     save_core = (pwrdm_read_next_pwrst(core_pwrdm) == PWRDM_POWER_OFF);
> +     save_per = (pwrdm_read_next_pwrst(per_pwrdm) ==
> PWRDM_POWER_OFF);

Just read next states here.

> +
> +     if (save_core) {
> +             omap3_save_core_ctx();
> +             omap3_save_prcm_ctx();
> +     }

And do this if core next_st < PWRDM_POWER_ON

> +
> +     if (save_per)
> +             omap3_save_per_ctx();

And same here. Additionally, do this only if core next_st <
PWRDM_POWER_ON.

>  
> -     omap3_save_per_ctx();
>       omap2_gpio_prepare_for_retention();
>  
>       /* XXX This is for gpio fclk hack. Will be removed as gpio driver
>        * handqles fcks correctly */
>       per_gpio_clk_disable();
>  
> -     omap_save_uart_ctx();
> +     if (save_per)
> +             omap_save_uart_ctx();

Again, do this only if core next_st < PWRDM_POWER_ON and per next_st ==
PWRDM_POWER_OFF.

> +
>       omap_serial_enable_clocks(0);

Consider Rajendras idea to do this only if needed.

>  
>       *(scratchpad_restore_addr) = restore_pointer_address;
> @@ -277,19 +290,24 @@ void omap_sram_idle(void)
>       if (pwrdm_read_prev_pwrst(mpu_pwrdm) == 0x0)
>               restore_table_entry();
>  
> -     omap3_restore_prcm_ctx();
> -     omap3_restore_sram_ctx();
> -     omap3_restore_core_ctx();
> +     if (save_core) {
> +             omap3_restore_prcm_ctx();
> +             omap3_restore_sram_ctx();
> +             omap3_restore_core_ctx();
> +     }
>  
>       omap_serial_enable_clocks(1); /* Causes crash with CORE off */
>  
> -     omap_restore_uart_ctx();
> +     if (save_per)
> +             omap_restore_uart_ctx();
>  
>       /* XXX This is for gpio fclk hack. Will be removed as gpio driver
>        * handles fcks correctly */
>  
>       per_gpio_clk_enable();
> -     omap3_restore_per_ctx();
> +
> +     if (save_per)
> +             omap3_restore_per_ctx();
>  
>       omap2_gpio_resume_after_retention();

Same comments to restore part as before wfi. I think you should look
at what Rajendra has done (logic in omap3_enter_idle). You might also
want to look at previous discussion related to this. Something like this:

void omap_sram_idle(void)
{
        /* Variable to tell what needs to be saved and restored
         * in omap_sram_idle*/
        /* save_state = 0 => Nothing to save and restored */
        /* save_state = 1 => Only L1 and logic lost */
        /* save_state = 2 => Only L2 lost */
        /* save_state = 3 => L1, L2 and logic lost */
        int save_state = 0;
        int mpu_next_state = PWRDM_POWER_ON, core_next_state = PWRDM_POWER_ON,
                per_next_state = PWRDM_POWER_ON;
        int neon_state;

        if (!_omap_sram_idle)
                return;

        mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
        switch (mpu_next_state) {
        case PWRDM_POWER_ON:
        case PWRDM_POWER_RET:
                /* No need to save context */
                save_state = 0;
                break;
        case PWRDM_POWER_OFF:
                save_state = 3;
                break;
        default:
                /* Invalid state */
                printk(KERN_ERR "Invalid mpu state in sram_idle\n");
                return;
        }

        pm_dbg_pre_suspend();

        /* NEON control */
        if (mpu_next_state < PWRDM_POWER_ON) {
                neon_state = pwrdm_read_pwrst(neon_pwrdm);
                if (neon_state == PWRDM_POWER_ON)
                        pwrdm_set_next_pwrst(neon_pwrdm, mpu_next_state);
        }

        /* CORE & PER */
        core_next_state = pwrdm_read_next_pwrst(core_pwrdm);
        if (core_next_state < PWRDM_POWER_ON) {
                /* PER changes only with core */
                per_next_state = pwrdm_read_next_pwrst(per_pwrdm);
                if (per_next_state < PWRDM_POWER_ON) {
                        if (per_next_state == PWRDM_POWER_OFF) {
                                omap3_save_per_ctx();
                                /* This would be actually more effective */
                                /* omap_save_uart_ctx(2); */
                        }
                        if (clocks_off_while_idle)
                                per_gpio_clk_disable();
                        /* This would be actually more effective */
                        /* omap_serial_enable_clocks(0, 2); */
                }
                if (core_next_state == PWRDM_POWER_OFF) {
                        omap3_save_core_ctx();
                        omap3_save_prcm_ctx();
                        /* omap_save_uart_ctx(2); */
                        /* omap_save_uart_ctx(2); */
                }
                if (core_next_state == PWRDM_POWER_OFF || per_next_state == 
PWRDM_POWER_OFF)
                        omap_save_uart_ctx();
                if (clocks_off_while_idle)
                        omap_serial_enable_clocks(0);
                /* omap_serial_enable_clocks(0, 2); */
                /* omap_serial_enable_clocks(0, 2); */
                
        }

        /* Is this related to per transition or transition in general? */
        omap2_gpio_prepare_for_retention();

        *(scratchpad_restore_addr) = restore_pointer_address;

        _omap_sram_idle(context_mem, save_state);

        *(scratchpad_restore_addr) = 0x0;

        if (pwrdm_read_prev_pwrst(mpu_pwrdm) == 0x0)
                restore_table_entry();
        
        if (core_next_state < PWRDM_POWER_ON) {
                if (core_next_state == PWRDM_POWER_OFF) {
                        omap3_restore_core_ctx();
                        omap3_restore_sram_ctx();
                        omap3_restore_prcm_ctx();
                        /* omap_restore_uart_ctx(0); */
                        /* omap_restore_uart_ctx(1); */
                }
                if (per_next_state < PWRDM_POWER_ON) {
                        if (per_next_state == PWRDM_POWER_OFF) {
                                omap3_restore_per_ctx();
                                /* This would be actually more effective */
                                /* omap_restore_uart_ctx(2); */
                        }
                        if (clocks_off_while_idle) {
                                per_gpio_clk_enable();
                                /* This would be actually more effective */
                                /* omap_serial_enable_clocks(0, 2); */
                        }
                }
                if (core_next_state == PWRDM_POWER_OFF || per_next_state == 
PWRDM_POWER_OFF)
                        omap_restore_uart_ctx();
                if (clocks_off_while_idle)
                        omap_serial_enable_clocks(1);
                /* omap_serial_enable_clocks(1, 0); */
                /* omap_serial_enable_clocks(1, 1); */
        }

        omap2_gpio_resume_after_retention();

        pm_dbg_post_suspend();
}


>  }
> @@ -718,10 +736,13 @@ int __init omap3_pm_init(void)
>       }
>  
>       mpu_pwrdm = pwrdm_lookup("mpu_pwrdm");
> +     core_pwrdm = pwrdm_lookup("core_pwrdm");
> +     per_pwrdm = pwrdm_lookup("per_pwrdm");
>       neon_pwrdm = pwrdm_lookup("neon_pwrdm");
>  
> -     if (mpu_pwrdm == NULL || neon_pwrdm == NULL) {
> -             printk(KERN_ERR "Failed to get mpu_pwrdm or neon_pwrdm\n");
> +     if (mpu_pwrdm == NULL || neon_pwrdm == NULL || per_pwrdm == NULL ||
> +                     core_pwrdm == NULL) {
> +             printk(KERN_ERR "Failed to get pwrdm pointers\n");

Neon handling is missing.

>               goto err2;
>       }
>  
> -- 
> 1.5.4.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to [EMAIL PROTECTED]
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>

-- 
Jouni Högander

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to