Skip to content

Commit 6183e8c

Browse files
ujfalusiabonislawski
authored andcommitted
intel: ssp: Revise receive FIFO draining
The receive FIFO needs to be drained in a different way depending when it is done. - before start If the RX FIFO is in overflow state then we must read all the entries out to empty it (it was after all full). - before stop The DMA might be already running to read out data. Check the FIFO level change in one sample time which gives us the needed information to decide to wait for another loop for the DMA burst to finish, wait for the DMA to start it's burst (DMA request was asserted) or drain the FIFO directly. No need to drain the RX fifo at probe time. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> (cherry picked from commit 69d56a7) (cherry picked from commit 6571598)
1 parent 01fbc23 commit 6183e8c

1 file changed

Lines changed: 57 additions & 34 deletions

File tree

  • src/drivers/intel/ssp

src/drivers/intel/ssp/ssp.c

Lines changed: 57 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -64,49 +64,74 @@ static void ssp_empty_tx_fifo(struct dai *dai)
6464
ssp_write(dai, SSSR, sssr);
6565
}
6666

67-
/* empty SSP receive FIFO */
68-
static void ssp_empty_rx_fifo(struct dai *dai)
67+
static void ssp_empty_rx_fifo_on_start(struct dai *dai)
68+
{
69+
uint32_t retry = SSP_RX_FLUSH_RETRY_MAX;
70+
uint32_t i, sssr;
71+
72+
sssr = ssp_read(dai, SSSR);
73+
74+
if (sssr & SSSR_ROR) {
75+
/* The RX FIFO is in overflow condition, empty it */
76+
for (i = 0; i < SSP_FIFO_DEPTH; i++)
77+
ssp_read(dai, SSDR);
78+
79+
/* Clear the overflow status */
80+
ssp_update_bits(dai, SSSR, SSSR_ROR, SSSR_ROR);
81+
/* Re-read the SSSR register */
82+
sssr = ssp_read(dai, SSSR);
83+
}
84+
85+
while ((sssr & SSSR_RNE) && retry--) {
86+
uint32_t entries = SSCR3_RFL_VAL(ssp_read(dai, SSCR3));
87+
88+
/* Empty the RX FIFO (the DMA is not running at this point) */
89+
for (i = 0; i < entries + 1; i++)
90+
ssp_read(dai, SSDR);
91+
92+
sssr = ssp_read(dai, SSSR);
93+
}
94+
}
95+
96+
static void ssp_empty_rx_fifo_on_stop(struct dai *dai)
6997
{
7098
struct ssp_pdata *ssp = dai_get_drvdata(dai);
7199
uint64_t sample_ticks = clock_ticks_per_sample(PLATFORM_DEFAULT_CLOCK,
72100
ssp->params.fsync_rate);
73101
uint32_t retry = SSP_RX_FLUSH_RETRY_MAX;
74-
bool direct_reads = ssp->state[DAI_DIR_CAPTURE] <= COMP_STATE_PREPARE;
75-
uint32_t entries;
76-
uint32_t i;
102+
uint32_t entries[2];
103+
uint32_t i, sssr;
77104

78-
#if CONFIG_DMA_SUSPEND_DRAIN
79-
/*
80-
* In drain mode, DMA is stopped before DAI, so flush must be
81-
* always done with direct register read.
82-
*/
83-
direct_reads = true;
84-
#endif
105+
sssr = ssp_read(dai, SSSR);
106+
entries[0] = SSCR3_RFL_VAL(ssp_read(dai, SSCR3));
85107

86-
/*
87-
* To make sure all the RX FIFO entries are read out for the flushing,
88-
* we need to wait a minimal SSP port delay after entries are all read,
89-
* and then re-check to see if there is any subsequent entries written
90-
* to the FIFO. This will help to make sure there is no sample mismatched
91-
* issue for the next run with the SSP RX.
92-
*/
93-
while ((ssp_read(dai, SSSR) & SSSR_RNE) && retry--) {
94-
entries = SSCR3_RFL_VAL(ssp_read(dai, SSCR3));
95-
dai_dbg(dai, "ssp_empty_rx_fifo(), before flushing, entries %d", entries);
108+
while ((sssr & SSSR_RNE) && retry--) {
109+
/* Wait one sample time */
110+
wait_delay(sample_ticks);
96111

97-
/* let DMA consume data or read RX FIFO directly */
98-
if (direct_reads) {
99-
for (i = 0; i < entries + 1; i++)
112+
entries[1] = SSCR3_RFL_VAL(ssp_read(dai, SSCR3));
113+
sssr = ssp_read(dai, SSSR);
114+
115+
if (entries[0] > entries[1]) {
116+
/*
117+
* The DMA is reading the FIFO, check the status in the
118+
* next loop
119+
*/
120+
entries[0] = entries[1];
121+
} else if (!(sssr & SSSR_RFS)) {
122+
/*
123+
* The DMA request is not asserted, read the FIFO
124+
* directly, otherwise let the next loop iteration to
125+
* check the status
126+
*/
127+
for (i = 0; i < entries[1] + 1; i++)
100128
ssp_read(dai, SSDR);
101129
}
102130

103-
/* wait to get valid fifo status and re-check */
104-
wait_delay(sample_ticks);
105-
entries = SSCR3_RFL_VAL(ssp_read(dai, SSCR3));
106-
dai_dbg(dai, "ssp_empty_rx_fifo(), after flushing, entries %d", entries);
131+
sssr = ssp_read(dai, SSSR);
107132
}
108133

109-
/* clear interrupt */
134+
/* Just in case clear the overflow status */
110135
ssp_update_bits(dai, SSSR, SSSR_ROR, SSSR_ROR);
111136
}
112137

@@ -915,7 +940,7 @@ static void ssp_start(struct dai *dai, int direction)
915940

916941
/* RX fifo must be cleared before start */
917942
if (direction == DAI_DIR_CAPTURE)
918-
ssp_empty_rx_fifo(dai);
943+
ssp_empty_rx_fifo_on_start(dai);
919944

920945
/* request mclk/bclk */
921946
ssp_pre_start(dai);
@@ -968,7 +993,7 @@ static void ssp_stop(struct dai *dai, int direction)
968993
if (direction == DAI_DIR_CAPTURE &&
969994
ssp->state[SOF_IPC_STREAM_CAPTURE] != COMP_STATE_PREPARE) {
970995
ssp_update_bits(dai, SSRSA, SSRSA_RXEN, 0);
971-
ssp_empty_rx_fifo(dai);
996+
ssp_empty_rx_fifo_on_stop(dai);
972997
ssp->state[SOF_IPC_STREAM_CAPTURE] = COMP_STATE_PREPARE;
973998
dai_info(dai, "ssp_stop(), RX stop");
974999
}
@@ -1078,8 +1103,6 @@ static int ssp_probe(struct dai *dai)
10781103
/* Disable dynamic clock gating before touching any register */
10791104
pm_runtime_get_sync(SSP_CLK, dai->index);
10801105

1081-
ssp_empty_rx_fifo(dai);
1082-
10831106
return 0;
10841107
}
10851108

0 commit comments

Comments
 (0)