From 753aa2d1f62e1517618366fcea28bada522e6fe1 Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Fri, 3 Nov 2023 13:53:54 +0800 Subject: [PATCH 1/3] arch/soc: introduce config for custom arch_cpu_idle implementation Each arch platform may has a general arch_cpu_idle implementation but each vendor may has a custom one, so this config will be used for vendor to override it. Some workarounds were introduced for intel cavs2.5 platform bring up. It is not general so move them to platform code. Signed-off-by: Rander Wang --- arch/Kconfig | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/Kconfig b/arch/Kconfig index 65b73557f7b678..c30fd4bb7847a6 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -976,3 +976,10 @@ config TOOLCHAIN_HAS_BUILTIN_FFS default y if !(64BIT && RISCV) help Hidden option to signal that toolchain has __builtin_ffs*(). + +config ARCH_CPU_IDLE_CUSTOM + bool "Custom arch_cpu_idle implementation" + default n + help + This options allows applications to override the default arch idle implementation with + a custom one. From 4bea568af0eb2857f6c16f6a36f688d1dd68de81 Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Fri, 3 Nov 2023 14:13:37 +0800 Subject: [PATCH 2/3] soc: intel_adsp/cavs: add arch_cpu_idle support Cavs platforms starts from Apllolake to Raptorlake. Some of them need some workaround for arch_cpu_idle so create a bespoken one. Each workaround is configured by kconfig setting. Signed-off-by: Rander Wang --- soc/xtensa/intel_adsp/cavs/power.c | 45 ++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/soc/xtensa/intel_adsp/cavs/power.c b/soc/xtensa/intel_adsp/cavs/power.c index bc955b3cb90e21..c0a75f5c0ecec4 100644 --- a/soc/xtensa/intel_adsp/cavs/power.c +++ b/soc/xtensa/intel_adsp/cavs/power.c @@ -180,6 +180,51 @@ void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) } #endif /* CONFIG_PM */ +#ifdef CONFIG_ARCH_CPU_IDLE_CUSTOM +/* xt-clang removes any NOPs more than 8. So we need to set + * no optimization to avoid those NOPs from being removed. + * + * This function is simply enough and full of hand written + * assembly that optimization is not really meaningful + * anyway. So we can skip optimization unconditionally. + * Re-evalulate its use and add #ifdef if this assumption + * is no longer valid. + */ +__no_optimization +void arch_cpu_idle(void) +{ + sys_trace_idle(); + + /* Just spin forever with interrupts unmasked, for platforms + * where WAITI can't be used or where its behavior is + * complicated (Intel DSPs will power gate on idle entry under + * some circumstances) + */ + if (IS_ENABLED(CONFIG_XTENSA_CPU_IDLE_SPIN)) { + __asm__ volatile("rsil a0, 0"); + __asm__ volatile("loop_forever: j loop_forever"); + return; + } + + /* Cribbed from SOF: workaround for a bug in some versions of + * the LX6 IP. Preprocessor ugliness avoids the need to + * figure out how to get the compiler to unroll a loop. + */ + if (IS_ENABLED(CONFIG_XTENSA_WAITI_BUG)) { +#define NOP4 __asm__ volatile("nop; nop; nop; nop"); +#define NOP32 NOP4 NOP4 NOP4 NOP4 NOP4 NOP4 NOP4 NOP4 +#define NOP128() NOP32 NOP32 NOP32 NOP32 + NOP128(); +#undef NOP128 +#undef NOP32 +#undef NOP4 + __asm__ volatile("isync; extw"); + } + +__asm__ volatile ("waiti 0"); +} +#endif + __imr void power_init(void) { /* Request HP ring oscillator and From 0b1b664b08ac7024eff51aaecce129eb1902b073 Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Fri, 3 Nov 2023 13:53:54 +0800 Subject: [PATCH 3/3] arch/xtensa: clean up arch_cpu_idle function Some workarounds were introduced for intel cavs2.5 platform bring up. It is not general so move them to platform code. Signed-off-by: Rander Wang --- arch/xtensa/Kconfig | 12 ----------- arch/xtensa/core/cpu_idle.c | 39 ++--------------------------------- soc/xtensa/intel_adsp/Kconfig | 12 +++++++++++ 3 files changed, 14 insertions(+), 49 deletions(-) diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 29c06667f55555..a1517f17ed0976 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -50,18 +50,6 @@ config XTENSA_ENABLE_BACKTRACE help Enable this config option to print backtrace on panic exception -config XTENSA_CPU_IDLE_SPIN - bool "Use busy loop for k_cpu_idle" - help - Use a spin loop instead of WAITI for the CPU idle state. - -config XTENSA_WAITI_BUG - bool "Workaround sequence for WAITI bug on LX6" - help - SOF traditionally contains this workaround on its ADSP - platforms which prefixes a WAITI entry with 128 NOP - instructions followed by an ISYNC and EXTW. - config XTENSA_SMALL_VECTOR_TABLE_ENTRY bool "Workaround for small vector table entries" help diff --git a/arch/xtensa/core/cpu_idle.c b/arch/xtensa/core/cpu_idle.c index fa9384d8445a8e..dae79f023ff7a3 100644 --- a/arch/xtensa/core/cpu_idle.c +++ b/arch/xtensa/core/cpu_idle.c @@ -6,48 +6,13 @@ #include #include -/* xt-clang removes any NOPs more than 8. So we need to set - * no optimization to avoid those NOPs from being removed. - * - * This function is simply enough and full of hand written - * assembly that optimization is not really meaningful - * anyway. So we can skip optimization unconditionally. - * Re-evalulate its use and add #ifdef if this assumption - * is no longer valid. - */ -__no_optimization +#ifndef CONFIG_ARCH_CPU_IDLE_CUSTOM void arch_cpu_idle(void) { sys_trace_idle(); - - /* Just spin forever with interrupts unmasked, for platforms - * where WAITI can't be used or where its behavior is - * complicated (Intel DSPs will power gate on idle entry under - * some circumstances) - */ - if (IS_ENABLED(CONFIG_XTENSA_CPU_IDLE_SPIN)) { - __asm__ volatile("rsil a0, 0"); - __asm__ volatile("loop_forever: j loop_forever"); - return; - } - - /* Cribbed from SOF: workaround for a bug in some versions of - * the LX6 IP. Preprocessor ugliness avoids the need to - * figure out how to get the compiler to unroll a loop. - */ - if (IS_ENABLED(CONFIG_XTENSA_WAITI_BUG)) { -#define NOP4 __asm__ volatile("nop; nop; nop; nop"); -#define NOP32 NOP4 NOP4 NOP4 NOP4 NOP4 NOP4 NOP4 NOP4 -#define NOP128() NOP32 NOP32 NOP32 NOP32 - NOP128(); -#undef NOP128 -#undef NOP32 -#undef NOP4 - __asm__ volatile("isync; extw"); - } - __asm__ volatile ("waiti 0"); } +#endif void arch_cpu_atomic_idle(unsigned int key) { diff --git a/soc/xtensa/intel_adsp/Kconfig b/soc/xtensa/intel_adsp/Kconfig index f04286ccae12b4..a3d93d976ea1a8 100644 --- a/soc/xtensa/intel_adsp/Kconfig +++ b/soc/xtensa/intel_adsp/Kconfig @@ -113,4 +113,16 @@ config ADSP_IMR_CONTEXT_SAVE entering D3 state. Later this context can be used to FW restore when Host power up DSP again. +config XTENSA_CPU_IDLE_SPIN + bool "Use busy loop for k_cpu_idle" + help + Use a spin loop instead of WAITI for the CPU idle state. + +config XTENSA_WAITI_BUG + bool "Workaround sequence for WAITI bug on LX6" + help + SOF traditionally contains this workaround on its ADSP + platforms which prefixes a WAITI entry with 128 NOP + instructions followed by an ISYNC and EXTW. + endif # SOC_FAMILY_INTEL_ADSP