From c3a6274bf5e47a384ab2036c00450f69f5ee215e 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 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 --- .../ace/include/intel_ace15_mtpm/adsp_power.h | 9 +++++++++ .../ace/include/intel_ace20_lnl/adsp_power.h | 10 ++++++++++ soc/xtensa/intel_adsp/ace/multiprocessing.c | 6 ++++++ soc/xtensa/intel_adsp/ace/power.c | 16 ++++++++++++++++ 4 files changed, 41 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 6efcde4a491..594fc414bbc 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/include/intel_ace20_lnl/adsp_power.h b/soc/xtensa/intel_adsp/ace/include/intel_ace20_lnl/adsp_power.h index 60631945da3..5d12c79fdcb 100644 --- a/soc/xtensa/intel_adsp/ace/include/intel_ace20_lnl/adsp_power.h +++ b/soc/xtensa/intel_adsp/ace/include/intel_ace20_lnl/adsp_power.h @@ -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_ */ diff --git a/soc/xtensa/intel_adsp/ace/multiprocessing.c b/soc/xtensa/intel_adsp/ace/multiprocessing.c index 750dc06d74e..08a0aab16c4 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,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; } diff --git a/soc/xtensa/intel_adsp/ace/power.c b/soc/xtensa/intel_adsp/ace/power.c index cee8047d4a2..7c50923abdd 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 @@ -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 |=