-
Notifications
You must be signed in to change notification settings - Fork 321
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[DNM] intel_adsp: ace: dynamic clock switching #8423
[DNM] intel_adsp: ace: dynamic clock switching #8423
Conversation
21a83d2
to
f89029e
Compare
f89029e
to
687de9f
Compare
src/ipc/ipc4/handler.c
Outdated
@@ -516,13 +516,18 @@ static int ipc_wait_for_compound_msg(void) | |||
int try_count = 30; /* timeout out is 30 x 10ms so 300ms for IPC */ | |||
|
|||
while (atomic_read(&msg_data.delayed_reply)) { | |||
/* preventing clock switching in idle */ | |||
pm_runtime_disable(CORE_HP_CLK, PLATFORM_PRIMARY_CORE_ID); | |||
k_sleep(Z_TIMEOUT_MS(10)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know the hardware details, but naively this feels like the opposite to what one would want: when sleeping you'd want preferably to switch off any clocks, do some kind of a wait-for-interrupt operation, and instead we turn the clock on to a maximum frequency?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I implemented it in the wrong function. But the goal here is not to turn on the highest clock but to prevent switching to the lowest one if a higher one is already in use.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, so the risk is that the sleep() would put us in a lower clock at Zephyr level and may impact other audio or the timeout ? Maybe best to add more context in the comments to reflect the why.
c08a156
to
16145c1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tmleman I assume you are happy with the testing/validation ?
src/ipc/ipc4/handler.c
Outdated
@@ -516,13 +516,18 @@ static int ipc_wait_for_compound_msg(void) | |||
int try_count = 30; /* timeout out is 30 x 10ms so 300ms for IPC */ | |||
|
|||
while (atomic_read(&msg_data.delayed_reply)) { | |||
/* preventing clock switching in idle */ | |||
pm_runtime_disable(CORE_HP_CLK, PLATFORM_PRIMARY_CORE_ID); | |||
k_sleep(Z_TIMEOUT_MS(10)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, so the risk is that the sleep() would put us in a lower clock at Zephyr level and may impact other audio or the timeout ? Maybe best to add more context in the comments to reflect the why.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this PR a replacement with:#8019
No, this change is not intended to replace it. It's more of an extension. Thanks for asking; I've added this PR as a dependency. |
16145c1
to
8d5e0aa
Compare
8d5e0aa
to
b6e1620
Compare
50bcb65
to
9574435
Compare
Stable-v2.9 branched, this didn't make the cut, bumping to 2.10. |
9574435
to
9b542d8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but we need to plan to move our platform PM logic into Zephyr.
@@ -74,6 +80,12 @@ void platform_pm_runtime_enable(uint32_t context, uint32_t index) | |||
tr_dbg(&power_tr, "removing prevent on d0i3 (lock is active=%d)", | |||
pm_policy_state_lock_is_active(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES)); | |||
break; | |||
#if CONFIG_ADSP_DYNAMIC_CLOCK_SWITCHING |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw, what's the long term plan to move this into Zephyr as I would expect we should all the platform PM logic in Zephyr.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We won't be able to move everything related to PM to Zephyr. We need to prevent changes to the clock and dynamic power gating on the application side. What can definitely be moved to Zephyr is the custom power policy (several changes in this direction have already been made).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ack, but we should do that with Zephyr PM APIs. e.g. zephyr_pm_prevent_clock_gating(CLOCK_ID)
so that eventually we have zero IP code in SOF and its all in Zephyr. I know we cant yet do this today, but just for the record that we may have to extend Zephyr APIs here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
zephyr_pm_prevent_clock_gating(CLOCK_ID)
btw, we have clock gating, this is about clock switching.
I was wondering if there is really a benefit from idle clock switching (with switching overhead) if we have hw clock gating anyway
9b542d8
to
9c18503
Compare
PR containing the required changes. Signed-off-by: Tomasz Leman <[email protected]>
Enable the CONFIG_ARCH_CPU_IDLE_CUSTOM option for ACE platforms (meteorlake and lunarlake). This configuration allows the use of a custom arch_cpu_idle implementation, providing opportunities for platform-specific optimizations in power management. Signed-off-by: Tomasz Leman <[email protected]>
Integrate dynamic clock switching support into the power management runtime system for Intel ADSP platforms. This patch ensures that the clock switching mechanism is controlled in a thread-safe manner during power management operations. Changes include: - Initializing the intel_adsp_ace_pm_data structure to manage the clock switching lock state. - Modifying platform_pm_runtime_enable/disable functions to lock and unlock clock switching when the CORE_HP_CLK context is affected. Signed-off-by: Tomasz Leman <[email protected]>
Ensure a stable clock frequency in the IPC4 handler during the wait for a delayed reply. This is achieved by disabling dynamic clock switching when entering the wait loop and re-enabling it upon exit or when a timeout occurs. The patch addresses potential timing issues that could arise from clock frequency changes while the core is in an idle state awaiting a response from a different thread that was scheduled by this IPC. The added calls to pm_runtime_disable/enable ensure that the high performance clock remains active during the critical wait period, thus maintaining the necessary processing speed and responsiveness of the IPC mechanism. Signed-off-by: Tomasz Leman <[email protected]>
With this patch, the adsp_clock_idle_exit function is called within the IPC message handler to reset the clock frequency if it was lowered during idle periods. This is crucial for maintaining the performance and responsiveness of the system when processing incoming IPC messages. The patch is conditionally compiled only when the CONFIG_ADSP_DYNAMIC_CLOCK_SWITCHING configuration option is enabled, ensuring that the functionality is available only on systems that support dynamic clock management. Signed-off-by: Tomasz Leman <[email protected]>
The adsp_clock_idle_exit function is invoked at the beginning of the scheduler thread function to reset the clock frequency if it was lowered during idle periods. This change is crucial for maintaining the performance and responsiveness of the system when it resumes work after being idle. This patch is conditionally compiled with CONFIG_ADSP_DYNAMIC_CLOCK_SWITCHING to ensure that the functionality is available only on systems that support dynamic clock management. Signed-off-by: Tomasz Leman <[email protected]>
Enable the dynamic clock switching feature for Intel ADSP platforms. This feature allows the DSP to adjust its clock frequency dynamically when all cores enter the idle state, reducing energy consumption while waiting for interrupts. The following Kconfig options are added to MTL and LNL configuration: - CONFIG_PM_STATE_CUSTOM_DATA: Allows setting custom data pointers for specific power states. - CONFIG_ADSP_DYNAMIC_CLOCK_SWITCHING: Enables dynamic clock switching during idle states, dependent on the availability of custom power state data. This change is part of ongoing efforts to enhance power management capabilities and improve the energy efficiency of these platforms. Signed-off-by: Tomasz Leman <[email protected]>
9c18503
to
c11531b
Compare
@@ -15,13 +15,17 @@ CONFIG_PM_DEVICE_RUNTIME=y | |||
CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE=n | |||
CONFIG_PM_DEVICE_POWER_DOMAIN=y | |||
CONFIG_PM_POLICY_CUSTOM=y | |||
CONFIG_PM_STATE_CUSTOM_DATA=y | |||
CONFIG_ADSP_DYNAMIC_CLOCK_SWITCHING=y |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I strongly suggest to rename it (in zephyr) to CONFIG_ADSP_IDLE_DYNAMIC_CLOCK_SWITCHING or something like that to avoid confusion with all kconfigs about clocks and kcps
@@ -536,16 +536,20 @@ static int ipc_wait_for_compound_msg(void) | |||
{ | |||
int try_count = 30; | |||
|
|||
pm_runtime_disable(CORE_HP_CLK, PLATFORM_PRIMARY_CORE_ID); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this still needed? Will this work correctly with KCPS which changes clock during IPC?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few comments inline.
@@ -22,6 +22,8 @@ CONFIG_POWER_DOMAIN_INTEL_ADSP=y | |||
CONFIG_ADSP_IMR_CONTEXT_SAVE=y | |||
CONFIG_ADSP_IDLE_CLOCK_GATING=y | |||
|
|||
CONFIG_ARCH_CPU_IDLE_CUSTOM=y |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw, why do you need this? I don't see a custom idle handled added in this patch.
This setting is now enabled in upstream by default (the new icache-workaround), so no need to enable this on SOF side anymore.
@@ -536,16 +536,20 @@ static int ipc_wait_for_compound_msg(void) | |||
{ | |||
int try_count = 30; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we generalize this a bit? I guess this could be a Kconfig to "keep core clock high when responding to IPC".
The actual implementation will vary on different platforms, so ideally we'd have a Zephyr interface to communicate this constraints, but for the time being we might need glue code on SOF side (e.g. for Intel this is turned into pm_runtime call on CORE_HP_CLK).
I'm ok to also go with a TODO comment for now if there's no direct Zephyr interface yet.
The changes this PR depends on will not be merged into Zephyr in the near future, so I'm closing it. |
This pull request introduces a series of enhancements to the power management capabilities of the Intel ADSP platforms. The changes include the implementation of dynamic clock switching, which allows the DSP to adjust its clock frequency based on the idle state of the cores, thereby reducing power consumption during idle periods.
Depends on: