soc: intel_adsp: Manage power gating based on core activity

This patch enhances the power management capabilities of the Intel ADSP
by ensuring that power gating states are appropriately managed based on
core activity. It prevents the primary core from entering power gating
if secondary cores are active and re-enables power gating when all
secondary cores are off, using pm_policy_state_lock_get and
pm_policy_state_lock_put functions.

The Sound Open Firmware (SOF) project currently uses a custom power
management policy to achieve these effects. With this patch, the default
power management policy can be utilized, allowing the option to disable
the custom policy while maintaining system reliability and performance
across different core states.

Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
This commit is contained in:
Tomasz Leman 2025-05-06 15:35:00 +02:00 committed by Benjamin Cabé
commit fbafada9b6
2 changed files with 11 additions and 0 deletions

View file

@ -11,6 +11,7 @@
#include <zephyr/arch/cpu.h>
#include <zephyr/arch/xtensa/arch.h>
#include <zephyr/pm/pm.h>
#include <zephyr/pm/policy.h>
#include <zephyr/pm/device_runtime.h>
#include <ksched.h>
@ -147,6 +148,11 @@ void soc_start_core(int cpu_num)
} else {
*rom_jump_vector = (uint32_t) dsp_restore_vector;
}
/* The primary core cannot enter power gating if any of the secondary cores are
* active.
*/
pm_policy_state_lock_get(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES);
#else
*rom_jump_vector = (uint32_t) z_soc_mp_asm_entry;
#endif

View file

@ -5,6 +5,7 @@
*/
#include <zephyr/kernel.h>
#include <zephyr/pm/pm.h>
#include <zephyr/pm/policy.h>
#include <zephyr/pm/device_runtime.h>
#include <zephyr/device.h>
#include <zephyr/debug/sparse.h>
@ -342,6 +343,10 @@ void pm_state_set(enum pm_state state, uint8_t substate_id)
/* do power down - this function won't return */
power_down(true, IS_ENABLED(CONFIG_ADSP_POWER_DOWN_HPSRAM), true);
} else {
/* When all secondary cores are turned off, power gating for the primary
* core will be re-enabled.
*/
pm_policy_state_lock_put(PM_STATE_RUNTIME_IDLE, PM_ALL_SUBSTATES);
power_gate_entry(cpu);
}
break;