Skip to content

Commit 0ee57fd

Browse files
plbossartmwasko
authored andcommitted
intel: ssp: handle TSRE and RSRE along with SSE
The current code does not follow recommended programming sequences: TSRE and RSRE should be set before SSE and conversely cleared before SSE. Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Brent Lu <brent.lu@intel.com>
1 parent 8233990 commit 0ee57fd

1 file changed

Lines changed: 25 additions & 9 deletions

File tree

  • src/drivers/intel/ssp

src/drivers/intel/ssp/ssp.c

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,8 @@ static int ssp_set_config(struct dai *dai,
285285
*/
286286
sscr0 = SSCR0_PSP | SSCR0_RIM | SSCR0_TIM;
287287

288-
/* sscr1 dynamic settings are SFRMDIR, SCLKDIR, SCFR */
289-
sscr1 = SSCR1_TTE | SSCR1_TTELP | SSCR1_TRAIL | SSCR1_RSRE | SSCR1_TSRE;
288+
/* sscr1 dynamic settings are SFRMDIR, SCLKDIR, SCFR, RSRE, TSRE */
289+
sscr1 = SSCR1_TTE | SSCR1_TTELP | SSCR1_TRAIL;
290290

291291
/* sscr2 dynamic setting is LJDFD */
292292
sscr2 = SSCR2_SDFD | SSCR2_TURM1;
@@ -737,6 +737,12 @@ static int ssp_set_config(struct dai *dai,
737737
ssp->clk_active |= SSP_CLK_BCLK_ES_REQ;
738738

739739
if (enable_sse) {
740+
741+
/* enable TRSE/RSRE before SSE */
742+
ssp_update_bits(dai, SSCR1,
743+
SSCR1_TSRE | SSCR1_RSRE,
744+
SSCR1_TSRE | SSCR1_RSRE);
745+
740746
/* enable port */
741747
ssp_update_bits(dai, SSCR0, SSCR0_SSE, SSCR0_SSE);
742748

@@ -752,6 +758,11 @@ static int ssp_set_config(struct dai *dai,
752758
dai_info(dai, "ssp_set_config(): hw_free stage: releasing BCLK clocks for SSP%d...",
753759
dai->index);
754760
if (ssp->clk_active & SSP_CLK_BCLK_ACTIVE) {
761+
/* clear TRSE/RSRE before SSE */
762+
ssp_update_bits(dai, SSCR1,
763+
SSCR1_TSRE | SSCR1_RSRE,
764+
0);
765+
755766
ssp_update_bits(dai, SSCR0, SSCR0_SSE, 0);
756767
dai_info(dai, "ssp_set_config(): SSE clear for SSP%d", dai->index);
757768
}
@@ -872,6 +883,11 @@ static void ssp_start(struct dai *dai, int direction)
872883
ssp_pre_start(dai);
873884

874885
if (!(ssp->clk_active & SSP_CLK_BCLK_ES_REQ)) {
886+
/* enable TRSE/RSRE before SSE */
887+
ssp_update_bits(dai, SSCR1,
888+
SSCR1_TSRE | SSCR1_RSRE,
889+
SSCR1_TSRE | SSCR1_RSRE);
890+
875891
/* enable port */
876892
ssp_update_bits(dai, SSCR0, SSCR0_SSE, SSCR0_SSE);
877893
dai_info(dai, "ssp_start(): SSE set for SSP%d", dai->index);
@@ -889,13 +905,10 @@ static void ssp_start(struct dai *dai, int direction)
889905
}
890906

891907
/* enable DMA */
892-
if (direction == DAI_DIR_PLAYBACK) {
893-
ssp_update_bits(dai, SSCR1, SSCR1_TSRE, SSCR1_TSRE);
908+
if (direction == DAI_DIR_PLAYBACK)
894909
ssp_update_bits(dai, SSTSA, SSTSA_TXEN, SSTSA_TXEN);
895-
} else {
896-
ssp_update_bits(dai, SSCR1, SSCR1_RSRE, SSCR1_RSRE);
910+
else
897911
ssp_update_bits(dai, SSRSA, SSRSA_RXEN, SSRSA_RXEN);
898-
}
899912

900913
/* wait to get valid fifo status */
901914
wait_delay(PLATFORM_SSP_DELAY);
@@ -916,7 +929,6 @@ static void ssp_stop(struct dai *dai, int direction)
916929
/* stop Rx if neeed */
917930
if (direction == DAI_DIR_CAPTURE &&
918931
ssp->state[SOF_IPC_STREAM_CAPTURE] != COMP_STATE_PREPARE) {
919-
ssp_update_bits(dai, SSCR1, SSCR1_RSRE, 0);
920932
ssp_update_bits(dai, SSRSA, SSRSA_RXEN, 0);
921933
ssp_empty_rx_fifo(dai);
922934
ssp->state[SOF_IPC_STREAM_CAPTURE] = COMP_STATE_PREPARE;
@@ -927,7 +939,6 @@ static void ssp_stop(struct dai *dai, int direction)
927939
if (direction == DAI_DIR_PLAYBACK &&
928940
ssp->state[SOF_IPC_STREAM_PLAYBACK] != COMP_STATE_PREPARE) {
929941
ssp_empty_tx_fifo(dai);
930-
ssp_update_bits(dai, SSCR1, SSCR1_TSRE, 0);
931942
ssp_update_bits(dai, SSTSA, SSTSA_TXEN, 0);
932943
ssp->state[SOF_IPC_STREAM_PLAYBACK] = COMP_STATE_PREPARE;
933944
dai_info(dai, "ssp_stop(), TX stop");
@@ -937,6 +948,11 @@ static void ssp_stop(struct dai *dai, int direction)
937948
if (ssp->state[SOF_IPC_STREAM_CAPTURE] == COMP_STATE_PREPARE &&
938949
ssp->state[SOF_IPC_STREAM_PLAYBACK] == COMP_STATE_PREPARE) {
939950
if (!(ssp->clk_active & SSP_CLK_BCLK_ES_REQ)) {
951+
/* clear TRSE/RSRE before SSE */
952+
ssp_update_bits(dai, SSCR1,
953+
SSCR1_TSRE | SSCR1_RSRE,
954+
0);
955+
940956
ssp_update_bits(dai, SSCR0, SSCR0_SSE, 0);
941957
dai_info(dai, "ssp_stop(): SSE clear SSP%d", dai->index);
942958
}

0 commit comments

Comments
 (0)