Topics

RFC: 3/5 Provide a Mechanism to enter CPU to Low Power State


Thomas, Ramesh
 

Problem Statement:
Zephyr needs to provide an architecture independent method for power
management application to invoke a low power state on the CPU.

Why this is a problem:
-----------------------------
LPS state transition operations impact kernel idle logic e.g. interrupts
need to be atomically enabled before entering CPU low power idle state.
Power Management Application policy enforcement requires that code to be
easily ported/reused across architectures.

What should be done:
-----------------------------
At the arch specific regions in the kernel, provide API to transition to
LPS for each architecture.
Kernel dependent operations like atomically enabling interrupts should
be done in this API.

Key
----
PMA: Power Manager Application
ISR: Interrupt Service Routine

Proposed PMA Low Power State Entry Flow:
+---------+ +-----+ +---------+ +-----+
| Events | | ISR | | Kernel | | PMA |
+---------+ +-----+ +---------+ +-----+
| | | ----------\ |
| | |-| Compute | |
| | | | idle | |
| | | | ticks | |
| | | |---------| |
| | | -----------\ |
| | |-| Schedule | |
| | | | next | |
| | | | event | |
| | | |----------| |
| | | |
| | | _sys_soc_suspend(ticks) |
| | |--------------------------->|
| | | -----------\ |
| | | | Select |-|
| | | | policy | |
| | | | based on | |
| | | | ticks | |
| | | |----------| |
| | | -----------\ |
| | | | Execute |-|
| | | | LPS | |
| | | | entry | |
| | | | policies | |
| | | |----------| |
| | | |
| | | _sys_soc_push_LPS() |
| | |<---------------------------|
| | | |
| | | CPU LPS |
| | | wait |
| | |-------- |
| | | | |
| | |<------- |
| | | |


Proposed PMA Low Power State Exit Flow:
+---------+ +-----+ +---------+ +-----+
| Events | | ISR | | Kernel | | PMA |
+---------+ +-----+ +---------+ +-----+
| | | |
| intr | | |
|-------->| | |
| | | |
| | process interrupt | |
| |----------------------->| |
| | | |
| | | _sys_soc_resume() |
| | |----------------------->|
| | | ----------\ |
| | | | Execute |-|
| | | | LPS | |
| | | | exit | |
| | | | policy | |
| | | |---------| |
| | | |
| | | return to kernel |
| | |<-----------------------|
| | | |
| | return to ISR | |
| |<-----------------------| |
| | -------------\ | |
| |-| re-compute | | |
| | | Tickless | | |
| | | timeouts | | |
| | |------------| | |
| | -----------\ | |
| |-| schedule | | |
| | | next | | |
| | | task | | |
| | |----------| | |
| | | --------------\ |
| | |-| next kernel | |
| | | | idle | |
| | | |-------------| |
| | | |
| | | prior call to |
| | | _sys_soc_push_LPS() |
| | | returns |
| | |----------------------->|
| | | |
| | | prior call to |
| | | _sys_soc_suspend() |
| | | returns PM_SOC_LPS |
| | |<-----------------------|
| | | |