ssp: SSCR reset - hardware specific flow

hardware specific flow using bit 20 (SSCR2_SFRMEN)  for reset

Signed-off-by: Arsen Eloglian <ArsenX.Eloglian@intel.com>
This commit is contained in:
Arsen Eloglian 2022-05-24 15:52:34 +02:00 committed by Carles Cufí
commit d4c1c1ebef
5 changed files with 29 additions and 5 deletions

View file

@ -21,3 +21,5 @@ CONFIG_BUILD_OUTPUT_BIN=n
CONFIG_CLEANUP_INTERMEDIATE_FILES=y CONFIG_CLEANUP_INTERMEDIATE_FILES=y
CONFIG_MP_NUM_CPUS=4 CONFIG_MP_NUM_CPUS=4
CONFIG_DAI_SSP_HAS_POWER_CONTROL=y

View file

@ -19,3 +19,5 @@ CONFIG_CAVS_ICTL=y
CONFIG_BOOTLOADER_SRAM_SIZE=192 CONFIG_BOOTLOADER_SRAM_SIZE=192
CONFIG_BUILD_OUTPUT_BIN=n CONFIG_BUILD_OUTPUT_BIN=n
CONFIG_CLEANUP_INTERMEDIATE_FILES=y CONFIG_CLEANUP_INTERMEDIATE_FILES=y
CONFIG_DAI_SSP_HAS_POWER_CONTROL=y

View file

@ -12,3 +12,7 @@ config DAI_INTEL_SSP
help help
Enable Inter Sound (I2S) bus driver based on Enable Inter Sound (I2S) bus driver based on
Synchronous Serial Port (SSP) module. Synchronous Serial Port (SSP) module.
config DAI_SSP_HAS_POWER_CONTROL
bool "DAI ssp pm_runtime en/dis ssp power"
depends on DAI_INTEL_SSP

View file

@ -5,6 +5,7 @@
*/ */
#include <errno.h> #include <errno.h>
#include <zephyr/sys/util_macro.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <zephyr/spinlock.h> #include <zephyr/spinlock.h>
@ -706,7 +707,7 @@ static inline void dai_ssp_pm_runtime_en_ssp_clk_gating(struct dai_intel_ssp *dp
static void dai_ssp_pm_runtime_en_ssp_power(struct dai_intel_ssp *dp, uint32_t index) static void dai_ssp_pm_runtime_en_ssp_power(struct dai_intel_ssp *dp, uint32_t index)
{ {
#if CONFIG_SOC_SERIES_INTEL_CAVS_V25 #if CONFIG_DAI_SSP_HAS_POWER_CONTROL
int ret; int ret;
LOG_INF("%s en_ssp_power index %d", __func__, index); LOG_INF("%s en_ssp_power index %d", __func__, index);
@ -724,12 +725,15 @@ static void dai_ssp_pm_runtime_en_ssp_power(struct dai_intel_ssp *dp, uint32_t i
} }
LOG_INF("%s I2SLCTL", __func__); LOG_INF("%s I2SLCTL", __func__);
#endif #else
ARG_UNUSED(dp);
ARG_UNUSED(index);
#endif /* CONFIG_DAI_SSP_HAS_POWER_CONTROL */
} }
static void dai_ssp_pm_runtime_dis_ssp_power(struct dai_intel_ssp *dp, uint32_t index) static void dai_ssp_pm_runtime_dis_ssp_power(struct dai_intel_ssp *dp, uint32_t index)
{ {
#if CONFIG_SOC_SERIES_INTEL_CAVS_V25 #if CONFIG_DAI_SSP_HAS_POWER_CONTROL
int ret; int ret;
LOG_INF("%s index %d", __func__, index); LOG_INF("%s index %d", __func__, index);
@ -747,7 +751,10 @@ static void dai_ssp_pm_runtime_dis_ssp_power(struct dai_intel_ssp *dp, uint32_t
} }
LOG_INF("%s I2SLCTL", __func__); LOG_INF("%s I2SLCTL", __func__);
#endif #else
ARG_UNUSED(dp);
ARG_UNUSED(index);
#endif /* CONFIG_DAI_SSP_HAS_POWER_CONTROL */
} }
/* empty SSP transmit FIFO */ /* empty SSP transmit FIFO */
@ -1538,7 +1545,11 @@ static int dai_ssp_set_config_blob(struct dai_intel_ssp *dp, const void *spec_co
ssrsa = blob->i2s_driver_config.i2s_config.ssrsa; ssrsa = blob->i2s_driver_config.i2s_config.ssrsa;
sys_write32(ssc0, dai_base(dp) + SSCR0); sys_write32(ssc0, dai_base(dp) + SSCR0);
sys_write32(blob->i2s_driver_config.i2s_config.ssc2 & ~SSCR2_SFRMEN,
dai_base(dp) + SSCR2); /* hardware specific flow */
sys_write32(blob->i2s_driver_config.i2s_config.ssc1, dai_base(dp) + SSCR1); sys_write32(blob->i2s_driver_config.i2s_config.ssc1, dai_base(dp) + SSCR1);
sys_write32(blob->i2s_driver_config.i2s_config.ssc2 | SSCR2_SFRMEN,
dai_base(dp) + SSCR2); /* hardware specific flow */
sys_write32(blob->i2s_driver_config.i2s_config.ssc2, dai_base(dp) + SSCR2); sys_write32(blob->i2s_driver_config.i2s_config.ssc2, dai_base(dp) + SSCR2);
sys_write32(blob->i2s_driver_config.i2s_config.ssc3, dai_base(dp) + SSCR3); sys_write32(blob->i2s_driver_config.i2s_config.ssc3, dai_base(dp) + SSCR3);
sys_write32(blob->i2s_driver_config.i2s_config.sspsp, dai_base(dp) + SSPSP); sys_write32(blob->i2s_driver_config.i2s_config.sspsp, dai_base(dp) + SSPSP);
@ -1748,7 +1759,10 @@ static void dai_ssp_stop(struct dai_intel_ssp *dp, int direction)
/* disable SSP port if no users */ /* disable SSP port if no users */
if (ssp->state[DAI_DIR_CAPTURE] == DAI_STATE_PRE_RUNNING && if (ssp->state[DAI_DIR_CAPTURE] == DAI_STATE_PRE_RUNNING &&
ssp->state[DAI_DIR_PLAYBACK] == DAI_STATE_PRE_RUNNING) { ssp->state[DAI_DIR_PLAYBACK] == DAI_STATE_PRE_RUNNING) {
if (!(ssp->clk_active & SSP_CLK_BCLK_ES_REQ)) { bool clear_rse_bits = COND_CODE_1(CONFIG_INTEL_ADSP_CAVS,
(!(ssp->clk_active & SSP_CLK_BCLK_ES_REQ)),
(false));
if (clear_rse_bits) {
/* clear TRSE/RSRE before SSE */ /* clear TRSE/RSRE before SSE */
dai_ssp_update_bits(dp, SSCR1, SSCR1_TSRE | SSCR1_RSRE, 0); dai_ssp_update_bits(dp, SSCR1, SSCR1_TSRE | SSCR1_RSRE, 0);
dai_ssp_update_bits(dp, SSCR0, SSCR0_SSE, 0); dai_ssp_update_bits(dp, SSCR0, SSCR0_SSE, 0);

View file

@ -130,6 +130,8 @@
#define SSCR2_LJDFD BIT(17) #define SSCR2_LJDFD BIT(17)
#define SSCR2_MMRATF BIT(18) #define SSCR2_MMRATF BIT(18)
#define SSCR2_SMTATF BIT(19) #define SSCR2_SMTATF BIT(19)
#define SSCR2_SFRMEN BIT(20)
#define SSCR2_ACIOLBS BIT(21)
/* SSR bits */ /* SSR bits */
#define SSSR_TNF BIT(2) #define SSSR_TNF BIT(2)