From 8a21dc8245aa0c8a0beafe9935a53b5114a025a9 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 2 Aug 2021 10:09:11 -0700 Subject: [PATCH] xtensa: intel_adsp: align SoC initialization with SOF This aligns the SoC initialization with the one in SOF, especially the manipulation of clock control and power control registers. These registers are not entirely the same across CAVS versions, so we need to deal with them according to which version we are building for. This also consolidates the macros for these registers to the one provided by SOF (soc/shim.h) to avoid duplication. Another note is that the usage of clock gating bit was not correct. In SOF, clock gating of SoC cores should be allowed but the old code in Zephyr prevented clock gating, which has the potential to prevent the whole DSP from going into low power mode. Signed-off-by: Daniel Leung --- soc/xtensa/intel_adsp/common/include/soc.h | 47 ------------- soc/xtensa/intel_adsp/common/soc.c | 79 ++++++++++++++++------ 2 files changed, 60 insertions(+), 66 deletions(-) diff --git a/soc/xtensa/intel_adsp/common/include/soc.h b/soc/xtensa/intel_adsp/common/include/soc.h index 63dae0c6765..3430ee0fd76 100644 --- a/soc/xtensa/intel_adsp/common/include/soc.h +++ b/soc/xtensa/intel_adsp/common/include/soc.h @@ -72,53 +72,6 @@ #define SOC_DSP_SHIM_REG_BASE 0x00071f00 #endif -/* SOC DSP SHIM Register - Clock Control */ -#define SOC_CLKCTL_REQ_AUDIO_PLL_CLK BIT(31) -#define SOC_CLKCTL_REQ_XTAL_CLK BIT(30) -#define SOC_CLKCTL_REQ_FAST_CLK BIT(29) - -#define SOC_CLKCTL_TCPLCG_POS(x) (16 + x) -#define SOC_CLKCTL_TCPLCG_DIS(x) (1 << SOC_CLKCTL_TCPLCG_POS(x)) - -#define SOC_CLKCTL_DPCS_POS(x) (8 + x) -#define SOC_CLKCTL_DPCS_DIV1(x) (0 << SOC_CLKCTL_DPCS_POS(x)) -#define SOC_CLKCTL_DPCS_DIV2(x) (1 << SOC_CLKCTL_DPCS_POS(x)) -#define SOC_CLKCTL_DPCS_DIV4(x) (3 << SOC_CLKCTL_DPCS_POS(x)) - -#define SOC_CLKCTL_TCPAPLLS BIT(7) - -#define SOC_CLKCTL_LDCS_POS (5) -#define SOC_CLKCTL_LDCS_LMPCS (0 << SOC_CLKCTL_LDCS_POS) -#define SOC_CLKCTL_LDCS_LDOCS (1 << SOC_CLKCTL_LDCS_POS) - -#define SOC_CLKCTL_HDCS_POS (4) -#define SOC_CLKCTL_HDCS_HMPCS (0 << SOC_CLKCTL_HDCS_POS) -#define SOC_CLKCTL_HDCS_HDOCS (1 << SOC_CLKCTL_HDCS_POS) - -#define SOC_CLKCTL_LDOCS_POS (3) -#define SOC_CLKCTL_LDOCS_PLL (0 << SOC_CLKCTL_LDOCS_POS) -#define SOC_CLKCTL_LDOCS_FAST (1 << SOC_CLKCTL_LDOCS_POS) - -#define SOC_CLKCTL_HDOCS_POS (2) -#define SOC_CLKCTL_HDOCS_PLL (0 << SOC_CLKCTL_HDOCS_POS) -#define SOC_CLKCTL_HDOCS_FAST (1 << SOC_CLKCTL_HDOCS_POS) - -#define SOC_CLKCTL_LPMEM_PLL_CLK_SEL_POS (1) -#define SOC_CLKCTL_LPMEM_PLL_CLK_SEL_DIV2 \ - (0 << SOC_CLKCTL_LPMEM_PLL_CLK_SEL_POS) -#define SOC_CLKCTL_LPMEM_PLL_CLK_SEL_DIV4 \ - (1 << SOC_CLKCTL_LPMEM_PLL_CLK_SEL_POS) - -#define SOC_CLKCTL_HPMEM_PLL_CLK_SEL_POS (0) -#define SOC_CLKCTL_HPMEM_PLL_CLK_SEL_DIV2 \ - (0 << SOC_CLKCTL_HPMEM_PLL_CLK_SEL_POS) -#define SOC_CLKCTL_HPMEM_PLL_CLK_SEL_DIV4 \ - (1 << SOC_CLKCTL_HPMEM_PLL_CLK_SEL_POS) - -/* SOC DSP SHIM Register - Power Control */ -#define SOC_PWRCTL_DISABLE_PWR_GATING_DSP0 BIT(0) -#define SOC_PWRCTL_DISABLE_PWR_GATING_DSP1 BIT(1) - /* DSP Wall Clock Timers (0 and 1) */ #define DSP_WCT_IRQ(x) \ SOC_AGGREGATE_IRQ((22 + x), CAVS_L2_AGG_INT_LEVEL2) diff --git a/soc/xtensa/intel_adsp/common/soc.c b/soc/xtensa/intel_adsp/common/soc.c index de94fc1c81d..0ddb2e4b3bb 100644 --- a/soc/xtensa/intel_adsp/common/soc.c +++ b/soc/xtensa/intel_adsp/common/soc.c @@ -10,6 +10,7 @@ #include #include +#include #include "soc.h" #ifdef CONFIG_DYNAMIC_INTERRUPTS @@ -195,34 +196,74 @@ static inline void soc_set_power_and_clock(void) volatile struct soc_dsp_shim_regs *dsp_shim_regs = (volatile struct soc_dsp_shim_regs *)SOC_DSP_SHIM_REG_BASE; +#ifdef CONFIG_SOC_SERIES_INTEL_CAVS_V15 /* + * HP domain clocked by PLL + * LP domain clocked by PLL * DSP Core 0 PLL Clock Select divide by 1 * DSP Core 1 PLL Clock Select divide by 1 - * Low Power Domain Clock Select depends on LMPCS bit - * High Power Domain Clock Select depands on HMPCS bit - * Low Power Domain PLL Clock Select device by 4 * High Power Domain PLL Clock Select device by 2 - * Tensilica Core Prevent Audio PLL Shutdown (TCPAPLLS) - * Tensilica Core Prevent Local Clock Gating (Core 0) - * Tensilica Core Prevent Local Clock Gating (Core 1) + * Low Power Domain PLL Clock Select device by 4 + * Disable Tensilica Core Prevent Audio PLL Shutdown (TCPAPLLS) + * Disable Tensilica Core Prevent Local Clock Gating (Core 0) + * Disable Tensilica Core Prevent Local Clock Gating (Core 1) + * - Disabling "prevent clock gating" means allowing clock gating */ dsp_shim_regs->clkctl = - SOC_CLKCTL_DPCS_DIV1(0) | - SOC_CLKCTL_DPCS_DIV1(1) | - SOC_CLKCTL_LDCS_LMPCS | - SOC_CLKCTL_HDCS_HMPCS | - SOC_CLKCTL_LPMEM_PLL_CLK_SEL_DIV4 | - SOC_CLKCTL_HPMEM_PLL_CLK_SEL_DIV2 | - SOC_CLKCTL_TCPAPLLS | - SOC_CLKCTL_TCPLCG_DIS(0) | - SOC_CLKCTL_TCPLCG_DIS(1); - - /* Disable power gating for both cores */ - dsp_shim_regs->pwrctl |= SOC_PWRCTL_DISABLE_PWR_GATING_DSP1 | - SOC_PWRCTL_DISABLE_PWR_GATING_DSP0; + SHIM_CLKCTL_HDCS_PLL | + SHIM_CLKCTL_LDCS_PLL | + SHIM_CLKCTL_DPCS_DIV1(0) | + SHIM_CLKCTL_DPCS_DIV1(1) | + SHIM_CLKCTL_HPMPCS_DIV2 | + SHIM_CLKCTL_LPMPCS_DIV4 | + SHIM_CLKCTL_TCPAPLLS_DIS | + SHIM_CLKCTL_TCPLCG_DIS(0) | + SHIM_CLKCTL_TCPLCG_DIS(1); /* Rewrite the low power sequencing control bits */ dsp_shim_regs->lpsctl = dsp_shim_regs->lpsctl; +#endif /* CONFIG_SOC_SERIES_INTEL_CAVS_V15 */ + +#if defined(CONFIG_SOC_SERIES_INTEL_CAVS_V18) || \ + defined(CONFIG_SOC_SERIES_INTEL_CAVS_V20) || \ + defined(CONFIG_SOC_SERIES_INTEL_CAVS_V25) + + /* + * Request HP ring oscillator and + * wait for status to indicate it's ready. + */ + dsp_shim_regs->clkctl |= SHIM_CLKCTL_RHROSCC; + while ((dsp_shim_regs->clkctl & SHIM_CLKCTL_RHROSCC) != + SHIM_CLKCTL_RHROSCC) { + k_busy_wait(10); + } + + /* + * Request HP Ring Oscillator + * Select HP Ring Oscillator + * High Power Domain PLL Clock Select device by 2 + * Low Power Domain PLL Clock Select device by 4 + * Disable Tensilica Core(s) Prevent Local Clock Gating + * - Disabling "prevent clock gating" means allowing clock gating + */ + dsp_shim_regs->clkctl = + SHIM_CLKCTL_RHROSCC | + SHIM_CLKCTL_OCS_HP_RING | + SHIM_CLKCTL_HMCS_DIV2 | + SHIM_CLKCTL_LMCS_DIV4 | + SHIM_CLKCTL_TCPLCG_DIS_ALL; + + /* Prevent LP GPDMA 0 & 1 clock gating */ + sys_write32(SHIM_CLKCTL_LPGPDMAFDCGB, SHIM_GPDMA_CLKCTL(0)); + sys_write32(SHIM_CLKCTL_LPGPDMAFDCGB, SHIM_GPDMA_CLKCTL(1)); + + /* Disable power gating for first cores */ + dsp_shim_regs->pwrctl |= SHIM_PWRCTL_TCPDSPPG(0); + +#endif /* CONFIG_SOC_SERIES_INTEL_CAVS_V18 || + * CONFIG_SOC_SERIES_INTEL_CAVS_V20 || + * CONFIG_SOC_SERIES_INTEL_CAVS_V25 + */ } static int soc_init(const struct device *dev)