[PATCH 06/12] ARM: OMAP44xx: PM: convert to use the functional power states API
Jean Pihet
jean.pihet at newoldbits.com
Wed Dec 12 05:41:12 EST 2012
Paul,
On Sun, Dec 9, 2012 at 6:53 PM, Paul Walmsley <paul at pwsan.com> wrote:
> From: Jean Pihet <jean.pihet at newoldbits.com>
>
> Use the functional power states as the API to control power
> domains:
> - use the PWRDM_FUNC_PWRST_* and PWRDM_LOGIC_MEM_PWRST_*
> macros for the power states and logic settings,
> - the function pwrdm_set_next_fpwrst, which controls
> the power domains next power and logic settings, shall
> be used instead of pwrdm_set_next_pwrst to program the
> power domains next states,
> - the function pwrdm_set_fpwrst, which programs the power
> domains power and logic settings, shall be used instead
> of omap_set_pwrdm_state.
>
> Signed-off-by: Jean Pihet <j-pihet at ti.com>
> [paul at pwsan.com: split the original patch into OMAP2/3/4 variants;
> warn if sets fail; various other changes]
> Signed-off-by: Paul Walmsley <paul at pwsan.com>
> ---
> arch/arm/mach-omap2/common.h | 7 +--
> arch/arm/mach-omap2/cpuidle44xx.c | 32 +++++--------
> arch/arm/mach-omap2/omap-hotplug.c | 2 -
> arch/arm/mach-omap2/omap-mpuss-lowpower.c | 69 +++++++++++++++++------------
> arch/arm/mach-omap2/pm44xx.c | 42 +++++++++---------
> 5 files changed, 79 insertions(+), 73 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
> index c57eeea..5ad846a 100644
> --- a/arch/arm/mach-omap2/common.h
> +++ b/arch/arm/mach-omap2/common.h
> @@ -235,14 +235,13 @@ extern void omap5_secondary_startup(void);
>
> #if defined(CONFIG_SMP) && defined(CONFIG_PM)
> extern int omap4_mpuss_init(void);
> -extern int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state);
> +extern int omap4_mpuss_enter_lowpower(unsigned int cpu, u8 fpwrst);
> extern int omap4_finish_suspend(unsigned long cpu_state);
> extern void omap4_cpu_resume(void);
> -extern int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state);
> +extern int omap4_mpuss_hotplug_cpu(unsigned int cpu, u8 fpwrst);
> extern u32 omap4_mpuss_read_prev_context_state(void);
> #else
> -static inline int omap4_enter_lowpower(unsigned int cpu,
> - unsigned int power_state)
> +static inline int omap4_mpuss_enter_lowpower(unsigned int cpu, u8 fpwrst)
> {
> cpu_do_idle();
> return 0;
> diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
> index d639aef..2cb5332 100644
> --- a/arch/arm/mach-omap2/cpuidle44xx.c
> +++ b/arch/arm/mach-omap2/cpuidle44xx.c
> @@ -25,26 +25,22 @@
>
> /* Machine specific information */
> struct omap4_idle_statedata {
> - u32 cpu_state;
> - u32 mpu_logic_state;
> - u32 mpu_state;
> + u8 cpu_pwrst;
> + u8 mpu_pwrst;
This should be cpu_fpwrst and mpu_fwprst for consistency.
> };
>
> static struct omap4_idle_statedata omap4_idle_data[] = {
> {
> - .cpu_state = PWRDM_POWER_ON,
> - .mpu_state = PWRDM_POWER_ON,
> - .mpu_logic_state = PWRDM_POWER_RET,
> + .cpu_pwrst = PWRDM_FUNC_PWRST_ON,
> + .mpu_pwrst = PWRDM_FUNC_PWRST_ON,
> },
> {
> - .cpu_state = PWRDM_POWER_OFF,
> - .mpu_state = PWRDM_POWER_RET,
> - .mpu_logic_state = PWRDM_POWER_RET,
> + .cpu_pwrst = PWRDM_FUNC_PWRST_OFF,
> + .mpu_pwrst = PWRDM_FUNC_PWRST_CSWR,
> },
> {
> - .cpu_state = PWRDM_POWER_OFF,
> - .mpu_state = PWRDM_POWER_RET,
> - .mpu_logic_state = PWRDM_POWER_OFF,
> + .cpu_pwrst = PWRDM_FUNC_PWRST_OFF,
> + .mpu_pwrst = PWRDM_FUNC_PWRST_OSWR,
> },
> };
>
> @@ -93,7 +89,7 @@ static int omap4_enter_idle_coupled(struct cpuidle_device *dev,
> * out of coherency and in OFF mode.
> */
> if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) {
> - while (pwrdm_read_pwrst(cpu_pd[1]) != PWRDM_POWER_OFF) {
> + while (pwrdm_read_fpwrst(cpu_pd[1]) != PWRDM_FUNC_PWRST_OFF) {
> cpu_relax();
>
> /*
> @@ -118,19 +114,17 @@ static int omap4_enter_idle_coupled(struct cpuidle_device *dev,
> cpu_pm_enter();
>
> if (dev->cpu == 0) {
> - pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state);
> - omap_set_pwrdm_state(mpu_pd, cx->mpu_state);
> + WARN_ON(pwrdm_set_fpwrst(mpu_pd, cx->mpu_pwrst));
>
> /*
> * Call idle CPU cluster PM enter notifier chain
> * to save GIC and wakeupgen context.
> */
> - if ((cx->mpu_state == PWRDM_POWER_RET) &&
> - (cx->mpu_logic_state == PWRDM_POWER_OFF))
> - cpu_cluster_pm_enter();
> + if (cx->mpu_pwrst == PWRDM_FUNC_PWRST_OSWR)
> + cpu_cluster_pm_enter();
> }
>
> - omap4_enter_lowpower(dev->cpu, cx->cpu_state);
> + omap4_mpuss_enter_lowpower(dev->cpu, cx->cpu_pwrst);
> cpu_done[dev->cpu] = true;
>
> /* Wakeup CPU1 only if it is not offlined */
> diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c
> index e712d17..d38b12d 100644
> --- a/arch/arm/mach-omap2/omap-hotplug.c
> +++ b/arch/arm/mach-omap2/omap-hotplug.c
> @@ -53,7 +53,7 @@ void __ref omap4_cpu_die(unsigned int cpu)
> /*
> * Enter into low power state
> */
> - omap4_hotplug_cpu(cpu, PWRDM_POWER_OFF);
> + omap4_mpuss_hotplug_cpu(cpu, PWRDM_FUNC_PWRST_OFF);
>
> if (omap_secure_apis_support())
> boot_cpu = omap_read_auxcoreboot0();
> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> index 80d4742..4dcebda 100644
> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> @@ -82,31 +82,40 @@ static inline void set_cpu_wakeup_addr(unsigned int cpu_id, u32 addr)
> {
> struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
>
> + /*
> + * XXX should not be writing directly into another IP block's
> + * address space!
> + */
> __raw_writel(addr, pm_info->wkup_sar_addr);
> }
>
> /*
> * Store the SCU power status value to scratchpad memory
> */
> -static void scu_pwrst_prepare(unsigned int cpu_id, unsigned int cpu_state)
> +static void scu_pwrst_prepare(unsigned int cpu_id, u8 fpwrst)
> {
> struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
> u32 scu_pwr_st;
>
> - switch (cpu_state) {
> - case PWRDM_POWER_RET:
> + switch (fpwrst) {
> + case PWRDM_FUNC_PWRST_CSWR:
> + case PWRDM_FUNC_PWRST_OSWR: /* XXX is this accurate? */
> scu_pwr_st = SCU_PM_DORMANT;
> break;
> - case PWRDM_POWER_OFF:
> + case PWRDM_FUNC_PWRST_OFF:
> scu_pwr_st = SCU_PM_POWEROFF;
> break;
> - case PWRDM_POWER_ON:
> - case PWRDM_POWER_INACTIVE:
> + case PWRDM_FUNC_PWRST_ON:
> + case PWRDM_FUNC_PWRST_INACTIVE:
> default:
> scu_pwr_st = SCU_PM_NORMAL;
> break;
> }
>
> + /*
> + * XXX should not be writing directly into another IP block's
> + * address space!
> + */
> __raw_writel(scu_pwr_st, pm_info->scu_sar_addr);
> }
>
> @@ -159,6 +168,10 @@ static void l2x0_pwrst_prepare(unsigned int cpu_id, unsigned int save_state)
> {
> struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
>
> + /*
> + * XXX should not be writing directly into another IP block's
> + * address space!
> + */
> __raw_writel(save_state, pm_info->l2x0_sar_addr);
> }
>
> @@ -183,11 +196,11 @@ static void save_l2x0_context(void)
> #endif
>
> /**
> - * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function
> + * omap4_mpuss_enter_lowpower: OMAP4 MPUSS Low Power Entry Function
> * The purpose of this function is to manage low power programming
> * of OMAP4 MPUSS subsystem
> * @cpu : CPU ID
> - * @power_state: Low power state.
> + * @fpwrst: functional powerstate for the MPUSS to enter
> *
> * MPUSS states for the context save:
> * save_state =
> @@ -196,7 +209,7 @@ static void save_l2x0_context(void)
> * 2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR
> * 3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF
> */
> -int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
> +int omap4_mpuss_enter_lowpower(unsigned int cpu, u8 fpwrst)
> {
> struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu);
> unsigned int save_state = 0;
> @@ -205,15 +218,16 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
> if (omap_rev() == OMAP4430_REV_ES1_0)
> return -ENXIO;
>
> - switch (power_state) {
> - case PWRDM_POWER_ON:
> - case PWRDM_POWER_INACTIVE:
> + switch (fpwrst) {
> + case PWRDM_FUNC_PWRST_ON:
> + case PWRDM_FUNC_PWRST_INACTIVE:
> save_state = 0;
> break;
> - case PWRDM_POWER_OFF:
> + case PWRDM_FUNC_PWRST_OFF:
> save_state = 1;
> break;
> - case PWRDM_POWER_RET:
> + case PWRDM_FUNC_PWRST_CSWR:
> + case PWRDM_FUNC_PWRST_OSWR:
> default:
> /*
> * CPUx CSWR is invalid hardware state. Also CPUx OSWR
> @@ -229,17 +243,16 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
>
> /*
> * Check MPUSS next state and save interrupt controller if needed.
> - * In MPUSS OSWR or device OFF, interrupt controller contest is lost.
> + * In MPUSS OSWR or device OFF, interrupt controller context is lost.
> */
> mpuss_clear_prev_logic_pwrst();
> - if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) &&
> - (pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF))
> + if (pwrdm_read_next_fpwrst(mpuss_pd) == PWRDM_FUNC_PWRST_OSWR)
> save_state = 2;
>
> cpu_clear_prev_logic_pwrst(cpu);
> - pwrdm_set_next_pwrst(pm_info->pwrdm, power_state);
> + WARN_ON(pwrdm_set_next_fpwrst(pm_info->pwrdm, fpwrst));
> set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume));
> - scu_pwrst_prepare(cpu, power_state);
> + scu_pwrst_prepare(cpu, fpwrst);
> l2x0_pwrst_prepare(cpu, save_state);
>
> /*
> @@ -255,7 +268,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
> * domain transition
> */
> wakeup_cpu = smp_processor_id();
> - pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
> + WARN_ON(pwrdm_set_next_fpwrst(pm_info->pwrdm, PWRDM_FUNC_PWRST_ON));
>
> pwrdm_post_transition(NULL);
>
> @@ -265,9 +278,9 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
> /**
> * omap4_hotplug_cpu: OMAP4 CPU hotplug entry
> * @cpu : CPU ID
> - * @power_state: CPU low power state.
> + * @fpwrst: functional power state to program the CPU powerdomain to enter
> */
> -int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
> +int __cpuinit omap4_mpuss_hotplug_cpu(unsigned int cpu, u8 fpwrst)
> {
> struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu);
> unsigned int cpu_state = 0;
> @@ -275,13 +288,13 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
> if (omap_rev() == OMAP4430_REV_ES1_0)
> return -ENXIO;
>
> - if (power_state == PWRDM_POWER_OFF)
> + if (fpwrst == PWRDM_FUNC_PWRST_OFF || fpwrst == PWRDM_FUNC_PWRST_OSWR)
> cpu_state = 1;
>
> pwrdm_clear_all_prev_pwrst(pm_info->pwrdm);
> - pwrdm_set_next_pwrst(pm_info->pwrdm, power_state);
> + WARN_ON(pwrdm_set_next_fpwrst(pm_info->pwrdm, fpwrst));
> set_cpu_wakeup_addr(cpu, virt_to_phys(omap_secondary_startup));
> - scu_pwrst_prepare(cpu, power_state);
> + scu_pwrst_prepare(cpu, fpwrst);
>
> /*
> * CPU never retuns back if targeted power state is OFF mode.
> @@ -290,7 +303,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
> */
> omap4_finish_suspend(cpu_state);
>
> - pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
> + WARN_ON(pwrdm_set_next_fpwrst(pm_info->pwrdm, PWRDM_FUNC_PWRST_ON));
> return 0;
> }
>
> @@ -325,7 +338,7 @@ int __init omap4_mpuss_init(void)
> cpu_clear_prev_logic_pwrst(0);
>
> /* Initialise CPU0 power domain state to ON */
> - pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
> + WARN_ON(pwrdm_set_next_fpwrst(pm_info->pwrdm, PWRDM_FUNC_PWRST_ON));
>
> pm_info = &per_cpu(omap4_pm_info, 0x1);
> pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;
> @@ -342,7 +355,7 @@ int __init omap4_mpuss_init(void)
> cpu_clear_prev_logic_pwrst(1);
>
> /* Initialise CPU1 power domain state to ON */
> - pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
> + WARN_ON(pwrdm_set_next_fpwrst(pm_info->pwrdm, PWRDM_FUNC_PWRST_ON));
>
> mpuss_pd = pwrdm_lookup("mpu_pwrdm");
> if (!mpuss_pd) {
> diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
> index 7da75ae..595f84e 100644
> --- a/arch/arm/mach-omap2/pm44xx.c
> +++ b/arch/arm/mach-omap2/pm44xx.c
> @@ -26,10 +26,9 @@
>
> struct power_state {
> struct powerdomain *pwrdm;
> - u32 next_state;
> + u8 next_fpwrst;
> #ifdef CONFIG_SUSPEND
> - u32 saved_state;
> - u32 saved_logic_state;
> + u8 saved_fpwrst;
> #endif
> struct list_head node;
> };
> @@ -40,20 +39,19 @@ static LIST_HEAD(pwrst_list);
> static int omap4_pm_suspend(void)
> {
> struct power_state *pwrst;
> - int state, ret = 0;
> + int prev_fpwrst;
> + int ret = 0;
> u32 cpu_id = smp_processor_id();
>
> + /* XXX Seems like these two loops could be combined into one loop? */
> +
> /* Save current powerdomain state */
> - list_for_each_entry(pwrst, &pwrst_list, node) {
> - pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm);
> - pwrst->saved_logic_state = pwrdm_read_logic_retst(pwrst->pwrdm);
> - }
> + list_for_each_entry(pwrst, &pwrst_list, node)
> + pwrst->saved_fpwrst = pwrdm_read_next_fpwrst(pwrst->pwrdm);
>
> /* Set targeted power domain states by suspend */
> - list_for_each_entry(pwrst, &pwrst_list, node) {
> - omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
> - pwrdm_set_logic_retst(pwrst->pwrdm, PWRDM_POWER_OFF);
> - }
> + list_for_each_entry(pwrst, &pwrst_list, node)
> + WARN_ON(pwrdm_set_fpwrst(pwrst->pwrdm, pwrst->next_fpwrst));
>
> /*
> * For MPUSS to hit power domain retention(CSWR or OSWR),
> @@ -64,18 +62,20 @@ static int omap4_pm_suspend(void)
> * domain CSWR is not supported by hardware.
> * More details can be found in OMAP4430 TRM section 4.3.4.2.
> */
> - omap4_enter_lowpower(cpu_id, PWRDM_POWER_OFF);
> + omap4_mpuss_enter_lowpower(cpu_id, PWRDM_FUNC_PWRST_OFF);
>
> /* Restore next powerdomain state */
> list_for_each_entry(pwrst, &pwrst_list, node) {
> - state = pwrdm_read_prev_pwrst(pwrst->pwrdm);
> - if (state > pwrst->next_state) {
> - pr_info("Powerdomain (%s) didn't enter target state %d\n",
> - pwrst->pwrdm->name, pwrst->next_state);
> + prev_fpwrst = pwrdm_read_prev_fpwrst(pwrst->pwrdm);
> + /* XXX test below should be != */
Is a change needed here?
> + if (prev_fpwrst > pwrst->next_fpwrst) {
> + pr_info("Powerdomain (%s) didn't enter target state %s - entered state %s instead\n",
> + pwrst->pwrdm->name,
> + pwrdm_convert_fpwrst_to_name(pwrst->next_fpwrst),
> + pwrdm_convert_fpwrst_to_name(prev_fpwrst));
> ret = -1;
> }
> - omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
> - pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->saved_logic_state);
> + WARN_ON(pwrdm_set_fpwrst(pwrst->pwrdm, pwrst->saved_fpwrst));
> }
> if (ret)
> pr_crit("Could not enter target state in pm_suspend\n");
> @@ -113,10 +113,10 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
> return -ENOMEM;
>
> pwrst->pwrdm = pwrdm;
> - pwrst->next_state = PWRDM_POWER_RET;
> + pwrst->next_fpwrst = PWRDM_FUNC_PWRST_CSWR;
> list_add(&pwrst->node, &pwrst_list);
>
> - return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
> + return WARN_ON(pwrdm_set_fpwrst(pwrst->pwrdm, pwrst->next_fpwrst));
> }
>
> /**
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
Regards,
Jean
More information about the linux-arm-kernel
mailing list