Subversion Repositories Kolibri OS

Rev

Rev 6104 | 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 
6104 serge 27
#include 
2997 Serge 28
#include 
29
#include 
1403 serge 30
#include "radeon.h"
1963 serge 31
#include "radeon_asic.h"
6104 serge 32
#include "radeon_audio.h"
2997 Serge 33
#include "r600d.h"
1403 serge 34
#include "atom.h"
35
 
36
/*
37
 * HDMI color format
38
 */
39
enum r600_hdmi_color_format {
40
	RGB = 0,
41
	YCC_422 = 1,
42
	YCC_444 = 2
43
};
44
 
45
/*
46
 * IEC60958 status bits
47
 */
48
enum r600_hdmi_iec_status_bits {
49
	AUDIO_STATUS_DIG_ENABLE   = 0x01,
6104 serge 50
	AUDIO_STATUS_V            = 0x02,
51
	AUDIO_STATUS_VCFG         = 0x04,
1403 serge 52
	AUDIO_STATUS_EMPHASIS     = 0x08,
53
	AUDIO_STATUS_COPYRIGHT    = 0x10,
54
	AUDIO_STATUS_NONAUDIO     = 0x20,
55
	AUDIO_STATUS_PROFESSIONAL = 0x40,
6104 serge 56
	AUDIO_STATUS_LEVEL        = 0x80
1403 serge 57
};
58
 
5271 serge 59
static struct r600_audio_pin r600_audio_status(struct radeon_device *rdev)
60
{
61
	struct r600_audio_pin status;
62
	uint32_t value;
63
 
64
	value = RREG32(R600_AUDIO_RATE_BPS_CHANNEL);
65
 
66
	/* number of channels */
67
	status.channels = (value & 0x7) + 1;
68
 
69
	/* bits per sample */
70
	switch ((value & 0xF0) >> 4) {
71
	case 0x0:
72
		status.bits_per_sample = 8;
73
		break;
74
	case 0x1:
75
		status.bits_per_sample = 16;
76
		break;
77
	case 0x2:
78
		status.bits_per_sample = 20;
79
		break;
80
	case 0x3:
81
		status.bits_per_sample = 24;
82
		break;
83
	case 0x4:
84
		status.bits_per_sample = 32;
85
		break;
86
	default:
87
		dev_err(rdev->dev, "Unknown bits per sample 0x%x, using 16\n",
88
			(int)value);
89
		status.bits_per_sample = 16;
90
	}
91
 
92
	/* current sampling rate in HZ */
93
	if (value & 0x4000)
94
		status.rate = 44100;
95
	else
96
		status.rate = 48000;
97
	status.rate *= ((value >> 11) & 0x7) + 1;
98
	status.rate /= ((value >> 8) & 0x7) + 1;
99
 
100
	value = RREG32(R600_AUDIO_STATUS_BITS);
101
 
102
	/* iec 60958 status bits */
103
	status.status_bits = value & 0xff;
104
 
105
	/* iec 60958 category code */
106
	status.category_code = (value >> 8) & 0xff;
107
 
108
	return status;
109
}
110
 
111
/*
112
 * update all hdmi interfaces with current audio parameters
113
 */
114
void r600_audio_update_hdmi(struct work_struct *work)
115
{
116
	struct radeon_device *rdev = container_of(work, struct radeon_device,
117
						  audio_work);
118
	struct drm_device *dev = rdev->ddev;
119
	struct r600_audio_pin audio_status = r600_audio_status(rdev);
120
	struct drm_encoder *encoder;
121
	bool changed = false;
122
 
123
	if (rdev->audio.pin[0].channels != audio_status.channels ||
124
	    rdev->audio.pin[0].rate != audio_status.rate ||
125
	    rdev->audio.pin[0].bits_per_sample != audio_status.bits_per_sample ||
126
	    rdev->audio.pin[0].status_bits != audio_status.status_bits ||
127
	    rdev->audio.pin[0].category_code != audio_status.category_code) {
128
		rdev->audio.pin[0] = audio_status;
129
		changed = true;
130
	}
131
 
132
	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
133
		if (!radeon_encoder_is_digital(encoder))
134
			continue;
135
		if (changed || r600_hdmi_buffer_status_changed(encoder))
136
			r600_hdmi_update_audio_settings(encoder);
137
	}
138
}
139
 
140
/* enable the audio stream */
141
void r600_audio_enable(struct radeon_device *rdev,
142
		       struct r600_audio_pin *pin,
143
		       u8 enable_mask)
144
{
145
	u32 tmp = RREG32(AZ_HOT_PLUG_CONTROL);
146
 
147
	if (!pin)
148
		return;
149
 
150
	if (enable_mask) {
151
		tmp |= AUDIO_ENABLED;
152
		if (enable_mask & 1)
153
			tmp |= PIN0_AUDIO_ENABLED;
154
		if (enable_mask & 2)
155
			tmp |= PIN1_AUDIO_ENABLED;
156
		if (enable_mask & 4)
157
			tmp |= PIN2_AUDIO_ENABLED;
158
		if (enable_mask & 8)
159
			tmp |= PIN3_AUDIO_ENABLED;
160
	} else {
161
		tmp &= ~(AUDIO_ENABLED |
162
			 PIN0_AUDIO_ENABLED |
163
			 PIN1_AUDIO_ENABLED |
164
			 PIN2_AUDIO_ENABLED |
165
			 PIN3_AUDIO_ENABLED);
166
	}
167
 
168
	WREG32(AZ_HOT_PLUG_CONTROL, tmp);
169
}
170
 
171
struct r600_audio_pin *r600_audio_get_pin(struct radeon_device *rdev)
172
{
173
	/* only one pin on 6xx-NI */
174
	return &rdev->audio.pin[0];
175
}
176
 
6104 serge 177
void r600_hdmi_update_acr(struct drm_encoder *encoder, long offset,
178
	const struct radeon_hdmi_acr *acr)
1403 serge 179
{
180
	struct drm_device *dev = encoder->dev;
181
	struct radeon_device *rdev = dev->dev_private;
182
 
6104 serge 183
	/* DCE 3.0 uses register that's normally for CRC_CONTROL */
184
	uint32_t acr_ctl = ASIC_IS_DCE3(rdev) ? DCE3_HDMI0_ACR_PACKET_CONTROL :
185
				       HDMI0_ACR_PACKET_CONTROL;
186
	WREG32_P(acr_ctl + offset,
187
		HDMI0_ACR_SOURCE |		/* select SW CTS value */
188
		HDMI0_ACR_AUTO_SEND,	/* allow hw to sent ACR packets when required */
189
		~(HDMI0_ACR_SOURCE |
190
		HDMI0_ACR_AUTO_SEND));
191
 
5078 serge 192
	WREG32_P(HDMI0_ACR_32_0 + offset,
6104 serge 193
		HDMI0_ACR_CTS_32(acr->cts_32khz),
194
		~HDMI0_ACR_CTS_32_MASK);
5078 serge 195
	WREG32_P(HDMI0_ACR_32_1 + offset,
6104 serge 196
		HDMI0_ACR_N_32(acr->n_32khz),
197
		~HDMI0_ACR_N_32_MASK);
1403 serge 198
 
5078 serge 199
	WREG32_P(HDMI0_ACR_44_0 + offset,
6104 serge 200
		HDMI0_ACR_CTS_44(acr->cts_44_1khz),
201
		~HDMI0_ACR_CTS_44_MASK);
5078 serge 202
	WREG32_P(HDMI0_ACR_44_1 + offset,
6104 serge 203
		HDMI0_ACR_N_44(acr->n_44_1khz),
204
		~HDMI0_ACR_N_44_MASK);
1403 serge 205
 
5078 serge 206
	WREG32_P(HDMI0_ACR_48_0 + offset,
6104 serge 207
		HDMI0_ACR_CTS_48(acr->cts_48khz),
208
		~HDMI0_ACR_CTS_48_MASK);
5078 serge 209
	WREG32_P(HDMI0_ACR_48_1 + offset,
6104 serge 210
		HDMI0_ACR_N_48(acr->n_48khz),
211
		~HDMI0_ACR_N_48_MASK);
1403 serge 212
}
213
 
214
/*
215
 * build a HDMI Video Info Frame
216
 */
6104 serge 217
void r600_set_avi_packet(struct radeon_device *rdev, u32 offset,
7146 serge 218
			 unsigned char *buffer, size_t size)
1403 serge 219
{
3764 Serge 220
	uint8_t *frame = buffer + 3;
1403 serge 221
 
2997 Serge 222
	WREG32(HDMI0_AVI_INFO0 + offset,
1403 serge 223
		frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
2997 Serge 224
	WREG32(HDMI0_AVI_INFO1 + offset,
1403 serge 225
		frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x7] << 24));
2997 Serge 226
	WREG32(HDMI0_AVI_INFO2 + offset,
1403 serge 227
		frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24));
2997 Serge 228
	WREG32(HDMI0_AVI_INFO3 + offset,
6104 serge 229
		frame[0xC] | (frame[0xD] << 8) | (buffer[1] << 24));
230
 
231
	WREG32_OR(HDMI0_INFOFRAME_CONTROL1 + offset,
232
		  HDMI0_AVI_INFO_LINE(2));	/* anything other than 0 */
233
 
234
	WREG32_OR(HDMI0_INFOFRAME_CONTROL0 + offset,
235
		  HDMI0_AVI_INFO_SEND |	/* enable AVI info frames */
236
		  HDMI0_AVI_INFO_CONT);	/* send AVI info frames every frame/field */
237
 
1403 serge 238
}
239
 
240
/*
241
 * build a Audio Info Frame
242
 */
3764 Serge 243
static void r600_hdmi_update_audio_infoframe(struct drm_encoder *encoder,
244
					     const void *buffer, size_t size)
1403 serge 245
{
246
	struct drm_device *dev = encoder->dev;
247
	struct radeon_device *rdev = dev->dev_private;
2997 Serge 248
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
249
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
250
	uint32_t offset = dig->afmt->offset;
3764 Serge 251
	const u8 *frame = buffer + 3;
1403 serge 252
 
2997 Serge 253
	WREG32(HDMI0_AUDIO_INFO0 + offset,
1403 serge 254
		frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
2997 Serge 255
	WREG32(HDMI0_AUDIO_INFO1 + offset,
1403 serge 256
		frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x8] << 24));
257
}
258
 
259
/*
260
 * test if audio buffer is filled enough to start playing
261
 */
2997 Serge 262
static bool r600_hdmi_is_audio_buffer_filled(struct drm_encoder *encoder)
1403 serge 263
{
264
	struct drm_device *dev = encoder->dev;
265
	struct radeon_device *rdev = dev->dev_private;
2997 Serge 266
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
267
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
268
	uint32_t offset = dig->afmt->offset;
1403 serge 269
 
2997 Serge 270
	return (RREG32(HDMI0_STATUS + offset) & 0x10) != 0;
1403 serge 271
}
272
 
273
/*
274
 * have buffer status changed since last call?
275
 */
276
int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder)
277
{
278
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
2997 Serge 279
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
1403 serge 280
	int status, result;
281
 
2997 Serge 282
	if (!dig->afmt || !dig->afmt->enabled)
1403 serge 283
		return 0;
284
 
285
	status = r600_hdmi_is_audio_buffer_filled(encoder);
2997 Serge 286
	result = dig->afmt->last_buffer_filled_status != status;
287
	dig->afmt->last_buffer_filled_status = status;
1403 serge 288
 
289
	return result;
290
}
291
 
292
/*
293
 * write the audio workaround status to the hardware
294
 */
5078 serge 295
void r600_hdmi_audio_workaround(struct drm_encoder *encoder)
1403 serge 296
{
297
	struct drm_device *dev = encoder->dev;
298
	struct radeon_device *rdev = dev->dev_private;
299
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
2997 Serge 300
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
301
	uint32_t offset = dig->afmt->offset;
302
	bool hdmi_audio_workaround = false; /* FIXME */
303
	u32 value;
1403 serge 304
 
2997 Serge 305
	if (!hdmi_audio_workaround ||
306
	    r600_hdmi_is_audio_buffer_filled(encoder))
307
		value = 0; /* disable workaround */
308
	else
309
		value = HDMI0_AUDIO_TEST_EN; /* enable workaround */
310
	WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset,
311
		 value, ~HDMI0_AUDIO_TEST_EN);
1403 serge 312
}
313
 
6104 serge 314
void r600_hdmi_audio_set_dto(struct radeon_device *rdev,
7146 serge 315
			     struct radeon_crtc *crtc, unsigned int clock)
3764 Serge 316
{
6104 serge 317
	struct radeon_encoder *radeon_encoder;
318
	struct radeon_encoder_atom_dig *dig;
1403 serge 319
 
6104 serge 320
	if (!crtc)
3764 Serge 321
		return;
322
 
6104 serge 323
	radeon_encoder = to_radeon_encoder(crtc->encoder);
324
	dig = radeon_encoder->enc_priv;
5078 serge 325
 
6104 serge 326
	if (!dig)
327
		return;
328
 
329
	if (dig->dig_encoder == 0) {
330
		WREG32(DCCG_AUDIO_DTO0_PHASE, 24000 * 100);
3764 Serge 331
		WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100);
332
		WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */
333
	} else {
6104 serge 334
		WREG32(DCCG_AUDIO_DTO1_PHASE, 24000 * 100);
335
		WREG32(DCCG_AUDIO_DTO1_MODULE, clock * 100);
336
		WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */
3764 Serge 337
	}
338
}
339
 
6104 serge 340
void r600_set_vbi_packet(struct drm_encoder *encoder, u32 offset)
1403 serge 341
{
342
	struct drm_device *dev = encoder->dev;
343
	struct radeon_device *rdev = dev->dev_private;
344
 
6104 serge 345
	WREG32_OR(HDMI0_VBI_PACKET_CONTROL + offset,
346
		HDMI0_NULL_SEND |	/* send null packets when required */
347
		HDMI0_GC_SEND |		/* send general control packets */
348
		HDMI0_GC_CONT);		/* send general control packets every frame */
349
}
5078 serge 350
 
6104 serge 351
void r600_set_audio_packet(struct drm_encoder *encoder, u32 offset)
352
{
353
	struct drm_device *dev = encoder->dev;
354
	struct radeon_device *rdev = dev->dev_private;
1963 serge 355
 
5078 serge 356
	WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset,
6104 serge 357
		HDMI0_AUDIO_SAMPLE_SEND |			/* send audio packets */
358
		HDMI0_AUDIO_DELAY_EN(1) |			/* default audio delay */
359
		HDMI0_AUDIO_PACKETS_PER_LINE(3) |	/* should be suffient for all audio modes and small enough for all hblanks */
360
		HDMI0_60958_CS_UPDATE,				/* allow 60958 channel status fields to be updated */
361
		~(HDMI0_AUDIO_SAMPLE_SEND |
362
		HDMI0_AUDIO_DELAY_EN_MASK |
363
		HDMI0_AUDIO_PACKETS_PER_LINE_MASK |
364
		HDMI0_60958_CS_UPDATE));
1403 serge 365
 
5078 serge 366
	WREG32_OR(HDMI0_INFOFRAME_CONTROL0 + offset,
6104 serge 367
		HDMI0_AUDIO_INFO_SEND |		/* enable audio info frames (frames won't be set until audio is enabled) */
368
		HDMI0_AUDIO_INFO_UPDATE);	/* required for audio info values to be updated */
2997 Serge 369
 
5078 serge 370
	WREG32_P(HDMI0_INFOFRAME_CONTROL1 + offset,
6104 serge 371
		HDMI0_AUDIO_INFO_LINE(2),	/* anything other than 0 */
372
		~HDMI0_AUDIO_INFO_LINE_MASK);
2997 Serge 373
 
5078 serge 374
	WREG32_AND(HDMI0_GENERIC_PACKET_CONTROL + offset,
6104 serge 375
		~(HDMI0_GENERIC0_SEND |
376
		HDMI0_GENERIC0_CONT |
377
		HDMI0_GENERIC0_UPDATE |
378
		HDMI0_GENERIC1_SEND |
379
		HDMI0_GENERIC1_CONT |
380
		HDMI0_GENERIC0_LINE_MASK |
381
		HDMI0_GENERIC1_LINE_MASK));
5078 serge 382
 
383
	WREG32_P(HDMI0_60958_0 + offset,
6104 serge 384
		HDMI0_60958_CS_CHANNEL_NUMBER_L(1),
385
		~(HDMI0_60958_CS_CHANNEL_NUMBER_L_MASK |
386
		HDMI0_60958_CS_CLOCK_ACCURACY_MASK));
5078 serge 387
 
388
	WREG32_P(HDMI0_60958_1 + offset,
6104 serge 389
		HDMI0_60958_CS_CHANNEL_NUMBER_R(2),
390
		~HDMI0_60958_CS_CHANNEL_NUMBER_R_MASK);
391
}
5078 serge 392
 
6104 serge 393
void r600_set_mute(struct drm_encoder *encoder, u32 offset, bool mute)
394
{
395
	struct drm_device *dev = encoder->dev;
396
	struct radeon_device *rdev = dev->dev_private;
1403 serge 397
 
6104 serge 398
	if (mute)
399
		WREG32_OR(HDMI0_GC + offset, HDMI0_GC_AVMUTE);
400
	else
401
		WREG32_AND(HDMI0_GC + offset, ~HDMI0_GC_AVMUTE);
1403 serge 402
}
403
 
5078 serge 404
/**
405
 * r600_hdmi_update_audio_settings - Update audio infoframe
406
 *
407
 * @encoder: drm encoder
408
 *
409
 * Gets info about current audio stream and updates audio infoframe.
1403 serge 410
 */
1963 serge 411
void r600_hdmi_update_audio_settings(struct drm_encoder *encoder)
1403 serge 412
{
413
	struct drm_device *dev = encoder->dev;
414
	struct radeon_device *rdev = dev->dev_private;
2997 Serge 415
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
416
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
5078 serge 417
	struct r600_audio_pin audio = r600_audio_status(rdev);
3764 Serge 418
	uint8_t buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE];
419
	struct hdmi_audio_infoframe frame;
2997 Serge 420
	uint32_t offset;
5078 serge 421
	uint32_t value;
3764 Serge 422
	ssize_t err;
1403 serge 423
 
2997 Serge 424
	if (!dig->afmt || !dig->afmt->enabled)
1403 serge 425
		return;
2997 Serge 426
	offset = dig->afmt->offset;
1403 serge 427
 
428
	DRM_DEBUG("%s with %d channels, %d Hz sampling rate, %d bits per sample,\n",
429
		 r600_hdmi_is_audio_buffer_filled(encoder) ? "playing" : "stopped",
2997 Serge 430
		  audio.channels, audio.rate, audio.bits_per_sample);
1403 serge 431
	DRM_DEBUG("0x%02X IEC60958 status bits and 0x%02X category code\n",
2997 Serge 432
		  (int)audio.status_bits, (int)audio.category_code);
1403 serge 433
 
3764 Serge 434
	err = hdmi_audio_infoframe_init(&frame);
435
	if (err < 0) {
436
		DRM_ERROR("failed to setup audio infoframe\n");
437
		return;
438
	}
1403 serge 439
 
3764 Serge 440
	frame.channels = audio.channels;
441
 
442
	err = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
443
	if (err < 0) {
444
		DRM_ERROR("failed to pack audio infoframe\n");
445
		return;
446
	}
447
 
5078 serge 448
	value = RREG32(HDMI0_AUDIO_PACKET_CONTROL + offset);
449
	if (value & HDMI0_AUDIO_TEST_EN)
450
		WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset,
451
		       value & ~HDMI0_AUDIO_TEST_EN);
452
 
453
	WREG32_OR(HDMI0_CONTROL + offset,
454
		  HDMI0_ERROR_ACK);
455
 
456
	WREG32_AND(HDMI0_INFOFRAME_CONTROL0 + offset,
457
		   ~HDMI0_AUDIO_INFO_SOURCE);
458
 
3764 Serge 459
	r600_hdmi_update_audio_infoframe(encoder, buffer, sizeof(buffer));
5078 serge 460
 
461
	WREG32_OR(HDMI0_INFOFRAME_CONTROL0 + offset,
462
		  HDMI0_AUDIO_INFO_CONT |
463
		  HDMI0_AUDIO_INFO_UPDATE);
1963 serge 464
}
465
 
1403 serge 466
/*
1963 serge 467
 * enable the HDMI engine
1403 serge 468
 */
3764 Serge 469
void r600_hdmi_enable(struct drm_encoder *encoder, bool enable)
1403 serge 470
{
471
	struct drm_device *dev = encoder->dev;
472
	struct radeon_device *rdev = dev->dev_private;
473
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
2997 Serge 474
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
3764 Serge 475
	u32 hdmi = HDMI0_ERROR_ACK;
1403 serge 476
 
5078 serge 477
	if (!dig || !dig->afmt)
478
		return;
479
 
2997 Serge 480
	/* Older chipsets require setting HDMI and routing manually */
3764 Serge 481
	if (!ASIC_IS_DCE3(rdev)) {
482
		if (enable)
483
			hdmi |= HDMI0_ENABLE;
6104 serge 484
		switch (radeon_encoder->encoder_id) {
485
		case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
3764 Serge 486
			if (enable) {
487
				WREG32_OR(AVIVO_TMDSA_CNTL, AVIVO_TMDSA_CNTL_HDMI_EN);
6104 serge 488
				hdmi |= HDMI0_STREAM(HDMI0_STREAM_TMDSA);
3764 Serge 489
			} else {
490
				WREG32_AND(AVIVO_TMDSA_CNTL, ~AVIVO_TMDSA_CNTL_HDMI_EN);
491
			}
6104 serge 492
			break;
493
		case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
3764 Serge 494
			if (enable) {
495
				WREG32_OR(AVIVO_LVTMA_CNTL, AVIVO_LVTMA_CNTL_HDMI_EN);
6104 serge 496
				hdmi |= HDMI0_STREAM(HDMI0_STREAM_LVTMA);
3764 Serge 497
			} else {
498
				WREG32_AND(AVIVO_LVTMA_CNTL, ~AVIVO_LVTMA_CNTL_HDMI_EN);
499
			}
2997 Serge 500
			break;
501
		case ENCODER_OBJECT_ID_INTERNAL_DDI:
3764 Serge 502
			if (enable) {
503
				WREG32_OR(DDIA_CNTL, DDIA_HDMI_EN);
6104 serge 504
				hdmi |= HDMI0_STREAM(HDMI0_STREAM_DDIA);
3764 Serge 505
			} else {
506
				WREG32_AND(DDIA_CNTL, ~DDIA_HDMI_EN);
507
			}
2997 Serge 508
			break;
509
		case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
3764 Serge 510
			if (enable)
6104 serge 511
				hdmi |= HDMI0_STREAM(HDMI0_STREAM_DVOA);
512
			break;
513
		default:
2997 Serge 514
			dev_err(rdev->dev, "Invalid encoder for HDMI: 0x%X\n",
515
				radeon_encoder->encoder_id);
6104 serge 516
			break;
517
		}
3764 Serge 518
		WREG32(HDMI0_CONTROL + dig->afmt->offset, hdmi);
1963 serge 519
	}
520
 
2997 Serge 521
	if (rdev->irq.installed) {
1963 serge 522
		/* if irq is available use it */
3764 Serge 523
		/* XXX: shouldn't need this on any asics.  Double check DCE2/3 */
524
//       if (enable)
525
//           radeon_irq_kms_enable_afmt(rdev, dig->afmt->id);
526
//       else
527
//           radeon_irq_kms_disable_afmt(rdev, dig->afmt->id);
2997 Serge 528
	}
1963 serge 529
 
3764 Serge 530
	dig->afmt->enabled = enable;
2997 Serge 531
 
3764 Serge 532
	DRM_DEBUG("%sabling HDMI interface @ 0x%04X for encoder 0x%x\n",
533
		  enable ? "En" : "Dis", dig->afmt->offset, radeon_encoder->encoder_id);
1403 serge 534
}
535