Power Domain Framework
The Power Domain Framework is an important component in the overall Power Management Frameworks. It comprises of all the various power domain structures supported for the active SOCs.
Each power domain can have one or multiple clock domains which in turn are the host to various clocks. The Power domain management is the highest level of control available to transition the system level components.
The power domain can transition to a low power state only if all the clock domains registered for it have transitioned to a low power state. Current power domain framework needs a bit of a revamp and the proposal for the same has been mentioned under the head of Power Domain Cleanup.
 Clock Domain Framework
The clock domain framework is the next important framework following the power domain framework. It comprises of all the various clock domain structures supported for the active SOCs.
Each clock domain can have one or multiple clocks which can be enabled or disabled individually.
The clock domain can transition to low power state only if all the clocks registered for it are disabled. Also there are Clock Domain Dependencies between various clock domains which determine the sleep and wakeup conditions for the given clock domain. Current clock domain framework needs a bit of a revamp and the proposal for the same has been mentioned under the head of Clock Domain Cleanup.
 Features under Development
 Power Domain Cleanup - The Approach
The following two phase approach is adopted for power domain cleanup
- Phase 1
- Clean up instances of usage of PRM/ CM APIs outside power domain & clock domain frameworks. Move these instances to appropriate frameworks.
- This work can go ahead; there is enough clarity - Rajendra
- Need to figure out how to handle PRM FSM in some of the APIs - Rajendra & Benoit
- Phase 2
- Split the power domain and clock domain framework into platform and platform independent parts
- Adopt the approach of doing the changes first and then moving
- Some work has been done by Abhijit but need more discussions
 More Details on Phase 2 - The Splitting Part
The powerdomain and clockdomain frameworks need to be redesigned in such a way that there is a platform independent part doing the usecounting et al and anything else that is platform independent and a platform dependent part which has platform specific implementations. The idea is to implement the platform specific hooks using function pointers which can then be called from platform independent part. This is the design that other power frameworks follow today, like the clock framework and Shared resource framework.
Structural Diagram of the Power Domain Revamp Design:
List of CPU Independent APIs:
pwrdm_lookup: Returns the handle of the specified power domain
pwrdm_for_each: Executes the given API for all registered power domains
pwrdm_add_clkdm: Attaches the specified clock domain to the power domain
pwrdm_del_clkdm: Detaches the specified clock domain to the power domain
pwrdm_for_each_clkdm: Executes the given API for all registered clock domains for the given power domain
pwrdm_get_mem_bank_count: Gives the number of memory banks registered for the given powerdomain
pwrdm_has_hdwr_sar: Tells whether a given power domain supports SAR or not
pwrdm_pre_transition: Calls the pre transition power domain state switch
pwrdm_post_transition: Calls the post transition power domain state switch
List of CPU Dependent APIs:
pwrdm_init: Registers all the listed power domains
pwrdm_set_next_pwrst: Prepares the power domain to enter the specified state
pwrdm_read_next_pwrst: Reads which state is the power domain supposed to enter
pwrdm_read_pwrst: Reads the current entered state of the power domain
pwrdm_read_prev_pwrst: Reads the earlier state before the power domain transitioned to the next state
pwrdm_clear_all_prev_pwrst: Clears the previous power state records for the given powerdomain
pwrdm_set_logic_retst: Set powerdomain logic power state while the power domain is in retention
pwrdm_set_mem_onst: Set memory power state while the power domain is ON
pwrdm_set_mem_retst: Set memory power state while power domain is in retention
pwrdm_read_logic_pwrst: Read current power domain logic retention power state
pwrdm_read_prev_logic_pwrst: Read previous power domain logic power state
pwrdm_read_logic_retst: Read next power domain logic power state
pwrdm_read_mem_pwrst: Read current memory bank power state
pwrdm_read_prev_mem_pwrst: Read previous memory bank power state
pwrdm_read_mem_retst: Read next memory bank power state
pwrdm_enable_hdwr_sar: enable automatic hardware SAR for the given power domain
pwrdm_disable_hdwr_sar: disable automatic hardware SAR for the given power domain
pwrdm_wait_transition: wait for power domain power transition to finish
pwrdm_state_switch: Switch the state of the power domain to the one specified
pwrdm_clkdm_state_switch: Switch the state of the clock domain in the power domain to the one specified
Implementation Details of CPU Dependent APIs
The function pointers have to be registered for calling the CPU specific execution part from the Platform independent part. There are two sets of implementations possible when it comes to linking the Public APIs to the CPU specific implementations.
(Group A) Individual API having a respective function pointer for implementation: Here the API has a one function pointer registered uniquely for itself. The parameters passed between the main API and the registered function will be just the same. The implementation will just differ from CPU to CPU. (These APIs will be hence forth referred to as Group A)
(Group B) Multiple APIs having a single function pointer registered for implementation: The APIs in this category will have a flag registered for them individually. They will have a single function pointer which they will call. The only additional part will be they will pass their individual flags for the CPU specific part to understand which API called the registered function. This technique would avoid the populating of too many function pointers. There would be two different function pointers for setting and reading the registers in this case. (These APIs will be hence forth referred to as Group B)
List of the specific APIs as per their Implementations:
PWRDM_INIT PWRDM_WAIT_TRANSITION PWRDM_STATE_SWITCH
PWRDM_SET_NEXT_PWRST PWRDM_READ_NEXT_PWRST PWRDM_READ_PWRST PWRDM_READ_PREV_PWRST PWRDM_CLEAR_ALL_PREV_PWRST PWRDM_SET_LOGIC_RETST PWRDM_SET_MEM_ONST PWRDSM_SET_MEM_RETST PWRDM_READ_LOGIC_PWRST PWRDM_READ_PREV_LOGIC_PWRST PWRDM_READ_LOGIC_RETST PWRDM_READ_MEM_PWRST PWRDM_READ_PREV_MEM_PWRST PWRDM_READ_MEM_RETST
Note: pwrdm_clkdm_state_switch does not fall either in Group A or Group B. It calls a couple of Group A APIs internally.
Also except for the above mentioned APIs in this slide the remaining APIs will not call into CPU specific registered function pointers.
List of the Function Pointers to be registered per CPU
Power domain init: This would take care of the initialization and registration of the power domains
Power domain modify: This would take care of all the APIs which would do the register write into specific registers
Power domain read: This would take care of all the APIs which are meant to read from the specific registers
Power domain transition wait: Ensures appropriate wait time for the power domain to safely transition
Power domain state switch: This would be used to make the power domain transition its state.
 Clock Domain Cleanup