intel_adsp: ace: power: Prevent HST domain power gating

This patch introduces power management for the HOST (HST) domain within
the Intel ADSP ACE IP. It adds macros to access the node identifier and
device pointer for the HST power domain and integrates power management
calls into the system initialization and power state transition
functions.

The patch ensures that power gating of the HST domain is prevented when
the primary core of the audio DSP is active. Preventing power gating is
crucial for maintaining the functionality of the HST domain while the
primary DSP core is performing critical tasks.

Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
This commit is contained in:
Tomasz Leman 2023-12-13 20:39:16 +01:00 committed by Carles Cufí
commit c3a6274bf5
4 changed files with 41 additions and 0 deletions

View file

@ -88,5 +88,14 @@ static ALWAYS_INLINE bool soc_cpu_is_powered(int cpu_num)
return (ACE_PWRSTS->dsphpxpgs & BIT(cpu_num)) == BIT(cpu_num);
}
/**
* @brief Retrieve node identifier for Intel ADSP HOST power domain.
*/
#define INTEL_ADSP_HST_DOMAIN_DTNODE DT_NODELABEL(hst_domain)
/**
* @brief Intel ADSP HOST power domain pointer.
*/
#define INTEL_ADSP_HST_DOMAIN_DEV DEVICE_DT_GET(INTEL_ADSP_HST_DOMAIN_DTNODE)
#endif /* ZEPHYR_SOC_INTEL_ADSP_POWER_H_ */

View file

@ -88,4 +88,14 @@ static ALWAYS_INLINE bool soc_cpu_is_powered(int cpu_num)
return (ACE_PWRSTS->dsphpxpgs & BIT(cpu_num)) == BIT(cpu_num);
}
/**
* @brief Retrieve node identifier for Intel ADSP HOST power domain.
*/
#define INTEL_ADSP_HST_DOMAIN_DTNODE DT_NODELABEL(hst_domain)
/**
* @brief Intel ADSP HOST power domain pointer.
*/
#define INTEL_ADSP_HST_DOMAIN_DEV DEVICE_DT_GET(INTEL_ADSP_HST_DOMAIN_DTNODE)
#endif /* ZEPHYR_SOC_INTEL_ADSP_POWER_H_ */

View file

@ -9,6 +9,7 @@
#include <zephyr/sys/check.h>
#include <zephyr/arch/cpu.h>
#include <zephyr/pm/pm.h>
#include <zephyr/pm/device_runtime.h>
#include <soc.h>
#include <adsp_boot.h>
@ -79,6 +80,11 @@ void soc_mp_init(void)
IDC[i].agents[0].ipc.ctl = BIT(0); /* IPCTBIE */
}
int ret = pm_device_runtime_get(INTEL_ADSP_HST_DOMAIN_DEV);
ARG_UNUSED(ret);
__ASSERT_NO_MSG(ret == 0);
/* Set the core 0 active */
soc_cpus_active[0] = true;
}

View file

@ -5,6 +5,7 @@
*/
#include <zephyr/kernel.h>
#include <zephyr/pm/pm.h>
#include <zephyr/pm/device_runtime.h>
#include <zephyr/device.h>
#include <zephyr/debug/sparse.h>
#include <zephyr/cache.h>
@ -234,6 +235,9 @@ void pm_state_set(enum pm_state state, uint8_t substate_id)
{
ARG_UNUSED(substate_id);
uint32_t cpu = arch_proc_id();
int ret = 0;
ARG_UNUSED(ret);
/* save interrupt state and turn off all interrupts */
core_desc[cpu].intenable = XTENSA_RSR("INTENABLE");
@ -296,6 +300,8 @@ void pm_state_set(enum pm_state state, uint8_t substate_id)
hpsram_mask = (1 << ebb_banks) - 1;
#endif /* CONFIG_ADSP_POWER_DOWN_HPSRAM */
/* do power down - this function won't return */
ret = pm_device_runtime_put(INTEL_ADSP_HST_DOMAIN_DEV);
__ASSERT_NO_MSG(ret == 0);
power_down(true, uncache_to_cache(&hpsram_mask),
true);
} else {
@ -311,6 +317,9 @@ void pm_state_set(enum pm_state state, uint8_t substate_id)
battr |= (DSPBR_BATTR_LPSCTL_RESTORE_BOOT & LPSCTL_BATTR_MASK);
DSPCS.bootctl[cpu].battr = battr;
}
ret = pm_device_runtime_put(INTEL_ADSP_HST_DOMAIN_DEV);
__ASSERT_NO_MSG(ret == 0);
power_gate_entry(cpu);
} else {
__ASSERT(false, "invalid argument - unsupported power state");
@ -323,6 +332,13 @@ void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id)
ARG_UNUSED(substate_id);
uint32_t cpu = arch_proc_id();
if (cpu == 0) {
int ret = pm_device_runtime_get(INTEL_ADSP_HST_DOMAIN_DEV);
ARG_UNUSED(ret);
__ASSERT_NO_MSG(ret == 0);
}
if (state == PM_STATE_SOFT_OFF) {
/* restore clock gating state */
DSPCS.bootctl[cpu].bctl |=