Line data Source code
1 : /*
2 : * Copyright 2012-15 Advanced Micro Devices, Inc.
3 : *
4 : * Permission is hereby granted, free of charge, to any person obtaining a
5 : * copy of this software and associated documentation files (the "Software"),
6 : * to deal in the Software without restriction, including without limitation
7 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 : * and/or sell copies of the Software, and to permit persons to whom the
9 : * Software is furnished to do so, subject to the following conditions:
10 : *
11 : * The above copyright notice and this permission notice shall be included in
12 : * all copies or substantial portions of the Software.
13 : *
14 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 : * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 : * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 : * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 : * OTHER DEALINGS IN THE SOFTWARE.
21 : *
22 : * Authors: AMD
23 : *
24 : */
25 :
26 : #include "reg_helper.h"
27 : #include "dce_audio.h"
28 : #include "dce/dce_11_0_d.h"
29 : #include "dce/dce_11_0_sh_mask.h"
30 :
31 : #define DCE_AUD(audio)\
32 : container_of(audio, struct dce_audio, base)
33 :
34 : #define CTX \
35 : aud->base.ctx
36 :
37 : #define DC_LOGGER_INIT()
38 :
39 : #define REG(reg)\
40 : (aud->regs->reg)
41 :
42 : #undef FN
43 : #define FN(reg_name, field_name) \
44 : aud->shifts->field_name, aud->masks->field_name
45 :
46 : #define IX_REG(reg)\
47 : ix ## reg
48 :
49 : #define AZ_REG_READ(reg_name) \
50 : read_indirect_azalia_reg(audio, IX_REG(reg_name))
51 :
52 : #define AZ_REG_WRITE(reg_name, value) \
53 : write_indirect_azalia_reg(audio, IX_REG(reg_name), value)
54 :
55 0 : static void write_indirect_azalia_reg(struct audio *audio,
56 : uint32_t reg_index,
57 : uint32_t reg_data)
58 : {
59 0 : struct dce_audio *aud = DCE_AUD(audio);
60 :
61 : /* AZALIA_F0_CODEC_ENDPOINT_INDEX endpoint index */
62 0 : REG_SET(AZALIA_F0_CODEC_ENDPOINT_INDEX, 0,
63 : AZALIA_ENDPOINT_REG_INDEX, reg_index);
64 :
65 : /* AZALIA_F0_CODEC_ENDPOINT_DATA endpoint data */
66 0 : REG_SET(AZALIA_F0_CODEC_ENDPOINT_DATA, 0,
67 : AZALIA_ENDPOINT_REG_DATA, reg_data);
68 0 : }
69 :
70 0 : static uint32_t read_indirect_azalia_reg(struct audio *audio, uint32_t reg_index)
71 : {
72 0 : struct dce_audio *aud = DCE_AUD(audio);
73 :
74 0 : uint32_t value = 0;
75 :
76 : /* AZALIA_F0_CODEC_ENDPOINT_INDEX endpoint index */
77 0 : REG_SET(AZALIA_F0_CODEC_ENDPOINT_INDEX, 0,
78 : AZALIA_ENDPOINT_REG_INDEX, reg_index);
79 :
80 : /* AZALIA_F0_CODEC_ENDPOINT_DATA endpoint data */
81 0 : value = REG_READ(AZALIA_F0_CODEC_ENDPOINT_DATA);
82 :
83 0 : return value;
84 : }
85 :
86 : static bool is_audio_format_supported(
87 : const struct audio_info *audio_info,
88 : enum audio_format_code audio_format_code,
89 : uint32_t *format_index)
90 : {
91 : uint32_t index;
92 0 : uint32_t max_channe_index = 0;
93 0 : bool found = false;
94 :
95 0 : if (audio_info == NULL)
96 : return found;
97 :
98 : /* pass through whole array */
99 0 : for (index = 0; index < audio_info->mode_count; index++) {
100 0 : if (audio_info->modes[index].format_code == audio_format_code) {
101 0 : if (found) {
102 : /* format has multiply entries, choose one with
103 : * highst number of channels */
104 0 : if (audio_info->modes[index].channel_count >
105 0 : audio_info->modes[max_channe_index].channel_count) {
106 0 : max_channe_index = index;
107 : }
108 : } else {
109 : /* format found, save it's index */
110 : found = true;
111 : max_channe_index = index;
112 : }
113 : }
114 : }
115 :
116 : /* return index */
117 0 : if (found && format_index != NULL)
118 0 : *format_index = max_channe_index;
119 :
120 : return found;
121 : }
122 :
123 : /*For HDMI, calculate if specified sample rates can fit into a given timing */
124 0 : static void check_audio_bandwidth_hdmi(
125 : const struct audio_crtc_info *crtc_info,
126 : uint32_t channel_count,
127 : union audio_sample_rates *sample_rates)
128 : {
129 : uint32_t samples;
130 : uint32_t h_blank;
131 0 : bool limit_freq_to_48_khz = false;
132 0 : bool limit_freq_to_88_2_khz = false;
133 0 : bool limit_freq_to_96_khz = false;
134 0 : bool limit_freq_to_174_4_khz = false;
135 0 : if (!crtc_info)
136 : return;
137 :
138 : /* For two channels supported return whatever sink support,unmodified*/
139 0 : if (channel_count > 2) {
140 :
141 : /* Based on HDMI spec 1.3 Table 7.5 */
142 0 : if ((crtc_info->requested_pixel_clock_100Hz <= 270000) &&
143 0 : (crtc_info->v_active <= 576) &&
144 0 : !(crtc_info->interlaced) &&
145 0 : !(crtc_info->pixel_repetition == 2 ||
146 : crtc_info->pixel_repetition == 4)) {
147 : limit_freq_to_48_khz = true;
148 :
149 0 : } else if ((crtc_info->requested_pixel_clock_100Hz <= 270000) &&
150 0 : (crtc_info->v_active <= 576) &&
151 0 : (crtc_info->interlaced) &&
152 0 : (crtc_info->pixel_repetition == 2)) {
153 : limit_freq_to_88_2_khz = true;
154 :
155 0 : } else if ((crtc_info->requested_pixel_clock_100Hz <= 540000) &&
156 0 : (crtc_info->v_active <= 576) &&
157 0 : !(crtc_info->interlaced)) {
158 0 : limit_freq_to_174_4_khz = true;
159 : }
160 : }
161 :
162 : /* Also do some calculation for the available Audio Bandwidth for the
163 : * 8 ch (i.e. for the Layout 1 => ch > 2)
164 : */
165 0 : h_blank = crtc_info->h_total - crtc_info->h_active;
166 :
167 0 : if (crtc_info->pixel_repetition)
168 0 : h_blank *= crtc_info->pixel_repetition;
169 :
170 : /*based on HDMI spec 1.3 Table 7.5 */
171 0 : h_blank -= 58;
172 : /*for Control Period */
173 0 : h_blank -= 16;
174 :
175 0 : samples = h_blank * 10;
176 : /* Number of Audio Packets (multiplied by 10) per Line (for 8 ch number
177 : * of Audio samples per line multiplied by 10 - Layout 1)
178 : */
179 0 : samples /= 32;
180 0 : samples *= crtc_info->v_active;
181 : /*Number of samples multiplied by 10, per second */
182 0 : samples *= crtc_info->refresh_rate;
183 : /*Number of Audio samples per second */
184 0 : samples /= 10;
185 :
186 : /* @todo do it after deep color is implemented
187 : * 8xx - deep color bandwidth scaling
188 : * Extra bandwidth is avaliable in deep color b/c link runs faster than
189 : * pixel rate. This has the effect of allowing more tmds characters to
190 : * be transmitted during blank
191 : */
192 :
193 0 : switch (crtc_info->color_depth) {
194 : case COLOR_DEPTH_888:
195 0 : samples *= 4;
196 0 : break;
197 : case COLOR_DEPTH_101010:
198 0 : samples *= 5;
199 0 : break;
200 : case COLOR_DEPTH_121212:
201 0 : samples *= 6;
202 0 : break;
203 : default:
204 0 : samples *= 4;
205 0 : break;
206 : }
207 :
208 0 : samples /= 4;
209 :
210 : /*check limitation*/
211 0 : if (samples < 88200)
212 : limit_freq_to_48_khz = true;
213 0 : else if (samples < 96000)
214 : limit_freq_to_88_2_khz = true;
215 0 : else if (samples < 176400)
216 : limit_freq_to_96_khz = true;
217 0 : else if (samples < 192000)
218 0 : limit_freq_to_174_4_khz = true;
219 :
220 0 : if (sample_rates != NULL) {
221 : /* limit frequencies */
222 0 : if (limit_freq_to_174_4_khz)
223 0 : sample_rates->rate.RATE_192 = 0;
224 :
225 0 : if (limit_freq_to_96_khz) {
226 0 : sample_rates->rate.RATE_192 = 0;
227 0 : sample_rates->rate.RATE_176_4 = 0;
228 : }
229 0 : if (limit_freq_to_88_2_khz) {
230 0 : sample_rates->rate.RATE_192 = 0;
231 0 : sample_rates->rate.RATE_176_4 = 0;
232 0 : sample_rates->rate.RATE_96 = 0;
233 : }
234 0 : if (limit_freq_to_48_khz) {
235 0 : sample_rates->rate.RATE_192 = 0;
236 0 : sample_rates->rate.RATE_176_4 = 0;
237 0 : sample_rates->rate.RATE_96 = 0;
238 0 : sample_rates->rate.RATE_88_2 = 0;
239 : }
240 : }
241 : }
242 :
243 : /*For DP SST, calculate if specified sample rates can fit into a given timing */
244 : static void check_audio_bandwidth_dpsst(
245 : const struct audio_crtc_info *crtc_info,
246 : uint32_t channel_count,
247 : union audio_sample_rates *sample_rates)
248 : {
249 : /* do nothing */
250 : }
251 :
252 : /*For DP MST, calculate if specified sample rates can fit into a given timing */
253 : static void check_audio_bandwidth_dpmst(
254 : const struct audio_crtc_info *crtc_info,
255 : uint32_t channel_count,
256 : union audio_sample_rates *sample_rates)
257 : {
258 : /* do nothing */
259 : }
260 :
261 : static void check_audio_bandwidth(
262 : const struct audio_crtc_info *crtc_info,
263 : uint32_t channel_count,
264 : enum signal_type signal,
265 : union audio_sample_rates *sample_rates)
266 : {
267 0 : switch (signal) {
268 : case SIGNAL_TYPE_HDMI_TYPE_A:
269 0 : check_audio_bandwidth_hdmi(
270 : crtc_info, channel_count, sample_rates);
271 : break;
272 : case SIGNAL_TYPE_EDP:
273 : case SIGNAL_TYPE_DISPLAY_PORT:
274 : check_audio_bandwidth_dpsst(
275 : crtc_info, channel_count, sample_rates);
276 : break;
277 : case SIGNAL_TYPE_DISPLAY_PORT_MST:
278 : check_audio_bandwidth_dpmst(
279 : crtc_info, channel_count, sample_rates);
280 : break;
281 : default:
282 : break;
283 : }
284 : }
285 :
286 : /* expose/not expose HBR capability to Audio driver */
287 0 : static void set_high_bit_rate_capable(
288 : struct audio *audio,
289 : bool capable)
290 : {
291 0 : uint32_t value = 0;
292 :
293 : /* set high bit rate audio capable*/
294 0 : value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR);
295 :
296 0 : set_reg_field_value(value, capable,
297 : AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR,
298 : HBR_CAPABLE);
299 :
300 0 : AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR, value);
301 0 : }
302 :
303 : /* set video latency in in ms/2+1 */
304 0 : static void set_video_latency(
305 : struct audio *audio,
306 : int latency_in_ms)
307 : {
308 0 : uint32_t value = 0;
309 :
310 0 : if ((latency_in_ms < 0) || (latency_in_ms > 255))
311 : return;
312 :
313 0 : value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC);
314 :
315 0 : set_reg_field_value(value, latency_in_ms,
316 : AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
317 : VIDEO_LIPSYNC);
318 :
319 0 : AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
320 : value);
321 : }
322 :
323 : /* set audio latency in ms/2+1 */
324 0 : static void set_audio_latency(
325 : struct audio *audio,
326 : int latency_in_ms)
327 : {
328 0 : uint32_t value = 0;
329 :
330 0 : if (latency_in_ms < 0)
331 0 : latency_in_ms = 0;
332 :
333 0 : if (latency_in_ms > 255)
334 0 : latency_in_ms = 255;
335 :
336 0 : value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC);
337 :
338 0 : set_reg_field_value(value, latency_in_ms,
339 : AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
340 : AUDIO_LIPSYNC);
341 :
342 0 : AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
343 : value);
344 0 : }
345 :
346 0 : void dce_aud_az_enable(struct audio *audio)
347 : {
348 0 : uint32_t value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
349 : DC_LOGGER_INIT();
350 :
351 0 : set_reg_field_value(value, 1,
352 : AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
353 : CLOCK_GATING_DISABLE);
354 0 : set_reg_field_value(value, 1,
355 : AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
356 : AUDIO_ENABLED);
357 :
358 0 : AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
359 0 : set_reg_field_value(value, 0,
360 : AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
361 : CLOCK_GATING_DISABLE);
362 0 : AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
363 :
364 : DC_LOG_HW_AUDIO("\n\t========= AUDIO:dce_aud_az_enable: index: %u data: 0x%x\n",
365 : audio->inst, value);
366 0 : }
367 :
368 0 : void dce_aud_az_disable(struct audio *audio)
369 : {
370 : uint32_t value;
371 : DC_LOGGER_INIT();
372 :
373 0 : value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
374 0 : set_reg_field_value(value, 1,
375 : AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
376 : CLOCK_GATING_DISABLE);
377 0 : AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
378 :
379 0 : set_reg_field_value(value, 0,
380 : AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
381 : AUDIO_ENABLED);
382 0 : AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
383 :
384 0 : set_reg_field_value(value, 0,
385 : AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
386 : CLOCK_GATING_DISABLE);
387 0 : AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
388 0 : value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
389 : DC_LOG_HW_AUDIO("\n\t========= AUDIO:dce_aud_az_disable: index: %u data: 0x%x\n",
390 : audio->inst, value);
391 0 : }
392 :
393 0 : void dce_aud_az_configure(
394 : struct audio *audio,
395 : enum signal_type signal,
396 : const struct audio_crtc_info *crtc_info,
397 : const struct audio_info *audio_info)
398 : {
399 0 : struct dce_audio *aud = DCE_AUD(audio);
400 :
401 0 : uint32_t speakers = audio_info->flags.info.ALLSPEAKERS;
402 : uint32_t value;
403 0 : uint32_t field = 0;
404 : enum audio_format_code audio_format_code;
405 : uint32_t format_index;
406 : uint32_t index;
407 0 : bool is_ac3_supported = false;
408 : union audio_sample_rates sample_rate;
409 0 : uint32_t strlen = 0;
410 0 : value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
411 0 : set_reg_field_value(value, 1,
412 : AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
413 : CLOCK_GATING_DISABLE);
414 0 : AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
415 :
416 : /* Speaker Allocation */
417 : /*
418 : uint32_t value;
419 : uint32_t field = 0;*/
420 0 : value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER);
421 :
422 0 : set_reg_field_value(value,
423 : speakers,
424 : AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
425 : SPEAKER_ALLOCATION);
426 :
427 : /* LFE_PLAYBACK_LEVEL = LFEPBL
428 : * LFEPBL = 0 : Unknown or refer to other information
429 : * LFEPBL = 1 : 0dB playback
430 : * LFEPBL = 2 : +10dB playback
431 : * LFE_BL = 3 : Reserved
432 : */
433 0 : set_reg_field_value(value,
434 : 0,
435 : AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
436 : LFE_PLAYBACK_LEVEL);
437 : /* todo: according to reg spec LFE_PLAYBACK_LEVEL is read only.
438 : * why are we writing to it? DCE8 does not write this */
439 :
440 :
441 0 : set_reg_field_value(value,
442 : 0,
443 : AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
444 : HDMI_CONNECTION);
445 :
446 0 : set_reg_field_value(value,
447 : 0,
448 : AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
449 : DP_CONNECTION);
450 :
451 0 : field = get_reg_field_value(value,
452 : AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
453 : EXTRA_CONNECTION_INFO);
454 :
455 0 : field &= ~0x1;
456 :
457 0 : set_reg_field_value(value,
458 : field,
459 : AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
460 : EXTRA_CONNECTION_INFO);
461 :
462 : /* set audio for output signal */
463 0 : switch (signal) {
464 : case SIGNAL_TYPE_HDMI_TYPE_A:
465 0 : set_reg_field_value(value,
466 : 1,
467 : AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
468 : HDMI_CONNECTION);
469 :
470 0 : break;
471 :
472 : case SIGNAL_TYPE_EDP:
473 : case SIGNAL_TYPE_DISPLAY_PORT:
474 : case SIGNAL_TYPE_DISPLAY_PORT_MST:
475 0 : set_reg_field_value(value,
476 : 1,
477 : AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
478 : DP_CONNECTION);
479 0 : break;
480 : default:
481 0 : BREAK_TO_DEBUGGER();
482 0 : break;
483 : }
484 :
485 0 : AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, value);
486 :
487 : /* ACP Data - Supports AI */
488 0 : value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_ACP_DATA);
489 :
490 0 : set_reg_field_value(
491 : value,
492 : audio_info->flags.info.SUPPORT_AI,
493 : AZALIA_F0_CODEC_PIN_CONTROL_ACP_DATA,
494 : SUPPORTS_AI);
495 :
496 0 : AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_ACP_DATA, value);
497 :
498 : /* Audio Descriptors */
499 : /* pass through all formats */
500 0 : for (format_index = 0; format_index < AUDIO_FORMAT_CODE_COUNT;
501 : format_index++) {
502 0 : audio_format_code =
503 : (AUDIO_FORMAT_CODE_FIRST + format_index);
504 :
505 : /* those are unsupported, skip programming */
506 0 : if (audio_format_code == AUDIO_FORMAT_CODE_1BITAUDIO ||
507 0 : audio_format_code == AUDIO_FORMAT_CODE_DST)
508 0 : continue;
509 :
510 0 : value = 0;
511 :
512 : /* check if supported */
513 0 : if (is_audio_format_supported(
514 : audio_info, audio_format_code, &index)) {
515 0 : const struct audio_mode *audio_mode =
516 : &audio_info->modes[index];
517 0 : union audio_sample_rates sample_rates =
518 : audio_mode->sample_rates;
519 0 : uint8_t byte2 = audio_mode->max_bit_rate;
520 0 : uint8_t channel_count = audio_mode->channel_count;
521 :
522 : /* adjust specific properties */
523 0 : switch (audio_format_code) {
524 : case AUDIO_FORMAT_CODE_LINEARPCM: {
525 :
526 0 : check_audio_bandwidth(
527 : crtc_info,
528 : channel_count,
529 : signal,
530 : &sample_rates);
531 :
532 0 : byte2 = audio_mode->sample_size;
533 :
534 0 : set_reg_field_value(value,
535 : sample_rates.all,
536 : AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
537 : SUPPORTED_FREQUENCIES_STEREO);
538 : }
539 0 : break;
540 : case AUDIO_FORMAT_CODE_AC3:
541 0 : is_ac3_supported = true;
542 0 : break;
543 : case AUDIO_FORMAT_CODE_DOLBYDIGITALPLUS:
544 : case AUDIO_FORMAT_CODE_DTS_HD:
545 : case AUDIO_FORMAT_CODE_MAT_MLP:
546 : case AUDIO_FORMAT_CODE_DST:
547 : case AUDIO_FORMAT_CODE_WMAPRO:
548 : byte2 = audio_mode->vendor_specific;
549 : break;
550 : default:
551 : break;
552 : }
553 :
554 : /* fill audio format data */
555 0 : set_reg_field_value(value,
556 : channel_count - 1,
557 : AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
558 : MAX_CHANNELS);
559 :
560 0 : set_reg_field_value(value,
561 : sample_rates.all,
562 : AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
563 : SUPPORTED_FREQUENCIES);
564 :
565 0 : set_reg_field_value(value,
566 : byte2,
567 : AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
568 : DESCRIPTOR_BYTE_2);
569 : } /* if */
570 :
571 0 : AZ_REG_WRITE(
572 : AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0 + format_index,
573 : value);
574 : } /* for */
575 :
576 0 : if (is_ac3_supported)
577 : /* todo: this reg global. why program global register? */
578 0 : REG_WRITE(AZALIA_F0_CODEC_FUNCTION_PARAMETER_STREAM_FORMATS,
579 : 0x05);
580 :
581 : /* check for 192khz/8-Ch support for HBR requirements */
582 0 : sample_rate.all = 0;
583 0 : sample_rate.rate.RATE_192 = 1;
584 :
585 0 : check_audio_bandwidth(
586 : crtc_info,
587 : 8,
588 : signal,
589 : &sample_rate);
590 :
591 0 : set_high_bit_rate_capable(audio, sample_rate.rate.RATE_192);
592 :
593 : /* Audio and Video Lipsync */
594 0 : set_video_latency(audio, audio_info->video_latency);
595 0 : set_audio_latency(audio, audio_info->audio_latency);
596 :
597 0 : value = 0;
598 0 : set_reg_field_value(value, audio_info->manufacture_id,
599 : AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0,
600 : MANUFACTURER_ID);
601 :
602 0 : set_reg_field_value(value, audio_info->product_id,
603 : AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0,
604 : PRODUCT_ID);
605 :
606 0 : AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0,
607 : value);
608 :
609 0 : value = 0;
610 :
611 : /*get display name string length */
612 0 : while (audio_info->display_name[strlen++] != '\0') {
613 0 : if (strlen >=
614 : MAX_HW_AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS)
615 : break;
616 : }
617 0 : set_reg_field_value(value, strlen,
618 : AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO1,
619 : SINK_DESCRIPTION_LEN);
620 :
621 0 : AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO1,
622 : value);
623 : DC_LOG_HW_AUDIO("\n\tAUDIO:az_configure: index: %u data, 0x%x, displayName %s: \n",
624 : audio->inst, value, audio_info->display_name);
625 :
626 : /*
627 : *write the port ID:
628 : *PORT_ID0 = display index
629 : *PORT_ID1 = 16bit BDF
630 : *(format MSB->LSB: 8bit Bus, 5bit Device, 3bit Function)
631 : */
632 :
633 0 : value = 0;
634 :
635 0 : set_reg_field_value(value, audio_info->port_id[0],
636 : AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO2,
637 : PORT_ID0);
638 :
639 0 : AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO2, value);
640 :
641 0 : value = 0;
642 0 : set_reg_field_value(value, audio_info->port_id[1],
643 : AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO3,
644 : PORT_ID1);
645 :
646 0 : AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO3, value);
647 :
648 : /*write the 18 char monitor string */
649 :
650 0 : value = 0;
651 0 : set_reg_field_value(value, audio_info->display_name[0],
652 : AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,
653 : DESCRIPTION0);
654 :
655 0 : set_reg_field_value(value, audio_info->display_name[1],
656 : AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,
657 : DESCRIPTION1);
658 :
659 0 : set_reg_field_value(value, audio_info->display_name[2],
660 : AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,
661 : DESCRIPTION2);
662 :
663 0 : set_reg_field_value(value, audio_info->display_name[3],
664 : AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,
665 : DESCRIPTION3);
666 :
667 0 : AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4, value);
668 :
669 0 : value = 0;
670 0 : set_reg_field_value(value, audio_info->display_name[4],
671 : AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,
672 : DESCRIPTION4);
673 :
674 0 : set_reg_field_value(value, audio_info->display_name[5],
675 : AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,
676 : DESCRIPTION5);
677 :
678 0 : set_reg_field_value(value, audio_info->display_name[6],
679 : AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,
680 : DESCRIPTION6);
681 :
682 0 : set_reg_field_value(value, audio_info->display_name[7],
683 : AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,
684 : DESCRIPTION7);
685 :
686 0 : AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5, value);
687 :
688 0 : value = 0;
689 0 : set_reg_field_value(value, audio_info->display_name[8],
690 : AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,
691 : DESCRIPTION8);
692 :
693 0 : set_reg_field_value(value, audio_info->display_name[9],
694 : AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,
695 : DESCRIPTION9);
696 :
697 0 : set_reg_field_value(value, audio_info->display_name[10],
698 : AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,
699 : DESCRIPTION10);
700 :
701 0 : set_reg_field_value(value, audio_info->display_name[11],
702 : AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,
703 : DESCRIPTION11);
704 :
705 0 : AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6, value);
706 :
707 0 : value = 0;
708 0 : set_reg_field_value(value, audio_info->display_name[12],
709 : AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,
710 : DESCRIPTION12);
711 :
712 0 : set_reg_field_value(value, audio_info->display_name[13],
713 : AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,
714 : DESCRIPTION13);
715 :
716 0 : set_reg_field_value(value, audio_info->display_name[14],
717 : AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,
718 : DESCRIPTION14);
719 :
720 0 : set_reg_field_value(value, audio_info->display_name[15],
721 : AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,
722 : DESCRIPTION15);
723 :
724 0 : AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7, value);
725 :
726 0 : value = 0;
727 0 : set_reg_field_value(value, audio_info->display_name[16],
728 : AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8,
729 : DESCRIPTION16);
730 :
731 0 : set_reg_field_value(value, audio_info->display_name[17],
732 : AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8,
733 : DESCRIPTION17);
734 :
735 0 : AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8, value);
736 0 : value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
737 0 : set_reg_field_value(value, 0,
738 : AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
739 : CLOCK_GATING_DISABLE);
740 0 : AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
741 0 : }
742 :
743 : /*
744 : * todo: wall clk related functionality probably belong to clock_src.
745 : */
746 :
747 : /* search pixel clock value for Azalia HDMI Audio */
748 : static void get_azalia_clock_info_hdmi(
749 : uint32_t crtc_pixel_clock_100hz,
750 : uint32_t actual_pixel_clock_100Hz,
751 : struct azalia_clock_info *azalia_clock_info)
752 : {
753 : /* audio_dto_phase= 24 * 10,000;
754 : * 24MHz in [100Hz] units */
755 0 : azalia_clock_info->audio_dto_phase =
756 : 24 * 10000;
757 :
758 : /* audio_dto_module = PCLKFrequency * 10,000;
759 : * [khz] -> [100Hz] */
760 0 : azalia_clock_info->audio_dto_module =
761 : actual_pixel_clock_100Hz;
762 : }
763 :
764 : static void get_azalia_clock_info_dp(
765 : uint32_t requested_pixel_clock_100Hz,
766 : const struct audio_pll_info *pll_info,
767 : struct azalia_clock_info *azalia_clock_info)
768 : {
769 : /* Reported dpDtoSourceClockInkhz value for
770 : * DCE8 already adjusted for SS, do not need any
771 : * adjustment here anymore
772 : */
773 :
774 : /*audio_dto_phase = 24 * 10,000;
775 : * 24MHz in [100Hz] units */
776 0 : azalia_clock_info->audio_dto_phase = 24 * 10000;
777 :
778 : /*audio_dto_module = dpDtoSourceClockInkhz * 10,000;
779 : * [khz] ->[100Hz] */
780 0 : azalia_clock_info->audio_dto_module =
781 0 : pll_info->dp_dto_source_clock_in_khz * 10;
782 : }
783 :
784 0 : void dce_aud_wall_dto_setup(
785 : struct audio *audio,
786 : enum signal_type signal,
787 : const struct audio_crtc_info *crtc_info,
788 : const struct audio_pll_info *pll_info)
789 : {
790 0 : struct dce_audio *aud = DCE_AUD(audio);
791 :
792 0 : struct azalia_clock_info clock_info = { 0 };
793 :
794 0 : if (dc_is_hdmi_tmds_signal(signal)) {
795 : uint32_t src_sel;
796 :
797 : /*DTO0 Programming goal:
798 : -generate 24MHz, 128*Fs from 24MHz
799 : -use DTO0 when an active HDMI port is connected
800 : (optionally a DP is connected) */
801 :
802 : /* calculate DTO settings */
803 0 : get_azalia_clock_info_hdmi(
804 : crtc_info->requested_pixel_clock_100Hz,
805 : crtc_info->calculated_pixel_clock_100Hz,
806 : &clock_info);
807 :
808 : DC_LOG_HW_AUDIO("\n%s:Input::requested_pixel_clock_100Hz = %d"\
809 : "calculated_pixel_clock_100Hz =%d\n"\
810 : "audio_dto_module = %d audio_dto_phase =%d \n\n", __func__,\
811 : crtc_info->requested_pixel_clock_100Hz,\
812 : crtc_info->calculated_pixel_clock_100Hz,\
813 : clock_info.audio_dto_module,\
814 : clock_info.audio_dto_phase);
815 :
816 : /* On TN/SI, Program DTO source select and DTO select before
817 : programming DTO modulo and DTO phase. These bits must be
818 : programmed first, otherwise there will be no HDMI audio at boot
819 : up. This is a HW sequence change (different from old ASICs).
820 : Caution when changing this programming sequence.
821 :
822 : HDMI enabled, using DTO0
823 : program master CRTC for DTO0 */
824 0 : src_sel = pll_info->dto_source - DTO_SOURCE_ID0;
825 0 : REG_UPDATE_2(DCCG_AUDIO_DTO_SOURCE,
826 : DCCG_AUDIO_DTO0_SOURCE_SEL, src_sel,
827 : DCCG_AUDIO_DTO_SEL, 0);
828 :
829 : /* module */
830 0 : REG_UPDATE(DCCG_AUDIO_DTO0_MODULE,
831 : DCCG_AUDIO_DTO0_MODULE, clock_info.audio_dto_module);
832 :
833 : /* phase */
834 0 : REG_UPDATE(DCCG_AUDIO_DTO0_PHASE,
835 : DCCG_AUDIO_DTO0_PHASE, clock_info.audio_dto_phase);
836 : } else {
837 : /*DTO1 Programming goal:
838 : -generate 24MHz, 512*Fs, 128*Fs from 24MHz
839 : -default is to used DTO1, and switch to DTO0 when an audio
840 : master HDMI port is connected
841 : -use as default for DP
842 :
843 : calculate DTO settings */
844 0 : get_azalia_clock_info_dp(
845 : crtc_info->requested_pixel_clock_100Hz,
846 : pll_info,
847 : &clock_info);
848 :
849 : /* Program DTO select before programming DTO modulo and DTO
850 : phase. default to use DTO1 */
851 :
852 0 : REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
853 : DCCG_AUDIO_DTO_SEL, 1);
854 :
855 : /* DCCG_AUDIO_DTO2_USE_512FBR_DTO, 1)
856 : * Select 512fs for DP TODO: web register definition
857 : * does not match register header file
858 : * DCE11 version it's commented out while DCE8 it's set to 1
859 : */
860 :
861 : /* module */
862 0 : REG_UPDATE(DCCG_AUDIO_DTO1_MODULE,
863 : DCCG_AUDIO_DTO1_MODULE, clock_info.audio_dto_module);
864 :
865 : /* phase */
866 0 : REG_UPDATE(DCCG_AUDIO_DTO1_PHASE,
867 : DCCG_AUDIO_DTO1_PHASE, clock_info.audio_dto_phase);
868 :
869 0 : REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
870 : DCCG_AUDIO_DTO2_USE_512FBR_DTO, 1);
871 :
872 : }
873 0 : }
874 :
875 : #if defined(CONFIG_DRM_AMD_DC_SI)
876 : static void dce60_aud_wall_dto_setup(
877 : struct audio *audio,
878 : enum signal_type signal,
879 : const struct audio_crtc_info *crtc_info,
880 : const struct audio_pll_info *pll_info)
881 : {
882 : struct dce_audio *aud = DCE_AUD(audio);
883 :
884 : struct azalia_clock_info clock_info = { 0 };
885 :
886 : if (dc_is_hdmi_signal(signal)) {
887 : uint32_t src_sel;
888 :
889 : /*DTO0 Programming goal:
890 : -generate 24MHz, 128*Fs from 24MHz
891 : -use DTO0 when an active HDMI port is connected
892 : (optionally a DP is connected) */
893 :
894 : /* calculate DTO settings */
895 : get_azalia_clock_info_hdmi(
896 : crtc_info->requested_pixel_clock_100Hz,
897 : crtc_info->calculated_pixel_clock_100Hz,
898 : &clock_info);
899 :
900 : DC_LOG_HW_AUDIO("\n%s:Input::requested_pixel_clock_100Hz = %d"\
901 : "calculated_pixel_clock_100Hz =%d\n"\
902 : "audio_dto_module = %d audio_dto_phase =%d \n\n", __func__,\
903 : crtc_info->requested_pixel_clock_100Hz,\
904 : crtc_info->calculated_pixel_clock_100Hz,\
905 : clock_info.audio_dto_module,\
906 : clock_info.audio_dto_phase);
907 :
908 : /* On TN/SI, Program DTO source select and DTO select before
909 : programming DTO modulo and DTO phase. These bits must be
910 : programmed first, otherwise there will be no HDMI audio at boot
911 : up. This is a HW sequence change (different from old ASICs).
912 : Caution when changing this programming sequence.
913 :
914 : HDMI enabled, using DTO0
915 : program master CRTC for DTO0 */
916 : src_sel = pll_info->dto_source - DTO_SOURCE_ID0;
917 : REG_UPDATE_2(DCCG_AUDIO_DTO_SOURCE,
918 : DCCG_AUDIO_DTO0_SOURCE_SEL, src_sel,
919 : DCCG_AUDIO_DTO_SEL, 0);
920 :
921 : /* module */
922 : REG_UPDATE(DCCG_AUDIO_DTO0_MODULE,
923 : DCCG_AUDIO_DTO0_MODULE, clock_info.audio_dto_module);
924 :
925 : /* phase */
926 : REG_UPDATE(DCCG_AUDIO_DTO0_PHASE,
927 : DCCG_AUDIO_DTO0_PHASE, clock_info.audio_dto_phase);
928 : } else {
929 : /*DTO1 Programming goal:
930 : -generate 24MHz, 128*Fs from 24MHz (DCE6 does not support 512*Fs)
931 : -default is to used DTO1, and switch to DTO0 when an audio
932 : master HDMI port is connected
933 : -use as default for DP
934 :
935 : calculate DTO settings */
936 : get_azalia_clock_info_dp(
937 : crtc_info->requested_pixel_clock_100Hz,
938 : pll_info,
939 : &clock_info);
940 :
941 : /* Program DTO select before programming DTO modulo and DTO
942 : phase. default to use DTO1 */
943 :
944 : REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
945 : DCCG_AUDIO_DTO_SEL, 1);
946 :
947 : /* DCCG_AUDIO_DTO2_USE_512FBR_DTO, 1)
948 : * Cannot select 512fs for DP
949 : *
950 : * DCE6 has no DCCG_AUDIO_DTO2_USE_512FBR_DTO mask
951 : */
952 :
953 : /* module */
954 : REG_UPDATE(DCCG_AUDIO_DTO1_MODULE,
955 : DCCG_AUDIO_DTO1_MODULE, clock_info.audio_dto_module);
956 :
957 : /* phase */
958 : REG_UPDATE(DCCG_AUDIO_DTO1_PHASE,
959 : DCCG_AUDIO_DTO1_PHASE, clock_info.audio_dto_phase);
960 :
961 : /* DCE6 has no DCCG_AUDIO_DTO2_USE_512FBR_DTO mask in DCCG_AUDIO_DTO_SOURCE reg */
962 :
963 : }
964 : }
965 : #endif
966 :
967 0 : static bool dce_aud_endpoint_valid(struct audio *audio)
968 : {
969 : uint32_t value;
970 : uint32_t port_connectivity;
971 :
972 0 : value = AZ_REG_READ(
973 : AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT);
974 :
975 0 : port_connectivity = get_reg_field_value(value,
976 : AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT,
977 : PORT_CONNECTIVITY);
978 :
979 0 : return !(port_connectivity == 1);
980 : }
981 :
982 : /* initialize HW state */
983 0 : void dce_aud_hw_init(
984 : struct audio *audio)
985 : {
986 : uint32_t value;
987 0 : struct dce_audio *aud = DCE_AUD(audio);
988 :
989 : /* we only need to program the following registers once, so we only do
990 : it for the inst 0*/
991 0 : if (audio->inst != 0)
992 : return;
993 :
994 : /* Suport R5 - 32khz
995 : * Suport R6 - 44.1khz
996 : * Suport R7 - 48khz
997 : */
998 : /*disable clock gating before write to endpoint register*/
999 0 : value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
1000 0 : set_reg_field_value(value, 1,
1001 : AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
1002 : CLOCK_GATING_DISABLE);
1003 0 : AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
1004 0 : REG_UPDATE(AZALIA_F0_CODEC_FUNCTION_PARAMETER_SUPPORTED_SIZE_RATES,
1005 : AUDIO_RATE_CAPABILITIES, 0x70);
1006 :
1007 : /*Keep alive bit to verify HW block in BU. */
1008 0 : REG_UPDATE_2(AZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES,
1009 : CLKSTOP, 1,
1010 : EPSS, 1);
1011 0 : set_reg_field_value(value, 0,
1012 : AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
1013 : CLOCK_GATING_DISABLE);
1014 0 : 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 0 : void dce_aud_destroy(struct audio **audio)
1040 : {
1041 0 : struct dce_audio *aud = DCE_AUD(*audio);
1042 :
1043 0 : kfree(aud);
1044 0 : *audio = NULL;
1045 0 : }
1046 :
1047 0 : 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 0 : struct dce_audio *audio = kzalloc(sizeof(*audio), GFP_KERNEL);
1056 :
1057 0 : if (audio == NULL) {
1058 0 : ASSERT_CRITICAL(audio);
1059 0 : return NULL;
1060 : }
1061 :
1062 0 : audio->base.ctx = ctx;
1063 0 : audio->base.inst = inst;
1064 0 : audio->base.funcs = &funcs;
1065 :
1066 0 : audio->regs = reg;
1067 0 : audio->shifts = shifts;
1068 0 : audio->masks = masks;
1069 0 : 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
|