• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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