Subversion Repositories Kolibri OS

Rev

Rev 2997 | Rev 5078 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1403 serge 1
/*
2
 * Copyright 2008 Advanced Micro Devices, Inc.
3
 * Copyright 2008 Red Hat Inc.
4
 * Copyright 2009 Christian König.
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the "Software"),
8
 * to deal in the Software without restriction, including without limitation
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
 * and/or sell copies of the Software, and to permit persons to whom the
11
 * Software is furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
 * OTHER DEALINGS IN THE SOFTWARE.
23
 *
24
 * Authors: Christian König
25
 */
3764 Serge 26
#include 
2997 Serge 27
#include 
28
#include 
1403 serge 29
#include "radeon.h"
1963 serge 30
#include "radeon_asic.h"
2997 Serge 31
#include "r600d.h"
1403 serge 32
#include "atom.h"
33
 
34
/*
35
 * HDMI color format
36
 */
37
enum r600_hdmi_color_format {
38
	RGB = 0,
39
	YCC_422 = 1,
40
	YCC_444 = 2
41
};
42
 
43
/*
44
 * IEC60958 status bits
45
 */
46
enum r600_hdmi_iec_status_bits {
47
	AUDIO_STATUS_DIG_ENABLE   = 0x01,
48
	AUDIO_STATUS_V	    = 0x02,
49
	AUDIO_STATUS_VCFG	 = 0x04,
50
	AUDIO_STATUS_EMPHASIS     = 0x08,
51
	AUDIO_STATUS_COPYRIGHT    = 0x10,
52
	AUDIO_STATUS_NONAUDIO     = 0x20,
53
	AUDIO_STATUS_PROFESSIONAL = 0x40,
54
	AUDIO_STATUS_LEVEL	= 0x80
55
};
56
 
2997 Serge 57
static const struct radeon_hdmi_acr r600_hdmi_predefined_acr[] = {
1403 serge 58
    /*	     32kHz	  44.1kHz	48kHz    */
59
    /* Clock      N     CTS      N     CTS      N     CTS */
60
    {  25174,  4576,  28125,  7007,  31250,  6864,  28125 }, /*  25,20/1.001 MHz */
61
    {  25200,  4096,  25200,  6272,  28000,  6144,  25200 }, /*  25.20       MHz */
62
    {  27000,  4096,  27000,  6272,  30000,  6144,  27000 }, /*  27.00       MHz */
63
    {  27027,  4096,  27027,  6272,  30030,  6144,  27027 }, /*  27.00*1.001 MHz */
64
    {  54000,  4096,  54000,  6272,  60000,  6144,  54000 }, /*  54.00       MHz */
65
    {  54054,  4096,  54054,  6272,  60060,  6144,  54054 }, /*  54.00*1.001 MHz */
66
    {  74175, 11648, 210937, 17836, 234375, 11648, 140625 }, /*  74.25/1.001 MHz */
67
    {  74250,  4096,  74250,  6272,  82500,  6144,  74250 }, /*  74.25       MHz */
68
    { 148351, 11648, 421875,  8918, 234375,  5824, 140625 }, /* 148.50/1.001 MHz */
69
    { 148500,  4096, 148500,  6272, 165000,  6144, 148500 }, /* 148.50       MHz */
70
    {      0,  4096,      0,  6272,      0,  6144,      0 }  /* Other */
71
};
72
 
73
/*
74
 * calculate CTS value if it's not found in the table
75
 */
2997 Serge 76
static void r600_hdmi_calc_cts(uint32_t clock, int *CTS, int N, int freq)
1403 serge 77
{
78
	if (*CTS == 0)
1963 serge 79
		*CTS = clock * N / (128 * freq) * 1000;
1403 serge 80
	DRM_DEBUG("Using ACR timing N=%d CTS=%d for frequency %d\n",
81
		  N, *CTS, freq);
82
}
83
 
2997 Serge 84
struct radeon_hdmi_acr r600_hdmi_acr(uint32_t clock)
85
{
86
	struct radeon_hdmi_acr res;
87
	u8 i;
88
 
89
	for (i = 0; r600_hdmi_predefined_acr[i].clock != clock &&
90
	     r600_hdmi_predefined_acr[i].clock != 0; i++)
91
		;
92
	res = r600_hdmi_predefined_acr[i];
93
 
94
	/* In case some CTS are missing */
95
	r600_hdmi_calc_cts(clock, &res.cts_32khz, res.n_32khz, 32000);
96
	r600_hdmi_calc_cts(clock, &res.cts_44_1khz, res.n_44_1khz, 44100);
97
	r600_hdmi_calc_cts(clock, &res.cts_48khz, res.n_48khz, 48000);
98
 
99
	return res;
100
}
101
 
1403 serge 102
/*
103
 * update the N and CTS parameters for a given pixel clock rate
104
 */
105
static void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock)
106
{
107
	struct drm_device *dev = encoder->dev;
108
	struct radeon_device *rdev = dev->dev_private;
2997 Serge 109
	struct radeon_hdmi_acr acr = r600_hdmi_acr(clock);
110
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
111
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
112
	uint32_t offset = dig->afmt->offset;
1403 serge 113
 
2997 Serge 114
	WREG32(HDMI0_ACR_32_0 + offset, HDMI0_ACR_CTS_32(acr.cts_32khz));
115
	WREG32(HDMI0_ACR_32_1 + offset, acr.n_32khz);
1403 serge 116
 
2997 Serge 117
	WREG32(HDMI0_ACR_44_0 + offset, HDMI0_ACR_CTS_44(acr.cts_44_1khz));
118
	WREG32(HDMI0_ACR_44_1 + offset, acr.n_44_1khz);
1403 serge 119
 
2997 Serge 120
	WREG32(HDMI0_ACR_48_0 + offset, HDMI0_ACR_CTS_48(acr.cts_48khz));
121
	WREG32(HDMI0_ACR_48_1 + offset, acr.n_48khz);
1403 serge 122
}
123
 
124
/*
125
 * build a HDMI Video Info Frame
126
 */
3764 Serge 127
static void r600_hdmi_update_avi_infoframe(struct drm_encoder *encoder,
128
					   void *buffer, size_t size)
1403 serge 129
{
130
	struct drm_device *dev = encoder->dev;
131
	struct radeon_device *rdev = dev->dev_private;
2997 Serge 132
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
133
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
134
	uint32_t offset = dig->afmt->offset;
3764 Serge 135
	uint8_t *frame = buffer + 3;
1403 serge 136
 
2997 Serge 137
	/* Our header values (type, version, length) should be alright, Intel
138
	 * is using the same. Checksum function also seems to be OK, it works
139
	 * fine for audio infoframe. However calculated value is always lower
140
	 * by 2 in comparison to fglrx. It breaks displaying anything in case
141
	 * of TVs that strictly check the checksum. Hack it manually here to
142
	 * workaround this issue. */
143
	frame[0x0] += 2;
1403 serge 144
 
2997 Serge 145
	WREG32(HDMI0_AVI_INFO0 + offset,
1403 serge 146
		frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
2997 Serge 147
	WREG32(HDMI0_AVI_INFO1 + offset,
1403 serge 148
		frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x7] << 24));
2997 Serge 149
	WREG32(HDMI0_AVI_INFO2 + offset,
1403 serge 150
		frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24));
2997 Serge 151
	WREG32(HDMI0_AVI_INFO3 + offset,
1403 serge 152
		frame[0xC] | (frame[0xD] << 8));
153
}
154
 
155
/*
156
 * build a Audio Info Frame
157
 */
3764 Serge 158
static void r600_hdmi_update_audio_infoframe(struct drm_encoder *encoder,
159
					     const void *buffer, size_t size)
1403 serge 160
{
161
	struct drm_device *dev = encoder->dev;
162
	struct radeon_device *rdev = dev->dev_private;
2997 Serge 163
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
164
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
165
	uint32_t offset = dig->afmt->offset;
3764 Serge 166
	const u8 *frame = buffer + 3;
1403 serge 167
 
2997 Serge 168
	WREG32(HDMI0_AUDIO_INFO0 + offset,
1403 serge 169
		frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
2997 Serge 170
	WREG32(HDMI0_AUDIO_INFO1 + offset,
1403 serge 171
		frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x8] << 24));
172
}
173
 
174
/*
175
 * test if audio buffer is filled enough to start playing
176
 */
2997 Serge 177
static bool r600_hdmi_is_audio_buffer_filled(struct drm_encoder *encoder)
1403 serge 178
{
179
	struct drm_device *dev = encoder->dev;
180
	struct radeon_device *rdev = dev->dev_private;
2997 Serge 181
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
182
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
183
	uint32_t offset = dig->afmt->offset;
1403 serge 184
 
2997 Serge 185
	return (RREG32(HDMI0_STATUS + offset) & 0x10) != 0;
1403 serge 186
}
187
 
188
/*
189
 * have buffer status changed since last call?
190
 */
191
int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder)
192
{
193
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
2997 Serge 194
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
1403 serge 195
	int status, result;
196
 
2997 Serge 197
	if (!dig->afmt || !dig->afmt->enabled)
1403 serge 198
		return 0;
199
 
200
	status = r600_hdmi_is_audio_buffer_filled(encoder);
2997 Serge 201
	result = dig->afmt->last_buffer_filled_status != status;
202
	dig->afmt->last_buffer_filled_status = status;
1403 serge 203
 
204
	return result;
205
}
206
 
207
/*
208
 * write the audio workaround status to the hardware
209
 */
2997 Serge 210
static void r600_hdmi_audio_workaround(struct drm_encoder *encoder)
1403 serge 211
{
212
	struct drm_device *dev = encoder->dev;
213
	struct radeon_device *rdev = dev->dev_private;
214
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
2997 Serge 215
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
216
	uint32_t offset = dig->afmt->offset;
217
	bool hdmi_audio_workaround = false; /* FIXME */
218
	u32 value;
1403 serge 219
 
2997 Serge 220
	if (!hdmi_audio_workaround ||
221
	    r600_hdmi_is_audio_buffer_filled(encoder))
222
		value = 0; /* disable workaround */
223
	else
224
		value = HDMI0_AUDIO_TEST_EN; /* enable workaround */
225
	WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset,
226
		 value, ~HDMI0_AUDIO_TEST_EN);
1403 serge 227
}
228
 
3764 Serge 229
void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock)
230
{
231
	struct drm_device *dev = encoder->dev;
232
	struct radeon_device *rdev = dev->dev_private;
233
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
234
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
235
	u32 base_rate = 24000;
1403 serge 236
 
3764 Serge 237
	if (!dig || !dig->afmt)
238
		return;
239
 
240
	/* there are two DTOs selected by DCCG_AUDIO_DTO_SELECT.
241
	 * doesn't matter which one you use.  Just use the first one.
242
	 */
243
	/* XXX two dtos; generally use dto0 for hdmi */
244
	/* Express [24MHz / target pixel clock] as an exact rational
245
	 * number (coefficient of two integer numbers.  DCCG_AUDIO_DTOx_PHASE
246
	 * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
247
	 */
248
	if (ASIC_IS_DCE3(rdev)) {
249
		/* according to the reg specs, this should DCE3.2 only, but in
250
		 * practice it seems to cover DCE3.0 as well.
251
		 */
252
		WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100);
253
		WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100);
254
		WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */
255
	} else {
256
		/* according to the reg specs, this should be DCE2.0 and DCE3.0 */
257
		WREG32(AUDIO_DTO, AUDIO_DTO_PHASE(base_rate / 10) |
258
		       AUDIO_DTO_MODULE(clock / 10));
259
	}
260
}
261
 
1403 serge 262
/*
263
 * update the info frames with the data from the current display mode
264
 */
265
void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode)
266
{
267
	struct drm_device *dev = encoder->dev;
268
	struct radeon_device *rdev = dev->dev_private;
2997 Serge 269
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
270
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
3764 Serge 271
	u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
272
	struct hdmi_avi_infoframe frame;
2997 Serge 273
	uint32_t offset;
3764 Serge 274
	ssize_t err;
1403 serge 275
 
2997 Serge 276
	/* Silent, r600_hdmi_enable will raise WARN for us */
277
	if (!dig->afmt->enabled)
1963 serge 278
		return;
2997 Serge 279
	offset = dig->afmt->offset;
1963 serge 280
 
2997 Serge 281
//	r600_audio_set_clock(encoder, mode->clock);
1403 serge 282
 
2997 Serge 283
	WREG32(HDMI0_VBI_PACKET_CONTROL + offset,
284
	       HDMI0_NULL_SEND); /* send null packets when required */
1403 serge 285
 
2997 Serge 286
	WREG32(HDMI0_AUDIO_CRC_CONTROL + offset, 0x1000);
1403 serge 287
 
2997 Serge 288
	if (ASIC_IS_DCE32(rdev)) {
289
		WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset,
290
		       HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */
291
		       HDMI0_AUDIO_PACKETS_PER_LINE(3)); /* should be suffient for all audio modes and small enough for all hblanks */
292
		WREG32(AFMT_AUDIO_PACKET_CONTROL + offset,
293
		       AFMT_AUDIO_SAMPLE_SEND | /* send audio packets */
294
		       AFMT_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */
295
	} else {
296
		WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset,
297
		       HDMI0_AUDIO_SAMPLE_SEND | /* send audio packets */
298
		       HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */
299
		       HDMI0_AUDIO_PACKETS_PER_LINE(3) | /* should be suffient for all audio modes and small enough for all hblanks */
300
		       HDMI0_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */
301
	}
1403 serge 302
 
2997 Serge 303
	WREG32(HDMI0_ACR_PACKET_CONTROL + offset,
304
	       HDMI0_ACR_AUTO_SEND | /* allow hw to sent ACR packets when required */
305
	       HDMI0_ACR_SOURCE); /* select SW CTS value */
1403 serge 306
 
2997 Serge 307
	WREG32(HDMI0_VBI_PACKET_CONTROL + offset,
308
	       HDMI0_NULL_SEND | /* send null packets when required */
309
	       HDMI0_GC_SEND | /* send general control packets */
310
	       HDMI0_GC_CONT); /* send general control packets every frame */
1403 serge 311
 
2997 Serge 312
	/* TODO: HDMI0_AUDIO_INFO_UPDATE */
313
	WREG32(HDMI0_INFOFRAME_CONTROL0 + offset,
314
	       HDMI0_AVI_INFO_SEND | /* enable AVI info frames */
315
	       HDMI0_AVI_INFO_CONT | /* send AVI info frames every frame/field */
316
	       HDMI0_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */
317
	       HDMI0_AUDIO_INFO_CONT); /* send audio info frames every frame/field */
318
 
319
	WREG32(HDMI0_INFOFRAME_CONTROL1 + offset,
320
	       HDMI0_AVI_INFO_LINE(2) | /* anything other than 0 */
321
	       HDMI0_AUDIO_INFO_LINE(2)); /* anything other than 0 */
322
 
323
	WREG32(HDMI0_GC + offset, 0); /* unset HDMI0_GC_AVMUTE */
324
 
3764 Serge 325
	err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
326
	if (err < 0) {
327
		DRM_ERROR("failed to setup AVI infoframe: %zd\n", err);
328
		return;
329
	}
1403 serge 330
 
3764 Serge 331
	err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer));
332
	if (err < 0) {
333
		DRM_ERROR("failed to pack AVI infoframe: %zd\n", err);
334
		return;
335
	}
336
 
337
	r600_hdmi_update_avi_infoframe(encoder, buffer, sizeof(buffer));
2997 Serge 338
	r600_hdmi_update_ACR(encoder, mode->clock);
339
 
1963 serge 340
	/* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */
2997 Serge 341
	WREG32(HDMI0_RAMP_CONTROL0 + offset, 0x00FFFFFF);
342
	WREG32(HDMI0_RAMP_CONTROL1 + offset, 0x007FFFFF);
343
	WREG32(HDMI0_RAMP_CONTROL2 + offset, 0x00000001);
344
	WREG32(HDMI0_RAMP_CONTROL3 + offset, 0x00000001);
1403 serge 345
 
346
	r600_hdmi_audio_workaround(encoder);
347
}
348
 
2997 Serge 349
#if 0
1403 serge 350
/*
351
 * update settings with current parameters from audio engine
352
 */
1963 serge 353
void r600_hdmi_update_audio_settings(struct drm_encoder *encoder)
1403 serge 354
{
355
	struct drm_device *dev = encoder->dev;
356
	struct radeon_device *rdev = dev->dev_private;
2997 Serge 357
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
358
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
359
	struct r600_audio audio = r600_audio_status(rdev);
3764 Serge 360
	uint8_t buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE];
361
	struct hdmi_audio_infoframe frame;
2997 Serge 362
	uint32_t offset;
1403 serge 363
	uint32_t iec;
3764 Serge 364
	ssize_t err;
1403 serge 365
 
2997 Serge 366
	if (!dig->afmt || !dig->afmt->enabled)
1403 serge 367
		return;
2997 Serge 368
	offset = dig->afmt->offset;
1403 serge 369
 
370
	DRM_DEBUG("%s with %d channels, %d Hz sampling rate, %d bits per sample,\n",
371
		 r600_hdmi_is_audio_buffer_filled(encoder) ? "playing" : "stopped",
2997 Serge 372
		  audio.channels, audio.rate, audio.bits_per_sample);
1403 serge 373
	DRM_DEBUG("0x%02X IEC60958 status bits and 0x%02X category code\n",
2997 Serge 374
		  (int)audio.status_bits, (int)audio.category_code);
1403 serge 375
 
376
	iec = 0;
2997 Serge 377
	if (audio.status_bits & AUDIO_STATUS_PROFESSIONAL)
1403 serge 378
		iec |= 1 << 0;
2997 Serge 379
	if (audio.status_bits & AUDIO_STATUS_NONAUDIO)
1403 serge 380
		iec |= 1 << 1;
2997 Serge 381
	if (audio.status_bits & AUDIO_STATUS_COPYRIGHT)
1403 serge 382
		iec |= 1 << 2;
2997 Serge 383
	if (audio.status_bits & AUDIO_STATUS_EMPHASIS)
1403 serge 384
		iec |= 1 << 3;
385
 
2997 Serge 386
	iec |= HDMI0_60958_CS_CATEGORY_CODE(audio.category_code);
1403 serge 387
 
2997 Serge 388
	switch (audio.rate) {
389
	case 32000:
390
		iec |= HDMI0_60958_CS_SAMPLING_FREQUENCY(0x3);
391
		break;
392
	case 44100:
393
		iec |= HDMI0_60958_CS_SAMPLING_FREQUENCY(0x0);
394
		break;
395
	case 48000:
396
		iec |= HDMI0_60958_CS_SAMPLING_FREQUENCY(0x2);
397
		break;
398
	case 88200:
399
		iec |= HDMI0_60958_CS_SAMPLING_FREQUENCY(0x8);
400
		break;
401
	case 96000:
402
		iec |= HDMI0_60958_CS_SAMPLING_FREQUENCY(0xa);
403
		break;
404
	case 176400:
405
		iec |= HDMI0_60958_CS_SAMPLING_FREQUENCY(0xc);
406
		break;
407
	case 192000:
408
		iec |= HDMI0_60958_CS_SAMPLING_FREQUENCY(0xe);
409
		break;
1403 serge 410
	}
411
 
2997 Serge 412
	WREG32(HDMI0_60958_0 + offset, iec);
1403 serge 413
 
414
	iec = 0;
2997 Serge 415
	switch (audio.bits_per_sample) {
416
	case 16:
417
		iec |= HDMI0_60958_CS_WORD_LENGTH(0x2);
1963 serge 418
			break;
2997 Serge 419
	case 20:
420
		iec |= HDMI0_60958_CS_WORD_LENGTH(0x3);
1963 serge 421
			break;
2997 Serge 422
	case 24:
423
		iec |= HDMI0_60958_CS_WORD_LENGTH(0xb);
1963 serge 424
			break;
425
		}
2997 Serge 426
	if (audio.status_bits & AUDIO_STATUS_V)
427
		iec |= 0x5 << 16;
428
	WREG32_P(HDMI0_60958_1 + offset, iec, ~0x5000f);
1963 serge 429
 
3764 Serge 430
	err = hdmi_audio_infoframe_init(&frame);
431
	if (err < 0) {
432
		DRM_ERROR("failed to setup audio infoframe\n");
433
		return;
434
	}
1403 serge 435
 
3764 Serge 436
	frame.channels = audio.channels;
437
 
438
	err = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
439
	if (err < 0) {
440
		DRM_ERROR("failed to pack audio infoframe\n");
441
		return;
442
	}
443
 
444
	r600_hdmi_update_audio_infoframe(encoder, buffer, sizeof(buffer));
2997 Serge 445
	r600_hdmi_audio_workaround(encoder);
1963 serge 446
}
2997 Serge 447
#endif
1963 serge 448
 
1403 serge 449
/*
1963 serge 450
 * enable the HDMI engine
1403 serge 451
 */
3764 Serge 452
void r600_hdmi_enable(struct drm_encoder *encoder, bool enable)
1403 serge 453
{
454
	struct drm_device *dev = encoder->dev;
455
	struct radeon_device *rdev = dev->dev_private;
456
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
2997 Serge 457
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
3764 Serge 458
	u32 hdmi = HDMI0_ERROR_ACK;
1403 serge 459
 
2997 Serge 460
	/* Silent, r600_hdmi_enable will raise WARN for us */
3764 Serge 461
	if (enable && dig->afmt->enabled)
1963 serge 462
		return;
3764 Serge 463
	if (!enable && !dig->afmt->enabled)
464
		return;
1403 serge 465
 
2997 Serge 466
	/* Older chipsets require setting HDMI and routing manually */
3764 Serge 467
	if (!ASIC_IS_DCE3(rdev)) {
468
		if (enable)
469
			hdmi |= HDMI0_ENABLE;
1403 serge 470
	switch (radeon_encoder->encoder_id) {
471
	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
3764 Serge 472
			if (enable) {
473
				WREG32_OR(AVIVO_TMDSA_CNTL, AVIVO_TMDSA_CNTL_HDMI_EN);
2997 Serge 474
			hdmi |= HDMI0_STREAM(HDMI0_STREAM_TMDSA);
3764 Serge 475
			} else {
476
				WREG32_AND(AVIVO_TMDSA_CNTL, ~AVIVO_TMDSA_CNTL_HDMI_EN);
477
			}
1403 serge 478
		break;
479
	case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
3764 Serge 480
			if (enable) {
481
				WREG32_OR(AVIVO_LVTMA_CNTL, AVIVO_LVTMA_CNTL_HDMI_EN);
2997 Serge 482
			hdmi |= HDMI0_STREAM(HDMI0_STREAM_LVTMA);
3764 Serge 483
			} else {
484
				WREG32_AND(AVIVO_LVTMA_CNTL, ~AVIVO_LVTMA_CNTL_HDMI_EN);
485
			}
2997 Serge 486
			break;
487
		case ENCODER_OBJECT_ID_INTERNAL_DDI:
3764 Serge 488
			if (enable) {
489
				WREG32_OR(DDIA_CNTL, DDIA_HDMI_EN);
2997 Serge 490
			hdmi |= HDMI0_STREAM(HDMI0_STREAM_DDIA);
3764 Serge 491
			} else {
492
				WREG32_AND(DDIA_CNTL, ~DDIA_HDMI_EN);
493
			}
2997 Serge 494
			break;
495
		case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
3764 Serge 496
			if (enable)
2997 Serge 497
			hdmi |= HDMI0_STREAM(HDMI0_STREAM_DVOA);
1403 serge 498
		break;
499
	default:
2997 Serge 500
			dev_err(rdev->dev, "Invalid encoder for HDMI: 0x%X\n",
501
				radeon_encoder->encoder_id);
1403 serge 502
		break;
503
	}
3764 Serge 504
		WREG32(HDMI0_CONTROL + dig->afmt->offset, hdmi);
1963 serge 505
	}
506
 
2997 Serge 507
	if (rdev->irq.installed) {
1963 serge 508
		/* if irq is available use it */
3764 Serge 509
		/* XXX: shouldn't need this on any asics.  Double check DCE2/3 */
510
//       if (enable)
511
//           radeon_irq_kms_enable_afmt(rdev, dig->afmt->id);
512
//       else
513
//           radeon_irq_kms_disable_afmt(rdev, dig->afmt->id);
2997 Serge 514
	}
1963 serge 515
 
3764 Serge 516
	dig->afmt->enabled = enable;
2997 Serge 517
 
3764 Serge 518
	DRM_DEBUG("%sabling HDMI interface @ 0x%04X for encoder 0x%x\n",
519
		  enable ? "En" : "Dis", dig->afmt->offset, radeon_encoder->encoder_id);
1403 serge 520
}
521