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 <daniel.leung@intel.com>
This commit is contained in:
Daniel Leung 2021-08-02 10:09:11 -07:00 committed by Anas Nashif
commit 8a21dc8245
2 changed files with 60 additions and 66 deletions

View file

@ -72,53 +72,6 @@
#define SOC_DSP_SHIM_REG_BASE 0x00071f00 #define SOC_DSP_SHIM_REG_BASE 0x00071f00
#endif #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) */ /* DSP Wall Clock Timers (0 and 1) */
#define DSP_WCT_IRQ(x) \ #define DSP_WCT_IRQ(x) \
SOC_AGGREGATE_IRQ((22 + x), CAVS_L2_AGG_INT_LEVEL2) SOC_AGGREGATE_IRQ((22 + x), CAVS_L2_AGG_INT_LEVEL2)

View file

@ -10,6 +10,7 @@
#include <xtensa/hal.h> #include <xtensa/hal.h>
#include <init.h> #include <init.h>
#include <soc/shim.h>
#include "soc.h" #include "soc.h"
#ifdef CONFIG_DYNAMIC_INTERRUPTS #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 *dsp_shim_regs =
(volatile struct soc_dsp_shim_regs *)SOC_DSP_SHIM_REG_BASE; (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 0 PLL Clock Select divide by 1
* DSP Core 1 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 * High Power Domain PLL Clock Select device by 2
* Tensilica Core Prevent Audio PLL Shutdown (TCPAPLLS) * Low Power Domain PLL Clock Select device by 4
* Tensilica Core Prevent Local Clock Gating (Core 0) * Disable Tensilica Core Prevent Audio PLL Shutdown (TCPAPLLS)
* Tensilica Core Prevent Local Clock Gating (Core 1) * 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 = dsp_shim_regs->clkctl =
SOC_CLKCTL_DPCS_DIV1(0) | SHIM_CLKCTL_HDCS_PLL |
SOC_CLKCTL_DPCS_DIV1(1) | SHIM_CLKCTL_LDCS_PLL |
SOC_CLKCTL_LDCS_LMPCS | SHIM_CLKCTL_DPCS_DIV1(0) |
SOC_CLKCTL_HDCS_HMPCS | SHIM_CLKCTL_DPCS_DIV1(1) |
SOC_CLKCTL_LPMEM_PLL_CLK_SEL_DIV4 | SHIM_CLKCTL_HPMPCS_DIV2 |
SOC_CLKCTL_HPMEM_PLL_CLK_SEL_DIV2 | SHIM_CLKCTL_LPMPCS_DIV4 |
SOC_CLKCTL_TCPAPLLS | SHIM_CLKCTL_TCPAPLLS_DIS |
SOC_CLKCTL_TCPLCG_DIS(0) | SHIM_CLKCTL_TCPLCG_DIS(0) |
SOC_CLKCTL_TCPLCG_DIS(1); SHIM_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;
/* Rewrite the low power sequencing control bits */ /* Rewrite the low power sequencing control bits */
dsp_shim_regs->lpsctl = dsp_shim_regs->lpsctl; 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) static int soc_init(const struct device *dev)