From ab42160a6dc17e67941e0d0cce43f36015738169 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Fri, 5 May 2023 15:46:55 +0300 Subject: [PATCH 1/2] intel: ssp: do not read data directly if DMA is active If DMA is active, do not read data directly from the SSP RX fifo. Signed-off-by: Kai Vehmanen --- src/drivers/intel/ssp/ssp.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/drivers/intel/ssp/ssp.c b/src/drivers/intel/ssp/ssp.c index 16e9e1727768..7ad1a4fea0f4 100644 --- a/src/drivers/intel/ssp/ssp.c +++ b/src/drivers/intel/ssp/ssp.c @@ -74,9 +74,18 @@ static void ssp_empty_rx_fifo(struct dai *dai) uint64_t sample_ticks = clock_ticks_per_sample(PLATFORM_DEFAULT_CLOCK, ssp->params.fsync_rate); uint32_t retry = SSP_RX_FLUSH_RETRY_MAX; + bool read_ssdr = ssp->state[DAI_DIR_CAPTURE] <= COMP_STATE_PREPARE; uint32_t entries; uint32_t i; +#if CONFIG_DMA_SUSPEND_DRAIN + /* + * in drain mode, DMA is stopped before DAI, + * so flush must be done with direct register read + */ + read_ssdr = true; +#endif + /* * To make sure all the RX FIFO entries are read out for the flushing, * we need to wait a minimal SSP port delay after entries are all read, @@ -87,7 +96,8 @@ static void ssp_empty_rx_fifo(struct dai *dai) while ((ssp_read(dai, SSSR) & SSSR_RNE) && retry--) { entries = SSCR3_RFL_VAL(ssp_read(dai, SSCR3)); dai_dbg(dai, "ssp_empty_rx_fifo(), before flushing, entries %d", entries); - for (i = 0; i < entries + 1; i++) + + for (i = 0; read_ssdr && i < entries + 1; i++) /* read to try empty fifo */ ssp_read(dai, SSDR); From 1bb0947c676f07e99b81b67168a8ec2a39bbd2d1 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Fri, 5 May 2023 15:37:22 +0300 Subject: [PATCH 2/2] intel: ssp: drain RX fifo when starting If DMA transaction is ongoing when RX enabled, this leads to stuck communication between DMA and SSP. To avoid this, flush the RX fifo before enabling SSP RX. Link: https://github.com/thesofproject/sof/issues/7548 Suggested-by: Peter Ujfalusi Signed-off-by: Kai Vehmanen --- src/drivers/intel/ssp/ssp.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/drivers/intel/ssp/ssp.c b/src/drivers/intel/ssp/ssp.c index 7ad1a4fea0f4..daf8f05464cd 100644 --- a/src/drivers/intel/ssp/ssp.c +++ b/src/drivers/intel/ssp/ssp.c @@ -973,6 +973,11 @@ static void ssp_early_start(struct dai *dai, int direction) key = k_spin_lock(&dai->lock); + if (direction == DAI_DIR_CAPTURE) { + /* RX fifo must be cleared before start */ + ssp_empty_rx_fifo(dai); + } + /* request mclk/bclk */ ssp_pre_start(dai);