Re: [PATCH 06/12] arm: omap3: am35x: Add full PWRDM_POWER_INACTIVE support

Jean Pihet
2012-04-11T20:56:01Z

Hi Mark,

On Wed, Apr 11, 2012 at 9:05 PM, Mark A. Greer <mgreer@animalcreek.com> wrote:
> From: "Mark A. Greer" <mgreer@animalcreek.com>
>
> The am35x family of SoCs only support PWRDM_POWER_ON
> and PWRDM_POWER_INACTIVE power states. This causes
> an issue in some areas of the OMAP3 power-related
> code because of assumptions that PWRDM_POWER_RET
> and/or PWRDM_POWER_OFF are always valid states.
>
> To get am35x SoCs to work properly, add missing support
> for PWRDM_POWER_INACTIVE and remove assumptions that
> PWRDM_POWER_RET and PWRDM_POWER_OFF are always valid states.
>
> Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>

I just posted a patch set '[RFC/PATCH v2 0/6] ARM: OMAP2+: PM:
introduce the power domains functional states' [1] which I think
should be used to base your patches on. This patch set introduces
functional states for the power domains power ans logic states, and
the conversion functions between the internal power and logic states
and the functional states.

I would be glad to help on the AM35x support for the functional states.

What do you think?

[1] http://marc.info/?l=linux-omap&m=133417729712693&w=2

Regards,
Jean

> ---
>  arch/arm/mach-omap2/cpuidle34xx.c |   29 +++++++++++++++++++++++--
>  arch/arm/mach-omap2/pm-debug.c    |    8 +++++--
>  arch/arm/mach-omap2/pm34xx.c      |   43 +++++++++++++++++++++++--------------
>  3 files changed, 60 insertions(+), 20 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
> index 12cf81d..187872a 100644
> --- a/arch/arm/mach-omap2/cpuidle34xx.c
> +++ b/arch/arm/mach-omap2/cpuidle34xx.c
> @@ -175,12 +175,23 @@ static int next_valid_state(struct cpuidle_device *dev,
>        struct cpuidle_state_usage *curr_usage = &dev->states_usage[index];
>        struct cpuidle_state *curr = &drv->states[index];
>        struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr_usage);
> -       u32 mpu_deepest_state = PWRDM_POWER_RET;
> -       u32 core_deepest_state = PWRDM_POWER_RET;
> +       u32 mpu_deepest_state;
> +       u32 core_deepest_state;
>        int next_index = -1;
>
> +       if (omap3_has_pwroff()) {
> +               mpu_deepest_state = PWRDM_POWER_RET;
> +               core_deepest_state = PWRDM_POWER_RET;
> +       } else {
> +               mpu_deepest_state = PWRDM_POWER_INACTIVE;
> +               core_deepest_state = PWRDM_POWER_INACTIVE;
> +       }
> +
>        if (enable_off_mode) {
> +               WARN_ON(!omap3_has_pwroff());
> +
>                mpu_deepest_state = PWRDM_POWER_OFF;
> +
>                /*
>                 * Erratum i583: valable for ES rev < Es1.2 on 3630.
>                 * CORE OFF mode is not supported in a stable form, restrict
> @@ -311,6 +322,9 @@ void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params)
>                        cpuidle_board_params[i].exit_latency;
>                cpuidle_params_table[i].target_residency =
>                        cpuidle_board_params[i].target_residency;
> +
> +               WARN_ON(!omap3_has_pwroff() && (i >= 2) &&
> +                               cpuidle_params_table[i].valid);
>        }
>        return;
>  }
> @@ -349,6 +363,16 @@ static inline struct omap3_idle_statedata *_fill_cstate_usage(
>        return cx;
>  }
>
> +/* Only C1 & C2 C states valid when RET & OFF states aren't supported */
> +static void omap3_cstate_valid_fixup(void)
> +{
> +       int idx;
> +
> +       if (!omap3_has_pwroff())
> +               for (idx = 2; idx < OMAP3_NUM_STATES; idx++)
> +                       cpuidle_params_table[idx].valid = 0;
> +}
> +
>  /**
>  * omap3_idle_init - Init routine for OMAP3 idle
>  *
> @@ -366,6 +390,7 @@ int __init omap3_idle_init(void)
>        per_pd = pwrdm_lookup("per_pwrdm");
>        cam_pd = pwrdm_lookup("cam_pwrdm");
>
> +       omap3_cstate_valid_fixup();
>
>        drv->safe_state_index = -1;
>        dev = &per_cpu(omap3_idle_dev, smp_processor_id());
> diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
> index 814bcd9..339ed42 100644
> --- a/arch/arm/mach-omap2/pm-debug.c
> +++ b/arch/arm/mach-omap2/pm-debug.c
> @@ -239,19 +239,23 @@ static int option_get(void *data, u64 *val)
>  static int option_set(void *data, u64 val)
>  {
>        u32 *option = data;
> +       int ret = -EINVAL;
>
>        *option = val;
>
> -       if (option == &enable_off_mode) {
> +       if (omap3_has_pwroff() && (option == &enable_off_mode)) {
>                if (val)
>                        omap_pm_enable_off_mode();
>                else
>                        omap_pm_disable_off_mode();
> +
>                if (cpu_is_omap34xx())
>                        omap3_pm_off_mode_enable(val);
> +
> +               ret = 0;
>        }
>
> -       return 0;
> +       return ret;
>  }
>
>  DEFINE_SIMPLE_ATTRIBUTE(pm_dbg_option_fops, option_get, option_set, "%llu\n");
> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
> index b7bbcee..00c4abe 100644
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -279,6 +279,7 @@ void omap_sram_idle(void)
>        mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
>        switch (mpu_next_state) {
>        case PWRDM_POWER_ON:
> +       case PWRDM_POWER_INACTIVE:
>        case PWRDM_POWER_RET:
>                /* No need to save context */
>                save_state = 0;
> @@ -614,6 +615,8 @@ void omap3_pm_off_mode_enable(int enable)
>        struct power_state *pwrst;
>        u32 state;
>
> +       WARN_ON(!omap3_has_pwroff());
> +
>        if (enable)
>                state = PWRDM_POWER_OFF;
>        else
> @@ -668,7 +671,12 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
>        if (!pwrst)
>                return -ENOMEM;
>        pwrst->pwrdm = pwrdm;
> -       pwrst->next_state = PWRDM_POWER_RET;
> +
> +       if (omap3_has_pwroff())
> +               pwrst->next_state = PWRDM_POWER_RET;
> +       else
> +               pwrst->next_state = PWRDM_POWER_INACTIVE;
> +
>        list_add(&pwrst->node, &pwrst_list);
>
>        if (pwrdm_has_hdwr_sar(pwrdm))
> @@ -781,25 +789,28 @@ static int __init omap3_pm_init(void)
>                omap3630_ctrl_disable_rta();
>
>        clkdm_add_wkdep(neon_clkdm, mpu_clkdm);
> -       if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
> -               omap3_secure_ram_storage =
> -                       kmalloc(0x803F, GFP_KERNEL);
> -               if (!omap3_secure_ram_storage)
> -                       pr_err("Memory allocation failed when "
> -                              "allocating for secure sram context\n");
>
> -               local_irq_disable();
> -               local_fiq_disable();
> +       if (omap3_has_pwroff()) {
> +               if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
> +                       omap3_secure_ram_storage =
> +                               kmalloc(0x803F, GFP_KERNEL);
> +                       if (!omap3_secure_ram_storage)
> +                               pr_err("Memory allocation failed when "
> +                                      "allocating for secure sram context\n");
>
> -               omap_dma_global_context_save();
> -               omap3_save_secure_ram_context();
> -               omap_dma_global_context_restore();
> +                       local_irq_disable();
> +                       local_fiq_disable();
>
> -               local_irq_enable();
> -               local_fiq_enable();
> -       }
> +                       omap_dma_global_context_save();
> +                       omap3_save_secure_ram_context();
> +                       omap_dma_global_context_restore();
> +
> +                       local_irq_enable();
> +                       local_fiq_enable();
>
> -       omap3_save_scratchpad_contents();
> +                       omap3_save_scratchpad_contents();
> +               }
> +       }
>        return ret;
>
>  err3:
> --
> 1.7.9.4
>
> --
> 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
--
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