From 5183a8b35700f9cebbcfac9008bed6d5d215d54f Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Tue, 31 Oct 2023 10:53:21 +0100 Subject: [PATCH 1/7] [DRAFT] west.yml: zephyr version update PR containing the required changes. Signed-off-by: Tomasz Leman --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index da914dbd854a..2af5fad3a9eb 100644 --- a/west.yml +++ b/west.yml @@ -43,7 +43,7 @@ manifest: - name: zephyr repo-path: zephyr - revision: 3614d4cb88f4714c47af66d7053304092659fb43 + revision: pull/66092/head remote: zephyrproject # Import some projects listed in zephyr/west.yml@revision From 1fe1d9aa7c519d58a985ad48b9d296cbd904be27 Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Thu, 21 Dec 2023 23:06:15 +0100 Subject: [PATCH 2/7] config: ace: enable ARCH_CPU_IDLE_CUSTOM 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 --- app/boards/intel_adsp_ace15_mtpm.conf | 2 ++ app/boards/intel_adsp_ace20_lnl.conf | 2 ++ 2 files changed, 4 insertions(+) diff --git a/app/boards/intel_adsp_ace15_mtpm.conf b/app/boards/intel_adsp_ace15_mtpm.conf index 5923272fa986..04881b857353 100644 --- a/app/boards/intel_adsp_ace15_mtpm.conf +++ b/app/boards/intel_adsp_ace15_mtpm.conf @@ -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 + # enable Zephyr drivers CONFIG_ZEPHYR_NATIVE_DRIVERS=y CONFIG_DAI=y diff --git a/app/boards/intel_adsp_ace20_lnl.conf b/app/boards/intel_adsp_ace20_lnl.conf index 88a8e6522cfe..242be7e71d28 100644 --- a/app/boards/intel_adsp_ace20_lnl.conf +++ b/app/boards/intel_adsp_ace20_lnl.conf @@ -18,6 +18,8 @@ CONFIG_ADSP_IDLE_CLOCK_GATING=y CONFIG_POWER_DOMAIN=y CONFIG_POWER_DOMAIN_INTEL_ADSP=y +CONFIG_ARCH_CPU_IDLE_CUSTOM=y + # enable Zephyr drivers CONFIG_ZEPHYR_NATIVE_DRIVERS=y CONFIG_DAI=y From 08a4a9479209b79ceacb7ef1433a0ee280387e23 Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Fri, 22 Dec 2023 12:31:14 +0100 Subject: [PATCH 3/7] zephyr: pm_runtime: integrate dynamic clock switching support 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 --- zephyr/lib/pm_runtime.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/zephyr/lib/pm_runtime.c b/zephyr/lib/pm_runtime.c index 6b46969adfd8..8831f560423c 100644 --- a/zephyr/lib/pm_runtime.c +++ b/zephyr/lib/pm_runtime.c @@ -12,6 +12,12 @@ #include #include +#if CONFIG_ADSP_DYNAMIC_CLOCK_SWITCHING +#include + +static struct intel_adsp_ace_pm_data pr_runtime_data; +#endif /* CONFIG_ADSP_DYNAMIC_CLOCK_SWITCHING */ + LOG_MODULE_REGISTER(power, CONFIG_SOF_LOG_LEVEL); /* 76cc9773-440c-4df9-95a8-72defe7796fc */ @@ -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 + case CORE_HP_CLK: + tr_info(&power_tr, "removing lock on clock switching"); + intel_adsp_release_clock_switch_lock(pm_state_custom_data_get(PM_STATE_ACTIVE, 0)); + break; +#endif /* CONFIG_ADSP_DYNAMIC_CLOCK_SWITCHING */ default: break; } @@ -86,13 +98,25 @@ void platform_pm_runtime_disable(uint32_t context, uint32_t index) tr_dbg(&power_tr, "putting prevent on d0i3"); pm_policy_state_lock_get(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES); break; +#if CONFIG_ADSP_DYNAMIC_CLOCK_SWITCHING + case CORE_HP_CLK: + tr_info(&power_tr, "putting lock on clock switching"); + intel_adsp_acquire_clock_switch_lock(pm_state_custom_data_get(PM_STATE_ACTIVE, 0)); + break; +#endif /* CONFIG_ADSP_DYNAMIC_CLOCK_SWITCHING */ default: break; } } void platform_pm_runtime_init(struct pm_runtime_data *prd) -{ } +{ +#if CONFIG_ADSP_DYNAMIC_CLOCK_SWITCHING + tr_info(&power_tr, "setting PM runtime data"); + pm_state_custom_data_set(PM_STATE_ACTIVE, 0, &pr_runtime_data); + prd->platform_data = &pr_runtime_data; +#endif /* CONFIG_ADSP_DYNAMIC_CLOCK_SWITCHING */ +} void platform_pm_runtime_get(enum pm_runtime_context context, uint32_t index, uint32_t flags) From a17cd0f1769b171f746643c2071d0be9c9cc28dc Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Fri, 22 Dec 2023 13:25:44 +0100 Subject: [PATCH 4/7] ipc4: handler: stabilize clock during delayed ipc reply 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 --- src/ipc/ipc4/handler.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ipc/ipc4/handler.c b/src/ipc/ipc4/handler.c index 5fd048624f08..1843aa654a9d 100644 --- a/src/ipc/ipc4/handler.c +++ b/src/ipc/ipc4/handler.c @@ -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); while (atomic_read(&msg_data.delayed_reply)) { + /* preventing clock switching in idle */ k_sleep(Z_TIMEOUT_US(250)); if (!try_count--) { atomic_set(&msg_data.delayed_reply, 0); ipc_cmd_err(&ipc_tr, "ipc4: failed to wait schedule thread"); + pm_runtime_enable(CORE_HP_CLK, PLATFORM_PRIMARY_CORE_ID); return IPC4_FAILURE; } } + pm_runtime_enable(CORE_HP_CLK, PLATFORM_PRIMARY_CORE_ID); return IPC4_SUCCESS; } From 2a4630308a8c97db9a0ad18dfa586f16504ee5bd Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Fri, 22 Dec 2023 13:34:05 +0100 Subject: [PATCH 5/7] ipc4: restore DSP clock on ipc message receipt 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 --- src/ipc/ipc-zephyr.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ipc/ipc-zephyr.c b/src/ipc/ipc-zephyr.c index 49a448850a99..1ec3d9c3ab2e 100644 --- a/src/ipc/ipc-zephyr.c +++ b/src/ipc/ipc-zephyr.c @@ -79,6 +79,10 @@ static bool message_handler(const struct device *dev, void *arg, uint32_t data, #if CONFIG_DEBUG_IPC_COUNTERS increment_ipc_received_counter(); +#endif +#if CONFIG_ADSP_DYNAMIC_CLOCK_SWITCHING + /* If the DSP has been in Idle we may need to restore previous clock. */ + soc_adsp_clock_idle_exit(); #endif ipc_schedule_process(ipc); From b005224d5349ea78b4e9c4bb5665c68a8e899f5c Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Fri, 22 Dec 2023 13:39:03 +0100 Subject: [PATCH 6/7] zephyr: ll-schedule: restore clock after idle in scheduler 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 --- src/schedule/zephyr_domain.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/schedule/zephyr_domain.c b/src/schedule/zephyr_domain.c index 7fb9b4ae0465..2b8e8b8a05cc 100644 --- a/src/schedule/zephyr_domain.c +++ b/src/schedule/zephyr_domain.c @@ -93,6 +93,10 @@ static void zephyr_domain_thread_fn(void *p1, void *p2, void *p3) #endif cycles0 = k_cycle_get_32(); +#if CONFIG_ADSP_DYNAMIC_CLOCK_SWITCHING + /* If the DSP has been in Idle we may need to restore previous clock. */ + soc_adsp_clock_idle_exit(); +#endif dt->handler(dt->arg); cycles1 = k_cycle_get_32(); From c11531b22089bcf6c8476b41c7a349faec583d38 Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Fri, 22 Dec 2023 13:48:02 +0100 Subject: [PATCH 7/7] config: ace: enable dynamic clock switching 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 --- app/boards/intel_adsp_ace15_mtpm.conf | 2 ++ app/boards/intel_adsp_ace20_lnl.conf | 2 ++ 2 files changed, 4 insertions(+) diff --git a/app/boards/intel_adsp_ace15_mtpm.conf b/app/boards/intel_adsp_ace15_mtpm.conf index 04881b857353..538ff40ae236 100644 --- a/app/boards/intel_adsp_ace15_mtpm.conf +++ b/app/boards/intel_adsp_ace15_mtpm.conf @@ -15,6 +15,8 @@ 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 CONFIG_POWER_DOMAIN=y CONFIG_POWER_DOMAIN_INTEL_ADSP=y diff --git a/app/boards/intel_adsp_ace20_lnl.conf b/app/boards/intel_adsp_ace20_lnl.conf index 242be7e71d28..1ba2bfa721b5 100644 --- a/app/boards/intel_adsp_ace20_lnl.conf +++ b/app/boards/intel_adsp_ace20_lnl.conf @@ -12,6 +12,8 @@ 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 CONFIG_ADSP_IMR_CONTEXT_SAVE=y CONFIG_ADSP_IDLE_CLOCK_GATING=y