Repository navigation
PM runtime dynamic clock switching implementation - #3205
Conversation
acd5df6 to
ad6204b
Compare
lgirdwood
left a comment
There was a problem hiding this comment.
This seems like a generic feature. We should have a CONFIG_DYNAMIC_CLOCK_SWITCHING that should enabled this. If CONFIG_DYNAMIC_CLOCK_SWITCHING is false then we use a static clock (default HP clock otherwise LPRO if selected).
There was a problem hiding this comment.
It's probably best to put this depends CONFIG_DEBUG sine it's debug only.
I would also say "Force use of Low Power Oscillator"
There was a problem hiding this comment.
It's probably best to put this depends CONFIG_DEBUG sine it's debug only.
Okay, let me add this dependency. @mmaka1 @lbetlej are you OK for this?
I would also say "Force use of Low Power Oscillator"
for Dynamic switching mode, the LPRO is also used, so anyway LPRO will always be used/enabled, LPRO_ONLY is more accurate here?
There was a problem hiding this comment.
I'd not couple CONFIG_DEBUG and LPRO_ONLY since the former is used to compile extra debugability which may not fit into smaller MCPS budget. On the other hand, it is still useful to create special non-debug build with LPRO_ONLY turned on and run simple pipeline test for quick verification of MCPS consumption by base components.
There was a problem hiding this comment.
It looks like most of these function bodies are conditionally compiled code, this may be better if you had two version of each function here, one for static clock (LPRO or HP clock) the other for dynamic clock.
There was a problem hiding this comment.
We don't have HPRO only mode, so basically
- by default clock switching is used, at least we need to switch to LPRO when in D0i3, and switch back to HPRO when performing D0i3 -> D0.
- if USE_LPRO_IN_WAITI is selected, it will switch to LPRO during WFI, no matter in D0 or in D0i3.
- LPRO only for debug purpose only, where only LPRO is used and therefore no clock switching is needed for all scenarios including 1) and 2).
The preserving of the LPRO_ONLY mode increases the complexity of this conditionally compiling, that's one of the reason why I wanted to remove the debug mode initially, @mmaka1 @lbetlej
There was a problem hiding this comment.
We want to keep LPRO_ONLY mode. It would improve readability if there are three ver. of the function compiled conditionally as @lgirdwood noted.
There was a problem hiding this comment.
We want to keep LPRO_ONLY mode. It would improve readability if there are three ver. of the function compiled conditionally as @lgirdwood noted.
OK, let me change to use 3 separated versions.
Thanks for reviewing. I thought about adding this, but then I realized that this item is not selectable(it should be always Y) since we have to use LPRO in D0i3. That's why we don't need adding CONFIG_DYNAMIC_CLOCK_SWITCHING item. |
There was a problem hiding this comment.
Clock switching may base on pm_runtime settings in short term. However, the pm_runtime calls should be prepared for unbalanced pm_gate ipc requests, by replacing ref-counter with a bitmap (one bit per client, could be reduced to a single bool/bit for host->pm_gate use only in short term).
There was a problem hiding this comment.
Clock switching may base on pm_runtime settings in short term. However, the pm_runtime calls should be prepared for unbalanced pm_gate ipc requests, by replacing ref-counter with a bitmap (one bit per client, could be reduced to a single bool/bit for host->pm_gate use only in short term).
Thanks for comments, @mmaka1 . I just created a new PR to handle that issue, please help to review:
#3252
There was a problem hiding this comment.
This looks over complex. Is there any reason why we dont store the clock status in uncache memory by default ? You are also checking PM and cached states twice which is not atomic.
There was a problem hiding this comment.
@keyonjie I'm still seeing the "complex" version here ? Have you pushed the new version ?
There was a problem hiding this comment.
also far easier to flow if you do
freq_idx = uncache(&active_freq_idx);
pm_is_active = pm_runtime_is_active(PM_blah, MASTER_CORE);
if (pm_is_active) {
if (freq_idx != LPRO)
do_this;
} else {
if (freq_idx != HPRO)
do_that;
}There was a problem hiding this comment.
also far easier to flow if you do
freq_idx = uncache(&active_freq_idx); pm_is_active = pm_runtime_is_active(PM_blah, MASTER_CORE); if (pm_is_active) { if (freq_idx != LPRO) do_this; } else { if (freq_idx != HPRO) do_that; }
sure, let me add these variables for easier understanding.
BTW, have you got my changes that adding the hold of lock for the atomic issue you were worrying about, is that OK to you?
There was a problem hiding this comment.
@lgirdwood BTW, I will prefer this as it is simple enough for understanding after 2 new variables introduced:
/* perform clock switching if the PM active status not aligned with the clock frequency */
if (!pm_is_active && freq_idx != CPU_LPRO_FREQ_IDX)
set_cpu_current_freq_idx(CPU_LPRO_FREQ_IDX, true);
else if (pm_is_active && freq_idx != CPU_HPRO_FREQ_IDX)
set_cpu_current_freq_idx(CPU_HPRO_FREQ_IDX, true);
There was a problem hiding this comment.
But you are checking the same logic twice, someone using a code scanning tool will just come along an fix it.
|
SOFCI TEST |
There was a problem hiding this comment.
This version of on_waiti/on_wakeup is removed by the previous commit and restored by this one. Should those two ones be squashed to avoid intermediate commit that has some regression?
There was a problem hiding this comment.
good point, let me squash them.
|
@mmaka1 @lgirdwood ping for review, I think this is the last debt for the TGL 007 release. |
There was a problem hiding this comment.
This looks over complex. Is there any reason why we dont store the clock status in uncache memory by default ? You are also checking PM and cached states twice which is not atomic.
|
@lgirdwood looks I can't reply your last comment and requested change directly, so type it here.
For the complex, I think you are referring to old version code (don't know why github shows you the old one). |
lgirdwood
left a comment
There was a problem hiding this comment.
Am I still seeing the old version of the patches ?
There was a problem hiding this comment.
@keyonjie I'm still seeing the "complex" version here ? Have you pushed the new version ?
I think so. the commit 9b079b224a7a007 actually looks like this: No those lines as you quoted below: |
|
@keyonjie ok, it looks like we are both looking at the same file. My comment still stands here. +void platform_clock_on_waiti(void)
{
- pm_runtime_get(CORE_HP_CLK, cpu_get_id());
+ /* perform the possible dynamic clock switching */
+ if (*cache_to_uncache(&active_freq_idx) != CPU_LPRO_FREQ_IDX &&
+ !pm_runtime_is_active(PM_RUNTIME_DSP, PLATFORM_MASTER_CORE_ID))
+ set_cpu_current_freq_idx(CPU_LPRO_FREQ_IDX, true);
+ else if (*cache_to_uncache(&active_freq_idx) != CPU_HPRO_FREQ_IDX &&
+ pm_runtime_is_active(PM_RUNTIME_DSP, PLATFORM_MASTER_CORE_ID))
+ set_cpu_current_freq_idx(CPU_HPRO_FREQ_IDX, true);
+
+ /* check if waiti HPRO->LPRO switching is needed */
+ pm_runtime_put(CORE_HP_CLK, cpu_get_id());
}This races as active_freq_idx can be changed in between first and second tests likewise with the pm_runtime_is_active() conditions. |
Got your point now, let me use the pm_runtime lock to make this atomic. |
|
SOFCI TEST |
Today how we are using CONFIG_CAVS_LPRO is actually using LPRO only, rename to make the naming accurate. Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
only The config item CONFIG_CAVS_LPRO (CONFIG_CAVS_LPRO_ONLY now) should be used for debugging only at the moment, remove it from Chrome configs. Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
LPRO_ONLY is not set When LPRO_ONLY is set, the item CAVS_USE_LPRO_IN_WAITI is not configurable, and no clock switching is possible. Change to enable CAVS_USE_LPRO_IN_WAITI selection only when LPRO_ONLY is not set. Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
Define CPU_LPRO_FREQ_IDX, CPU_HPRO_FREQ_IDX and CPU_DEFAULT_IDX for all cAVS platforms. Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
|
@lgirdwood updated now. |
There was a problem hiding this comment.
You are checking pm_is_active twice.
if (pm_is_active) {
/* set LPRO clock if not already enabled */
if (freq_idx != CPU_LPRO_FREQ_IDX)
set_cpu_current_freq_idx(CPU_LPRO_FREQ_IDX, true);
} else {
/* set HPRO clock if not already enabled */
if (req_idx != CPU_HPRO_FREQ_IDX)
set_cpu_current_freq_idx(CPU_HPRO_FREQ_IDX, true);
}Let's select WAKEUP_HOOK for all cAVS platforms, and just do nothing inside if that's the true. 1. When CONFIG_CAVS_LPRO_ONLY=y, use LPRO only, no clock switching. 2. When CONFIG_CAVS_LPRO_ONLY=n, dynamic clock switching will be enabled, and the clock switching will be performed during platform_wait_for_interrupt() only. In platform_clock_on_waiti(), perform dynamic clock switching if needed (active_freq_idx will be updated to denote the active non-wfi clock frequecy index), and then put CORE_HP_CLK to perform possible HPRO->LPRO switching if CONFIG_CAVS_USE_LPRO_IN_WAITI is selected. In platform_clock_on_wakeup(), when CONFIG_CAVS_USE_LPRO_IN_WAITI is selected, get CORE_HP_CLK to perform switching back to HPRO if HPRO is the saved non-wfi active clock, and no more switching needed. Otherwise, need to restore the active cpu freq_idx manually. Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
|
Thanks for reviewing, @mmaka1 and @lgirdwood |
This is to implement the pm runtime dynamic clock switching which is needed for the TGL 007 release, necessary for making WoV works with LPRO in S0Ix and HPRO for normal usage to meet the bandwidth requirement for DSM and other high MCPS scenarios. The LPRO_ONLY mode is also preserved for debug usage.