Revert "drivers: intel: ssp: Revise receive FIFO draining"

This reverts commit 97bb67d66c.

The revised FIFO draining seems to cause failures due
to channel shift with Intel MTL platform.

Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
This commit is contained in:
Kai Vehmanen 2023-10-26 19:46:06 +03:00 committed by Maureen Helm
parent 7b2cb95cd5
commit 3e4c50b0ef

View file

@ -837,73 +837,36 @@ static void dai_ssp_empty_tx_fifo(struct dai_intel_ssp *dp)
} }
} }
static void ssp_empty_rx_fifo_on_start(struct dai_intel_ssp *dp) /* empty SSP receive FIFO */
{ static void dai_ssp_empty_rx_fifo(struct dai_intel_ssp *dp)
uint32_t retry = DAI_INTEL_SSP_RX_FLUSH_RETRY_MAX;
uint32_t i, sssr;
sssr = sys_read32(dai_base(dp) + SSSR);
if (sssr & SSSR_ROR) {
/* The RX FIFO is in overflow condition, empty it */
for (i = 0; i < DAI_INTEL_SSP_FIFO_DEPTH; i++)
sys_read32(dai_base(dp) + SSDR);
/* Clear the overflow status */
dai_ssp_update_bits(dp, SSSR, SSSR_ROR, SSSR_ROR);
/* Re-read the SSSR register */
sssr = sys_read32(dai_base(dp) + SSSR);
}
while ((sssr & SSSR_RNE) && retry--) {
uint32_t entries = SSCR3_RFL_VAL(sys_read32(dai_base(dp) + SSCR3));
/* Empty the RX FIFO (the DMA is not running at this point) */
for (i = 0; i < entries + 1; i++)
sys_read32(dai_base(dp) + SSDR);
sssr = sys_read32(dai_base(dp) + SSSR);
}
}
static void ssp_empty_rx_fifo_on_stop(struct dai_intel_ssp *dp)
{ {
struct dai_intel_ssp_pdata *ssp = dai_get_drvdata(dp); struct dai_intel_ssp_pdata *ssp = dai_get_drvdata(dp);
uint64_t sample_ticks = ssp->params.fsync_rate ? 1000000 / ssp->params.fsync_rate : 0;
uint32_t retry = DAI_INTEL_SSP_RX_FLUSH_RETRY_MAX; uint32_t retry = DAI_INTEL_SSP_RX_FLUSH_RETRY_MAX;
uint32_t entries[2]; uint32_t entries;
uint32_t i, sssr; uint32_t i;
sssr = sys_read32(dai_base(dp) + SSSR); /*
entries[0] = SSCR3_RFL_VAL(sys_read32(dai_base(dp) + SSCR3)); * 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,
while ((sssr & SSSR_RNE) && retry--) { * and then re-check to see if there is any subsequent entries written
/* Wait one sample time */ * to the FIFO. This will help to make sure there is no sample mismatched
k_busy_wait(sample_ticks); * issue for the next run with the SSP RX.
*/
entries[1] = SSCR3_RFL_VAL(sys_read32(dai_base(dp) + SSCR3)); while ((sys_read32(dai_base(dp) + SSSR) & SSSR_RNE) && retry--) {
sssr = sys_read32(dai_base(dp) + SSSR); entries = SSCR3_RFL_VAL(sys_read32(dai_base(dp) + SSCR3));
LOG_DBG("%s before flushing, entries %d", __func__, entries);
if (entries[0] > entries[1]) { for (i = 0; i < entries + 1; i++) {
/* /* read to try empty fifo */
* The DMA is reading the FIFO, check the status in the sys_read32(dai_base(dp) + SSDR);
* next loop
*/
entries[0] = entries[1];
} else if (!(sssr & SSSR_RFS)) {
/*
* The DMA request is not asserted, read the FIFO
* directly, otherwise let the next loop iteration to
* check the status
*/
for (i = 0; i < entries[1] + 1; i++)
sys_read32(dai_base(dp) + SSDR);
} }
sssr = sys_read32(dai_base(dp) + SSSR); /* wait to get valid fifo status and re-check */
k_busy_wait(ssp->params.fsync_rate ? 1000000 / ssp->params.fsync_rate : 0);
entries = SSCR3_RFL_VAL(sys_read32(dai_base(dp) + SSCR3));
LOG_DBG("%s after flushing, entries %d", __func__, entries);
} }
/* Just in case clear the overflow status */ /* clear interrupt */
dai_ssp_update_bits(dp, SSSR, SSSR_ROR, SSSR_ROR); dai_ssp_update_bits(dp, SSSR, SSSR_ROR, SSSR_ROR);
} }
@ -1938,10 +1901,6 @@ static void dai_ssp_early_start(struct dai_intel_ssp *dp, int direction)
key = k_spin_lock(&dp->lock); key = k_spin_lock(&dp->lock);
/* RX fifo must be cleared before start */
if (direction == DAI_DIR_CAPTURE)
ssp_empty_rx_fifo_on_start(dp);
/* request mclk/bclk */ /* request mclk/bclk */
dai_ssp_pre_start(dp); dai_ssp_pre_start(dp);
@ -2022,7 +1981,7 @@ static void dai_ssp_stop(struct dai_intel_ssp *dp, int direction)
if (direction == DAI_DIR_CAPTURE && if (direction == DAI_DIR_CAPTURE &&
ssp->state[DAI_DIR_CAPTURE] != DAI_STATE_PRE_RUNNING) { ssp->state[DAI_DIR_CAPTURE] != DAI_STATE_PRE_RUNNING) {
dai_ssp_update_bits(dp, SSRSA, SSRSA_RXEN, 0); dai_ssp_update_bits(dp, SSRSA, SSRSA_RXEN, 0);
ssp_empty_rx_fifo_on_stop(dp); dai_ssp_empty_rx_fifo(dp);
ssp->state[DAI_DIR_CAPTURE] = DAI_STATE_PRE_RUNNING; ssp->state[DAI_DIR_CAPTURE] = DAI_STATE_PRE_RUNNING;
LOG_INF("%s RX stop", __func__); LOG_INF("%s RX stop", __func__);
} }
@ -2200,6 +2159,8 @@ static int dai_ssp_probe(struct dai_intel_ssp *dp)
/* Disable dynamic clock gating before touching any register */ /* Disable dynamic clock gating before touching any register */
dai_ssp_pm_runtime_dis_ssp_clk_gating(dp, dp->index); dai_ssp_pm_runtime_dis_ssp_clk_gating(dp, dp->index);
dai_ssp_empty_rx_fifo(dp);
return 0; return 0;
} }