Skip to content

Commit

Permalink
board: ace: enable CONFIG_PM_IDLE_POWER_OPTIMIZATIONS
Browse files Browse the repository at this point in the history
This patch enables zephyr power management feature that allows to use
board specific operations to improve power consumption during idle.

It also includes all required changes for ACE DSP.

Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
  • Loading branch information
tmleman committed Oct 31, 2023
1 parent 4c4318b commit 21a83d2
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 2 deletions.
1 change: 1 addition & 0 deletions app/boards/intel_adsp_ace15_mtpm.conf
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ CONFIG_PM_DEVICE_RUNTIME=y
CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE=n
CONFIG_PM_DEVICE_POWER_DOMAIN=y
CONFIG_PM_POLICY_CUSTOM=y
CONFIG_PM_IDLE_POWER_OPTIMIZATIONS=y

CONFIG_POWER_DOMAIN=y
CONFIG_POWER_DOMAIN_INTEL_ADSP=y
Expand Down
1 change: 1 addition & 0 deletions app/boards/intel_adsp_ace20_lnl.conf
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ CONFIG_PM_DEVICE_RUNTIME=y
CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE=n
CONFIG_PM_DEVICE_POWER_DOMAIN=y
CONFIG_PM_POLICY_CUSTOM=y
CONFIG_PM_IDLE_POWER_OPTIMIZATIONS=y
CONFIG_ADSP_IMR_CONTEXT_SAVE=y

CONFIG_POWER_DOMAIN=y
Expand Down
8 changes: 8 additions & 0 deletions src/ipc/ipc4/handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@
#include <stddef.h>
#include <stdint.h>

/* QUESTION: call zephyr API directly or add a wrapper in pm_runtime? */
#include <zephyr/pm/policy.h>

/* Command format errors during fuzzing are reported for virtually all
* commands, and the resulting flood of logging becomes a severe
* performance penalty (i.e. we get a lot less fuzzing done per CPU
Expand Down Expand Up @@ -509,13 +512,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_policy_state_lock_get(PM_STATE_ACTIVE, 2);
k_sleep(Z_TIMEOUT_MS(10));

if (!try_count--) {
atomic_set(&msg_data.delayed_reply, 0);
ipc_cmd_err(&ipc_tr, "ipc4: failed to wait schedule thread");
pm_policy_state_lock_put(PM_STATE_ACTIVE, 2);
return IPC4_FAILURE;
}

pm_policy_state_lock_put(PM_STATE_ACTIVE, 2);
}

return IPC4_SUCCESS;
Expand Down
4 changes: 4 additions & 0 deletions src/schedule/zephyr_domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ static void zephyr_domain_thread_fn(void *p1, void *p2, void *p3)
#endif

cycles0 = k_cycle_get_32();
#if CONFIG_PM_IDLE_POWER_OPTIMIZATIONS
/* If DSP has ben in Idle we may need to restore previous clock. */
adsp_clock_idle_exit();
#endif
dt->handler(dt->arg);
cycles1 = k_cycle_get_32();

Expand Down
11 changes: 9 additions & 2 deletions zephyr/lib/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,10 @@ int cpu_enable_core(int id)
k_busy_wait(100);

atomic_set(&start_flag, 1);

/* We need to prevent clock switching for each enabled core. Prevent will be removed when
* core enters idle or is disabled.
*/
pm_policy_state_lock_get(PM_STATE_ACTIVE, 2);
return 0;
}

Expand Down Expand Up @@ -202,8 +205,12 @@ void cpu_disable_core(int id)
return;
}

if (soc_adsp_halt_cpu(id) != 0)
if (soc_adsp_halt_cpu(id) != 0) {
tr_err(&zephyr_tr, "failed to disable core %d", id);
} else {
/* Core is now down and we can remove prevent for clock switching. */
pm_policy_state_lock_put(PM_STATE_ACTIVE, 2);
}
#endif /* CONFIG_PM */
}

Expand Down
5 changes: 5 additions & 0 deletions zephyr/wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,11 @@ int start_complete(void)
#if defined(CONFIG_PM)
pm_policy_state_lock_get(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES);
pm_policy_state_lock_get(PM_STATE_SOFT_OFF, PM_ALL_SUBSTATES);
/* Prevent dynamic clock switching during idle time. Prevention must set for all active
* cores, then each core will put the lock again and go into an idle state. The last
* active core will try to switch the clock to the lowest frequency.
*/
pm_policy_state_lock_get(PM_STATE_ACTIVE, 2);
#endif
return boot_complete();
}
Expand Down

0 comments on commit 21a83d2

Please sign in to comment.