0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include "reg_helper.h"
0027 #include "dce_audio.h"
0028 #include "dce/dce_11_0_d.h"
0029 #include "dce/dce_11_0_sh_mask.h"
0030
0031 #define DCE_AUD(audio)\
0032 container_of(audio, struct dce_audio, base)
0033
0034 #define CTX \
0035 aud->base.ctx
0036
0037 #define DC_LOGGER_INIT()
0038
0039 #define REG(reg)\
0040 (aud->regs->reg)
0041
0042 #undef FN
0043 #define FN(reg_name, field_name) \
0044 aud->shifts->field_name, aud->masks->field_name
0045
0046 #define IX_REG(reg)\
0047 ix ## reg
0048
0049 #define AZ_REG_READ(reg_name) \
0050 read_indirect_azalia_reg(audio, IX_REG(reg_name))
0051
0052 #define AZ_REG_WRITE(reg_name, value) \
0053 write_indirect_azalia_reg(audio, IX_REG(reg_name), value)
0054
0055 static void write_indirect_azalia_reg(struct audio *audio,
0056 uint32_t reg_index,
0057 uint32_t reg_data)
0058 {
0059 struct dce_audio *aud = DCE_AUD(audio);
0060
0061
0062 REG_SET(AZALIA_F0_CODEC_ENDPOINT_INDEX, 0,
0063 AZALIA_ENDPOINT_REG_INDEX, reg_index);
0064
0065
0066 REG_SET(AZALIA_F0_CODEC_ENDPOINT_DATA, 0,
0067 AZALIA_ENDPOINT_REG_DATA, reg_data);
0068 }
0069
0070 static uint32_t read_indirect_azalia_reg(struct audio *audio, uint32_t reg_index)
0071 {
0072 struct dce_audio *aud = DCE_AUD(audio);
0073
0074 uint32_t value = 0;
0075
0076
0077 REG_SET(AZALIA_F0_CODEC_ENDPOINT_INDEX, 0,
0078 AZALIA_ENDPOINT_REG_INDEX, reg_index);
0079
0080
0081 value = REG_READ(AZALIA_F0_CODEC_ENDPOINT_DATA);
0082
0083 return value;
0084 }
0085
0086 static bool is_audio_format_supported(
0087 const struct audio_info *audio_info,
0088 enum audio_format_code audio_format_code,
0089 uint32_t *format_index)
0090 {
0091 uint32_t index;
0092 uint32_t max_channe_index = 0;
0093 bool found = false;
0094
0095 if (audio_info == NULL)
0096 return found;
0097
0098
0099 for (index = 0; index < audio_info->mode_count; index++) {
0100 if (audio_info->modes[index].format_code == audio_format_code) {
0101 if (found) {
0102
0103
0104 if (audio_info->modes[index].channel_count >
0105 audio_info->modes[max_channe_index].channel_count) {
0106 max_channe_index = index;
0107 }
0108 } else {
0109
0110 found = true;
0111 max_channe_index = index;
0112 }
0113 }
0114 }
0115
0116
0117 if (found && format_index != NULL)
0118 *format_index = max_channe_index;
0119
0120 return found;
0121 }
0122
0123
0124 static void check_audio_bandwidth_hdmi(
0125 const struct audio_crtc_info *crtc_info,
0126 uint32_t channel_count,
0127 union audio_sample_rates *sample_rates)
0128 {
0129 uint32_t samples;
0130 uint32_t h_blank;
0131 bool limit_freq_to_48_khz = false;
0132 bool limit_freq_to_88_2_khz = false;
0133 bool limit_freq_to_96_khz = false;
0134 bool limit_freq_to_174_4_khz = false;
0135 if (!crtc_info)
0136 return;
0137
0138
0139 if (channel_count > 2) {
0140
0141
0142 if ((crtc_info->requested_pixel_clock_100Hz <= 270000) &&
0143 (crtc_info->v_active <= 576) &&
0144 !(crtc_info->interlaced) &&
0145 !(crtc_info->pixel_repetition == 2 ||
0146 crtc_info->pixel_repetition == 4)) {
0147 limit_freq_to_48_khz = true;
0148
0149 } else if ((crtc_info->requested_pixel_clock_100Hz <= 270000) &&
0150 (crtc_info->v_active <= 576) &&
0151 (crtc_info->interlaced) &&
0152 (crtc_info->pixel_repetition == 2)) {
0153 limit_freq_to_88_2_khz = true;
0154
0155 } else if ((crtc_info->requested_pixel_clock_100Hz <= 540000) &&
0156 (crtc_info->v_active <= 576) &&
0157 !(crtc_info->interlaced)) {
0158 limit_freq_to_174_4_khz = true;
0159 }
0160 }
0161
0162
0163
0164
0165 h_blank = crtc_info->h_total - crtc_info->h_active;
0166
0167 if (crtc_info->pixel_repetition)
0168 h_blank *= crtc_info->pixel_repetition;
0169
0170
0171 h_blank -= 58;
0172
0173 h_blank -= 16;
0174
0175 samples = h_blank * 10;
0176
0177
0178
0179 samples /= 32;
0180 samples *= crtc_info->v_active;
0181
0182 samples *= crtc_info->refresh_rate;
0183
0184 samples /= 10;
0185
0186
0187
0188
0189
0190
0191
0192
0193 switch (crtc_info->color_depth) {
0194 case COLOR_DEPTH_888:
0195 samples *= 4;
0196 break;
0197 case COLOR_DEPTH_101010:
0198 samples *= 5;
0199 break;
0200 case COLOR_DEPTH_121212:
0201 samples *= 6;
0202 break;
0203 default:
0204 samples *= 4;
0205 break;
0206 }
0207
0208 samples /= 4;
0209
0210
0211 if (samples < 88200)
0212 limit_freq_to_48_khz = true;
0213 else if (samples < 96000)
0214 limit_freq_to_88_2_khz = true;
0215 else if (samples < 176400)
0216 limit_freq_to_96_khz = true;
0217 else if (samples < 192000)
0218 limit_freq_to_174_4_khz = true;
0219
0220 if (sample_rates != NULL) {
0221
0222 if (limit_freq_to_174_4_khz)
0223 sample_rates->rate.RATE_192 = 0;
0224
0225 if (limit_freq_to_96_khz) {
0226 sample_rates->rate.RATE_192 = 0;
0227 sample_rates->rate.RATE_176_4 = 0;
0228 }
0229 if (limit_freq_to_88_2_khz) {
0230 sample_rates->rate.RATE_192 = 0;
0231 sample_rates->rate.RATE_176_4 = 0;
0232 sample_rates->rate.RATE_96 = 0;
0233 }
0234 if (limit_freq_to_48_khz) {
0235 sample_rates->rate.RATE_192 = 0;
0236 sample_rates->rate.RATE_176_4 = 0;
0237 sample_rates->rate.RATE_96 = 0;
0238 sample_rates->rate.RATE_88_2 = 0;
0239 }
0240 }
0241 }
0242
0243
0244 static void check_audio_bandwidth_dpsst(
0245 const struct audio_crtc_info *crtc_info,
0246 uint32_t channel_count,
0247 union audio_sample_rates *sample_rates)
0248 {
0249
0250 }
0251
0252
0253 static void check_audio_bandwidth_dpmst(
0254 const struct audio_crtc_info *crtc_info,
0255 uint32_t channel_count,
0256 union audio_sample_rates *sample_rates)
0257 {
0258
0259 }
0260
0261 static void check_audio_bandwidth(
0262 const struct audio_crtc_info *crtc_info,
0263 uint32_t channel_count,
0264 enum signal_type signal,
0265 union audio_sample_rates *sample_rates)
0266 {
0267 switch (signal) {
0268 case SIGNAL_TYPE_HDMI_TYPE_A:
0269 check_audio_bandwidth_hdmi(
0270 crtc_info, channel_count, sample_rates);
0271 break;
0272 case SIGNAL_TYPE_EDP:
0273 case SIGNAL_TYPE_DISPLAY_PORT:
0274 check_audio_bandwidth_dpsst(
0275 crtc_info, channel_count, sample_rates);
0276 break;
0277 case SIGNAL_TYPE_DISPLAY_PORT_MST:
0278 check_audio_bandwidth_dpmst(
0279 crtc_info, channel_count, sample_rates);
0280 break;
0281 default:
0282 break;
0283 }
0284 }
0285
0286
0287 static void set_high_bit_rate_capable(
0288 struct audio *audio,
0289 bool capable)
0290 {
0291 uint32_t value = 0;
0292
0293
0294 value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR);
0295
0296 set_reg_field_value(value, capable,
0297 AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR,
0298 HBR_CAPABLE);
0299
0300 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR, value);
0301 }
0302
0303
0304 static void set_video_latency(
0305 struct audio *audio,
0306 int latency_in_ms)
0307 {
0308 uint32_t value = 0;
0309
0310 if ((latency_in_ms < 0) || (latency_in_ms > 255))
0311 return;
0312
0313 value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC);
0314
0315 set_reg_field_value(value, latency_in_ms,
0316 AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
0317 VIDEO_LIPSYNC);
0318
0319 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
0320 value);
0321 }
0322
0323
0324 static void set_audio_latency(
0325 struct audio *audio,
0326 int latency_in_ms)
0327 {
0328 uint32_t value = 0;
0329
0330 if (latency_in_ms < 0)
0331 latency_in_ms = 0;
0332
0333 if (latency_in_ms > 255)
0334 latency_in_ms = 255;
0335
0336 value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC);
0337
0338 set_reg_field_value(value, latency_in_ms,
0339 AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
0340 AUDIO_LIPSYNC);
0341
0342 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
0343 value);
0344 }
0345
0346 void dce_aud_az_enable(struct audio *audio)
0347 {
0348 uint32_t value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
0349 DC_LOGGER_INIT();
0350
0351 set_reg_field_value(value, 1,
0352 AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
0353 CLOCK_GATING_DISABLE);
0354 set_reg_field_value(value, 1,
0355 AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
0356 AUDIO_ENABLED);
0357
0358 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
0359 set_reg_field_value(value, 0,
0360 AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
0361 CLOCK_GATING_DISABLE);
0362 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
0363
0364 DC_LOG_HW_AUDIO("\n\t========= AUDIO:dce_aud_az_enable: index: %u data: 0x%x\n",
0365 audio->inst, value);
0366 }
0367
0368 void dce_aud_az_disable(struct audio *audio)
0369 {
0370 uint32_t value;
0371 DC_LOGGER_INIT();
0372
0373 value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
0374 set_reg_field_value(value, 1,
0375 AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
0376 CLOCK_GATING_DISABLE);
0377 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
0378
0379 set_reg_field_value(value, 0,
0380 AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
0381 AUDIO_ENABLED);
0382 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
0383
0384 set_reg_field_value(value, 0,
0385 AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
0386 CLOCK_GATING_DISABLE);
0387 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
0388 value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
0389 DC_LOG_HW_AUDIO("\n\t========= AUDIO:dce_aud_az_disable: index: %u data: 0x%x\n",
0390 audio->inst, value);
0391 }
0392
0393 void dce_aud_az_configure(
0394 struct audio *audio,
0395 enum signal_type signal,
0396 const struct audio_crtc_info *crtc_info,
0397 const struct audio_info *audio_info)
0398 {
0399 struct dce_audio *aud = DCE_AUD(audio);
0400
0401 uint32_t speakers = audio_info->flags.info.ALLSPEAKERS;
0402 uint32_t value;
0403 uint32_t field = 0;
0404 enum audio_format_code audio_format_code;
0405 uint32_t format_index;
0406 uint32_t index;
0407 bool is_ac3_supported = false;
0408 union audio_sample_rates sample_rate;
0409 uint32_t strlen = 0;
0410 value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
0411 set_reg_field_value(value, 1,
0412 AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
0413 CLOCK_GATING_DISABLE);
0414 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
0415
0416
0417
0418
0419
0420 value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER);
0421
0422 set_reg_field_value(value,
0423 speakers,
0424 AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
0425 SPEAKER_ALLOCATION);
0426
0427
0428
0429
0430
0431
0432
0433 set_reg_field_value(value,
0434 0,
0435 AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
0436 LFE_PLAYBACK_LEVEL);
0437
0438
0439
0440
0441 set_reg_field_value(value,
0442 0,
0443 AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
0444 HDMI_CONNECTION);
0445
0446 set_reg_field_value(value,
0447 0,
0448 AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
0449 DP_CONNECTION);
0450
0451 field = get_reg_field_value(value,
0452 AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
0453 EXTRA_CONNECTION_INFO);
0454
0455 field &= ~0x1;
0456
0457 set_reg_field_value(value,
0458 field,
0459 AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
0460 EXTRA_CONNECTION_INFO);
0461
0462
0463 switch (signal) {
0464 case SIGNAL_TYPE_HDMI_TYPE_A:
0465 set_reg_field_value(value,
0466 1,
0467 AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
0468 HDMI_CONNECTION);
0469
0470 break;
0471
0472 case SIGNAL_TYPE_EDP:
0473 case SIGNAL_TYPE_DISPLAY_PORT:
0474 case SIGNAL_TYPE_DISPLAY_PORT_MST:
0475 set_reg_field_value(value,
0476 1,
0477 AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
0478 DP_CONNECTION);
0479 break;
0480 default:
0481 BREAK_TO_DEBUGGER();
0482 break;
0483 }
0484
0485 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, value);
0486
0487
0488 value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_ACP_DATA);
0489
0490 set_reg_field_value(
0491 value,
0492 audio_info->flags.info.SUPPORT_AI,
0493 AZALIA_F0_CODEC_PIN_CONTROL_ACP_DATA,
0494 SUPPORTS_AI);
0495
0496 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_ACP_DATA, value);
0497
0498
0499
0500 for (format_index = 0; format_index < AUDIO_FORMAT_CODE_COUNT;
0501 format_index++) {
0502 audio_format_code =
0503 (AUDIO_FORMAT_CODE_FIRST + format_index);
0504
0505
0506 if (audio_format_code == AUDIO_FORMAT_CODE_1BITAUDIO ||
0507 audio_format_code == AUDIO_FORMAT_CODE_DST)
0508 continue;
0509
0510 value = 0;
0511
0512
0513 if (is_audio_format_supported(
0514 audio_info, audio_format_code, &index)) {
0515 const struct audio_mode *audio_mode =
0516 &audio_info->modes[index];
0517 union audio_sample_rates sample_rates =
0518 audio_mode->sample_rates;
0519 uint8_t byte2 = audio_mode->max_bit_rate;
0520 uint8_t channel_count = audio_mode->channel_count;
0521
0522
0523 switch (audio_format_code) {
0524 case AUDIO_FORMAT_CODE_LINEARPCM: {
0525
0526 check_audio_bandwidth(
0527 crtc_info,
0528 channel_count,
0529 signal,
0530 &sample_rates);
0531
0532 byte2 = audio_mode->sample_size;
0533
0534 set_reg_field_value(value,
0535 sample_rates.all,
0536 AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
0537 SUPPORTED_FREQUENCIES_STEREO);
0538 }
0539 break;
0540 case AUDIO_FORMAT_CODE_AC3:
0541 is_ac3_supported = true;
0542 break;
0543 case AUDIO_FORMAT_CODE_DOLBYDIGITALPLUS:
0544 case AUDIO_FORMAT_CODE_DTS_HD:
0545 case AUDIO_FORMAT_CODE_MAT_MLP:
0546 case AUDIO_FORMAT_CODE_DST:
0547 case AUDIO_FORMAT_CODE_WMAPRO:
0548 byte2 = audio_mode->vendor_specific;
0549 break;
0550 default:
0551 break;
0552 }
0553
0554
0555 set_reg_field_value(value,
0556 channel_count - 1,
0557 AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
0558 MAX_CHANNELS);
0559
0560 set_reg_field_value(value,
0561 sample_rates.all,
0562 AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
0563 SUPPORTED_FREQUENCIES);
0564
0565 set_reg_field_value(value,
0566 byte2,
0567 AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
0568 DESCRIPTOR_BYTE_2);
0569 }
0570
0571 AZ_REG_WRITE(
0572 AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0 + format_index,
0573 value);
0574 }
0575
0576 if (is_ac3_supported)
0577
0578 REG_WRITE(AZALIA_F0_CODEC_FUNCTION_PARAMETER_STREAM_FORMATS,
0579 0x05);
0580
0581
0582 sample_rate.all = 0;
0583 sample_rate.rate.RATE_192 = 1;
0584
0585 check_audio_bandwidth(
0586 crtc_info,
0587 8,
0588 signal,
0589 &sample_rate);
0590
0591 set_high_bit_rate_capable(audio, sample_rate.rate.RATE_192);
0592
0593
0594 set_video_latency(audio, audio_info->video_latency);
0595 set_audio_latency(audio, audio_info->audio_latency);
0596
0597 value = 0;
0598 set_reg_field_value(value, audio_info->manufacture_id,
0599 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0,
0600 MANUFACTURER_ID);
0601
0602 set_reg_field_value(value, audio_info->product_id,
0603 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0,
0604 PRODUCT_ID);
0605
0606 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0,
0607 value);
0608
0609 value = 0;
0610
0611
0612 while (audio_info->display_name[strlen++] != '\0') {
0613 if (strlen >=
0614 MAX_HW_AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS)
0615 break;
0616 }
0617 set_reg_field_value(value, strlen,
0618 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO1,
0619 SINK_DESCRIPTION_LEN);
0620
0621 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO1,
0622 value);
0623 DC_LOG_HW_AUDIO("\n\tAUDIO:az_configure: index: %u data, 0x%x, displayName %s: \n",
0624 audio->inst, value, audio_info->display_name);
0625
0626
0627
0628
0629
0630
0631
0632
0633 value = 0;
0634
0635 set_reg_field_value(value, audio_info->port_id[0],
0636 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO2,
0637 PORT_ID0);
0638
0639 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO2, value);
0640
0641 value = 0;
0642 set_reg_field_value(value, audio_info->port_id[1],
0643 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO3,
0644 PORT_ID1);
0645
0646 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO3, value);
0647
0648
0649
0650 value = 0;
0651 set_reg_field_value(value, audio_info->display_name[0],
0652 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,
0653 DESCRIPTION0);
0654
0655 set_reg_field_value(value, audio_info->display_name[1],
0656 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,
0657 DESCRIPTION1);
0658
0659 set_reg_field_value(value, audio_info->display_name[2],
0660 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,
0661 DESCRIPTION2);
0662
0663 set_reg_field_value(value, audio_info->display_name[3],
0664 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,
0665 DESCRIPTION3);
0666
0667 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4, value);
0668
0669 value = 0;
0670 set_reg_field_value(value, audio_info->display_name[4],
0671 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,
0672 DESCRIPTION4);
0673
0674 set_reg_field_value(value, audio_info->display_name[5],
0675 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,
0676 DESCRIPTION5);
0677
0678 set_reg_field_value(value, audio_info->display_name[6],
0679 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,
0680 DESCRIPTION6);
0681
0682 set_reg_field_value(value, audio_info->display_name[7],
0683 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,
0684 DESCRIPTION7);
0685
0686 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5, value);
0687
0688 value = 0;
0689 set_reg_field_value(value, audio_info->display_name[8],
0690 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,
0691 DESCRIPTION8);
0692
0693 set_reg_field_value(value, audio_info->display_name[9],
0694 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,
0695 DESCRIPTION9);
0696
0697 set_reg_field_value(value, audio_info->display_name[10],
0698 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,
0699 DESCRIPTION10);
0700
0701 set_reg_field_value(value, audio_info->display_name[11],
0702 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,
0703 DESCRIPTION11);
0704
0705 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6, value);
0706
0707 value = 0;
0708 set_reg_field_value(value, audio_info->display_name[12],
0709 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,
0710 DESCRIPTION12);
0711
0712 set_reg_field_value(value, audio_info->display_name[13],
0713 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,
0714 DESCRIPTION13);
0715
0716 set_reg_field_value(value, audio_info->display_name[14],
0717 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,
0718 DESCRIPTION14);
0719
0720 set_reg_field_value(value, audio_info->display_name[15],
0721 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,
0722 DESCRIPTION15);
0723
0724 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7, value);
0725
0726 value = 0;
0727 set_reg_field_value(value, audio_info->display_name[16],
0728 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8,
0729 DESCRIPTION16);
0730
0731 set_reg_field_value(value, audio_info->display_name[17],
0732 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8,
0733 DESCRIPTION17);
0734
0735 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8, value);
0736 value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
0737 set_reg_field_value(value, 0,
0738 AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
0739 CLOCK_GATING_DISABLE);
0740 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
0741 }
0742
0743
0744
0745
0746
0747
0748 static void get_azalia_clock_info_hdmi(
0749 uint32_t crtc_pixel_clock_100hz,
0750 uint32_t actual_pixel_clock_100Hz,
0751 struct azalia_clock_info *azalia_clock_info)
0752 {
0753
0754
0755 azalia_clock_info->audio_dto_phase =
0756 24 * 10000;
0757
0758
0759
0760 azalia_clock_info->audio_dto_module =
0761 actual_pixel_clock_100Hz;
0762 }
0763
0764 static void get_azalia_clock_info_dp(
0765 uint32_t requested_pixel_clock_100Hz,
0766 const struct audio_pll_info *pll_info,
0767 struct azalia_clock_info *azalia_clock_info)
0768 {
0769
0770
0771
0772
0773
0774
0775
0776 azalia_clock_info->audio_dto_phase = 24 * 10000;
0777
0778
0779
0780 azalia_clock_info->audio_dto_module =
0781 pll_info->dp_dto_source_clock_in_khz * 10;
0782 }
0783
0784 void dce_aud_wall_dto_setup(
0785 struct audio *audio,
0786 enum signal_type signal,
0787 const struct audio_crtc_info *crtc_info,
0788 const struct audio_pll_info *pll_info)
0789 {
0790 struct dce_audio *aud = DCE_AUD(audio);
0791
0792 struct azalia_clock_info clock_info = { 0 };
0793
0794 if (dc_is_hdmi_tmds_signal(signal)) {
0795 uint32_t src_sel;
0796
0797
0798
0799
0800
0801
0802
0803 get_azalia_clock_info_hdmi(
0804 crtc_info->requested_pixel_clock_100Hz,
0805 crtc_info->calculated_pixel_clock_100Hz,
0806 &clock_info);
0807
0808 DC_LOG_HW_AUDIO("\n%s:Input::requested_pixel_clock_100Hz = %d"\
0809 "calculated_pixel_clock_100Hz =%d\n"\
0810 "audio_dto_module = %d audio_dto_phase =%d \n\n", __func__,\
0811 crtc_info->requested_pixel_clock_100Hz,\
0812 crtc_info->calculated_pixel_clock_100Hz,\
0813 clock_info.audio_dto_module,\
0814 clock_info.audio_dto_phase);
0815
0816
0817
0818
0819
0820
0821
0822
0823
0824 src_sel = pll_info->dto_source - DTO_SOURCE_ID0;
0825 REG_UPDATE_2(DCCG_AUDIO_DTO_SOURCE,
0826 DCCG_AUDIO_DTO0_SOURCE_SEL, src_sel,
0827 DCCG_AUDIO_DTO_SEL, 0);
0828
0829
0830 REG_UPDATE(DCCG_AUDIO_DTO0_MODULE,
0831 DCCG_AUDIO_DTO0_MODULE, clock_info.audio_dto_module);
0832
0833
0834 REG_UPDATE(DCCG_AUDIO_DTO0_PHASE,
0835 DCCG_AUDIO_DTO0_PHASE, clock_info.audio_dto_phase);
0836 } else {
0837
0838
0839
0840
0841
0842
0843
0844 get_azalia_clock_info_dp(
0845 crtc_info->requested_pixel_clock_100Hz,
0846 pll_info,
0847 &clock_info);
0848
0849
0850
0851
0852 REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
0853 DCCG_AUDIO_DTO_SEL, 1);
0854
0855
0856
0857
0858
0859
0860
0861
0862 REG_UPDATE(DCCG_AUDIO_DTO1_MODULE,
0863 DCCG_AUDIO_DTO1_MODULE, clock_info.audio_dto_module);
0864
0865
0866 REG_UPDATE(DCCG_AUDIO_DTO1_PHASE,
0867 DCCG_AUDIO_DTO1_PHASE, clock_info.audio_dto_phase);
0868
0869 REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
0870 DCCG_AUDIO_DTO2_USE_512FBR_DTO, 1);
0871
0872 }
0873 }
0874
0875 #if defined(CONFIG_DRM_AMD_DC_SI)
0876 static void dce60_aud_wall_dto_setup(
0877 struct audio *audio,
0878 enum signal_type signal,
0879 const struct audio_crtc_info *crtc_info,
0880 const struct audio_pll_info *pll_info)
0881 {
0882 struct dce_audio *aud = DCE_AUD(audio);
0883
0884 struct azalia_clock_info clock_info = { 0 };
0885
0886 if (dc_is_hdmi_signal(signal)) {
0887 uint32_t src_sel;
0888
0889
0890
0891
0892
0893
0894
0895 get_azalia_clock_info_hdmi(
0896 crtc_info->requested_pixel_clock_100Hz,
0897 crtc_info->calculated_pixel_clock_100Hz,
0898 &clock_info);
0899
0900 DC_LOG_HW_AUDIO("\n%s:Input::requested_pixel_clock_100Hz = %d"\
0901 "calculated_pixel_clock_100Hz =%d\n"\
0902 "audio_dto_module = %d audio_dto_phase =%d \n\n", __func__,\
0903 crtc_info->requested_pixel_clock_100Hz,\
0904 crtc_info->calculated_pixel_clock_100Hz,\
0905 clock_info.audio_dto_module,\
0906 clock_info.audio_dto_phase);
0907
0908
0909
0910
0911
0912
0913
0914
0915
0916 src_sel = pll_info->dto_source - DTO_SOURCE_ID0;
0917 REG_UPDATE_2(DCCG_AUDIO_DTO_SOURCE,
0918 DCCG_AUDIO_DTO0_SOURCE_SEL, src_sel,
0919 DCCG_AUDIO_DTO_SEL, 0);
0920
0921
0922 REG_UPDATE(DCCG_AUDIO_DTO0_MODULE,
0923 DCCG_AUDIO_DTO0_MODULE, clock_info.audio_dto_module);
0924
0925
0926 REG_UPDATE(DCCG_AUDIO_DTO0_PHASE,
0927 DCCG_AUDIO_DTO0_PHASE, clock_info.audio_dto_phase);
0928 } else {
0929
0930
0931
0932
0933
0934
0935
0936 get_azalia_clock_info_dp(
0937 crtc_info->requested_pixel_clock_100Hz,
0938 pll_info,
0939 &clock_info);
0940
0941
0942
0943
0944 REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
0945 DCCG_AUDIO_DTO_SEL, 1);
0946
0947
0948
0949
0950
0951
0952
0953
0954 REG_UPDATE(DCCG_AUDIO_DTO1_MODULE,
0955 DCCG_AUDIO_DTO1_MODULE, clock_info.audio_dto_module);
0956
0957
0958 REG_UPDATE(DCCG_AUDIO_DTO1_PHASE,
0959 DCCG_AUDIO_DTO1_PHASE, clock_info.audio_dto_phase);
0960
0961
0962
0963 }
0964 }
0965 #endif
0966
0967 static bool dce_aud_endpoint_valid(struct audio *audio)
0968 {
0969 uint32_t value;
0970 uint32_t port_connectivity;
0971
0972 value = AZ_REG_READ(
0973 AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT);
0974
0975 port_connectivity = get_reg_field_value(value,
0976 AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT,
0977 PORT_CONNECTIVITY);
0978
0979 return !(port_connectivity == 1);
0980 }
0981
0982
0983 void dce_aud_hw_init(
0984 struct audio *audio)
0985 {
0986 uint32_t value;
0987 struct dce_audio *aud = DCE_AUD(audio);
0988
0989
0990
0991 if (audio->inst != 0)
0992 return;
0993
0994
0995
0996
0997
0998
0999 value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
1000 set_reg_field_value(value, 1,
1001 AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
1002 CLOCK_GATING_DISABLE);
1003 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
1004 REG_UPDATE(AZALIA_F0_CODEC_FUNCTION_PARAMETER_SUPPORTED_SIZE_RATES,
1005 AUDIO_RATE_CAPABILITIES, 0x70);
1006
1007
1008 REG_UPDATE_2(AZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES,
1009 CLKSTOP, 1,
1010 EPSS, 1);
1011 set_reg_field_value(value, 0,
1012 AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
1013 CLOCK_GATING_DISABLE);
1014 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
1015 }
1016
1017 static const struct audio_funcs funcs = {
1018 .endpoint_valid = dce_aud_endpoint_valid,
1019 .hw_init = dce_aud_hw_init,
1020 .wall_dto_setup = dce_aud_wall_dto_setup,
1021 .az_enable = dce_aud_az_enable,
1022 .az_disable = dce_aud_az_disable,
1023 .az_configure = dce_aud_az_configure,
1024 .destroy = dce_aud_destroy,
1025 };
1026
1027 #if defined(CONFIG_DRM_AMD_DC_SI)
1028 static const struct audio_funcs dce60_funcs = {
1029 .endpoint_valid = dce_aud_endpoint_valid,
1030 .hw_init = dce_aud_hw_init,
1031 .wall_dto_setup = dce60_aud_wall_dto_setup,
1032 .az_enable = dce_aud_az_enable,
1033 .az_disable = dce_aud_az_disable,
1034 .az_configure = dce_aud_az_configure,
1035 .destroy = dce_aud_destroy,
1036 };
1037 #endif
1038
1039 void dce_aud_destroy(struct audio **audio)
1040 {
1041 struct dce_audio *aud = DCE_AUD(*audio);
1042
1043 kfree(aud);
1044 *audio = NULL;
1045 }
1046
1047 struct audio *dce_audio_create(
1048 struct dc_context *ctx,
1049 unsigned int inst,
1050 const struct dce_audio_registers *reg,
1051 const struct dce_audio_shift *shifts,
1052 const struct dce_audio_mask *masks
1053 )
1054 {
1055 struct dce_audio *audio = kzalloc(sizeof(*audio), GFP_KERNEL);
1056
1057 if (audio == NULL) {
1058 ASSERT_CRITICAL(audio);
1059 return NULL;
1060 }
1061
1062 audio->base.ctx = ctx;
1063 audio->base.inst = inst;
1064 audio->base.funcs = &funcs;
1065
1066 audio->regs = reg;
1067 audio->shifts = shifts;
1068 audio->masks = masks;
1069 return &audio->base;
1070 }
1071
1072 #if defined(CONFIG_DRM_AMD_DC_SI)
1073 struct audio *dce60_audio_create(
1074 struct dc_context *ctx,
1075 unsigned int inst,
1076 const struct dce_audio_registers *reg,
1077 const struct dce_audio_shift *shifts,
1078 const struct dce_audio_mask *masks
1079 )
1080 {
1081 struct dce_audio *audio = kzalloc(sizeof(*audio), GFP_KERNEL);
1082
1083 if (audio == NULL) {
1084 ASSERT_CRITICAL(audio);
1085 return NULL;
1086 }
1087
1088 audio->base.ctx = ctx;
1089 audio->base.inst = inst;
1090 audio->base.funcs = &dce60_funcs;
1091
1092 audio->regs = reg;
1093 audio->shifts = shifts;
1094 audio->masks = masks;
1095 return &audio->base;
1096 }
1097 #endif