Skip to content

Commit 4c1d449

Browse files
tlaudalrgirdwo
authored andcommitted
cnl: ssp: fix ssp settings
We change ssp settings in order to properly transmit and receive data: 1. Use frame end padding instead of dummy stop bits. This way alignment bits will be transmitted at the end of whole frame instead of every slot. 2. Disable receive without transmit mode. 3. Do not change the source for MCLK. 4. DSP_A format shouldn't have start delay. Signed-off-by: Tomasz Lauda <tomasz.lauda@linux.intel.com>
1 parent 856f768 commit 4c1d449

File tree

2 files changed

+19
-14
lines changed

2 files changed

+19
-14
lines changed

src/drivers/apl-ssp.c

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ static inline int ssp_set_config(struct dai *dai,
106106
uint32_t i2s_n;
107107
uint32_t data_size;
108108
uint32_t start_delay;
109-
uint32_t dummy_stop;
109+
uint32_t frame_end_padding;
110110
uint32_t frame_len = 0;
111111
uint32_t bdiv_min;
112112
uint32_t tft;
@@ -138,13 +138,13 @@ static inline int ssp_set_config(struct dai *dai,
138138
sscr0 = SSCR0_PSP | SSCR0_RIM | SSCR0_TIM;
139139

140140
/* sscr1 dynamic settings are SFRMDIR, SCLKDIR, SCFR */
141-
sscr1 = SSCR1_TTE | SSCR1_TTELP | SSCR1_RWOT | SSCR1_TRAIL;
141+
sscr1 = SSCR1_TTE | SSCR1_TTELP | SSCR1_TRAIL | SSCR1_RSRE | SSCR1_TSRE;
142142

143143
/* sscr2 dynamic setting is LJDFD */
144144
sscr2 = SSCR2_SDFD | SSCR2_TURM1;
145145

146146
/* sscr3 dynamic settings are TFT, RFT */
147-
sscr3 = 0;
147+
sscr3 = SSCR3_TX(8) | SSCR3_RX(8);
148148

149149
/* sspsp dynamic settings are SCMODE, SFRMP, DMYSTRT, SFRMWDTH */
150150
sspsp = 0;
@@ -283,7 +283,7 @@ static inline int ssp_set_config(struct dai *dai,
283283
goto out;
284284
}
285285

286-
/* must be enouch BCLKs for data */
286+
/* must be enough BCLKs for data */
287287
bdiv = config->bclk / config->fclk;
288288
if (bdiv < config->sample_container_bits * config->num_slots) {
289289
trace_ssp_error("ec8");
@@ -355,7 +355,7 @@ static inline int ssp_set_config(struct dai *dai,
355355
break;
356356
case SOF_DAI_FMT_DSP_A:
357357

358-
start_delay = 1;
358+
start_delay = 0;
359359

360360
sscr0 |= SSCR0_MOD | SSCR0_FRDC(config->num_slots);
361361

@@ -405,21 +405,21 @@ static inline int ssp_set_config(struct dai *dai,
405405
sspsp |= SSPSP_STRTDLY(start_delay);
406406
sspsp |= SSPSP_SFRMWDTH(frame_len);
407407

408-
/*
409-
* [dummy_start][valid_bits_slot[0...n-1]][dummy_stop],
410-
* but don't count dummy_start for dummy_stop calculation.
411-
*/
412408
bdiv_min = config->num_slots * config->sample_valid_bits;
413409
if (bdiv < bdiv_min) {
414410
trace_ssp_error("ecc");
415411
ret = -EINVAL;
416412
goto out;
417413
}
418414

419-
dummy_stop = bdiv - bdiv_min;
420-
sspsp |= SSPSP_DMYSTOP(SSPSP_DMYSTOP_MASK & dummy_stop);
421-
sspsp |= SSPSP_EDMYSTOP(SSPSP_EDMYSTOP_MASK &
422-
(dummy_stop >> SSPSP_DMYSTOP_BITS));
415+
frame_end_padding = bdiv - bdiv_min;
416+
if (frame_end_padding > SSPSP2_FEP_MASK) {
417+
trace_ssp_error("ecd");
418+
ret = -EINVAL;
419+
goto out;
420+
}
421+
422+
sspsp2 |= (frame_end_padding & SSPSP2_FEP_MASK);
423423

424424
data_size = config->sample_valid_bits;
425425

@@ -428,7 +428,11 @@ static inline int ssp_set_config(struct dai *dai,
428428
else
429429
sscr0 |= SSCR0_DSIZE(data_size);
430430

431+
#ifdef CONFIG_CANNONLAKE
432+
mdivc = 0x1;
433+
#else
431434
mdivc = 0x00100001;
435+
#endif
432436
/* bypass divider for MCLK */
433437
mdivr = 0x00000fff;
434438

src/include/reef/ssp.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,10 @@ extern const struct dai_ops ssp_ops;
167167
#if defined CONFIG_APOLLOLAKE || defined CONFIG_CANNONLAKE
168168
#define SSPSP_EDMYSTOP(x) ((x) << 26)
169169
#define SSPSP_EDMYSTOP_MASK 0x7
170+
#define SSPSP2_FEP_MASK 0xff
170171
#define SSTSS 0x38
171172
#define SSCR2 0x40
172-
#define SSPSP2 0x44
173+
#define SSPSP2 0x44
173174
#define SSCR3 0x48
174175
#define SSIOC 0x4C
175176

0 commit comments

Comments
 (0)