From 7495eb0f14fc7f2a16c9a718a9e535925ebf1ede Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Wed, 13 Dec 2023 20:39:16 +0100 Subject: [PATCH] intel_adsp: ace: power: prevent hst domain power gating This commit introduces a mechanism to prevent the power gating of the HST (Host) power domain when the primary core of the audio DSP is active. The power gating prevention is crucial for maintaining the functionality of the HST domain while the primary DSP core is performing critical tasks. Signed-off-by: Tomasz Leman --- .../ace/include/intel_ace15_mtpm/adsp_power.h | 9 +++++++++ soc/xtensa/intel_adsp/ace/multiprocessing.c | 5 +++++ soc/xtensa/intel_adsp/ace/power.c | 14 ++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/soc/xtensa/intel_adsp/ace/include/intel_ace15_mtpm/adsp_power.h b/soc/xtensa/intel_adsp/ace/include/intel_ace15_mtpm/adsp_power.h index 6efcde4a4913001..594fc414bbc734b 100644 --- a/soc/xtensa/intel_adsp/ace/include/intel_ace15_mtpm/adsp_power.h +++ b/soc/xtensa/intel_adsp/ace/include/intel_ace15_mtpm/adsp_power.h @@ -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_ */ diff --git a/soc/xtensa/intel_adsp/ace/multiprocessing.c b/soc/xtensa/intel_adsp/ace/multiprocessing.c index e762245e669ecbe..c6f691a10b69963 100644 --- a/soc/xtensa/intel_adsp/ace/multiprocessing.c +++ b/soc/xtensa/intel_adsp/ace/multiprocessing.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -79,6 +80,10 @@ 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(ret == 0, "HST power domain resume operation failed."); + /* Set the core 0 active */ soc_cpus_active[0] = true; } diff --git a/soc/xtensa/intel_adsp/ace/power.c b/soc/xtensa/intel_adsp/ace/power.c index ace2b27d802199a..93b4c67f2f4d794 100644 --- a/soc/xtensa/intel_adsp/ace/power.c +++ b/soc/xtensa/intel_adsp/ace/power.c @@ -5,6 +5,7 @@ */ #include #include +#include #include #include #include @@ -235,6 +236,8 @@ 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"); @@ -297,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(ret == 0, "HST power domain suspend operation failed."); power_down(true, uncache_to_cache(&hpsram_mask), true); } else { @@ -312,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(ret == 0, "HST power domain suspend operation failed."); power_gate_entry(cpu); } else { __ASSERT(false, "invalid argument - unsupported power state"); @@ -324,6 +332,12 @@ 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(ret == 0, "HST power domain resume operation failed."); + } + if (state == PM_STATE_SOFT_OFF) { /* restore clock gating state */ DSPCS.bootctl[cpu].bctl |=