mirror of https://github.com/thesofproject/sof.git
ssp: refine the RX FIFO flushing logic
The SSSR_BSY is not necessary for flushing, we need to read out entries every time the FIFO is not empty. This flushing may need take place several rounds, and we need to wait 1 sample time between 2 flushing rounds. Fixes #3525 Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
This commit is contained in:
parent
322839449d
commit
60dfaa7ee3
|
@ -67,24 +67,32 @@ static void ssp_empty_tx_fifo(struct dai *dai)
|
||||||
/* empty SSP receive FIFO */
|
/* empty SSP receive FIFO */
|
||||||
static void ssp_empty_rx_fifo(struct dai *dai)
|
static void ssp_empty_rx_fifo(struct dai *dai)
|
||||||
{
|
{
|
||||||
struct timer *timer = timer_get();
|
struct ssp_pdata *ssp = dai_get_drvdata(dai);
|
||||||
uint64_t deadline = platform_timer_get(timer) +
|
uint64_t sample_ticks = clock_ticks_per_sample(PLATFORM_DEFAULT_CLOCK,
|
||||||
clock_ms_to_ticks(PLATFORM_DEFAULT_CLOCK, 1) *
|
ssp->params.fsync_rate);
|
||||||
SSP_RX_FLUSH_TIMEOUT / 1000;
|
uint32_t retry = SSP_RX_FLUSH_RETRY_MAX;
|
||||||
|
uint32_t entries;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* To make sure all the RX FIFO entries are read out for the flushing,
|
* To make sure all the RX FIFO entries are read out for the flushing,
|
||||||
* we need to wait until the SSSR_RNE is cleared after the SSP link is
|
* we need to wait a minimal SSP port delay after entries are all read,
|
||||||
* stopped (the SSSR_BSY is cleared), otherwise, there might be
|
* and then re-check to see if there is any subsequent entries written
|
||||||
* obsoleted entries remained in the FIFO, which will impact the next
|
* to the FIFO. This will help to make sure there is no sample mismatched
|
||||||
* run with the SSP RX and lead to samples mismatched issue.
|
* issue for the next run with the SSP RX.
|
||||||
*/
|
*/
|
||||||
do {
|
while ((ssp_read(dai, SSSR) & SSSR_RNE) && retry--) {
|
||||||
while (ssp_read(dai, SSSR) & SSSR_RNE)
|
entries = SSCR3_RFL_VAL(ssp_read(dai, SSCR3));
|
||||||
/* read to empty the fifo */
|
dai_dbg(dai, "ssp_empty_rx_fifo(), before flushing, entries %d", entries);
|
||||||
|
for (i = 0; i < entries + 1; i++)
|
||||||
|
/* read to try empty fifo */
|
||||||
ssp_read(dai, SSDR);
|
ssp_read(dai, SSDR);
|
||||||
} while ((ssp_read(dai, SSSR) & SSSR_BSY) &&
|
|
||||||
platform_timer_get(timer) < deadline);
|
/* wait to get valid fifo status and re-check */
|
||||||
|
wait_delay(sample_ticks);
|
||||||
|
entries = SSCR3_RFL_VAL(ssp_read(dai, SSCR3));
|
||||||
|
dai_dbg(dai, "ssp_empty_rx_fifo(), after flushing, entries %d", entries);
|
||||||
|
}
|
||||||
|
|
||||||
/* clear interrupt */
|
/* clear interrupt */
|
||||||
ssp_update_bits(dai, SSSR, SSSR_ROR, SSSR_ROR);
|
ssp_update_bits(dai, SSSR, SSSR_ROR, SSSR_ROR);
|
||||||
|
|
|
@ -220,8 +220,8 @@ extern const struct dai_driver ssp_driver;
|
||||||
/* For 8000 Hz rate one sample is transmitted within 125us */
|
/* For 8000 Hz rate one sample is transmitted within 125us */
|
||||||
#define SSP_MAX_SEND_TIME_PER_SAMPLE 125
|
#define SSP_MAX_SEND_TIME_PER_SAMPLE 125
|
||||||
|
|
||||||
/* SSP flush timeout in microseconds */
|
/* SSP flush retry counts maximum */
|
||||||
#define SSP_RX_FLUSH_TIMEOUT 200
|
#define SSP_RX_FLUSH_RETRY_MAX 16
|
||||||
|
|
||||||
#define ssp_irq(ssp) \
|
#define ssp_irq(ssp) \
|
||||||
ssp->plat_data.irq
|
ssp->plat_data.irq
|
||||||
|
|
Loading…
Reference in New Issue