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 29static 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 41static 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 77static 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 552static 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 735int 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 761int 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 773int 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 797int 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 */ 818int 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 837int 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 */ 848int 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 884int 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 957int 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 1030int 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 1047int 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 1069int 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 1099int 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 1129int 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 1145int 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 1161int 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 1183int 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 1227int 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 */ 1244int 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