1 // SPDX-License-Identifier: BSD-3-Clause
2 //
3 // Copyright(c) 2021 Intel Corporation. All rights reserved.
4 //
5 // Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
6 // Keyon Jie <yang.jie@linux.intel.com>
7 // Rander Wang <rander.wang@linux.intel.com>
8 // Jaska Uimonen <jaska.uimonen@linux.intel.com>
9
10 #include "aconfig.h"
11 #include <stdint.h>
12 #include <errno.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <stdbool.h>
17 #include <alsa/global.h>
18 #include <alsa/input.h>
19 #include <alsa/output.h>
20 #include <alsa/conf.h>
21 #include <alsa/error.h>
22 #include "../intel-nhlt.h"
23 #include "../../nhlt.h"
24 #include "ssp-process.h"
25 #include "ssp-intel.h"
26 #include "ssp-internal.h"
27 #include "ssp-debug.h"
28
popcount(uint32_t value)29 static int popcount(uint32_t value)
30 {
31 int bits_set = 0;
32
33 while (value) {
34 bits_set += value & 1;
35 value >>= 1;
36 }
37
38 return bits_set;
39 }
40
ssp_calculate_intern_v15(struct intel_nhlt_params * nhlt,int hwi)41 static void ssp_calculate_intern_v15(struct intel_nhlt_params *nhlt, int hwi)
42 {
43 struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params;
44 int di = ssp->ssp_count;;
45 struct ssp_intel_config_data_1_5 *blob15 = &ssp->ssp_blob_1_5[di][hwi];
46 struct ssp_intel_config_data *blob = &ssp->ssp_blob[di][hwi];
47 int i;
48
49 blob15->gateway_attributes = ssp->ssp_blob[di][hwi].gateway_attributes;
50 blob15->version = SSP_BLOB_VER_1_5;
51
52 for (i = 0; i < 8; i++)
53 blob15->ts_group[i] = blob->ts_group[i];
54
55 blob15->ssc0 = blob->ssc0;
56 blob15->ssc1 = blob->ssc1;
57 blob15->sscto = blob->sscto;
58 blob15->sspsp = blob->sspsp;
59 blob15->sstsa = blob->sstsa;
60 blob15->ssrsa = blob->ssrsa;
61 blob15->ssc2 = blob->ssc2;
62 blob15->sspsp2 = blob->sspsp2;
63 blob15->ssc3 = blob->ssc3;
64 blob15->ssioc = blob->ssioc;
65
66 /* for now we use only 1 divider as in legacy */
67 blob15->mdivctlr = blob->mdivc;
68 ssp->ssp_prm[di].mdivr[hwi].count = 1;
69 blob15->mdivrcnt = ssp->ssp_prm[di].mdivr[hwi].count;
70 ssp->ssp_prm[di].mdivr[hwi].mdivrs[0] = blob->mdivr;
71
72 blob15->size = sizeof(struct ssp_intel_config_data_1_5) +
73 blob15->mdivrcnt * sizeof(uint32_t) +
74 ssp->ssp_blob_ext[di][hwi].size;
75 }
76
ssp_calculate_intern(struct intel_nhlt_params * nhlt,int hwi)77 static int ssp_calculate_intern(struct intel_nhlt_params *nhlt, int hwi)
78 {
79 struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params;
80 uint32_t active_tx_slots = 2;
81 uint32_t active_rx_slots = 2;
82 uint32_t inverted_frame = 0;
83 uint32_t inverted_bclk = 0;
84 uint32_t frame_end_padding;
85 uint32_t total_sample_size;
86 uint32_t slot_end_padding;
87 bool start_delay = false;
88 uint32_t frame_len = 0;
89 uint32_t sample_width;
90 uint32_t end_padding;
91 uint32_t data_size;
92 uint32_t bdiv_min;
93 bool cfs = false;
94 uint32_t clk_div;
95 uint32_t bdiv;
96 uint32_t tft;
97 uint32_t rft;
98 int di;
99 unsigned int i, j;
100
101 if (!ssp)
102 return -EINVAL;
103
104 di = ssp->ssp_count;
105
106 /* should be eventually the lp_mode defined in pipeline */
107 ssp->ssp_blob[di][hwi].gateway_attributes = 0;
108
109 for (j = 0; j < SSP_TDM_MAX_SLOT_MAP_COUNT; j++) {
110 for (i = 0; i < ssp->ssp_prm[di].hw_cfg[hwi].tdm_slots; i++)
111 ssp->ssp_blob[di][hwi].ts_group[j] |= (i << (i * 4));
112 for (; i < SSP_TDM_MAX_SLOT_MAP_COUNT; i++)
113 ssp->ssp_blob[di][hwi].ts_group[j] |= (0xF << (i * 4));
114 }
115
116 /* reset SSP settings */
117 /* sscr0 dynamic settings are DSS, EDSS, SCR, FRDC, ECS */
118 ssp->ssp_blob[di][hwi].ssc0 = SSCR0_PSP | SSCR0_RIM | SSCR0_TIM;
119
120 /* sscr1 dynamic settings are SFRMDIR, SCLKDIR, SCFR */
121 ssp->ssp_blob[di][hwi].ssc1 = SSCR1_TTE | SSCR1_TTELP | SSCR1_TRAIL | SSCR1_RSRE |
122 SSCR1_TSRE;
123
124 /* sscr2 dynamic setting is LJDFD */
125 ssp->ssp_blob[di][hwi].ssc2 = SSCR2_SDFD | SSCR2_TURM1;
126
127 /* sscr3 dynamic settings are TFT, RFT */
128 ssp->ssp_blob[di][hwi].ssc3 = 0;
129
130 /* sspsp dynamic settings are SCMODE, SFRMP, DMYSTRT, SFRMWDTH */
131 ssp->ssp_blob[di][hwi].sspsp = 0;
132
133 /* sspsp2 no dynamic setting */
134 ssp->ssp_blob[di][hwi].sspsp2 = 0x0;
135
136 /* ssioc dynamic setting is SFCR */
137 ssp->ssp_blob[di][hwi].ssioc = SSIOC_SCOE;
138
139 /* ssto no dynamic setting */
140 ssp->ssp_blob[di][hwi].sscto = 0x0;
141
142 /* sstsa dynamic setting is TTSA, default 2 slots */
143 ssp->ssp_blob[di][hwi].sstsa = SSTSA_SSTSA(ssp->ssp_prm[di].hw_cfg[hwi].tx_slots);
144
145 /* ssrsa dynamic setting is RTSA, default 2 slots */
146 ssp->ssp_blob[di][hwi].ssrsa = SSRSA_SSRSA(ssp->ssp_prm[di].hw_cfg[hwi].rx_slots);
147
148 switch (ssp->ssp_prm[di].hw_cfg[hwi].format & SSP_FMT_CLOCK_PROVIDER_MASK) {
149 case SSP_FMT_CBP_CFP:
150 ssp->ssp_blob[di][hwi].ssc1 |= SSCR1_SCLKDIR | SSCR1_SFRMDIR;
151 break;
152 case SSP_FMT_CBC_CFC:
153 ssp->ssp_blob[di][hwi].ssc1 |= SSCR1_SCFR;
154 cfs = true;
155 break;
156 case SSP_FMT_CBP_CFC:
157 ssp->ssp_blob[di][hwi].ssc1 |= SSCR1_SCLKDIR;
158 /* FIXME: this mode has not been tested */
159
160 cfs = true;
161 break;
162 case SSP_FMT_CBC_CFP:
163 ssp->ssp_blob[di][hwi].ssc1 |= SSCR1_SCFR | SSCR1_SFRMDIR;
164 /* FIXME: this mode has not been tested */
165 break;
166 default:
167 fprintf(stderr, "ssp_calculate(): format & PROVIDER_MASK EINVAL\n");
168 return -EINVAL;
169 }
170
171 /* clock signal polarity */
172 switch (ssp->ssp_prm[di].hw_cfg[hwi].format & SSP_FMT_INV_MASK) {
173 case SSP_FMT_NB_NF:
174 break;
175 case SSP_FMT_NB_IF:
176 inverted_frame = 1; /* handled later with format */
177 break;
178 case SSP_FMT_IB_IF:
179 inverted_bclk = 1; /* handled later with bclk idle */
180 inverted_frame = 1; /* handled later with format */
181 break;
182 case SSP_FMT_IB_NF:
183 inverted_bclk = 1; /* handled later with bclk idle */
184 break;
185 default:
186 fprintf(stderr, "ssp_calculate: format & INV_MASK EINVAL\n");
187 return -EINVAL;
188 }
189
190 /* supporting bclk idle state */
191 if (ssp->ssp_prm[di].clks_control &
192 SSP_INTEL_CLKCTRL_BCLK_IDLE_HIGH) {
193 /* bclk idle state high */
194 ssp->ssp_blob[di][hwi].sspsp |= SSPSP_SCMODE((inverted_bclk ^ 0x3) & 0x3);
195 } else {
196 /* bclk idle state low */
197 ssp->ssp_blob[di][hwi].sspsp |= SSPSP_SCMODE(inverted_bclk);
198 }
199
200 ssp->ssp_blob[di][hwi].ssc0 |= SSCR0_MOD | SSCR0_ACS;
201
202 /* Additional hardware settings */
203
204 /* Receiver Time-out Interrupt Disabled/Enabled */
205 ssp->ssp_blob[di][hwi].ssc1 |= (ssp->ssp_prm[di].quirks & SSP_INTEL_QUIRK_TINTE) ?
206 SSCR1_TINTE : 0;
207
208 /* Peripheral Trailing Byte Interrupts Disable/Enable */
209 ssp->ssp_blob[di][hwi].ssc1 |= (ssp->ssp_prm[di].quirks & SSP_INTEL_QUIRK_PINTE) ?
210 SSCR1_PINTE : 0;
211
212 /* Enable/disable internal loopback. Output of transmit serial
213 * shifter connected to input of receive serial shifter, internally.
214 */
215 ssp->ssp_blob[di][hwi].ssc1 |= (ssp->ssp_prm[di].quirks & SSP_INTEL_QUIRK_LBM) ?
216 SSCR1_LBM : 0;
217
218 /* Transmit data are driven at the same/opposite clock edge specified
219 * in SSPSP.SCMODE[1:0]
220 */
221 ssp->ssp_blob[di][hwi].ssc2 |= (ssp->ssp_prm[di].quirks & SSP_INTEL_QUIRK_SMTATF) ?
222 SSCR2_SMTATF : 0;
223
224 /* Receive data are sampled at the same/opposite clock edge specified
225 * in SSPSP.SCMODE[1:0]
226 */
227 ssp->ssp_blob[di][hwi].ssc2 |= (ssp->ssp_prm[di].quirks & SSP_INTEL_QUIRK_MMRATF) ?
228 SSCR2_MMRATF : 0;
229
230 /* Enable/disable the fix for PSP consumer mode TXD wait for frame
231 * de-assertion before starting the second channel
232 */
233 ssp->ssp_blob[di][hwi].ssc2 |= (ssp->ssp_prm[di].quirks & SSP_INTEL_QUIRK_PSPSTWFDFD) ?
234 SSCR2_PSPSTWFDFD : 0;
235
236 /* Enable/disable the fix for PSP provider mode FSRT with dummy stop &
237 * frame end padding capability
238 */
239 ssp->ssp_blob[di][hwi].ssc2 |= (ssp->ssp_prm[di].quirks & SSP_INTEL_QUIRK_PSPSRWFDFD) ?
240 SSCR2_PSPSRWFDFD : 0;
241
242 if (!ssp->ssp_prm[di].hw_cfg[hwi].mclk_rate) {
243 fprintf(stderr, "ssp_calculate(): invalid MCLK = %u \n",
244 ssp->ssp_prm[di].hw_cfg[hwi].mclk_rate);
245 return -EINVAL;
246 }
247
248 if (!ssp->ssp_prm[di].hw_cfg[hwi].bclk_rate ||
249 ssp->ssp_prm[di].hw_cfg[hwi].bclk_rate > ssp->ssp_prm[di].hw_cfg[hwi].mclk_rate) {
250 fprintf(stderr, "ssp_calculate(): BCLK %u Hz = 0 or > MCLK %u Hz\n",
251 ssp->ssp_prm[di].hw_cfg[hwi].bclk_rate,
252 ssp->ssp_prm[di].hw_cfg[hwi].mclk_rate);
253 return -EINVAL;
254 }
255
256 /* calc frame width based on BCLK and rate - must be divisible */
257 if (ssp->ssp_prm[di].hw_cfg[hwi].bclk_rate % ssp->ssp_prm[di].hw_cfg[hwi].fsync_rate) {
258 fprintf(stderr, "ssp_calculate(): BCLK %u is not divisible by rate %u\n",
259 ssp->ssp_prm[di].hw_cfg[hwi].bclk_rate,
260 ssp->ssp_prm[di].hw_cfg[hwi].fsync_rate);
261 return -EINVAL;
262 }
263
264 /* must be enough BCLKs for data */
265 bdiv = ssp->ssp_prm[di].hw_cfg[hwi].bclk_rate / ssp->ssp_prm[di].hw_cfg[hwi].fsync_rate;
266 if (bdiv < ssp->ssp_prm[di].hw_cfg[hwi].tdm_slot_width *
267 ssp->ssp_prm[di].hw_cfg[hwi].tdm_slots) {
268 fprintf(stderr, "ssp_calculate(): not enough BCLKs need %u\n",
269 ssp->ssp_prm[di].hw_cfg[hwi].tdm_slot_width *
270 ssp->ssp_prm[di].hw_cfg[hwi].tdm_slots);
271 return -EINVAL;
272 }
273
274 /* tdm_slot_width must be <= 38 for SSP */
275 if (ssp->ssp_prm[di].hw_cfg[hwi].tdm_slot_width > 38) {
276 fprintf(stderr, "ssp_calculate(): tdm_slot_width %u > 38\n",
277 ssp->ssp_prm[di].hw_cfg[hwi].tdm_slot_width);
278 return -EINVAL;
279 }
280
281 bdiv_min = ssp->ssp_prm[di].hw_cfg[hwi].tdm_slots *
282 (ssp->ssp_prm[di].tdm_per_slot_padding_flag ?
283 ssp->ssp_prm[di].hw_cfg[hwi].tdm_slot_width :
284 ssp->ssp_prm[di].sample_valid_bits);
285 if (bdiv < bdiv_min) {
286 fprintf(stderr, "ssp_calculate(): bdiv(%u) < bdiv_min(%u)\n",
287 bdiv, bdiv_min);
288 return -EINVAL;
289 }
290
291 frame_end_padding = bdiv - bdiv_min;
292 if (frame_end_padding > SSPSP2_FEP_MASK) {
293 fprintf(stderr, "ssp_calculate(): frame_end_padding too big: %u\n",
294 frame_end_padding);
295 return -EINVAL;
296 }
297
298 /* format */
299 switch (ssp->ssp_prm[di].hw_cfg[hwi].format & SSP_FMT_FORMAT_MASK) {
300 case SSP_FMT_I2S:
301
302 start_delay = true;
303
304 ssp->ssp_blob[di][hwi].ssc0 |= SSCR0_FRDC(ssp->ssp_prm[di].hw_cfg[hwi].tdm_slots);
305
306 if (bdiv % 2) {
307 fprintf(stderr, "ssp_calculate(): bdiv %u is not divisible by 2\n",
308 bdiv);
309 return -EINVAL;
310 }
311
312 /* set asserted frame length to half frame length */
313 frame_len = bdiv / 2;
314
315 /*
316 * handle frame polarity, I2S default is falling/active low,
317 * non-inverted(inverted_frame=0) -- active low(SFRMP=0),
318 * inverted(inverted_frame=1) -- rising/active high(SFRMP=1),
319 * so, we should set SFRMP to inverted_frame.
320 */
321 ssp->ssp_blob[di][hwi].sspsp |= SSPSP_SFRMP(inverted_frame);
322
323 /*
324 * for I2S/LEFT_J, the padding has to happen at the end
325 * of each slot
326 */
327 if (frame_end_padding % 2) {
328 fprintf(stderr, "ssp_calculate():frame_end_padding %u not divisible by 2\n",
329 frame_end_padding);
330 return -EINVAL;
331 }
332
333 slot_end_padding = frame_end_padding / 2;
334
335 if (slot_end_padding > SSP_INTEL_SLOT_PADDING_MAX) {
336 /* too big padding */
337 fprintf(stderr, "ssp_calculate(): slot_end_padding > %d\n",
338 SSP_INTEL_SLOT_PADDING_MAX);
339 return -EINVAL;
340 }
341
342 ssp->ssp_blob[di][hwi].sspsp |= SSPSP_DMYSTOP(slot_end_padding);
343 slot_end_padding >>= SSPSP_DMYSTOP_BITS;
344 ssp->ssp_blob[di][hwi].sspsp |= SSPSP_EDMYSTOP(slot_end_padding);
345
346 break;
347
348 case SSP_FMT_LEFT_J:
349
350 /* default start_delay value is set to false */
351
352 ssp->ssp_blob[di][hwi].ssc0 |= SSCR0_FRDC(ssp->ssp_prm[di].hw_cfg[hwi].tdm_slots);
353
354 /* LJDFD enable */
355 ssp->ssp_blob[di][hwi].ssc2 &= ~SSCR2_LJDFD;
356
357 if (bdiv % 2) {
358 fprintf(stderr, "ssp_calculate(): bdiv %u is not divisible by 2\n",
359 bdiv);
360 return -EINVAL;
361 }
362
363 /* set asserted frame length to half frame length */
364 frame_len = bdiv / 2;
365
366 /*
367 * handle frame polarity, LEFT_J default is rising/active high,
368 * non-inverted(inverted_frame=0) -- active high(SFRMP=1),
369 * inverted(inverted_frame=1) -- falling/active low(SFRMP=0),
370 * so, we should set SFRMP to !inverted_frame.
371 */
372 ssp->ssp_blob[di][hwi].sspsp |= SSPSP_SFRMP(!inverted_frame ? 1 : 0);
373
374 /*
375 * for I2S/LEFT_J, the padding has to happen at the end
376 * of each slot
377 */
378 if (frame_end_padding % 2) {
379 fprintf(stderr, "ssp_set_config(): frame padding %u not divisible by 2\n",
380 frame_end_padding);
381 return -EINVAL;
382 }
383
384 slot_end_padding = frame_end_padding / 2;
385
386 if (slot_end_padding > 15) {
387 /* can't handle padding over 15 bits */
388 fprintf(stderr, "ssp_set_config(): slot_end_padding %u > 15 bits\n",
389 slot_end_padding);
390 return -EINVAL;
391 }
392
393 ssp->ssp_blob[di][hwi].sspsp |= SSPSP_DMYSTOP(slot_end_padding);
394 slot_end_padding >>= SSPSP_DMYSTOP_BITS;
395 ssp->ssp_blob[di][hwi].sspsp |= SSPSP_EDMYSTOP(slot_end_padding);
396
397 break;
398 case SSP_FMT_DSP_A:
399
400 start_delay = true;
401
402 /* fallthrough */
403
404 case SSP_FMT_DSP_B:
405
406 /* default start_delay value is set to false */
407
408 ssp->ssp_blob[di][hwi].ssc0 |= SSCR0_MOD |
409 SSCR0_FRDC(ssp->ssp_prm[di].hw_cfg[hwi].tdm_slots);
410
411 /* set asserted frame length */
412 frame_len = 1; /* default */
413
414 if (cfs && ssp->ssp_prm[di].frame_pulse_width > 0 &&
415 ssp->ssp_prm[di].frame_pulse_width <=
416 SSP_INTEL_FRAME_PULSE_WIDTH_MAX) {
417 frame_len = ssp->ssp_prm[di].frame_pulse_width;
418 }
419
420 /* frame_pulse_width must less or equal 38 */
421 if (ssp->ssp_prm[di].frame_pulse_width >
422 SSP_INTEL_FRAME_PULSE_WIDTH_MAX) {
423 fprintf(stderr, "ssp_set_config(): frame_pulse_width > %d\n",
424 SSP_INTEL_FRAME_PULSE_WIDTH_MAX);
425 return -EINVAL;
426 }
427 /*
428 * handle frame polarity, DSP_B default is rising/active high,
429 * non-inverted(inverted_frame=0) -- active high(SFRMP=1),
430 * inverted(inverted_frame=1) -- falling/active low(SFRMP=0),
431 * so, we should set SFRMP to !inverted_frame.
432 */
433 ssp->ssp_blob[di][hwi].sspsp |= SSPSP_SFRMP(!inverted_frame ? 1 : 0);
434
435 active_tx_slots = popcount(ssp->ssp_prm[di].hw_cfg[hwi].tx_slots);
436 active_rx_slots = popcount(ssp->ssp_prm[di].hw_cfg[hwi].rx_slots);
437
438 /*
439 * handle TDM mode, TDM mode has padding at the end of
440 * each slot. The amount of padding is equal to result of
441 * subtracting slot width and valid bits per slot.
442 */
443 if (ssp->ssp_prm[di].tdm_per_slot_padding_flag) {
444 frame_end_padding = bdiv - ssp->ssp_prm[di].hw_cfg[hwi].tdm_slots *
445 ssp->ssp_prm[di].hw_cfg[hwi].tdm_slot_width;
446
447 slot_end_padding = ssp->ssp_prm[di].hw_cfg[hwi].tdm_slot_width -
448 ssp->ssp_prm[di].sample_valid_bits;
449
450 if (slot_end_padding >
451 SSP_INTEL_SLOT_PADDING_MAX) {
452 fprintf(stderr, "ssp_set_config(): slot_end_padding > %d\n",
453 SSP_INTEL_SLOT_PADDING_MAX);
454 return -EINVAL;
455 }
456
457 ssp->ssp_blob[di][hwi].sspsp |= SSPSP_DMYSTOP(slot_end_padding);
458 slot_end_padding >>= SSPSP_DMYSTOP_BITS;
459 ssp->ssp_blob[di][hwi].sspsp |= SSPSP_EDMYSTOP(slot_end_padding);
460 }
461
462 ssp->ssp_blob[di][hwi].sspsp2 |= (frame_end_padding & SSPSP2_FEP_MASK);
463
464 break;
465 default:
466 fprintf(stderr, "ssp_set_config(): invalid format 0x%04x\n",
467 ssp->ssp_prm[di].hw_cfg[hwi].format);
468 return -EINVAL;
469 }
470
471 if (start_delay)
472 ssp->ssp_blob[di][hwi].sspsp |= SSPSP_FSRT;
473
474 ssp->ssp_blob[di][hwi].sspsp |= SSPSP_SFRMWDTH(frame_len);
475
476 data_size = ssp->ssp_prm[di].sample_valid_bits;
477
478 if (data_size > 16)
479 ssp->ssp_blob[di][hwi].ssc0 |= (SSCR0_EDSS | SSCR0_DSIZE(data_size - 16));
480 else
481 ssp->ssp_blob[di][hwi].ssc0 |= SSCR0_DSIZE(data_size);
482
483 end_padding = 0;
484 total_sample_size = ssp->ssp_prm[di].hw_cfg[hwi].tdm_slot_width *
485 ssp->ssp_prm[di].hw_cfg[hwi].tdm_slots;
486 while (ssp->ssp_prm[di].io_clk % ((total_sample_size + end_padding) *
487 ssp->ssp_prm[di].hw_cfg[hwi].fsync_rate)) {
488 if (++end_padding >= 256)
489 break;
490 }
491
492 if (end_padding >= 256)
493 return -EINVAL;
494
495 /* calc scr divisor */
496 clk_div = ssp->ssp_prm[di].io_clk / ((total_sample_size + end_padding) *
497 ssp->ssp_prm[di].hw_cfg[hwi].fsync_rate);
498 if (clk_div >= 4095)
499 return -EINVAL;
500
501 ssp->ssp_blob[di][hwi].ssc0 |= SSCR0_SCR(clk_div - 1);
502
503 /* setting TFT and RFT */
504 switch (ssp->ssp_prm[di].sample_valid_bits) {
505 case 16:
506 /* use 2 bytes for each slot */
507 sample_width = 2;
508 break;
509 case 24:
510 case 32:
511 /* use 4 bytes for each slot */
512 sample_width = 4;
513 break;
514 default:
515 fprintf(stderr, "ssp_set_config(): sample_valid_bits %u\n",
516 ssp->ssp_prm[di].sample_valid_bits);
517 return -EINVAL;
518 }
519
520 tft = MIN((uint32_t)(SSP_FIFO_DEPTH - SSP_FIFO_WATERMARK),
521 sample_width * active_tx_slots);
522 rft = MIN((uint32_t)(SSP_FIFO_DEPTH - SSP_FIFO_WATERMARK),
523 sample_width * active_rx_slots);
524
525 ssp->ssp_blob[di][hwi].ssc3 |= SSCR3_TX(tft) | SSCR3_RX(rft);
526
527 /* calc mn divisor */
528 if (ssp->ssp_prm[di].io_clk % ssp->ssp_prm[di].hw_cfg[hwi].mclk_rate) {
529 fprintf(stderr, "ssp_set_config(): io_clk not divisible with mclk\n");
530 return -EINVAL;
531 }
532
533 clk_div = ssp->ssp_prm[di].io_clk / ssp->ssp_prm[di].hw_cfg[hwi].mclk_rate;
534 if (clk_div > 1)
535 clk_div -= 2;
536 else
537 clk_div = 0xFFF; /* bypass clk divider */
538
539 ssp->ssp_blob[di][hwi].mdivr = clk_div;
540 /* clock will always go through the divider */
541 ssp->ssp_blob[di][hwi].ssc0 |= SSCR0_ECS;
542 /* enable divider for this clock id */
543 ssp->ssp_blob[di][hwi].mdivc |= BIT(ssp->ssp_prm[di].mclk_id);
544 /* set mclk source always for audio cardinal clock */
545 ssp->ssp_blob[di][hwi].mdivc |= MCDSS(SSP_CLOCK_AUDIO_CARDINAL);
546 /* set bclk source for audio cardinal clock */
547 ssp->ssp_blob[di][hwi].mdivc |= MNDSS(SSP_CLOCK_AUDIO_CARDINAL);
548
549 return 0;
550 }
551
ssp_calculate_intern_ext(struct intel_nhlt_params * nhlt,int hwi)552 static int ssp_calculate_intern_ext(struct intel_nhlt_params *nhlt, int hwi)
553 {
554 size_t aux_size, mn_size, clk_size, tr_size, run_size, sync_size, node_size, ext_size,
555 link_size, size, total_size;
556 struct intel_ssp_params *ssp;
557 struct ssp_config_aux *aux;
558 struct ssp_intel_aux_tlv *tlv;
559 struct ssp_intel_mn_ctl *mn;
560 struct ssp_intel_clk_ctl *clk;
561 struct ssp_intel_tr_ctl *tr;
562 struct ssp_intel_run_ctl *run;
563 struct ssp_intel_sync_ctl *sync;
564 struct ssp_intel_node_ctl *node;
565 struct ssp_intel_ext_ctl *ext;
566 struct ssp_intel_link_ctl *link;
567 uint8_t *aux_blob;
568 uint32_t enabled;
569 unsigned int i;
570 int di;
571
572 aux_size = sizeof(struct ssp_intel_aux_tlv);
573 mn_size = sizeof(struct ssp_intel_mn_ctl);
574 clk_size = sizeof(struct ssp_intel_clk_ctl);
575 tr_size = sizeof(struct ssp_intel_tr_ctl);
576 run_size = sizeof(struct ssp_intel_run_ctl);
577 sync_size = sizeof(struct ssp_intel_sync_ctl);
578 node_size = sizeof(struct ssp_intel_node_ctl);
579 ext_size = sizeof(struct ssp_intel_ext_ctl);
580 link_size = sizeof(struct ssp_intel_link_ctl);
581
582 ssp = (struct intel_ssp_params *)nhlt->ssp_params;
583 di = ssp->ssp_count;
584 enabled = ssp->ssp_prm[di].aux_cfg[hwi].enabled;
585 aux = &(ssp->ssp_prm[di].aux_cfg[hwi]);
586 aux_blob = ssp->ssp_blob_ext[di][hwi].aux_blob;
587 total_size = 0;
588 size = 0;
589
590 if (enabled & BIT(SSP_MN_DIVIDER_CONTROLS)) {
591 tlv = (struct ssp_intel_aux_tlv *)aux_blob;
592 mn = (struct ssp_intel_mn_ctl *)(aux_blob + aux_size);
593 size = mn_size + aux_size;
594 tlv->type = SSP_MN_DIVIDER_CONTROLS;
595 tlv->size = mn_size;
596 mn->div_m = aux->mn.m_div;
597 mn->div_n = aux->mn.n_div;
598 aux_blob += size;
599 total_size += size;
600 }
601
602 if (enabled & BIT(SSP_DMA_CLK_CONTROLS)) {
603 tlv = (struct ssp_intel_aux_tlv *)aux_blob;
604 clk = (struct ssp_intel_clk_ctl *)(aux_blob + aux_size);
605 size = clk_size + aux_size;
606 tlv->type = SSP_DMA_CLK_CONTROLS;
607 tlv->size = clk_size;
608 clk->start |= SET_BITS(15, 0, aux->clk.clock_warm_up);
609 clk->start |= SET_BIT(16, aux->clk.mclk);
610 clk->start |= SET_BIT(17, aux->clk.warm_up_ovr);
611 clk->stop |= SET_BITS(15, 0, aux->clk.clock_stop_delay);
612 clk->stop |= SET_BIT(16, aux->clk.keep_running);
613 clk->stop |= SET_BIT(17, aux->clk.clock_stop_ovr);
614 aux_blob += size;
615 total_size += size;
616 }
617
618 if (enabled & BIT(SSP_DMA_TRANSMISSION_START)) {
619 tlv = (struct ssp_intel_aux_tlv *)aux_blob;
620 tr = (struct ssp_intel_tr_ctl *)(aux_blob + aux_size);
621 size = tr_size + aux_size;
622 tlv->type = SSP_DMA_TRANSMISSION_START;
623 tlv->size = tr_size;
624 tr->sampling_frequency = aux->tr_start.sampling_frequency;
625 tr->bit_depth = aux->tr_start.bit_depth;
626 tr->channel_map = aux->tr_start.channel_map;
627 tr->channel_config = aux->tr_start.channel_config;
628 tr->interleaving_style = aux->tr_start.interleaving_style;
629 tr->format |= SET_BITS(7, 0, aux->tr_start.number_of_channels);
630 tr->format |= SET_BITS(15, 8, aux->tr_start.valid_bit_depth);
631 tr->format |= SET_BITS(23, 16, aux->tr_start.sample_type);
632 aux_blob += size;
633 total_size += size;
634 }
635
636 if (enabled & BIT(SSP_DMA_TRANSMISSION_STOP)) {
637 tlv = (struct ssp_intel_aux_tlv *)aux_blob;
638 tr = (struct ssp_intel_tr_ctl *)(aux_blob + aux_size);
639 size = tr_size + aux_size;
640 tlv->type = SSP_DMA_TRANSMISSION_STOP;
641 tlv->size = tr_size;
642 tr->sampling_frequency = aux->tr_stop.sampling_frequency;
643 tr->bit_depth = aux->tr_stop.bit_depth;
644 tr->channel_map = aux->tr_stop.channel_map;
645 tr->channel_config = aux->tr_stop.channel_config;
646 tr->interleaving_style = aux->tr_stop.interleaving_style;
647 tr->format |= SET_BITS(7, 0, aux->tr_stop.number_of_channels);
648 tr->format |= SET_BITS(15, 8, aux->tr_stop.valid_bit_depth);
649 tr->format |= SET_BITS(23, 16, aux->tr_stop.sample_type);
650 aux_blob += size;
651 total_size += size;
652 }
653
654 if (enabled & BIT(SSP_DMA_ALWAYS_RUNNING_MODE)) {
655 tlv = (struct ssp_intel_aux_tlv *)aux_blob;
656 run = (struct ssp_intel_run_ctl *)(aux_blob + aux_size);
657 size = run_size + aux_size;
658 tlv->type = SSP_DMA_ALWAYS_RUNNING_MODE;
659 tlv->size = run_size;
660 run->enabled = aux->run.always_run;
661 aux_blob += size;
662 total_size += size;
663 }
664
665 if (enabled & BIT(SSP_DMA_SYNC_DATA)) {
666 tlv = (struct ssp_intel_aux_tlv *)aux_blob;
667 sync = (struct ssp_intel_sync_ctl *)(aux_blob + aux_size);
668 size = sync_size + aux_size;
669 tlv->type = SSP_DMA_SYNC_DATA;
670 tlv->size = sync_size;
671 sync->sync_denominator = aux->sync.sync_denominator;
672 sync->count = aux->sync.count;
673 aux_blob += size;
674 total_size += size;
675 for (i = 0; i < sync->count; i++) {
676 node = (struct ssp_intel_node_ctl *)(aux_blob);
677 size = node_size;
678 node->node_id = aux->sync.nodes[i].node_id;
679 node->sampling_rate = aux->sync.nodes[i].sampling_rate;
680 tlv->size += node_size;
681 aux_blob += size;
682 total_size += size;
683 }
684 }
685
686 if (enabled & BIT(SSP_DMA_CLK_CONTROLS_EXT)) {
687 tlv = (struct ssp_intel_aux_tlv *)aux_blob;
688 ext = (struct ssp_intel_ext_ctl *)(aux_blob + aux_size);
689 size = ext_size + aux_size;
690 tlv->type = SSP_DMA_CLK_CONTROLS_EXT;
691 tlv->size = ext_size;
692 ext->ext_data |= SET_BIT(0, aux->ext.mclk_policy_override);
693 ext->ext_data |= SET_BIT(1, aux->ext.mclk_always_running);
694 ext->ext_data |= SET_BIT(2, aux->ext.mclk_starts_on_gtw_init);
695 ext->ext_data |= SET_BIT(3, aux->ext.mclk_starts_on_run);
696 ext->ext_data |= SET_BIT(4, aux->ext.mclk_starts_on_pause);
697 ext->ext_data |= SET_BIT(5, aux->ext.mclk_stops_on_pause);
698 ext->ext_data |= SET_BIT(6, aux->ext.mclk_stops_on_reset);
699 ext->ext_data |= SET_BIT(8, aux->ext.bclk_policy_override);
700 ext->ext_data |= SET_BIT(9, aux->ext.bclk_always_running);
701 ext->ext_data |= SET_BIT(10, aux->ext.bclk_starts_on_gtw_init);
702 ext->ext_data |= SET_BIT(11, aux->ext.bclk_starts_on_run);
703 ext->ext_data |= SET_BIT(12, aux->ext.bclk_starts_on_pause);
704 ext->ext_data |= SET_BIT(13, aux->ext.bclk_stops_on_pause);
705 ext->ext_data |= SET_BIT(14, aux->ext.bclk_stops_on_reset);
706 ext->ext_data |= SET_BIT(16, aux->ext.sync_policy_override);
707 ext->ext_data |= SET_BIT(17, aux->ext.sync_always_running);
708 ext->ext_data |= SET_BIT(18, aux->ext.sync_starts_on_gtw_init);
709 ext->ext_data |= SET_BIT(19, aux->ext.sync_starts_on_run);
710 ext->ext_data |= SET_BIT(20, aux->ext.sync_starts_on_pause);
711 ext->ext_data |= SET_BIT(21, aux->ext.sync_stops_on_pause);
712 ext->ext_data |= SET_BIT(22, aux->ext.sync_stops_on_reset);
713 aux_blob += size;
714 total_size += size;
715 }
716
717 if (enabled & BIT(SSP_LINK_CLK_SOURCE)) {
718 tlv = (struct ssp_intel_aux_tlv *)aux_blob;
719 link = (struct ssp_intel_link_ctl *)(aux_blob + aux_size);
720 size = link_size + aux_size;
721 tlv->type = SSP_LINK_CLK_SOURCE;
722 tlv->size = link_size;
723 link->clock_source = aux->link.clock_source;
724 aux_blob += size;
725 total_size += size;
726 }
727
728 ssp->ssp_blob_ext[di][hwi].size = total_size;
729
730 return 0;
731 }
732
733
734
ssp_calculate(struct intel_nhlt_params * nhlt)735 int ssp_calculate(struct intel_nhlt_params *nhlt)
736 {
737 struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params;
738 unsigned int i;
739
740 if (!ssp)
741 return -EINVAL;
742
743 /* calculate blob for every hw config */
744 for (i = 0; i < ssp->ssp_hw_config_count[ssp->ssp_count]; i++) {
745 if (ssp_calculate_intern(nhlt, i) < 0)
746 return -EINVAL;
747 if (ssp_calculate_intern_ext(nhlt, i) < 0)
748 return -EINVAL;
749 /* v15 blob is made from legacy blob, so it can't fail */
750 ssp_calculate_intern_v15(nhlt, i);
751 }
752
753 ssp_print_internal(ssp);
754 ssp_print_calculated(ssp);
755
756 ssp->ssp_count++;
757
758 return 0;
759 }
760
ssp_get_dir(struct intel_nhlt_params * nhlt,int dai_index,uint8_t * dir)761 int ssp_get_dir(struct intel_nhlt_params *nhlt, int dai_index, uint8_t *dir)
762 {
763 struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params;
764
765 if (!ssp)
766 return -EINVAL;
767
768 *dir = ssp->ssp_prm[dai_index].direction;
769
770 return 0;
771 }
772
ssp_get_params(struct intel_nhlt_params * nhlt,int dai_index,uint32_t * virtualbus_id,uint32_t * formats_count,uint32_t * device_type,uint32_t * direction)773 int ssp_get_params(struct intel_nhlt_params *nhlt, int dai_index, uint32_t *virtualbus_id,
774 uint32_t *formats_count, uint32_t *device_type, uint32_t *direction)
775 {
776 struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params;
777
778 if (!ssp)
779 return -EINVAL;
780
781 *virtualbus_id = ssp->ssp_dai_index[dai_index];
782 *formats_count = ssp->ssp_hw_config_count[dai_index];
783 if (ssp->ssp_prm[dai_index].quirks & SSP_INTEL_QUIRK_BT_SIDEBAND)
784 *device_type = NHLT_DEVICE_TYPE_SSP_BT_SIDEBAND;
785 else
786 *device_type = 0;
787 if (ssp->ssp_prm[dai_index].quirks & SSP_INTEL_QUIRK_RENDER_FEEDBACK) {
788 if (*direction == NHLT_ENDPOINT_DIRECTION_RENDER)
789 *direction = NHLT_ENDPOINT_DIRECTION_RENDER_WITH_LOOPBACK;
790 else if (*direction == NHLT_ENDPOINT_DIRECTION_CAPTURE)
791 *direction = NHLT_ENDPOINT_DIRECTION_FEEDBACK_FOR_RENDER;
792 }
793
794 return 0;
795 }
796
ssp_get_hw_params(struct intel_nhlt_params * nhlt,int dai_index,int hw_index,uint32_t * sample_rate,uint16_t * channel_count,uint32_t * bits_per_sample)797 int ssp_get_hw_params(struct intel_nhlt_params *nhlt, int dai_index, int hw_index,
798 uint32_t *sample_rate, uint16_t *channel_count, uint32_t *bits_per_sample)
799 {
800 struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params;
801
802 if (!ssp)
803 return -EINVAL;
804
805 *channel_count = ssp->ssp_prm[dai_index].hw_cfg[hw_index].tdm_slots;
806 *sample_rate = ssp->ssp_prm[dai_index].hw_cfg[hw_index].fsync_rate;
807 *bits_per_sample = ssp->ssp_prm[dai_index].hw_cfg[hw_index].tdm_slot_width;
808
809 return 0;
810 }
811
812 /*
813 * Build ssp vendor blob from calculated parameters.
814 *
815 * Supposed to be called after all ssp DAIs are parsed from topology and the final nhlt blob is
816 * generated.
817 */
ssp_get_vendor_blob_size(struct intel_nhlt_params * nhlt,int dai_index,int hw_config_index,size_t * size)818 int ssp_get_vendor_blob_size(struct intel_nhlt_params *nhlt, int dai_index,
819 int hw_config_index, size_t *size)
820 {
821 struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params;
822
823 if (!ssp)
824 return -EINVAL;
825
826 /* set size for the blob */
827 if (ssp->ssp_prm[dai_index].version == SSP_BLOB_VER_1_5)
828 *size = ssp->ssp_blob_1_5[dai_index][hw_config_index].size;
829 else
830 /* legacy */
831 *size = sizeof(struct ssp_intel_config_data) +
832 ssp->ssp_blob_ext[dai_index][hw_config_index].size;
833
834 return 0;
835 }
836
ssp_get_vendor_blob_count(struct intel_nhlt_params * nhlt)837 int ssp_get_vendor_blob_count(struct intel_nhlt_params *nhlt)
838 {
839 struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params;
840
841 if (!ssp || !ssp->ssp_count)
842 return -EINVAL;
843
844 return ssp->ssp_count;
845 }
846
847 /* Get the size of dynamic vendor blob to reserve proper amount of memory */
ssp_get_vendor_blob(struct intel_nhlt_params * nhlt,uint8_t * vendor_blob,int dai_index,int hw_config_index)848 int ssp_get_vendor_blob(struct intel_nhlt_params *nhlt, uint8_t *vendor_blob,
849 int dai_index, int hw_config_index)
850 {
851 struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params;
852 uint32_t basic_len, clock_len;
853
854 if (!ssp)
855 return -EINVAL;
856
857 /* top level struct */
858 if (ssp->ssp_prm[dai_index].version == SSP_BLOB_VER_1_5) {
859 basic_len = sizeof(struct ssp_intel_config_data_1_5);
860 clock_len = sizeof(uint32_t) * ssp->ssp_prm[dai_index].mdivr[hw_config_index].count;
861 /* basic data */
862 memcpy(vendor_blob, &ssp->ssp_blob_1_5[dai_index][hw_config_index], basic_len);
863 /* clock data */
864 memcpy(vendor_blob + basic_len,
865 &ssp->ssp_prm[dai_index].mdivr[hw_config_index].mdivrs[0], clock_len);
866 /* ext data */
867 memcpy(vendor_blob + basic_len + clock_len,
868 ssp->ssp_blob_ext[dai_index][hw_config_index].aux_blob,
869 ssp->ssp_blob_ext[dai_index][hw_config_index].size);
870 }
871 else {
872 basic_len = sizeof(struct ssp_intel_config_data);
873 /*basic data */
874 memcpy(vendor_blob, &ssp->ssp_blob[dai_index][hw_config_index], basic_len);
875 /* ext data */
876 memcpy(vendor_blob + basic_len,
877 ssp->ssp_blob_ext[dai_index][hw_config_index].aux_blob,
878 ssp->ssp_blob_ext[dai_index][hw_config_index].size);
879 }
880
881 return 0;
882 }
883
ssp_set_params(struct intel_nhlt_params * nhlt,const char * dir,int dai_index,int io_clk,int bclk_delay,int sample_bits,int mclk_id,int clks_control,int frame_pulse_width,const char * tdm_padding_per_slot,const char * quirks,int version)884 int ssp_set_params(struct intel_nhlt_params *nhlt, const char *dir, int dai_index, int io_clk,
885 int bclk_delay, int sample_bits, int mclk_id, int clks_control,
886 int frame_pulse_width, const char *tdm_padding_per_slot, const char *quirks,
887 int version)
888 {
889 struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params;
890 char delim[] = ",";
891 char *buf, *token = NULL;
892
893 if (!ssp)
894 return -EINVAL;
895
896 if (dir) {
897 if (!strcmp(dir, "playback"))
898 ssp->ssp_prm[ssp->ssp_count].direction = NHLT_ENDPOINT_DIRECTION_RENDER;
899 else if (!strcmp(dir, "capture"))
900 ssp->ssp_prm[ssp->ssp_count].direction = NHLT_ENDPOINT_DIRECTION_CAPTURE;
901 else if (!strcmp(dir, "duplex"))
902 ssp->ssp_prm[ssp->ssp_count].direction =
903 NHLT_ENDPOINT_DIRECTION_FEEDBACK_FOR_RENDER + 1;
904 else
905 return -EINVAL;
906 }
907 ssp->ssp_dai_index[ssp->ssp_count] = dai_index;
908 ssp->ssp_prm[ssp->ssp_count].io_clk = io_clk;
909 ssp->ssp_prm[ssp->ssp_count].bclk_delay = bclk_delay;
910 ssp->ssp_prm[ssp->ssp_count].sample_valid_bits = sample_bits;
911 ssp->ssp_prm[ssp->ssp_count].mclk_id = mclk_id;
912 ssp->ssp_prm[ssp->ssp_count].clks_control = clks_control;
913 ssp->ssp_prm[ssp->ssp_count].frame_pulse_width = frame_pulse_width;
914 /* let's compare the lower 16 bits as we don't send the signature from topology */
915 if (version == (SSP_BLOB_VER_1_5 & ((1 << 16) - 1)))
916 ssp->ssp_prm[ssp->ssp_count].version = SSP_BLOB_VER_1_5;
917 if (tdm_padding_per_slot && !strcmp(tdm_padding_per_slot, "true"))
918 ssp->ssp_prm[ssp->ssp_count].tdm_per_slot_padding_flag = 1;
919 else
920 ssp->ssp_prm[ssp->ssp_count].tdm_per_slot_padding_flag = 0;
921
922 ssp->ssp_prm[ssp->ssp_count].quirks = 0;
923
924 if (quirks) {
925 buf = strdup(quirks);
926 if (!buf)
927 return -ENOMEM;
928
929 token = strtok(buf, delim);
930
931 while (token) {
932 if (!strcmp(token, "lbm_mode"))
933 ssp->ssp_prm[ssp->ssp_count].quirks |= SSP_INTEL_QUIRK_LBM;
934 else if (!strcmp(token, "bt_sideband"))
935 ssp->ssp_prm[ssp->ssp_count].quirks |= SSP_INTEL_QUIRK_BT_SIDEBAND;
936 else if (!strcmp(token, "render_feedback")) {
937 if (!strcmp(dir, "duplex"))
938 ssp->ssp_prm[ssp->ssp_count].quirks |= SSP_INTEL_QUIRK_RENDER_FEEDBACK;
939 } else {
940 fprintf(stderr, "ssp_set_params(): unknown quirk %s\n", token);
941 free(buf);
942 return -EINVAL;
943 }
944
945 token = strtok(NULL, delim);
946 }
947
948 free(buf);
949 }
950
951 /* reset hw config count for this ssp instance */
952 ssp->ssp_hw_config_count[ssp->ssp_count] = 0;
953
954 return 0;
955 }
956
ssp_hw_set_params(struct intel_nhlt_params * nhlt,const char * format,const char * mclk ATTRIBUTE_UNUSED,const char * bclk,const char * bclk_invert,const char * fsync,const char * fsync_invert,int mclk_freq,int bclk_freq,int fsync_freq,int tdm_slots,int tdm_slot_width,int tx_slots,int rx_slots)957 int ssp_hw_set_params(struct intel_nhlt_params *nhlt, const char *format,
958 const char *mclk ATTRIBUTE_UNUSED,
959 const char *bclk, const char *bclk_invert, const char *fsync,
960 const char *fsync_invert, int mclk_freq, int bclk_freq, int fsync_freq,
961 int tdm_slots, int tdm_slot_width, int tx_slots, int rx_slots)
962 {
963 struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params;
964 uint32_t hwi;
965
966 if (!ssp)
967 return -EINVAL;
968
969 /* check that the strings are defined ?*/
970
971 /* compose format out of clock related string variables */
972 hwi = ssp->ssp_hw_config_count[ssp->ssp_count];
973
974 if (!strcmp(format, "I2S")) {
975 ssp->ssp_prm[ssp->ssp_count].hw_cfg[hwi].format = SSP_FMT_I2S;
976 } else if (!strcmp(format, "RIGHT_J")) {
977 ssp->ssp_prm[ssp->ssp_count].hw_cfg[hwi].format = SSP_FMT_RIGHT_J;
978 } else if (!strcmp(format, "LEFT_J")) {
979 ssp->ssp_prm[ssp->ssp_count].hw_cfg[hwi].format = SSP_FMT_LEFT_J;
980 } else if (!strcmp(format, "DSP_A")) {
981 ssp->ssp_prm[ssp->ssp_count].hw_cfg[hwi].format = SSP_FMT_DSP_A;
982 } else if (!strcmp(format, "DSP_B")) {
983 ssp->ssp_prm[ssp->ssp_count].hw_cfg[hwi].format = SSP_FMT_DSP_B;
984 } else {
985 fprintf(stderr, "no valid format specified for ssp: %s\n", format);
986 return -EINVAL;
987 }
988
989 /* clock directions wrt codec */
990 if (bclk && !strcmp(bclk, "codec_provider")) {
991 /* codec is bclk provider */
992 if (fsync && !strcmp(fsync, "codec_provider"))
993 ssp->ssp_prm[ssp->ssp_count].hw_cfg[hwi].format |= SSP_FMT_CBP_CFP;
994 else
995 ssp->ssp_prm[ssp->ssp_count].hw_cfg[hwi].format |= SSP_FMT_CBP_CFC;
996 } else {
997 /* codec is bclk consumer */
998 if (fsync && !strcmp(fsync, "codec_provider"))
999 ssp->ssp_prm[ssp->ssp_count].hw_cfg[hwi].format |= SSP_FMT_CBC_CFP;
1000 else
1001 ssp->ssp_prm[ssp->ssp_count].hw_cfg[hwi].format |= SSP_FMT_CBC_CFC;
1002 }
1003
1004 /* inverted clocks ? */
1005 if (bclk_invert && !strcmp(bclk_invert, "true")) {
1006 if (fsync_invert && !strcmp(fsync_invert, "true"))
1007 ssp->ssp_prm[ssp->ssp_count].hw_cfg[hwi].format |= SSP_FMT_IB_IF;
1008 else
1009 ssp->ssp_prm[ssp->ssp_count].hw_cfg[hwi].format |= SSP_FMT_IB_NF;
1010 } else {
1011 if (fsync_invert && !strcmp(fsync_invert, "true"))
1012 ssp->ssp_prm[ssp->ssp_count].hw_cfg[hwi].format |= SSP_FMT_NB_IF;
1013 else
1014 ssp->ssp_prm[ssp->ssp_count].hw_cfg[hwi].format |= SSP_FMT_NB_NF;
1015 }
1016
1017 ssp->ssp_prm[ssp->ssp_count].hw_cfg[hwi].mclk_rate = mclk_freq;
1018 ssp->ssp_prm[ssp->ssp_count].hw_cfg[hwi].bclk_rate = bclk_freq;
1019 ssp->ssp_prm[ssp->ssp_count].hw_cfg[hwi].fsync_rate = fsync_freq;
1020 ssp->ssp_prm[ssp->ssp_count].hw_cfg[hwi].tdm_slots = tdm_slots;
1021 ssp->ssp_prm[ssp->ssp_count].hw_cfg[hwi].tdm_slot_width = tdm_slot_width;
1022 ssp->ssp_prm[ssp->ssp_count].hw_cfg[hwi].tx_slots = tx_slots;
1023 ssp->ssp_prm[ssp->ssp_count].hw_cfg[hwi].rx_slots = rx_slots;
1024
1025 ssp->ssp_hw_config_count[ssp->ssp_count]++;
1026
1027 return 0;
1028 }
1029
ssp_mn_set_params(struct intel_nhlt_params * nhlt,int m_div,int n_div)1030 int ssp_mn_set_params(struct intel_nhlt_params *nhlt, int m_div, int n_div)
1031 {
1032 struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params;
1033 int di = ssp->ssp_count;
1034 int hwi = ssp->ssp_hw_config_count[di];
1035
1036 if (di < 0 || hwi < 0)
1037 return -EINVAL;
1038
1039 ssp->ssp_prm[di].aux_cfg[hwi].enabled |= BIT(SSP_MN_DIVIDER_CONTROLS);
1040
1041 ssp->ssp_prm[di].aux_cfg[hwi].mn.m_div = m_div;
1042 ssp->ssp_prm[di].aux_cfg[hwi].mn.n_div = n_div;
1043
1044 return 0;
1045 }
1046
ssp_clk_set_params(struct intel_nhlt_params * nhlt,int clock_warm_up,int mclk,int warm_up_ovr,int clock_stop_delay,int keep_running,int clock_stop_ovr)1047 int ssp_clk_set_params(struct intel_nhlt_params *nhlt, int clock_warm_up, int mclk, int warm_up_ovr,
1048 int clock_stop_delay, int keep_running, int clock_stop_ovr)
1049 {
1050 struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params;
1051 int di = ssp->ssp_count;
1052 int hwi = ssp->ssp_hw_config_count[di];
1053
1054 if (di < 0 || hwi < 0)
1055 return -EINVAL;
1056
1057 ssp->ssp_prm[di].aux_cfg[hwi].enabled |= BIT(SSP_DMA_CLK_CONTROLS);
1058
1059 ssp->ssp_prm[di].aux_cfg[hwi].clk.clock_warm_up = clock_warm_up;
1060 ssp->ssp_prm[di].aux_cfg[hwi].clk.mclk = mclk;
1061 ssp->ssp_prm[di].aux_cfg[hwi].clk.warm_up_ovr = warm_up_ovr;
1062 ssp->ssp_prm[di].aux_cfg[hwi].clk.clock_stop_delay = clock_stop_delay;
1063 ssp->ssp_prm[di].aux_cfg[hwi].clk.keep_running = keep_running;
1064 ssp->ssp_prm[di].aux_cfg[hwi].clk.clock_stop_ovr = clock_stop_ovr;
1065
1066 return 0;
1067 }
1068
ssp_tr_start_set_params(struct intel_nhlt_params * nhlt,int sampling_frequency,int bit_depth,int channel_map,int channel_config,int interleaving_style,int number_of_channels,int valid_bit_depth,int sample_type)1069 int ssp_tr_start_set_params(struct intel_nhlt_params *nhlt, int sampling_frequency,
1070 int bit_depth, int channel_map, int channel_config,
1071 int interleaving_style, int number_of_channels,
1072 int valid_bit_depth, int sample_type)
1073 {
1074 struct intel_ssp_params *ssp;
1075 struct ssp_aux_config_tr *tr;
1076 int di, hwi;
1077
1078 ssp = (struct intel_ssp_params *)nhlt->ssp_params;
1079 di = ssp->ssp_count;
1080 hwi = ssp->ssp_hw_config_count[di];
1081 if (di < 0 || hwi < 0)
1082 return -EINVAL;
1083 tr = (struct ssp_aux_config_tr *)&(ssp->ssp_prm[di].aux_cfg[hwi].tr_start);
1084
1085 ssp->ssp_prm[di].aux_cfg[hwi].enabled |= BIT(SSP_DMA_TRANSMISSION_START);
1086
1087 tr->sampling_frequency = sampling_frequency;
1088 tr->bit_depth = bit_depth;
1089 tr->channel_map = channel_map;
1090 tr->channel_config = channel_config;
1091 tr->interleaving_style = interleaving_style;
1092 tr->number_of_channels = number_of_channels;
1093 tr->valid_bit_depth = valid_bit_depth;
1094 tr->sample_type = sample_type;
1095
1096 return 0;
1097 }
1098
ssp_tr_stop_set_params(struct intel_nhlt_params * nhlt,int sampling_frequency,int bit_depth,int channel_map,int channel_config,int interleaving_style,int number_of_channels,int valid_bit_depth,int sample_type)1099 int ssp_tr_stop_set_params(struct intel_nhlt_params *nhlt, int sampling_frequency,
1100 int bit_depth, int channel_map, int channel_config,
1101 int interleaving_style, int number_of_channels,
1102 int valid_bit_depth, int sample_type)
1103 {
1104 struct intel_ssp_params *ssp;
1105 struct ssp_aux_config_tr *tr;
1106 int di, hwi;
1107
1108 ssp = (struct intel_ssp_params *)nhlt->ssp_params;
1109 di = ssp->ssp_count;
1110 hwi = ssp->ssp_hw_config_count[di];
1111 if (di < 0 || hwi < 0)
1112 return -EINVAL;
1113 tr = (struct ssp_aux_config_tr *)&(ssp->ssp_prm[di].aux_cfg[hwi].tr_stop);
1114
1115 ssp->ssp_prm[di].aux_cfg[hwi].enabled |= BIT(SSP_DMA_TRANSMISSION_STOP);
1116
1117 tr->sampling_frequency = sampling_frequency;
1118 tr->bit_depth = bit_depth;
1119 tr->channel_map = channel_map;
1120 tr->channel_config = channel_config;
1121 tr->interleaving_style = interleaving_style;
1122 tr->number_of_channels = number_of_channels;
1123 tr->valid_bit_depth = valid_bit_depth;
1124 tr->sample_type = sample_type;
1125
1126 return 0;
1127 }
1128
ssp_run_set_params(struct intel_nhlt_params * nhlt,int always_run)1129 int ssp_run_set_params(struct intel_nhlt_params *nhlt, int always_run)
1130 {
1131 struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params;
1132 int di = ssp->ssp_count;
1133 int hwi = ssp->ssp_hw_config_count[di];
1134
1135 if (di < 0 || hwi < 0)
1136 return -EINVAL;
1137
1138 ssp->ssp_prm[di].aux_cfg[hwi].enabled |= BIT(SSP_DMA_ALWAYS_RUNNING_MODE);
1139
1140 ssp->ssp_prm[di].aux_cfg[hwi].run.always_run = always_run;
1141
1142 return 0;
1143 }
1144
ssp_sync_set_params(struct intel_nhlt_params * nhlt,int sync_denominator)1145 int ssp_sync_set_params(struct intel_nhlt_params *nhlt, int sync_denominator)
1146 {
1147 struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params;
1148 int di = ssp->ssp_count;
1149 int hwi = ssp->ssp_hw_config_count[di];
1150
1151 if (di < 0 || hwi < 0)
1152 return -EINVAL;
1153
1154 ssp->ssp_prm[di].aux_cfg[hwi].enabled |= BIT(SSP_DMA_SYNC_DATA);
1155
1156 ssp->ssp_prm[di].aux_cfg[hwi].sync.sync_denominator = sync_denominator;
1157
1158 return 0;
1159 }
1160
ssp_node_set_params(struct intel_nhlt_params * nhlt,int node_id,int sampling_rate)1161 int ssp_node_set_params(struct intel_nhlt_params *nhlt, int node_id, int sampling_rate)
1162 {
1163 struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params;
1164 int di = ssp->ssp_count;
1165 int hwi = ssp->ssp_hw_config_count[di];
1166 int count;
1167
1168 if (di < 0 || hwi < 0)
1169 return -EINVAL;
1170
1171 count = ssp->ssp_prm[di].aux_cfg[hwi].sync.count;
1172 if (count > SSP_MAX_DAIS)
1173 return -EINVAL;
1174
1175 ssp->ssp_prm[di].aux_cfg[hwi].sync.nodes[count].node_id = node_id;
1176 ssp->ssp_prm[di].aux_cfg[hwi].sync.nodes[count].sampling_rate = sampling_rate;
1177
1178 ssp->ssp_prm[di].aux_cfg[hwi].sync.count++;
1179
1180 return 0;
1181 }
1182
ssp_ext_set_params(struct intel_nhlt_params * nhlt,int mclk_policy_override,int mclk_always_running,int mclk_starts_on_gtw_init,int mclk_starts_on_run,int mclk_starts_on_pause,int mclk_stops_on_pause,int mclk_stops_on_reset,int bclk_policy_override,int bclk_always_running,int bclk_starts_on_gtw_init,int bclk_starts_on_run,int bclk_starts_on_pause,int bclk_stops_on_pause,int bclk_stops_on_reset,int sync_policy_override,int sync_always_running,int sync_starts_on_gtw_init,int sync_starts_on_run,int sync_starts_on_pause,int sync_stops_on_pause,int sync_stops_on_reset)1183 int ssp_ext_set_params(struct intel_nhlt_params *nhlt, int mclk_policy_override,
1184 int mclk_always_running, int mclk_starts_on_gtw_init, int mclk_starts_on_run,
1185 int mclk_starts_on_pause, int mclk_stops_on_pause, int mclk_stops_on_reset,
1186 int bclk_policy_override, int bclk_always_running,
1187 int bclk_starts_on_gtw_init, int bclk_starts_on_run,
1188 int bclk_starts_on_pause, int bclk_stops_on_pause, int bclk_stops_on_reset,
1189 int sync_policy_override, int sync_always_running,
1190 int sync_starts_on_gtw_init, int sync_starts_on_run,
1191 int sync_starts_on_pause, int sync_stops_on_pause, int sync_stops_on_reset)
1192 {
1193 struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params;
1194 int di = ssp->ssp_count;
1195 int hwi = ssp->ssp_hw_config_count[di];
1196
1197 if (di < 0 || hwi < 0)
1198 return -EINVAL;
1199
1200 ssp->ssp_prm[di].aux_cfg[hwi].enabled |= BIT(SSP_DMA_CLK_CONTROLS_EXT);
1201
1202 ssp->ssp_prm[di].aux_cfg[hwi].ext.mclk_policy_override = mclk_policy_override;
1203 ssp->ssp_prm[di].aux_cfg[hwi].ext.mclk_always_running = mclk_always_running;
1204 ssp->ssp_prm[di].aux_cfg[hwi].ext.mclk_starts_on_gtw_init = mclk_starts_on_gtw_init;
1205 ssp->ssp_prm[di].aux_cfg[hwi].ext.mclk_starts_on_run = mclk_starts_on_run;
1206 ssp->ssp_prm[di].aux_cfg[hwi].ext.mclk_starts_on_pause = mclk_starts_on_pause;
1207 ssp->ssp_prm[di].aux_cfg[hwi].ext.mclk_stops_on_pause = mclk_stops_on_pause;
1208 ssp->ssp_prm[di].aux_cfg[hwi].ext.mclk_stops_on_reset = mclk_stops_on_reset;
1209 ssp->ssp_prm[di].aux_cfg[hwi].ext.bclk_policy_override = bclk_policy_override;
1210 ssp->ssp_prm[di].aux_cfg[hwi].ext.bclk_always_running = bclk_always_running;
1211 ssp->ssp_prm[di].aux_cfg[hwi].ext.bclk_starts_on_gtw_init = bclk_starts_on_gtw_init;
1212 ssp->ssp_prm[di].aux_cfg[hwi].ext.bclk_starts_on_run = bclk_starts_on_run;
1213 ssp->ssp_prm[di].aux_cfg[hwi].ext.bclk_starts_on_pause = bclk_starts_on_pause;
1214 ssp->ssp_prm[di].aux_cfg[hwi].ext.bclk_stops_on_pause = bclk_stops_on_pause;
1215 ssp->ssp_prm[di].aux_cfg[hwi].ext.bclk_stops_on_reset = bclk_stops_on_reset;
1216 ssp->ssp_prm[di].aux_cfg[hwi].ext.sync_policy_override = sync_policy_override;
1217 ssp->ssp_prm[di].aux_cfg[hwi].ext.sync_always_running = sync_always_running;
1218 ssp->ssp_prm[di].aux_cfg[hwi].ext.sync_starts_on_gtw_init = sync_starts_on_gtw_init;
1219 ssp->ssp_prm[di].aux_cfg[hwi].ext.sync_starts_on_run = sync_starts_on_run;
1220 ssp->ssp_prm[di].aux_cfg[hwi].ext.sync_starts_on_pause = sync_starts_on_pause;
1221 ssp->ssp_prm[di].aux_cfg[hwi].ext.sync_stops_on_pause = sync_stops_on_pause;
1222 ssp->ssp_prm[di].aux_cfg[hwi].ext.sync_stops_on_reset = sync_stops_on_reset;
1223
1224 return 0;
1225 }
1226
ssp_link_set_params(struct intel_nhlt_params * nhlt,int clock_source)1227 int ssp_link_set_params(struct intel_nhlt_params *nhlt, int clock_source)
1228 {
1229 struct intel_ssp_params *ssp = (struct intel_ssp_params *)nhlt->ssp_params;
1230 int di = ssp->ssp_count;
1231 int hwi = ssp->ssp_hw_config_count[di];
1232
1233 if (di < 0 || hwi < 0)
1234 return -EINVAL;
1235
1236 ssp->ssp_prm[di].aux_cfg[hwi].enabled |= BIT(SSP_LINK_CLK_SOURCE);
1237
1238 ssp->ssp_prm[di].aux_cfg[hwi].link.clock_source = clock_source;
1239
1240 return 0;
1241 }
1242
1243 /* init ssp parameters, should be called before parsing dais */
ssp_init_params(struct intel_nhlt_params * nhlt)1244 int ssp_init_params(struct intel_nhlt_params *nhlt)
1245 {
1246 struct intel_ssp_params *ssp;
1247 int i, j;
1248
1249 ssp = calloc(1, sizeof(struct intel_ssp_params));
1250 if (!ssp)
1251 return -EINVAL;
1252
1253 nhlt->ssp_params = ssp;
1254 ssp->ssp_count = 0;
1255
1256 for (i = 0; i < SSP_MAX_DAIS; i++) {
1257 ssp->ssp_hw_config_count[i] = 0;
1258 for (j = 0; j < SSP_MAX_HW_CONFIG; j++)
1259 ssp->ssp_prm[i].aux_cfg[j].sync.count = 0;
1260 }
1261
1262 return 0;
1263 }
1264