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

Santosh santosh.shilimkar at ti.com
Fri Sep 9 05:59:47 EDT 2011


On Friday 09 September 2011 01:09 AM, Jean Pihet wrote:
> 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.
>
Will add that comment.

Regards
Santosh



More information about the linux-arm-kernel mailing list