From 0c584de831cdc3d98f4fb98a5e78bb97c145cf76 Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Thu, 7 Dec 2023 16:13:16 +0100 Subject: [PATCH] intel_adsp: power: clock gating in idle This patch enables DSP clock gating for ACE platforms. By default, clock gating is blocked by the firmware in the hardware configuration. If CONFIG_ADSP_IDLE_CLOCK_GATING is enabled, this prevent is not active and clock can be gated when core is in idle state. WIth this option disabled clock gating will only be enabled in hardware during power gating. Signed-off-by: Tomasz Leman --- soc/xtensa/intel_adsp/Kconfig | 8 ++++++++ soc/xtensa/intel_adsp/ace/multiprocessing.c | 10 +++++++--- soc/xtensa/intel_adsp/ace/power.c | 14 +++++++++++--- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/soc/xtensa/intel_adsp/Kconfig b/soc/xtensa/intel_adsp/Kconfig index a3d93d976ea1..ed491015fac3 100644 --- a/soc/xtensa/intel_adsp/Kconfig +++ b/soc/xtensa/intel_adsp/Kconfig @@ -125,4 +125,12 @@ config XTENSA_WAITI_BUG platforms which prefixes a WAITI entry with 128 NOP instructions followed by an ISYNC and EXTW. +config ADSP_IDLE_CLOCK_GATING + bool "DSP clock gating in Idle" + help + When true, FW will run with enabled clock gating. This options change + HW configuration of a DSP. Evry time core goes to the WAITI state + (wait for interrupt) during idle, the clock can be gated (however, this + does not mean that this will happen). + endif # SOC_FAMILY_INTEL_ADSP diff --git a/soc/xtensa/intel_adsp/ace/multiprocessing.c b/soc/xtensa/intel_adsp/ace/multiprocessing.c index e762245e669e..2d3d74fa724b 100644 --- a/soc/xtensa/intel_adsp/ace/multiprocessing.c +++ b/soc/xtensa/intel_adsp/ace/multiprocessing.c @@ -161,9 +161,13 @@ void soc_mp_startup(uint32_t cpu) /* Must have this enabled always */ z_xtensa_irq_enable(ACE_INTC_IRQ); - /* Prevent idle from powering us off */ - DSPCS.bootctl[cpu].bctl |= - DSPBR_BCTL_WAITIPCG | DSPBR_BCTL_WAITIPPG; +#if CONFIG_ADSP_IDLE_CLOCK_GATING + /* Disable idle power gating */ + DSPCS.bootctl[cpu].bctl |= DSPBR_BCTL_WAITIPPG; +#else + /* Disable idle power and clock gating */ + DSPCS.bootctl[cpu].bctl |= DSPBR_BCTL_WAITIPCG | DSPBR_BCTL_WAITIPPG; +#endif /* CONFIG_ADSP_IDLE_CLOCK_GATING */ } void arch_sched_ipi(void) diff --git a/soc/xtensa/intel_adsp/ace/power.c b/soc/xtensa/intel_adsp/ace/power.c index 7fe33c3feaf8..cee8047d4a27 100644 --- a/soc/xtensa/intel_adsp/ace/power.c +++ b/soc/xtensa/intel_adsp/ace/power.c @@ -26,8 +26,13 @@ __imr void power_init(void) { +#if CONFIG_ADSP_IDLE_CLOCK_GATING /* Disable idle power gating */ + DSPCS.bootctl[0].bctl |= DSPBR_BCTL_WAITIPPG; +#else + /* Disable idle power and clock gating */ DSPCS.bootctl[0].bctl |= DSPBR_BCTL_WAITIPCG | DSPBR_BCTL_WAITIPPG; +#endif /* CONFIG_ADSP_IDLE_CLOCK_GATING */ } #ifdef CONFIG_PM @@ -358,8 +363,11 @@ void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) k_panic(); } - DSPCS.bootctl[cpu].bctl |= - DSPBR_BCTL_WAITIPCG | DSPBR_BCTL_WAITIPPG; +#if CONFIG_ADSP_IDLE_CLOCK_GATING + DSPCS.bootctl[cpu].bctl |= DSPBR_BCTL_WAITIPPG; +#else + DSPCS.bootctl[cpu].bctl |= DSPBR_BCTL_WAITIPCG | DSPBR_BCTL_WAITIPPG; +#endif /* CONFIG_ADSP_IDLE_CLOCK_GATING */ if (cpu == 0) { DSPCS.bootctl[cpu].battr &= (~LPSCTL_BATTR_MASK); } @@ -373,4 +381,4 @@ void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) z_xt_ints_on(core_desc[cpu].intenable); } -#endif +#endif /* CONFIG_PM */