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