]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/gpu/drm/radeon/r600_hdmi.c
Merge tag 'v3.4-rc6' into drm-intel-next
[karo-tx-linux.git] / drivers / gpu / drm / radeon / r600_hdmi.c
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  */
26 #include "drmP.h"
27 #include "radeon_drm.h"
28 #include "radeon.h"
29 #include "radeon_asic.h"
30 #include "r600d.h"
31 #include "atom.h"
32
33 /*
34  * HDMI color format
35  */
36 enum r600_hdmi_color_format {
37         RGB = 0,
38         YCC_422 = 1,
39         YCC_444 = 2
40 };
41
42 /*
43  * IEC60958 status bits
44  */
45 enum r600_hdmi_iec_status_bits {
46         AUDIO_STATUS_DIG_ENABLE   = 0x01,
47         AUDIO_STATUS_V            = 0x02,
48         AUDIO_STATUS_VCFG         = 0x04,
49         AUDIO_STATUS_EMPHASIS     = 0x08,
50         AUDIO_STATUS_COPYRIGHT    = 0x10,
51         AUDIO_STATUS_NONAUDIO     = 0x20,
52         AUDIO_STATUS_PROFESSIONAL = 0x40,
53         AUDIO_STATUS_LEVEL        = 0x80
54 };
55
56 struct {
57         uint32_t Clock;
58
59         int N_32kHz;
60         int CTS_32kHz;
61
62         int N_44_1kHz;
63         int CTS_44_1kHz;
64
65         int N_48kHz;
66         int CTS_48kHz;
67
68 } r600_hdmi_ACR[] = {
69     /*       32kHz        44.1kHz       48kHz    */
70     /* Clock      N     CTS      N     CTS      N     CTS */
71     {  25174,  4576,  28125,  7007,  31250,  6864,  28125 }, /*  25,20/1.001 MHz */
72     {  25200,  4096,  25200,  6272,  28000,  6144,  25200 }, /*  25.20       MHz */
73     {  27000,  4096,  27000,  6272,  30000,  6144,  27000 }, /*  27.00       MHz */
74     {  27027,  4096,  27027,  6272,  30030,  6144,  27027 }, /*  27.00*1.001 MHz */
75     {  54000,  4096,  54000,  6272,  60000,  6144,  54000 }, /*  54.00       MHz */
76     {  54054,  4096,  54054,  6272,  60060,  6144,  54054 }, /*  54.00*1.001 MHz */
77     {  74175, 11648, 210937, 17836, 234375, 11648, 140625 }, /*  74.25/1.001 MHz */
78     {  74250,  4096,  74250,  6272,  82500,  6144,  74250 }, /*  74.25       MHz */
79     { 148351, 11648, 421875,  8918, 234375,  5824, 140625 }, /* 148.50/1.001 MHz */
80     { 148500,  4096, 148500,  6272, 165000,  6144, 148500 }, /* 148.50       MHz */
81     {      0,  4096,      0,  6272,      0,  6144,      0 }  /* Other */
82 };
83
84 /*
85  * calculate CTS value if it's not found in the table
86  */
87 static void r600_hdmi_calc_CTS(uint32_t clock, int *CTS, int N, int freq)
88 {
89         if (*CTS == 0)
90                 *CTS = clock * N / (128 * freq) * 1000;
91         DRM_DEBUG("Using ACR timing N=%d CTS=%d for frequency %d\n",
92                   N, *CTS, freq);
93 }
94
95 /*
96  * update the N and CTS parameters for a given pixel clock rate
97  */
98 static void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock)
99 {
100         struct drm_device *dev = encoder->dev;
101         struct radeon_device *rdev = dev->dev_private;
102         uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
103         int CTS;
104         int N;
105         int i;
106
107         for (i = 0; r600_hdmi_ACR[i].Clock != clock && r600_hdmi_ACR[i].Clock != 0; i++);
108
109         CTS = r600_hdmi_ACR[i].CTS_32kHz;
110         N = r600_hdmi_ACR[i].N_32kHz;
111         r600_hdmi_calc_CTS(clock, &CTS, N, 32000);
112         WREG32(HDMI0_ACR_32_0 + offset, HDMI0_ACR_CTS_32(CTS));
113         WREG32(HDMI0_ACR_32_1 + offset, N);
114
115         CTS = r600_hdmi_ACR[i].CTS_44_1kHz;
116         N = r600_hdmi_ACR[i].N_44_1kHz;
117         r600_hdmi_calc_CTS(clock, &CTS, N, 44100);
118         WREG32(HDMI0_ACR_44_0 + offset, HDMI0_ACR_CTS_44(CTS));
119         WREG32(HDMI0_ACR_44_1 + offset, N);
120
121         CTS = r600_hdmi_ACR[i].CTS_48kHz;
122         N = r600_hdmi_ACR[i].N_48kHz;
123         r600_hdmi_calc_CTS(clock, &CTS, N, 48000);
124         WREG32(HDMI0_ACR_48_0 + offset, HDMI0_ACR_CTS_48(CTS));
125         WREG32(HDMI0_ACR_48_1 + offset, N);
126 }
127
128 /*
129  * calculate the crc for a given info frame
130  */
131 static void r600_hdmi_infoframe_checksum(uint8_t packetType,
132                                          uint8_t versionNumber,
133                                          uint8_t length,
134                                          uint8_t *frame)
135 {
136         int i;
137         frame[0] = packetType + versionNumber + length;
138         for (i = 1; i <= length; i++)
139                 frame[0] += frame[i];
140         frame[0] = 0x100 - frame[0];
141 }
142
143 /*
144  * build a HDMI Video Info Frame
145  */
146 static void r600_hdmi_videoinfoframe(
147         struct drm_encoder *encoder,
148         enum r600_hdmi_color_format color_format,
149         int active_information_present,
150         uint8_t active_format_aspect_ratio,
151         uint8_t scan_information,
152         uint8_t colorimetry,
153         uint8_t ex_colorimetry,
154         uint8_t quantization,
155         int ITC,
156         uint8_t picture_aspect_ratio,
157         uint8_t video_format_identification,
158         uint8_t pixel_repetition,
159         uint8_t non_uniform_picture_scaling,
160         uint8_t bar_info_data_valid,
161         uint16_t top_bar,
162         uint16_t bottom_bar,
163         uint16_t left_bar,
164         uint16_t right_bar
165 )
166 {
167         struct drm_device *dev = encoder->dev;
168         struct radeon_device *rdev = dev->dev_private;
169         uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
170
171         uint8_t frame[14];
172
173         frame[0x0] = 0;
174         frame[0x1] =
175                 (scan_information & 0x3) |
176                 ((bar_info_data_valid & 0x3) << 2) |
177                 ((active_information_present & 0x1) << 4) |
178                 ((color_format & 0x3) << 5);
179         frame[0x2] =
180                 (active_format_aspect_ratio & 0xF) |
181                 ((picture_aspect_ratio & 0x3) << 4) |
182                 ((colorimetry & 0x3) << 6);
183         frame[0x3] =
184                 (non_uniform_picture_scaling & 0x3) |
185                 ((quantization & 0x3) << 2) |
186                 ((ex_colorimetry & 0x7) << 4) |
187                 ((ITC & 0x1) << 7);
188         frame[0x4] = (video_format_identification & 0x7F);
189         frame[0x5] = (pixel_repetition & 0xF);
190         frame[0x6] = (top_bar & 0xFF);
191         frame[0x7] = (top_bar >> 8);
192         frame[0x8] = (bottom_bar & 0xFF);
193         frame[0x9] = (bottom_bar >> 8);
194         frame[0xA] = (left_bar & 0xFF);
195         frame[0xB] = (left_bar >> 8);
196         frame[0xC] = (right_bar & 0xFF);
197         frame[0xD] = (right_bar >> 8);
198
199         r600_hdmi_infoframe_checksum(0x82, 0x02, 0x0D, frame);
200         /* Our header values (type, version, length) should be alright, Intel
201          * is using the same. Checksum function also seems to be OK, it works
202          * fine for audio infoframe. However calculated value is always lower
203          * by 2 in comparison to fglrx. It breaks displaying anything in case
204          * of TVs that strictly check the checksum. Hack it manually here to
205          * workaround this issue. */
206         frame[0x0] += 2;
207
208         WREG32(HDMI0_AVI_INFO0 + offset,
209                 frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
210         WREG32(HDMI0_AVI_INFO1 + offset,
211                 frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x7] << 24));
212         WREG32(HDMI0_AVI_INFO2 + offset,
213                 frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24));
214         WREG32(HDMI0_AVI_INFO3 + offset,
215                 frame[0xC] | (frame[0xD] << 8));
216 }
217
218 /*
219  * build a Audio Info Frame
220  */
221 static void r600_hdmi_audioinfoframe(
222         struct drm_encoder *encoder,
223         uint8_t channel_count,
224         uint8_t coding_type,
225         uint8_t sample_size,
226         uint8_t sample_frequency,
227         uint8_t format,
228         uint8_t channel_allocation,
229         uint8_t level_shift,
230         int downmix_inhibit
231 )
232 {
233         struct drm_device *dev = encoder->dev;
234         struct radeon_device *rdev = dev->dev_private;
235         uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
236
237         uint8_t frame[11];
238
239         frame[0x0] = 0;
240         frame[0x1] = (channel_count & 0x7) | ((coding_type & 0xF) << 4);
241         frame[0x2] = (sample_size & 0x3) | ((sample_frequency & 0x7) << 2);
242         frame[0x3] = format;
243         frame[0x4] = channel_allocation;
244         frame[0x5] = ((level_shift & 0xF) << 3) | ((downmix_inhibit & 0x1) << 7);
245         frame[0x6] = 0;
246         frame[0x7] = 0;
247         frame[0x8] = 0;
248         frame[0x9] = 0;
249         frame[0xA] = 0;
250
251         r600_hdmi_infoframe_checksum(0x84, 0x01, 0x0A, frame);
252
253         WREG32(HDMI0_AUDIO_INFO0 + offset,
254                 frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
255         WREG32(HDMI0_AUDIO_INFO1 + offset,
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  */
262 static int r600_hdmi_is_audio_buffer_filled(struct drm_encoder *encoder)
263 {
264         struct drm_device *dev = encoder->dev;
265         struct radeon_device *rdev = dev->dev_private;
266         uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
267
268         return (RREG32(HDMI0_STATUS + offset) & 0x10) != 0;
269 }
270
271 /*
272  * have buffer status changed since last call?
273  */
274 int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder)
275 {
276         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
277         int status, result;
278
279         if (!radeon_encoder->hdmi_enabled)
280                 return 0;
281
282         status = r600_hdmi_is_audio_buffer_filled(encoder);
283         result = radeon_encoder->hdmi_buffer_status != status;
284         radeon_encoder->hdmi_buffer_status = status;
285
286         return result;
287 }
288
289 /*
290  * write the audio workaround status to the hardware
291  */
292 void r600_hdmi_audio_workaround(struct drm_encoder *encoder)
293 {
294         struct drm_device *dev = encoder->dev;
295         struct radeon_device *rdev = dev->dev_private;
296         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
297         uint32_t offset = radeon_encoder->hdmi_offset;
298
299         if (!radeon_encoder->hdmi_enabled)
300                 return;
301
302         if (!radeon_encoder->hdmi_audio_workaround ||
303                 r600_hdmi_is_audio_buffer_filled(encoder)) {
304
305                 /* disable audio workaround */
306                 WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset, 0x0001, ~0x1001);
307
308         } else {
309                 /* enable audio workaround */
310                 WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset, 0x1001, ~0x1001);
311         }
312 }
313
314
315 /*
316  * update the info frames with the data from the current display mode
317  */
318 void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode)
319 {
320         struct drm_device *dev = encoder->dev;
321         struct radeon_device *rdev = dev->dev_private;
322         uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
323
324         if (ASIC_IS_DCE5(rdev))
325                 return;
326
327         if (!to_radeon_encoder(encoder)->hdmi_enabled)
328                 return;
329
330         r600_audio_set_clock(encoder, mode->clock);
331
332         WREG32(HDMI0_AUDIO_CRC_CONTROL + offset, 0x1000);
333         WREG32(HDMI0_GC + offset, 0x0);
334         WREG32(HDMI0_ACR_PACKET_CONTROL + offset, 0x1000);
335
336         r600_hdmi_update_ACR(encoder, mode->clock);
337
338         WREG32(HDMI0_INFOFRAME_CONTROL0 + offset, 0x13);
339
340         WREG32(HDMI0_INFOFRAME_CONTROL1 + offset, 0x202);
341
342         r600_hdmi_videoinfoframe(encoder, RGB, 0, 0, 0, 0,
343                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
344
345         /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */
346         WREG32(HDMI0_RAMP_CONTROL0 + offset, 0x00FFFFFF);
347         WREG32(HDMI0_RAMP_CONTROL1 + offset, 0x007FFFFF);
348         WREG32(HDMI0_RAMP_CONTROL2 + offset, 0x00000001);
349         WREG32(HDMI0_RAMP_CONTROL3 + offset, 0x00000001);
350
351         r600_hdmi_audio_workaround(encoder);
352
353         /* audio packets per line, does anyone know how to calc this ? */
354         WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset, 0x00040000, ~0x001F0000);
355 }
356
357 /*
358  * update settings with current parameters from audio engine
359  */
360 void r600_hdmi_update_audio_settings(struct drm_encoder *encoder)
361 {
362         struct drm_device *dev = encoder->dev;
363         struct radeon_device *rdev = dev->dev_private;
364         uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
365
366         int channels = r600_audio_channels(rdev);
367         int rate = r600_audio_rate(rdev);
368         int bps = r600_audio_bits_per_sample(rdev);
369         uint8_t status_bits = r600_audio_status_bits(rdev);
370         uint8_t category_code = r600_audio_category_code(rdev);
371
372         uint32_t iec;
373
374         if (!to_radeon_encoder(encoder)->hdmi_enabled)
375                 return;
376
377         DRM_DEBUG("%s with %d channels, %d Hz sampling rate, %d bits per sample,\n",
378                  r600_hdmi_is_audio_buffer_filled(encoder) ? "playing" : "stopped",
379                 channels, rate, bps);
380         DRM_DEBUG("0x%02X IEC60958 status bits and 0x%02X category code\n",
381                   (int)status_bits, (int)category_code);
382
383         iec = 0;
384         if (status_bits & AUDIO_STATUS_PROFESSIONAL)
385                 iec |= 1 << 0;
386         if (status_bits & AUDIO_STATUS_NONAUDIO)
387                 iec |= 1 << 1;
388         if (status_bits & AUDIO_STATUS_COPYRIGHT)
389                 iec |= 1 << 2;
390         if (status_bits & AUDIO_STATUS_EMPHASIS)
391                 iec |= 1 << 3;
392
393         iec |= category_code << 8;
394
395         switch (rate) {
396         case  32000: iec |= 0x3 << 24; break;
397         case  44100: iec |= 0x0 << 24; break;
398         case  88200: iec |= 0x8 << 24; break;
399         case 176400: iec |= 0xc << 24; break;
400         case  48000: iec |= 0x2 << 24; break;
401         case  96000: iec |= 0xa << 24; break;
402         case 192000: iec |= 0xe << 24; break;
403         }
404
405         WREG32(HDMI0_60958_0 + offset, iec);
406
407         iec = 0;
408         switch (bps) {
409         case 16: iec |= 0x2; break;
410         case 20: iec |= 0x3; break;
411         case 24: iec |= 0xb; break;
412         }
413         if (status_bits & AUDIO_STATUS_V)
414                 iec |= 0x5 << 16;
415
416         WREG32_P(HDMI0_60958_1 + offset, iec, ~0x5000f);
417
418         /* 0x021 or 0x031 sets the audio frame length */
419         WREG32(HDMI0_VBI_PACKET_CONTROL + offset, 0x31);
420         r600_hdmi_audioinfoframe(encoder, channels-1, 0, 0, 0, 0, 0, 0, 0);
421
422         r600_hdmi_audio_workaround(encoder);
423 }
424
425 static void r600_hdmi_assign_block(struct drm_encoder *encoder)
426 {
427         struct drm_device *dev = encoder->dev;
428         struct radeon_device *rdev = dev->dev_private;
429         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
430         struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
431
432         u16 eg_offsets[] = {
433                 EVERGREEN_CRTC0_REGISTER_OFFSET,
434                 EVERGREEN_CRTC1_REGISTER_OFFSET,
435                 EVERGREEN_CRTC2_REGISTER_OFFSET,
436                 EVERGREEN_CRTC3_REGISTER_OFFSET,
437                 EVERGREEN_CRTC4_REGISTER_OFFSET,
438                 EVERGREEN_CRTC5_REGISTER_OFFSET,
439         };
440
441         if (!dig) {
442                 dev_err(rdev->dev, "Enabling HDMI on non-dig encoder\n");
443                 return;
444         }
445
446         if (ASIC_IS_DCE5(rdev)) {
447                 /* TODO */
448         } else if (ASIC_IS_DCE4(rdev)) {
449                 if (dig->dig_encoder >= ARRAY_SIZE(eg_offsets)) {
450                         dev_err(rdev->dev, "Enabling HDMI on unknown dig\n");
451                         return;
452                 }
453                 radeon_encoder->hdmi_offset = eg_offsets[dig->dig_encoder];
454                 /* Temp hack for Evergreen until we split r600_hdmi.c
455                  * Evergreen first block is 0x7030 instead of 0x7400.
456                  */
457                 radeon_encoder->hdmi_offset -= 0x3d0;
458         } else if (ASIC_IS_DCE3(rdev)) {
459                 radeon_encoder->hdmi_offset = dig->dig_encoder ?
460                         DCE3_HDMI_OFFSET1 : DCE3_HDMI_OFFSET0;
461         } else if (rdev->family >= CHIP_R600) {
462                 /* 2 routable blocks, but using dig_encoder should be fine */
463                 radeon_encoder->hdmi_offset = dig->dig_encoder ?
464                         DCE2_HDMI_OFFSET1 : DCE2_HDMI_OFFSET0;
465         } else if (rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690 ||
466                    rdev->family == CHIP_RS740) {
467                 /* Only 1 routable block */
468                 radeon_encoder->hdmi_offset = DCE2_HDMI_OFFSET0;
469         }
470         radeon_encoder->hdmi_enabled = true;
471 }
472
473 /*
474  * enable the HDMI engine
475  */
476 void r600_hdmi_enable(struct drm_encoder *encoder)
477 {
478         struct drm_device *dev = encoder->dev;
479         struct radeon_device *rdev = dev->dev_private;
480         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
481         uint32_t offset;
482
483         if (ASIC_IS_DCE5(rdev))
484                 return;
485
486         if (!radeon_encoder->hdmi_enabled) {
487                 r600_hdmi_assign_block(encoder);
488                 if (!radeon_encoder->hdmi_enabled) {
489                         dev_warn(rdev->dev, "Could not find HDMI block for "
490                                 "0x%x encoder\n", radeon_encoder->encoder_id);
491                         return;
492                 }
493         }
494
495         offset = radeon_encoder->hdmi_offset;
496         if (ASIC_IS_DCE5(rdev)) {
497                 /* TODO */
498         } else if (ASIC_IS_DCE4(rdev)) {
499                 WREG32_P(0x74fc + radeon_encoder->hdmi_offset, 0x1, ~0x1);
500         } else if (ASIC_IS_DCE32(rdev)) {
501                 WREG32_P(AFMT_AUDIO_PACKET_CONTROL + radeon_encoder->hdmi_offset, 0x1, ~0x1);
502         } else if (ASIC_IS_DCE3(rdev)) {
503                 /* TODO */
504         } else if (rdev->family >= CHIP_R600) {
505                 switch (radeon_encoder->encoder_id) {
506                 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
507                         WREG32_P(AVIVO_TMDSA_CNTL, AVIVO_TMDSA_CNTL_HDMI_EN,
508                                  ~AVIVO_TMDSA_CNTL_HDMI_EN);
509                         WREG32(HDMI0_CONTROL + offset, 0x101);
510                         break;
511                 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
512                         WREG32_P(AVIVO_LVTMA_CNTL, AVIVO_LVTMA_CNTL_HDMI_EN,
513                                  ~AVIVO_LVTMA_CNTL_HDMI_EN);
514                         WREG32(HDMI0_CONTROL + offset, 0x105);
515                         break;
516                 default:
517                         dev_err(rdev->dev, "Unknown HDMI output type\n");
518                         break;
519                 }
520         }
521
522         if (rdev->irq.installed) {
523                 /* if irq is available use it */
524                 rdev->irq.afmt[offset == 0 ? 0 : 1] = true;
525                 radeon_irq_set(rdev);
526         }
527
528         DRM_DEBUG("Enabling HDMI interface @ 0x%04X for encoder 0x%x\n",
529                 radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
530 }
531
532 /*
533  * disable the HDMI engine
534  */
535 void r600_hdmi_disable(struct drm_encoder *encoder)
536 {
537         struct drm_device *dev = encoder->dev;
538         struct radeon_device *rdev = dev->dev_private;
539         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
540         uint32_t offset;
541
542         if (ASIC_IS_DCE5(rdev))
543                 return;
544
545         offset = radeon_encoder->hdmi_offset;
546         if (!radeon_encoder->hdmi_enabled) {
547                 dev_err(rdev->dev, "Disabling not enabled HDMI\n");
548                 return;
549         }
550
551         DRM_DEBUG("Disabling HDMI interface @ 0x%04X for encoder 0x%x\n",
552                 offset, radeon_encoder->encoder_id);
553
554         /* disable irq */
555         rdev->irq.afmt[offset == 0 ? 0 : 1] = false;
556         radeon_irq_set(rdev);
557
558
559         if (ASIC_IS_DCE5(rdev)) {
560                 /* TODO */
561         } else if (ASIC_IS_DCE4(rdev)) {
562                 WREG32_P(0x74fc + radeon_encoder->hdmi_offset, 0, ~0x1);
563         } else if (ASIC_IS_DCE32(rdev)) {
564                 WREG32_P(AFMT_AUDIO_PACKET_CONTROL + radeon_encoder->hdmi_offset, 0, ~0x1);
565         } else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
566                 switch (radeon_encoder->encoder_id) {
567                 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
568                         WREG32_P(AVIVO_TMDSA_CNTL, 0,
569                                  ~AVIVO_TMDSA_CNTL_HDMI_EN);
570                         WREG32(HDMI0_CONTROL + offset, 0);
571                         break;
572                 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
573                         WREG32_P(AVIVO_LVTMA_CNTL, 0,
574                                  ~AVIVO_LVTMA_CNTL_HDMI_EN);
575                         WREG32(HDMI0_CONTROL + offset, 0);
576                         break;
577                 default:
578                         dev_err(rdev->dev, "Unknown HDMI output type\n");
579                         break;
580                 }
581         }
582
583         radeon_encoder->hdmi_enabled = false;
584         radeon_encoder->hdmi_offset = 0;
585 }