[PATCH 14/25] OMAP4: PM: Add CPUX OFF mode support

Jean Pihet jean.pihet at newoldbits.com
Thu Sep 8 15:39:28 EDT 2011


On Sun, Sep 4, 2011 at 3:54 PM, Santosh Shilimkar
<santosh.shilimkar at ti.com> wrote:
> This patch adds the CPU0 and CPU1 off mode support. CPUX close switch
> retention (CSWR) is not supported by hardware design.
>
> The CPUx OFF mode isn't supported on OMAP4430 ES1.0
>
> CPUx sleep code is common for hotplug, suspend and CPUilde.
>
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar at ti.com>
> Cc: Kevin Hilman <khilman at ti.com>
> ---
>  arch/arm/mach-omap2/Makefile                    |    3 +-
>  arch/arm/mach-omap2/include/mach/omap-secure.h  |    8 +
>  arch/arm/mach-omap2/include/mach/omap4-common.h |   25 +++
>  arch/arm/mach-omap2/omap-mpuss-lowpower.c       |  249 +++++++++++++++++++++++
>  arch/arm/mach-omap2/omap-smp.c                  |    6 +
>  arch/arm/mach-omap2/omap4-sar-layout.h          |    9 +
>  arch/arm/mach-omap2/pm44xx.c                    |    6 +
>  arch/arm/mach-omap2/sleep44xx.S                 |  213 +++++++++++++++++++
>  8 files changed, 518 insertions(+), 1 deletions(-)
>  create mode 100644 arch/arm/mach-omap2/omap-mpuss-lowpower.c
>
> diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
> index b032c21..b4f2eeb 100644
> --- a/arch/arm/mach-omap2/Makefile
> +++ b/arch/arm/mach-omap2/Makefile
> @@ -63,7 +63,8 @@ obj-$(CONFIG_ARCH_OMAP2)              += pm24xx.o
>  obj-$(CONFIG_ARCH_OMAP2)               += sleep24xx.o
>  obj-$(CONFIG_ARCH_OMAP3)               += pm34xx.o sleep34xx.o \
>                                           cpuidle34xx.o
> -obj-$(CONFIG_ARCH_OMAP4)               += pm44xx.o sleep44xx.o
> +obj-$(CONFIG_ARCH_OMAP4)               += pm44xx.o sleep44xx.o \
> +                                          omap-mpuss-lowpower.o
>  obj-$(CONFIG_PM_DEBUG)                 += pm-debug.o
>  obj-$(CONFIG_OMAP_SMARTREFLEX)          += sr_device.o smartreflex.o
>  obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3)  += smartreflex-class3.o
> diff --git a/arch/arm/mach-omap2/include/mach/omap-secure.h b/arch/arm/mach-omap2/include/mach/omap-secure.h
> index e2f95a0..0062d49 100644
> --- a/arch/arm/mach-omap2/include/mach/omap-secure.h
> +++ b/arch/arm/mach-omap2/include/mach/omap-secure.h
> @@ -35,10 +35,18 @@
>  #define OMAP4_HAL_SAVEALL_INDEX                0x1c
>  #define OMAP4_HAL_SAVEGIC_INDEX                0x1d
>
> +/* Secure Monitor mode APIs */
> +#define OMAP4_MON_SCU_PWR_INDEX                0x108
> +
> +/* Secure PPA(Primary Protected Application) APIs */
> +#define OMAP4_PPA_CPU_ACTRL_SMP_INDEX  0x25
> +
> +#ifndef __ASSEMBLER__
>  extern u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs,
>                                u32 arg1, u32 arg2, u32 arg3, u32 arg4);
>  extern u32 omap_smc2(u32 id, u32 falg, u32 pargs);
>  extern phys_addr_t omap_secure_ram_mempool_base(void);
>  extern int omap_secure_ram_reserve_memblock(void);
>
> +#endif /* __ASSEMBLER__ */
>  #endif /* OMAP_ARCH_OMAP_SECURE_H */
> diff --git a/arch/arm/mach-omap2/include/mach/omap4-common.h b/arch/arm/mach-omap2/include/mach/omap4-common.h
> index 040dcf6..662f37c 100644
> --- a/arch/arm/mach-omap2/include/mach/omap4-common.h
> +++ b/arch/arm/mach-omap2/include/mach/omap4-common.h
> @@ -45,5 +45,30 @@ extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask);
>  extern void omap_auxcoreboot_addr(u32 cpu_addr);
>  extern u32 omap_read_auxcoreboot0(void);
>  #endif
> +
> +#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_finish_suspend(unsigned long cpu_state);
> +extern void omap4_cpu_resume(void);
> +#else
> +static inline int omap4_enter_lowpower(unsigned int cpu,
> +                                       unsigned int power_state)
> +{
> +       omap_do_wfi();
> +       return 0;
> +}
> +
> +static inline int omap4_mpuss_init(void)
> +{
> +       return 0;
> +}
> +
> +static inline int omap4_finish_suspend(unsigned long cpu_state)
> +{}
The int function should return something (0?)
Has the code been test compiled without SMP and/or PM?

> +static inline void omap4_cpu_resume(void)
> +{}
> +#endif
> +
>  #endif /* __ASSEMBLER__ */
>  #endif /* OMAP_ARCH_OMAP4_COMMON_H */
> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
...

> +/**
> + * omap4_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.
> + */
> +int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
> +{
> +       unsigned int save_state = 0;
> +       unsigned int wakeup_cpu;
> +
> +       if (omap_rev() == OMAP4430_REV_ES1_0)
> +               return -ENXIO;
> +
> +       switch (power_state) {
> +       case PWRDM_POWER_ON:
> +       case PWRDM_POWER_INACTIVE:
> +               save_state = 0;
> +               break;
> +       case PWRDM_POWER_OFF:
> +               save_state = 1;
> +               break;
> +       case PWRDM_POWER_RET:
> +       default:
> +               /*
> +                * CPUx CSWR is invalid hardware state. Also CPUx OSWR
> +                * doesn't make much scense, since logic is lost and $L1
> +                * needs to be cleaned because of coherency. This makes
> +                * CPUx OSWR equivalent to CPUX OFF and hence not supported
> +                */
> +               WARN_ON(1);
> +               return -ENXIO;
> +       }
> +
> +       clear_cpu_prev_pwrst(cpu);
> +       set_cpu_next_pwrst(cpu, power_state);
> +       set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume));
> +       scu_pwrst_prepare(cpu, power_state);
> +
> +       /*
> +        * Call low level function  with targeted CPU id
> +        * and its low power state.
> +        */
> +       cpu_suspend(save_state, omap4_finish_suspend);
There is no CPU id parameter to the call although the above comment says so.

...

> diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S
...

> +/*
> + * =============================
> + * == CPU suspend finisher ==
> + * =============================
> + *
> + * void omap4_finish_suspend(unsigned long cpu_state)
> + *
> + * This function code saves the CPU context and performs the CPU
> + * power down sequence. Calling WFI effectively changes the CPU
> + * power domains states to the desired target power state.
> + *
> + * @cpu_state : contains context save state (r0)
> + *     0 - No context lost
> + *     1 - CPUx L1 and logic lost: MPUSS CSWR
> + *     2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR
> + *     3 - CPUx L1 and logic lost + GIC + L2 lost: MPUSS OFF
> + * @return: This function never returns for CPU OFF and DORMANT power states.
> + * Post WFI, CPU transitions to DORMANT or OFF power state and on wake-up
> + * from this follows a full CPU reset path via ROM code to CPU restore code.
Is the ROM code jumping to the physical address of omap4_cpu_resume?
If so please add it in the comment.

...

> +/*
> + * ============================
> + * == CPU resume entry point ==
> + * ============================
> + *
> + * void omap4_cpu_resume(void)
> + *
> + * ROM code jumps to this function while waking up from CPU
> + * OFF or DORMANT state. Physical address of the function is
> + * stored in the SAR RAM while entering to OFF or DORMANT mode.
Which code stores the address in the SAR RAM? Please describe it here.

> + */
> +ENTRY(omap4_cpu_resume)
> +       /*
...

Regards,
Jean



More information about the linux-arm-kernel mailing list