@@ -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