Skip to content

Commit f5e7843

Browse files
bkokoszxlgirdwood
authored andcommitted
cavs: ssp: generic ssp mclk configuration for cavs
Unification in setting mclk and bclk in ssp_config() for cavs platform. Now ssp clk information are placed in include/platform/clk-map.h. I've added also possibility to select PLL Fixed clock as a mclk and bclk source for cavs platforms. issue: #560 Signed-off-by: Bartosz Kokoszko <bartoszx.kokoszko@linux.intel.com>
1 parent 1a89f40 commit f5e7843

File tree

9 files changed

+83
-96
lines changed

9 files changed

+83
-96
lines changed

src/drivers/intel/cavs/ssp.c

Lines changed: 39 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,6 @@
4545
#define trace_ssp_error(__e, ...) trace_error(TRACE_CLASS_SSP, __e, ##__VA_ARGS__)
4646
#define tracev_ssp(__e, ...) tracev_event(TRACE_CLASS_SSP, __e, ##__VA_ARGS__)
4747

48-
#define F_19200_kHz 19200000
49-
#define F_24000_kHz 24000000
50-
#define F_24576_kHz 24576000
51-
#define F_38400_kHz 38400000
52-
5348
/* FIXME: move this to a helper and optimize */
5449
static int hweight_32(uint32_t mask)
5550
{
@@ -168,6 +163,9 @@ static inline int ssp_set_config(struct dai *dai,
168163
bool inverted_frame = false;
169164
bool cfs = false;
170165
bool start_delay = false;
166+
167+
int i;
168+
int clk_index = -1;
171169
int ret = 0;
172170

173171
spin_lock(&dai->lock);
@@ -328,14 +326,16 @@ static inline int ssp_set_config(struct dai *dai,
328326
sscr2 |= (ssp->params.quirks & SOF_DAI_INTEL_SSP_QUIRK_PSPSRWFDFD) ?
329327
SSCR2_PSPSRWFDFD : 0;
330328

331-
#if defined(CONFIG_ICELAKE)
332-
if (!config->ssp.mclk_rate || config->ssp.mclk_rate > F_38400_kHz) {
329+
if (!config->ssp.mclk_rate ||
330+
config->ssp.mclk_rate > ssp_freq[MAX_SSP_FREQ_INDEX].freq) {
333331
trace_ssp_error("ssp_set_config() error: "
334-
"invalid MCLK = %d Hz (valid < 38400kHz)",
335-
config->ssp.mclk_rate);
332+
"invalid MCLK = %d Hz (valid < %d)",
333+
config->ssp.mclk_rate,
334+
ssp_freq[MAX_SSP_FREQ_INDEX].freq);
336335
ret = -EINVAL;
337336
goto out;
338337
}
338+
339339
if (!config->ssp.bclk_rate ||
340340
config->ssp.bclk_rate > config->ssp.mclk_rate) {
341341
trace_ssp_error("ssp_set_config() error: "
@@ -345,102 +345,53 @@ static inline int ssp_set_config(struct dai *dai,
345345
goto out;
346346
}
347347

348-
if (F_38400_kHz % config->ssp.mclk_rate == 0) {
349-
mdivr_val = F_38400_kHz / config->ssp.mclk_rate;
350-
} else {
351-
trace_ssp_error("ssp_set_config() error: 38.4MHz / %d Hz MCLK not divisable",
352-
config->ssp.mclk_rate);
353-
ret = -EINVAL;
354-
goto out;
355-
}
348+
/* MCLK config */
349+
/* searching the smallest possible mclk source */
350+
for (i = MAX_SSP_FREQ_INDEX; i >= 0; i--) {
351+
if (config->ssp.mclk_rate > ssp_freq[i].freq)
352+
break;
356353

357-
if (F_38400_kHz % config->ssp.bclk_rate == 0) {
358-
mdiv = F_38400_kHz / config->ssp.bclk_rate;
359-
} else {
360-
trace_ssp_error("ssp_set_config() error: 38.4MHz / %d Hz BCLK not divisable",
361-
config->ssp.bclk_rate);
362-
ret = -EINVAL;
363-
goto out;
364-
}
365-
#elif defined(CONFIG_CANNONLAKE)
366-
if (!config->ssp.mclk_rate || config->ssp.mclk_rate > F_24000_kHz) {
367-
trace_ssp_error("ssp_set_config() error: "
368-
"invalid MCLK = %d Hz (valid < 24000kHz)",
369-
config->ssp.mclk_rate);
370-
ret = -EINVAL;
371-
goto out;
372-
}
373-
if (!config->ssp.bclk_rate ||
374-
config->ssp.bclk_rate > config->ssp.mclk_rate) {
375-
trace_ssp_error("ssp_set_config() error: "
376-
"BCLK %d Hz = 0 or > MCLK %d Hz",
377-
config->ssp.bclk_rate, config->ssp.mclk_rate);
378-
ret = -EINVAL;
379-
goto out;
354+
if (ssp_freq[i].freq % config->ssp.mclk_rate == 0)
355+
clk_index = i;
380356
}
381357

382-
if (F_24000_kHz % config->ssp.mclk_rate == 0) {
383-
mdivr_val = F_24000_kHz / config->ssp.mclk_rate;
358+
if (clk_index >= 0) {
359+
mdivc |= MCDSS(ssp_freq[clk_index].enc);
360+
mdivr_val = ssp_freq[clk_index].freq / config->ssp.mclk_rate;
384361
} else {
385-
trace_ssp_error("ssp_set_config() error: 24.0MHz / %d Hz MCLK not divisable",
362+
trace_ssp_error("ssp_set_config() error: MCLK %d",
386363
config->ssp.mclk_rate);
387364
ret = -EINVAL;
388365
goto out;
389366
}
390367

391-
if (F_24000_kHz % config->ssp.bclk_rate == 0) {
392-
mdiv = F_24000_kHz / config->ssp.bclk_rate;
393-
} else {
394-
trace_ssp_error("ssp_set_config() error: 24.0MHz / %d Hz BCLK not divisable",
395-
config->ssp.bclk_rate);
396-
ret = -EINVAL;
397-
goto out;
398-
}
399-
#else
400-
if (!config->ssp.mclk_rate || config->ssp.mclk_rate > F_24576_kHz) {
401-
trace_ssp_error("ssp_set_config() error: "
402-
"invalid MCLK = %d Hz (valid < 24567kHz)",
403-
config->ssp.mclk_rate);
404-
ret = -EINVAL;
405-
goto out;
406-
}
407-
if (!config->ssp.bclk_rate ||
408-
config->ssp.bclk_rate > config->ssp.mclk_rate) {
409-
trace_ssp_error("ssp_set_config() error: "
410-
"BCLK %d Hz = 0 or > MCLK %d Hz",
411-
config->ssp.bclk_rate, config->ssp.mclk_rate);
412-
ret = -EINVAL;
413-
goto out;
414-
}
415-
if (F_24576_kHz % config->ssp.mclk_rate == 0) {
416-
/* select Audio Cardinal clock for MCLK */
417-
mdivc |= MCDSS(1);
418-
mdivr_val = F_24576_kHz / config->ssp.mclk_rate;
419-
} else if (config->ssp.mclk_rate <= F_19200_kHz &&
420-
F_19200_kHz % config->ssp.mclk_rate == 0) {
421-
mdivr_val = F_19200_kHz / config->ssp.mclk_rate;
422-
} else {
423-
trace_ssp_error("ssp_set_config() error: MCLK %d",
424-
config->ssp.mclk_rate);
425-
ret = -EINVAL;
426-
goto out;
368+
/* BCLK config */
369+
/* searching the smallest possible bclk source */
370+
clk_index = -1;
371+
for (i = MAX_SSP_FREQ_INDEX; i >= 0; i--) {
372+
if (config->ssp.bclk_rate > ssp_freq[i].freq)
373+
break;
374+
375+
if (ssp_freq[i].freq % config->ssp.bclk_rate == 0)
376+
clk_index = i;
427377
}
428378

429-
if (F_24576_kHz % config->ssp.bclk_rate == 0) {
430-
/* select Audio Cardinal clock for M/N dividers */
431-
mdivc |= MNDSS(1);
432-
mdiv = F_24576_kHz / config->ssp.bclk_rate;
433-
/* select M/N output for bclk */
434-
sscr0 |= SSCR0_ECS;
435-
} else if (F_19200_kHz % config->ssp.bclk_rate == 0) {
436-
mdiv = F_19200_kHz / config->ssp.bclk_rate;
379+
if (clk_index >= 0) {
380+
mdivc |= MNDSS(ssp_freq[clk_index].enc);
381+
mdiv = ssp_freq[clk_index].freq / config->ssp.bclk_rate;
382+
383+
/* select M/N output for bclk in case of Audio Cardinal
384+
* or PLL Fixed clock.
385+
*/
386+
if (ssp_freq[clk_index].enc != CLOCK_SSP_XTAL_OSCILLATOR)
387+
sscr0 |= SSCR0_ECS;
437388
} else {
438389
trace_ssp_error("ssp_set_config() error: BCLK %d",
439390
config->ssp.bclk_rate);
440391
ret = -EINVAL;
441392
goto out;
442393
}
443-
#endif
394+
444395

445396
switch (mdivr_val) {
446397
case 1:

src/include/sof/clk.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@
3636
#define CLOCK_NOTIFY_PRE 0
3737
#define CLOCK_NOTIFY_POST 1
3838

39+
#define CLOCK_SSP_XTAL_OSCILLATOR 0x0
40+
#define CLOCK_SSP_AUDIO_CARDINAL 0x1
41+
#define CLOCK_SSP_PLL_FIXED 0x2
42+
3943
struct clock_notify_data {
4044
uint32_t old_freq;
4145
uint32_t old_ticks_per_msec;

src/include/sof/ssp.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <sof/schedule.h>
3838
#include <sof/trace.h>
3939
#include <sof/wait.h>
40+
#include <platform/clk-map.h>
4041

4142
#define SSP_CLK_AUDIO 0
4243
#define SSP_CLK_NET_PLL 1
@@ -225,6 +226,11 @@ extern const struct dai_ops ssp_ops;
225226
#define MCDSS(x) ((x) << 16)
226227
#endif
227228

229+
#if CONFIG_CAVS
230+
/* max possible index in ssp_freq array */
231+
#define MAX_SSP_FREQ_INDEX (ARRAY_SIZE(ssp_freq) - 1)
232+
#endif
233+
228234
/* tracing */
229235
#define trace_ssp(__e, ...) trace_event(TRACE_CLASS_SSP, __e, ##__VA_ARGS__)
230236
#define trace_ssp_error(__e, ...) trace_error(TRACE_CLASS_SSP, __e, ##__VA_ARGS__)

src/platform/apollolake/include/platform/clk-map.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,21 @@
3131
#ifndef __INCLUDE_CLOCK_MAP__
3232
#define __INCLUDE_CLOCK_MAP__
3333

34+
#include <sof/clk.h>
35+
3436
static const struct freq_table cpu_freq[] = {
3537
{100000000, 100000, 0x3},
3638
{200000000, 200000, 0x1},
3739
{400000000, 400000, 0x0}, /* default */
3840
};
3941

42+
/* IMPORTANT: array should be filled in increasing order
43+
* (regarding to .freq field)
44+
*/
4045
static const struct freq_table ssp_freq[] = {
41-
{19200000, 19200, }, /* default */
42-
{24576000, 24576, },
46+
{ 19200000, 19200, CLOCK_SSP_XTAL_OSCILLATOR },
47+
{ 24576000, 24576, CLOCK_SSP_AUDIO_CARDINAL },
48+
{ 96000000, 96000, CLOCK_SSP_PLL_FIXED },
4349
};
4450

4551
#endif

src/platform/baytrail/include/platform/clk-map.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#ifndef __INCLUDE_CLOCK_MAP__
3232
#define __INCLUDE_CLOCK_MAP__
3333

34+
#include <sof/clk.h>
35+
3436
#if defined CONFIG_BAYTRAIL
3537
static const struct freq_table cpu_freq[] = {
3638
{25000000, 25000, 0x0},

src/platform/cannonlake/include/platform/clk-map.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,19 @@
3131
#ifndef __INCLUDE_CLOCK_MAP__
3232
#define __INCLUDE_CLOCK_MAP__
3333

34+
#include <sof/clk.h>
35+
3436
static const struct freq_table cpu_freq[] = {
3537
{120000000, 120000, 0x0},
3638
{400000000, 400000, 0x4}, /* default */
3739
};
3840

41+
/* IMPORTANT: array should be filled in increasing order
42+
* (regarding to .freq field)
43+
*/
3944
static const struct freq_table ssp_freq[] = {
40-
{19200000, 19200, }, /* default */
41-
{24000000, 24000, },
45+
{ 24000000, 24000, CLOCK_SSP_XTAL_OSCILLATOR },
46+
{ 96000000, 96000, CLOCK_SSP_PLL_FIXED },
4247
};
4348

4449
#endif

src/platform/haswell/include/platform/clk-map.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#ifndef __INCLUDE_CLOCK_MAP__
3232
#define __INCLUDE_CLOCK_MAP__
3333

34+
#include <sof/clk.h>
35+
3436
static const struct freq_table cpu_freq[] = {
3537
{32000000, 32000, 0x6},
3638
{80000000, 80000, 0x2},

src/platform/icelake/include/platform/clk-map.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,20 @@
3131
#ifndef __INCLUDE_CLOCK_MAP__
3232
#define __INCLUDE_CLOCK_MAP__
3333

34+
#include <sof/clk.h>
35+
3436
static const struct freq_table cpu_freq[] = {
3537
{120000000, 120000, 0x0},
3638
{400000000, 400000, 0x4}, /* default */
3739
};
3840

41+
/* IMPORTANT: array should be filled in increasing order
42+
* (regarding to .freq field)
43+
*/
3944
static const struct freq_table ssp_freq[] = {
40-
{19200000, 19200, }, /* default */
41-
{38400000, 38400, },
45+
{ 24576000, 24576, CLOCK_SSP_AUDIO_CARDINAL },
46+
{ 38400000, 38400, CLOCK_SSP_XTAL_OSCILLATOR },
47+
{ 96000000, 96000, CLOCK_SSP_PLL_FIXED },
4248
};
4349

4450
#endif

src/platform/suecreek/include/platform/clk-map.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,19 @@
3131
#ifndef __INCLUDE_CLOCK_MAP__
3232
#define __INCLUDE_CLOCK_MAP__
3333

34+
#include <sof/clk.h>
35+
3436
static const struct freq_table cpu_freq[] = {
3537
{120000000, 120000, 0x0},
3638
{400000000, 400000, 0x4}, /* default */
3739
};
3840

41+
/* IMPORTANT: array should be filled in increasing order
42+
* (regarding to .freq field)
43+
*/
3944
static const struct freq_table ssp_freq[] = {
40-
{19200000, 19200, }, /* default */
41-
{24000000, 24000, },
45+
{ 38400000, 38400, CLOCK_SSP_XTAL_OSCILLATOR },
46+
{ 96000000, 96000, CLOCK_SSP_PLL_FIXED },
4247
};
4348

4449
#endif

0 commit comments

Comments
 (0)